Transition the core i/o bits away from a couple of flat arrays to use a structure naming the read/write callbacks. For now, retain the flat array interface for the drivers.
Signed-off-by: Richard Henderson <r...@twiddle.net> --- cpu-common.h | 14 ++- exec-all.h | 3 +- exec.c | 321 ++++++++++++++++++++++++++------------------------- softmmu_template.h | 36 ++++-- 4 files changed, 203 insertions(+), 171 deletions(-) diff --git a/cpu-common.h b/cpu-common.h index b730ca0..0566654 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -25,8 +25,17 @@ typedef unsigned long ram_addr_t; /* memory API */ -typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value); -typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr); +typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t, uint32_t); +typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t); + +typedef struct CPUIOMemoryOps { + CPUReadMemoryFunc *readb; + CPUReadMemoryFunc *readw; + CPUReadMemoryFunc *readl; + CPUWriteMemoryFunc *writeb; + CPUWriteMemoryFunc *writew; + CPUWriteMemoryFunc *writel; +} CPUIOMemoryOps; void cpu_register_physical_memory_offset(target_phys_addr_t start_addr, ram_addr_t size, @@ -47,6 +56,7 @@ void *qemu_get_ram_ptr(ram_addr_t addr); /* This should not be used by devices. */ ram_addr_t qemu_ram_addr_from_host(void *ptr); +int cpu_register_io_memory_st(const CPUIOMemoryOps *mem_ops, void *opaque); int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read, CPUWriteMemoryFunc * const *mem_write, void *opaque); diff --git a/exec-all.h b/exec-all.h index 4bae1e2..5007d59 100644 --- a/exec-all.h +++ b/exec-all.h @@ -267,8 +267,7 @@ extern int tb_invalidated_flag; #if !defined(CONFIG_USER_ONLY) -extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; -extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; +extern CPUIOMemoryOps io_mem_ops[IO_MEM_NB_ENTRIES]; extern void *io_mem_opaque[IO_MEM_NB_ENTRIES]; void tlb_fill(target_ulong addr, int is_write, int mmu_idx, diff --git a/exec.c b/exec.c index 43366ac..d8691c9 100644 --- a/exec.c +++ b/exec.c @@ -215,8 +215,7 @@ static void *l1_phys_map[P_L1_SIZE]; static void io_mem_init(void); /* io memory support */ -CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; -CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4]; +CPUIOMemoryOps io_mem_ops[IO_MEM_NB_ENTRIES]; void *io_mem_opaque[IO_MEM_NB_ENTRIES]; static char io_mem_used[IO_MEM_NB_ENTRIES]; static int io_mem_watch; @@ -2549,10 +2548,9 @@ static inline void tlb_set_dirty(CPUState *env, #define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK) typedef struct subpage_t { target_phys_addr_t base; - CPUReadMemoryFunc * const *mem_read[TARGET_PAGE_SIZE][4]; - CPUWriteMemoryFunc * const *mem_write[TARGET_PAGE_SIZE][4]; - void *opaque[TARGET_PAGE_SIZE][2][4]; - ram_addr_t region_offset[TARGET_PAGE_SIZE][2][4]; + CPUIOMemoryOps mem_ops[TARGET_PAGE_SIZE]; + void *opaque[TARGET_PAGE_SIZE]; + ram_addr_t region_offset[TARGET_PAGE_SIZE]; } subpage_t; static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, @@ -2962,16 +2960,20 @@ static void unassigned_mem_writel(void *opaque, target_phys_addr_t addr, uint32_ #endif } -static CPUReadMemoryFunc * const unassigned_mem_read[3] = { - unassigned_mem_readb, - unassigned_mem_readw, - unassigned_mem_readl, +static const CPUIOMemoryOps unassigned_mem_ops = { + .readb = unassigned_mem_readb, + .readw = unassigned_mem_readw, + .readl = unassigned_mem_readl, + .writeb = unassigned_mem_writeb, + .writew = unassigned_mem_writew, + .writel = unassigned_mem_writel, }; -static CPUWriteMemoryFunc * const unassigned_mem_write[3] = { - unassigned_mem_writeb, - unassigned_mem_writew, - unassigned_mem_writel, +static const CPUIOMemoryOps rom_mem_ops = { + /* Read functions never used. */ + .writeb = unassigned_mem_writeb, + .writew = unassigned_mem_writew, + .writel = unassigned_mem_writel, }; static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr, @@ -3034,16 +3036,11 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr, tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr); } -static CPUReadMemoryFunc * const error_mem_read[3] = { - NULL, /* never used */ - NULL, /* never used */ - NULL, /* never used */ -}; - -static CPUWriteMemoryFunc * const notdirty_mem_write[3] = { - notdirty_mem_writeb, - notdirty_mem_writew, - notdirty_mem_writel, +static const CPUIOMemoryOps notdirty_mem_ops = { + /* Read functions never used. */ + .writeb = notdirty_mem_writeb, + .writew = notdirty_mem_writew, + .writel = notdirty_mem_writel, }; /* Generate a debug exception if a watchpoint has been hit. */ @@ -3133,121 +3130,115 @@ static void watch_mem_writel(void *opaque, target_phys_addr_t addr, stl_phys(addr, val); } -static CPUReadMemoryFunc * const watch_mem_read[3] = { - watch_mem_readb, - watch_mem_readw, - watch_mem_readl, -}; - -static CPUWriteMemoryFunc * const watch_mem_write[3] = { - watch_mem_writeb, - watch_mem_writew, - watch_mem_writel, +static const CPUIOMemoryOps watch_mem_ops = { + .readb = watch_mem_readb, + .readw = watch_mem_readw, + .readl = watch_mem_readl, + .writeb = watch_mem_writeb, + .writew = watch_mem_writew, + .writel = watch_mem_writel, }; -static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t addr, - unsigned int len) -{ - uint32_t ret; - unsigned int idx; - - idx = SUBPAGE_IDX(addr); -#if defined(DEBUG_SUBPAGE) - printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__, - mmio, len, addr, idx); -#endif - ret = (**mmio->mem_read[idx][len])(mmio->opaque[idx][0][len], - addr + mmio->region_offset[idx][0][len]); - - return ret; -} - -static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr, - uint32_t value, unsigned int len) -{ - unsigned int idx; - - idx = SUBPAGE_IDX(addr); -#if defined(DEBUG_SUBPAGE) - printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value %08x\n", __func__, - mmio, len, addr, idx, value); -#endif - (**mmio->mem_write[idx][len])(mmio->opaque[idx][1][len], - addr + mmio->region_offset[idx][1][len], - value); -} - static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr) { + subpage_t *mmio = opaque; + unsigned int idx = SUBPAGE_IDX(addr); + #if defined(DEBUG_SUBPAGE) - printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr); + printf("%s: subpage %p addr " TARGET_FMT_plx " idx %d\n", + __func__, mmio, addr, idx); #endif - - return subpage_readlen(opaque, addr, 0); + + return mmio->mem_ops[idx].readb(mmio->opaque[idx], + addr + mmio->region_offset[idx]); } static void subpage_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) { + subpage_t *mmio = opaque; + unsigned int idx = SUBPAGE_IDX(addr); + #if defined(DEBUG_SUBPAGE) - printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value); + printf("%s: subpage %p addr " TARGET_FMT_plx " idx %d\n", + __func__, mmio, addr, idx); #endif - subpage_writelen(opaque, addr, value, 0); + + return mmio->mem_ops[idx].writeb(mmio->opaque[idx], + addr + mmio->region_offset[idx], value); } static uint32_t subpage_readw (void *opaque, target_phys_addr_t addr) { + subpage_t *mmio = opaque; + unsigned int idx = SUBPAGE_IDX(addr); + #if defined(DEBUG_SUBPAGE) - printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr); + printf("%s: subpage %p addr " TARGET_FMT_plx " idx %d\n", + __func__, mmio, addr, idx); #endif - - return subpage_readlen(opaque, addr, 1); + + return mmio->mem_ops[idx].readw(mmio->opaque[idx], + addr + mmio->region_offset[idx]); } static void subpage_writew (void *opaque, target_phys_addr_t addr, uint32_t value) { + subpage_t *mmio = opaque; + unsigned int idx = SUBPAGE_IDX(addr); + #if defined(DEBUG_SUBPAGE) - printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value); + printf("%s: subpage %p addr " TARGET_FMT_plx " idx %d\n", + __func__, mmio, addr, idx); #endif - subpage_writelen(opaque, addr, value, 1); + + return mmio->mem_ops[idx].writew(mmio->opaque[idx], + addr + mmio->region_offset[idx], value); } static uint32_t subpage_readl (void *opaque, target_phys_addr_t addr) { + subpage_t *mmio = opaque; + unsigned int idx = SUBPAGE_IDX(addr); + #if defined(DEBUG_SUBPAGE) - printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr); + printf("%s: subpage %p addr " TARGET_FMT_plx " idx %d\n", + __func__, mmio, addr, idx); #endif - - return subpage_readlen(opaque, addr, 2); + + return mmio->mem_ops[idx].readl(mmio->opaque[idx], + addr + mmio->region_offset[idx]); } static void subpage_writel (void *opaque, target_phys_addr_t addr, uint32_t value) { + subpage_t *mmio = opaque; + unsigned int idx = SUBPAGE_IDX(addr); + #if defined(DEBUG_SUBPAGE) - printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value); + printf("%s: subpage %p addr " TARGET_FMT_plx " idx %d\n", + __func__, mmio, addr, idx); #endif - subpage_writelen(opaque, addr, value, 2); -} -static CPUReadMemoryFunc * const subpage_read[] = { - &subpage_readb, - &subpage_readw, - &subpage_readl, -}; + return mmio->mem_ops[idx].writel(mmio->opaque[idx], + addr + mmio->region_offset[idx], value); +} -static CPUWriteMemoryFunc * const subpage_write[] = { - &subpage_writeb, - &subpage_writew, - &subpage_writel, +static const CPUIOMemoryOps subpage_ops = { + .readb = subpage_readb, + .readw = subpage_readw, + .readl = subpage_readl, + .writeb = subpage_writeb, + .writew = subpage_writew, + .writel = subpage_writel, }; static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, ram_addr_t memory, ram_addr_t region_offset) { int idx, eidx; - unsigned int i; if (start >= TARGET_PAGE_SIZE || end >= TARGET_PAGE_SIZE) return -1; @@ -3258,19 +3249,11 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end, mmio, start, end, idx, eidx, memory); #endif memory >>= IO_MEM_SHIFT; + for (; idx <= eidx; idx++) { - for (i = 0; i < 4; i++) { - if (io_mem_read[memory][i]) { - mmio->mem_read[idx][i] = &io_mem_read[memory][i]; - mmio->opaque[idx][0][i] = io_mem_opaque[memory]; - mmio->region_offset[idx][0][i] = region_offset; - } - if (io_mem_write[memory][i]) { - mmio->mem_write[idx][i] = &io_mem_write[memory][i]; - mmio->opaque[idx][1][i] = io_mem_opaque[memory]; - mmio->region_offset[idx][1][i] = region_offset; - } - } + mmio->mem_ops[idx] = io_mem_ops[memory]; + mmio->opaque[idx] = io_mem_opaque[memory]; + mmio->region_offset[idx] = region_offset; } return 0; @@ -3285,7 +3268,7 @@ static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys, mmio = qemu_mallocz(sizeof(subpage_t)); mmio->base = base; - subpage_memory = cpu_register_io_memory(subpage_read, subpage_write, mmio); + subpage_memory = cpu_register_io_memory_st(&subpage_ops, mmio); #if defined(DEBUG_SUBPAGE) printf("%s: %p base " TARGET_FMT_plx " len %08x %d\n", __func__, mmio, base, TARGET_PAGE_SIZE, subpage_memory); @@ -3310,19 +3293,17 @@ static int get_free_io_mem_idx(void) return -1; } -/* mem_read and mem_write are arrays of functions containing the - function to access byte (index 0), word (index 1) and dword (index - 2). Functions can be omitted with a NULL function pointer. - If io_index is non zero, the corresponding io zone is - modified. If it is zero, a new io zone is allocated. The return - value can be used with cpu_register_physical_memory(). (-1) is - returned if error. */ +/* MEM_OPS contains pointers to the functions giving sized acceses to + the I/O. Access functions may be omitted with a NULL function pointer. + If IO_INDEX is non zero, the corresponding io zone is modified. If it + is zero, a new io zone is allocated. The return value can be used with + cpu_register_physical_memory(); -1 is returned if error. */ + static int cpu_register_io_memory_fixed(int io_index, - CPUReadMemoryFunc * const *mem_read, - CPUWriteMemoryFunc * const *mem_write, + const CPUIOMemoryOps *mem_ops, void *opaque) { - int i, subwidth = 0; + int subwidth = 0; if (io_index <= 0) { io_index = get_free_io_mem_idx(); @@ -3334,32 +3315,45 @@ static int cpu_register_io_memory_fixed(int io_index, return -1; } - for(i = 0;i < 3; i++) { - if (!mem_read[i] || !mem_write[i]) - subwidth = IO_MEM_SUBWIDTH; - io_mem_read[io_index][i] = mem_read[i]; - io_mem_write[io_index][i] = mem_write[i]; - } + io_mem_ops[io_index] = *mem_ops; io_mem_opaque[io_index] = opaque; + + if (!mem_ops->readl || !mem_ops->writel + || !mem_ops->readw || !mem_ops->writew + || !mem_ops->readb || !mem_ops->writeb) { + subwidth = IO_MEM_SUBWIDTH; + } + return (io_index << IO_MEM_SHIFT) | subwidth; } +int cpu_register_io_memory_st(const CPUIOMemoryOps *mem_ops, void *opaque) +{ + return cpu_register_io_memory_fixed(0, mem_ops, opaque); +} + +/* Temporarily leave the existing array-based interface in place while + drivers are updated. */ int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read, CPUWriteMemoryFunc * const *mem_write, void *opaque) { - return cpu_register_io_memory_fixed(0, mem_read, mem_write, opaque); + CPUIOMemoryOps ops; + ops.readb = mem_read[0]; + ops.readw = mem_read[1]; + ops.readl = mem_read[2]; + ops.writeb = mem_write[0]; + ops.writew = mem_write[1]; + ops.writel = mem_write[2]; + + return cpu_register_io_memory_fixed(0, &ops, opaque); } void cpu_unregister_io_memory(int io_table_address) { - int i; int io_index = io_table_address >> IO_MEM_SHIFT; - for (i=0;i < 3; i++) { - io_mem_read[io_index][i] = unassigned_mem_read[i]; - io_mem_write[io_index][i] = unassigned_mem_write[i]; - } + io_mem_ops[io_index] = unassigned_mem_ops; io_mem_opaque[io_index] = NULL; io_mem_used[io_index] = 0; } @@ -3368,14 +3362,14 @@ static void io_mem_init(void) { int i; - cpu_register_io_memory_fixed(IO_MEM_ROM, error_mem_read, unassigned_mem_write, NULL); - cpu_register_io_memory_fixed(IO_MEM_UNASSIGNED, unassigned_mem_read, unassigned_mem_write, NULL); - cpu_register_io_memory_fixed(IO_MEM_NOTDIRTY, error_mem_read, notdirty_mem_write, NULL); - for (i=0; i<5; i++) + cpu_register_io_memory_fixed(IO_MEM_ROM, &rom_mem_ops, NULL); + cpu_register_io_memory_fixed(IO_MEM_UNASSIGNED, &unassigned_mem_ops, NULL); + cpu_register_io_memory_fixed(IO_MEM_NOTDIRTY, ¬dirty_mem_ops, NULL); + for (i=0; i<5; i++) { io_mem_used[i] = 1; + } - io_mem_watch = cpu_register_io_memory(watch_mem_read, - watch_mem_write, NULL); + io_mem_watch = cpu_register_io_memory_st(&watch_mem_ops, NULL); } #endif /* !defined(CONFIG_USER_ONLY) */ @@ -3425,7 +3419,7 @@ int cpu_memory_rw_debug(CPUState *env, target_ulong addr, void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, int len, int is_write) { - int l, io_index; + int l; uint8_t *ptr; uint32_t val; target_phys_addr_t page; @@ -3447,7 +3441,8 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, if (is_write) { if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { target_phys_addr_t addr1 = addr; - io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); + int io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); + void *opaque = io_mem_opaque[io_index]; if (p) addr1 = (addr & ~TARGET_PAGE_MASK) + p->region_offset; /* XXX: could force cpu_single_env to NULL to avoid @@ -3455,17 +3450,17 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, if (l >= 4 && ((addr1 & 3) == 0)) { /* 32 bit write access */ val = ldl_p(buf); - io_mem_write[io_index][2](io_mem_opaque[io_index], addr1, val); + io_mem_ops[io_index].writel(opaque, addr1, val); l = 4; } else if (l >= 2 && ((addr1 & 1) == 0)) { /* 16 bit write access */ val = lduw_p(buf); - io_mem_write[io_index][1](io_mem_opaque[io_index], addr1, val); + io_mem_ops[io_index].writew(opaque, addr1, val); l = 2; } else { /* 8 bit write access */ val = ldub_p(buf); - io_mem_write[io_index][0](io_mem_opaque[io_index], addr1, val); + io_mem_ops[io_index].writeb(opaque, addr1, val); l = 1; } } else { @@ -3487,22 +3482,23 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, !(pd & IO_MEM_ROMD)) { target_phys_addr_t addr1 = addr; /* I/O case */ - io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); + int io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); + void *opaque = io_mem_opaque[io_index]; if (p) addr1 = (addr & ~TARGET_PAGE_MASK) + p->region_offset; if (l >= 4 && ((addr1 & 3) == 0)) { /* 32 bit read access */ - val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr1); + val = io_mem_ops[io_index].readl(opaque, addr1); stl_p(buf, val); l = 4; } else if (l >= 2 && ((addr1 & 1) == 0)) { /* 16 bit read access */ - val = io_mem_read[io_index][1](io_mem_opaque[io_index], addr1); + val = io_mem_ops[io_index].readw(opaque, addr1); stw_p(buf, val); l = 2; } else { /* 8 bit read access */ - val = io_mem_read[io_index][0](io_mem_opaque[io_index], addr1); + val = io_mem_ops[io_index].readb(opaque, addr1); stb_p(buf, val); l = 1; } @@ -3724,7 +3720,7 @@ uint32_t ldl_phys(target_phys_addr_t addr) io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; - val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr); + val = io_mem_ops[io_index].readl(io_mem_opaque[io_index], addr); } else { /* RAM case */ ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + @@ -3737,7 +3733,6 @@ uint32_t ldl_phys(target_phys_addr_t addr) /* warning: addr must be aligned */ uint64_t ldq_phys(target_phys_addr_t addr) { - int io_index; uint8_t *ptr; uint64_t val; unsigned long pd; @@ -3753,15 +3748,22 @@ uint64_t ldq_phys(target_phys_addr_t addr) if ((pd & ~TARGET_PAGE_MASK) > IO_MEM_ROM && !(pd & IO_MEM_ROMD)) { /* I/O case */ - io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); + int io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); + void *opaque = io_mem_opaque[io_index]; + CPUReadMemoryFunc *readl; + uint32_t v1, v2; + if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; + + readl = io_mem_ops[io_index].readl; + v1 = readl(opaque, addr); + v2 = readl(opaque, addr + 4); + #ifdef TARGET_WORDS_BIGENDIAN - val = (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr) << 32; - val |= io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4); + val = ((uint64_t)v1 << 32) | v2; #else - val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr); - val |= (uint64_t)io_mem_read[io_index][2](io_mem_opaque[io_index], addr + 4) << 32; + val = ((uint64_t)v2 << 32) | v1; #endif } else { /* RAM case */ @@ -3809,7 +3811,7 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val) io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; - io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val); + io_mem_ops[io_index].writel(io_mem_opaque[io_index], addr, val); } else { unsigned long addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); ptr = qemu_get_ram_ptr(addr1); @@ -3829,7 +3831,6 @@ void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val) void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val) { - int io_index; uint8_t *ptr; unsigned long pd; PhysPageDesc *p; @@ -3842,16 +3843,22 @@ void stq_phys_notdirty(target_phys_addr_t addr, uint64_t val) } if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) { - io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); + int io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); + void *opaque = io_mem_opaque[io_index]; + CPUWriteMemoryFunc *writel; + uint32_t v1, v2; + if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; #ifdef TARGET_WORDS_BIGENDIAN - io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val >> 32); - io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val); + v1 = val >> 32, v2 = val; #else - io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val); - io_mem_write[io_index][2](io_mem_opaque[io_index], addr + 4, val >> 32); + v1 = val, v2 = val >> 32; #endif + writel = io_mem_ops[io_index].writel; + + writel(opaque, addr, v1); + writel(opaque, addr + 4, v2); } else { ptr = qemu_get_ram_ptr(pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); @@ -3878,7 +3885,7 @@ void stl_phys(target_phys_addr_t addr, uint32_t val) io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); if (p) addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset; - io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val); + io_mem_ops[io_index].writel(io_mem_opaque[io_index], addr, val); } else { unsigned long addr1; addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); diff --git a/softmmu_template.h b/softmmu_template.h index c2df9ec..27e23c9 100644 --- a/softmmu_template.h +++ b/softmmu_template.h @@ -57,6 +57,8 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr, { DATA_TYPE res; int index; + void *opaque; + index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); physaddr = (physaddr & TARGET_PAGE_MASK) + addr; env->mem_io_pc = (unsigned long)retaddr; @@ -66,16 +68,21 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr, } env->mem_io_vaddr = addr; + opaque = io_mem_opaque[index]; #if SHIFT <= 2 - res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr); + res = io_mem_ops[index].glue(read,SUFFIX)(opaque, physaddr); #else + { + CPUReadMemoryFunc *readl = io_mem_ops[index].readl; + uint32_t v1 = readl(opaque, physaddr); + uint32_t v2 = readl(opaque, physaddr + 4); + #ifdef TARGET_WORDS_BIGENDIAN - res = (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr) << 32; - res |= io_mem_read[index][2](io_mem_opaque[index], physaddr + 4); + res = ((uint64_t)v1 << 32) | v2; #else - res = io_mem_read[index][2](io_mem_opaque[index], physaddr); - res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr + 4) << 32; + res = ((uint64_t)v2 << 32) | v1; #endif + } #endif /* SHIFT > 2 */ return res; } @@ -200,6 +207,8 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr, void *retaddr) { int index; + void *opaque; + index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1); physaddr = (physaddr & TARGET_PAGE_MASK) + addr; if (index > (IO_MEM_NOTDIRTY >> IO_MEM_SHIFT) @@ -209,16 +218,23 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr, env->mem_io_vaddr = addr; env->mem_io_pc = (unsigned long)retaddr; + opaque = io_mem_opaque[index]; #if SHIFT <= 2 - io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val); + io_mem_ops[index].glue(write,SUFFIX)(opaque, physaddr, val); #else + { + CPUWriteMemoryFunc *writel = io_mem_ops[index].writel; + uint32_t v1, v2; + #ifdef TARGET_WORDS_BIGENDIAN - io_mem_write[index][2](io_mem_opaque[index], physaddr, val >> 32); - io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val); + v1 = val >> 32, v2 = val; #else - io_mem_write[index][2](io_mem_opaque[index], physaddr, val); - io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32); + v1 = val, v2 = val >> 32; #endif + + writel(opaque, physaddr, v1); + writel(opaque, physaddr + 4, v2); + } #endif /* SHIFT > 2 */ } -- 1.6.6.1