[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Attached are the patches for new ioemu communication mechanism. The new
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 0c0d929e787c0848ba26168cd0fbebb6dad2aaf2 # Parent 0746ef61733bffaccba394c191d7617ea2a67600 Attached are the patches for new ioemu communication mechanism. The new mechanism provides richer I/O operation semantics, such as and,or,xor operation on MMIO space. This is necessary for operating systems such as Windows XP and Windows 2003. This is the first part of a two part patch. This patch applies to ioemu. Signed-Off-By: Leendert van Doorn <leendert@xxxxxxxxxxxxxx> diff -r 0746ef61733b -r 0c0d929e787c tools/ioemu/exec.c --- a/tools/ioemu/exec.c Fri Sep 2 17:54:53 2005 +++ b/tools/ioemu/exec.c Fri Sep 2 17:55:24 2005 @@ -142,6 +142,10 @@ #else setvbuf(logfile, NULL, _IOLBF, 0); #endif +/* + stdout = logfile; + stderr = logfile; +*/ } } @@ -386,9 +390,6 @@ io_mem_write[io_index][1](io_mem_opaque[io_index], addr, val); l = 2; } else { - if (l!=1){ - fprintf(logfile, "ERROR 8 bit mmio\n"); - } /* 8 bit access */ val = ldub_raw(buf); io_mem_write[io_index][0](io_mem_opaque[io_index], addr, val); diff -r 0746ef61733b -r 0c0d929e787c tools/ioemu/target-i386-dm/helper2.c --- a/tools/ioemu/target-i386-dm/helper2.c Fri Sep 2 17:54:53 2005 +++ b/tools/ioemu/target-i386-dm/helper2.c Fri Sep 2 17:55:24 2005 @@ -169,133 +169,217 @@ unsigned long do_inp(CPUState *env, unsigned long addr, unsigned long size) { - switch(size) { - case 1: - return cpu_inb(env, addr); - case 2: - return cpu_inw(env, addr); - case 4: - return cpu_inl(env, addr); - default: - fprintf(logfile, "inp: bad size: %lx %lx\n", addr, size); - exit(-1); - } + switch(size) { + case 1: + return cpu_inb(env, addr); + case 2: + return cpu_inw(env, addr); + case 4: + return cpu_inl(env, addr); + default: + fprintf(logfile, "inp: bad size: %lx %lx\n", addr, size); + exit(-1); + } } void do_outp(CPUState *env, unsigned long addr, unsigned long size, unsigned long val) { - switch(size) { - case 1: - return cpu_outb(env, addr, val); - case 2: - return cpu_outw(env, addr, val); - case 4: - return cpu_outl(env, addr, val); - default: - fprintf(logfile, "outp: bad size: %lx %lx\n", addr, size); - exit(-1); - } + switch(size) { + case 1: + return cpu_outb(env, addr, val); + case 2: + return cpu_outw(env, addr, val); + case 4: + return cpu_outl(env, addr, val); + default: + fprintf(logfile, "outp: bad size: %lx %lx\n", addr, size); + exit(-1); + } } extern void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, int len, int is_write); static inline void -read_physical(target_phys_addr_t addr, unsigned long size, void *val) -{ - return cpu_physical_memory_rw(addr, val, size, 0); +read_physical(u64 addr, unsigned long size, void *val) +{ + return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0); } static inline void -write_physical(target_phys_addr_t addr, unsigned long size, void *val) -{ - return cpu_physical_memory_rw(addr, val, size, 1); -} - -//send the ioreq to device model -void cpu_dispatch_ioreq(CPUState *env, ioreq_t *req) -{ - int i; - int sign; - - sign = (req->df) ? -1 : 1; - - if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) { - if (req->size != 4) { - // Bochs expects higher bits to be 0 - req->u.data &= (1UL << (8 * req->size))-1; - } - } - - if (req->port_mm == 0){//port io - if(req->dir == IOREQ_READ){//read - if (!req->pdata_valid) { - req->u.data = do_inp(env, req->addr, req->size); - } else { - unsigned long tmp; - - for (i = 0; i < req->count; i++) { - tmp = do_inp(env, req->addr, req->size); - write_physical((target_phys_addr_t)req->u.pdata + (sign * i * req->size), - req->size, &tmp); - } - } - } else if(req->dir == IOREQ_WRITE) { - if (!req->pdata_valid) { - do_outp(env, req->addr, req->size, req->u.data); - } else { - for (i = 0; i < req->count; i++) { - unsigned long tmp; - - read_physical((target_phys_addr_t)req->u.pdata + (sign * i * req->size), req->size, - &tmp); - do_outp(env, req->addr, req->size, tmp); - } - } - - } - } else if (req->port_mm == 1){//memory map io +write_physical(u64 addr, unsigned long size, void *val) +{ + return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1); +} + +void +cpu_ioreq_pio(CPUState *env, ioreq_t *req) +{ + int i, sign; + + sign = req->df ? -1 : 1; + + if (req->dir == IOREQ_READ) { if (!req->pdata_valid) { - //handle stos - if(req->dir == IOREQ_READ) { //read - for (i = 0; i < req->count; i++) { - read_physical((target_phys_addr_t)req->addr + (sign * i * req->size), req->size, &req->u.data); - } - } else if(req->dir == IOREQ_WRITE) { //write - for (i = 0; i < req->count; i++) { - write_physical((target_phys_addr_t)req->addr + (sign * i * req->size), req->size, &req->u.data); - } - } + req->u.data = do_inp(env, req->addr, req->size); } else { - //handle movs - unsigned long tmp; - if (req->dir == IOREQ_READ) { - for (i = 0; i < req->count; i++) { - read_physical((target_phys_addr_t)req->addr + (sign * i * req->size), req->size, &tmp); - write_physical((target_phys_addr_t)req->u.pdata + (sign * i * req->size), req->size, &tmp); - } - } else if (req->dir == IOREQ_WRITE) { - for (i = 0; i < req->count; i++) { - read_physical((target_phys_addr_t)req->u.pdata + (sign * i * req->size), req->size, &tmp); - write_physical((target_phys_addr_t)req->addr + (sign * i * req->size), req->size, &tmp); - } - } - } - } - /* No state change if state = STATE_IORESP_HOOK */ - if (req->state == STATE_IOREQ_INPROCESS) - req->state = STATE_IORESP_READY; - env->send_event = 1; + unsigned long tmp; + + for (i = 0; i < req->count; i++) { + tmp = do_inp(env, req->addr, req->size); + write_physical((target_phys_addr_t) req->u.pdata + + (sign * i * req->size), + req->size, &tmp); + } + } + } else if (req->dir == IOREQ_WRITE) { + if (!req->pdata_valid) { + do_outp(env, req->addr, req->size, req->u.data); + } else { + for (i = 0; i < req->count; i++) { + unsigned long tmp; + + read_physical((target_phys_addr_t) req->u.pdata + + (sign * i * req->size), + req->size, &tmp); + do_outp(env, req->addr, req->size, tmp); + } + } + } +} + +void +cpu_ioreq_move(CPUState *env, ioreq_t *req) +{ + int i, sign; + + sign = req->df ? -1 : 1; + + if (!req->pdata_valid) { + if (req->dir == IOREQ_READ) { + for (i = 0; i < req->count; i++) { + read_physical(req->addr + + (sign * i * req->size), + req->size, &req->u.data); + } + } else if (req->dir == IOREQ_WRITE) { + for (i = 0; i < req->count; i++) { + write_physical(req->addr + + (sign * i * req->size), + req->size, &req->u.data); + } + } + } else { + unsigned long tmp; + + if (req->dir == IOREQ_READ) { + for (i = 0; i < req->count; i++) { + read_physical(req->addr + + (sign * i * req->size), + req->size, &tmp); + write_physical((target_phys_addr_t )req->u.pdata + + (sign * i * req->size), + req->size, &tmp); + } + } else if (req->dir == IOREQ_WRITE) { + for (i = 0; i < req->count; i++) { + read_physical((target_phys_addr_t) req->u.pdata + + (sign * i * req->size), + req->size, &tmp); + write_physical(req->addr + + (sign * i * req->size), + req->size, &tmp); + } + } + } +} + +void +cpu_ioreq_and(CPUState *env, ioreq_t *req) +{ + unsigned long tmp1, tmp2; + + if (req->pdata_valid != 0) + hw_error("expected scalar value"); + + read_physical(req->addr, req->size, &tmp1); + if (req->dir == IOREQ_WRITE) { + tmp2 = tmp1 & (unsigned long) req->u.data; + write_physical(req->addr, req->size, &tmp2); + } + req->u.data = tmp1; +} + +void +cpu_ioreq_or(CPUState *env, ioreq_t *req) +{ + unsigned long tmp1, tmp2; + + if (req->pdata_valid != 0) + hw_error("expected scalar value"); + + read_physical(req->addr, req->size, &tmp1); + if (req->dir == IOREQ_WRITE) { + tmp2 = tmp1 | (unsigned long) req->u.data; + write_physical(req->addr, req->size, &tmp2); + } + req->u.data = tmp1; +} + +void +cpu_ioreq_xor(CPUState *env, ioreq_t *req) +{ + unsigned long tmp1, tmp2; + + if (req->pdata_valid != 0) + hw_error("expected scalar value"); + + read_physical(req->addr, req->size, &tmp1); + if (req->dir == IOREQ_WRITE) { + tmp2 = tmp1 ^ (unsigned long) req->u.data; + write_physical(req->addr, req->size, &tmp2); + } + req->u.data = tmp1; } void cpu_handle_ioreq(CPUState *env) { ioreq_t *req = cpu_get_ioreq(); - if (req) - cpu_dispatch_ioreq(env, req); + + if (req) { + if ((!req->pdata_valid) && (req->dir == IOREQ_WRITE)) { + if (req->size != 4) + req->u.data &= (1UL << (8 * req->size))-1; + } + + switch (req->type) { + case IOREQ_TYPE_PIO: + cpu_ioreq_pio(env, req); + break; + case IOREQ_TYPE_COPY: + cpu_ioreq_move(env, req); + break; + case IOREQ_TYPE_AND: + cpu_ioreq_and(env, req); + break; + case IOREQ_TYPE_OR: + cpu_ioreq_or(env, req); + break; + case IOREQ_TYPE_XOR: + cpu_ioreq_xor(env, req); + break; + default: + hw_error("Invalid ioreq type 0x%x", req->type); + } + + /* No state change if state = STATE_IORESP_HOOK */ + if (req->state == STATE_IOREQ_INPROCESS) + req->state = STATE_IORESP_READY; + env->send_event = 1; + } } void @@ -321,7 +405,7 @@ // Send a message on the event channel. Add the vector to the shared mem // page. - intr = &(shared_page->sp_global.pic_intr[0]); + intr = (unsigned long *) &(shared_page->sp_global.pic_intr[0]); atomic_set_bit(vector, intr); if (loglevel & CPU_LOG_INT) fprintf(logfile, "injecting vector: %x\n", vector); diff -r 0746ef61733b -r 0c0d929e787c tools/ioemu/vl.c --- a/tools/ioemu/vl.c Fri Sep 2 17:54:53 2005 +++ b/tools/ioemu/vl.c Fri Sep 2 17:55:24 2005 @@ -413,6 +413,11 @@ fprintf(stderr, "qemu: hardware error: "); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n"); + if (logfile) { + fprintf(logfile, "qemu: hardware error: "); + vfprintf(logfile, fmt, ap); + fprintf(logfile, "\n"); + } va_end(ap); abort(); } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |