@@ -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);
@@ -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,
@@ -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);
@@ -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 */
}
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 <rth@twiddle.net> --- cpu-common.h | 14 ++- exec-all.h | 3 +- exec.c | 321 ++++++++++++++++++++++++++------------------------- softmmu_template.h | 36 ++++-- 4 files changed, 203 insertions(+), 171 deletions(-)