qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC] 64 bit i/o


From: Robert Reif
Subject: [Qemu-devel] [RFC] 64 bit i/o
Date: Tue, 01 Jan 2008 22:29:11 -0500
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4.2) Gecko/20040308

Sparc32 has a 64 bit counter that should be read and written as 64
bits but that isn't supported in QEMU.  I did a quick hack to add
64 bit i/o and converted sparc32 to use it and it seems to work.
I'm suppling the sparc changes to get comments on if this is worth
pursuing.  This has only received enough testing to verify that the
64 bit counter was being read and written as 64 bits.  I was able to
run the linux kernel in sparc-test.  QEMU will crash on accessing
an unsupported size because the latest io changes are partially
disabled until I figure out a clean way to call do_unassigned_access.
A lot of the embedded processors use the same function for accessing
all sizes so converting them will be painful.
Index: cpu-all.h
===================================================================
RCS file: /sources/qemu/qemu/cpu-all.h,v
retrieving revision 1.81
diff -p -u -r1.81 cpu-all.h
--- cpu-all.h   1 Jan 2008 16:57:19 -0000       1.81
+++ cpu-all.h   2 Jan 2008 03:07:01 -0000
@@ -823,8 +823,31 @@ extern uint8_t *phys_ram_dirty;
 #define IO_MEM_SUBPAGE     (2)
 #define IO_MEM_SUBWIDTH    (4)
 
-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 CPUWriteMemoryFunc8(void *opaque, target_phys_addr_t addr, 
uint8_t value);
+typedef uint8_t CPUReadMemoryFunc8(void *opaque, target_phys_addr_t addr);
+
+typedef void CPUWriteMemoryFunc16(void *opaque, target_phys_addr_t addr, 
uint16_t value);
+typedef uint16_t CPUReadMemoryFunc16(void *opaque, target_phys_addr_t addr);
+
+typedef void CPUWriteMemoryFunc32(void *opaque, target_phys_addr_t addr, 
uint32_t value);
+typedef uint32_t CPUReadMemoryFunc32(void *opaque, target_phys_addr_t addr);
+
+typedef void CPUWriteMemoryFunc64(void *opaque, target_phys_addr_t addr, 
uint64_t value);
+typedef uint64_t CPUReadMemoryFunc64(void *opaque, target_phys_addr_t addr);
+
+typedef struct CPUWriteMemoryFuncs {
+    CPUWriteMemoryFunc8  *b;
+    CPUWriteMemoryFunc16 *w;
+    CPUWriteMemoryFunc32 *l;
+    CPUWriteMemoryFunc64 *q;
+} CPUWriteMemoryFuncs;
+
+typedef struct CPUReadMemoryFuncs {
+    CPUReadMemoryFunc8  *b;
+    CPUReadMemoryFunc16 *w;
+    CPUReadMemoryFunc32 *l;
+    CPUReadMemoryFunc64 *q;
+} CPUReadMemoryFuncs;
 
 void cpu_register_physical_memory(target_phys_addr_t start_addr,
                                   unsigned long size,
@@ -833,11 +856,11 @@ uint32_t cpu_get_physical_page_desc(targ
 ram_addr_t qemu_ram_alloc(unsigned int size);
 void qemu_ram_free(ram_addr_t addr);
 int cpu_register_io_memory(int io_index,
-                           CPUReadMemoryFunc **mem_read,
-                           CPUWriteMemoryFunc **mem_write,
+                           CPUReadMemoryFuncs *mem_read,
+                           CPUWriteMemoryFuncs *mem_write,
                            void *opaque);
-CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
-CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);
+CPUWriteMemoryFuncs *cpu_get_io_memory_write(int io_index);
+CPUReadMemoryFuncs *cpu_get_io_memory_read(int io_index);
 
 void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,
                             int len, int is_write);
Index: exec-all.h
===================================================================
RCS file: /sources/qemu/qemu/exec-all.h,v
retrieving revision 1.73
diff -p -u -r1.73 exec-all.h
--- exec-all.h  11 Dec 2007 19:35:45 -0000      1.73
+++ exec-all.h  2 Jan 2008 03:07:01 -0000
@@ -336,8 +336,8 @@ dummy_label ## n: ;\
 
 #endif
 
-extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
-extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
+extern CPUWriteMemoryFuncs io_mem_write[IO_MEM_NB_ENTRIES];
+extern CPUReadMemoryFuncs io_mem_read[IO_MEM_NB_ENTRIES];
 extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
 
 #if defined(__powerpc__)
Index: exec.c
===================================================================
RCS file: /sources/qemu/qemu/exec.c,v
retrieving revision 1.121
diff -p -u -r1.121 exec.c
--- exec.c      1 Jan 2008 16:57:19 -0000       1.121
+++ exec.c      2 Jan 2008 03:07:03 -0000
@@ -141,8 +141,8 @@ static PageDesc *l1_map[L1_SIZE];
 PhysPageDesc **l1_phys_map;
 
 /* io memory support */
-CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
-CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
+CPUWriteMemoryFuncs io_mem_write[IO_MEM_NB_ENTRIES];
+CPUReadMemoryFuncs io_mem_read[IO_MEM_NB_ENTRIES];
 void *io_mem_opaque[IO_MEM_NB_ENTRIES];
 static int io_mem_nb;
 #if defined(CONFIG_SOFTMMU)
@@ -163,8 +163,8 @@ static int tb_phys_invalidate_count;
 #define SUBPAGE_IDX(addr) ((addr) & ~TARGET_PAGE_MASK)
 typedef struct subpage_t {
     target_phys_addr_t base;
-    CPUReadMemoryFunc *mem_read[TARGET_PAGE_SIZE][4];
-    CPUWriteMemoryFunc *mem_write[TARGET_PAGE_SIZE][4];
+    CPUReadMemoryFuncs *mem_read[TARGET_PAGE_SIZE];
+    CPUWriteMemoryFuncs *mem_write[TARGET_PAGE_SIZE];
     void *opaque[TARGET_PAGE_SIZE];
 } subpage_t;
 
@@ -2100,44 +2100,105 @@ void qemu_ram_free(ram_addr_t addr)
 {
 }
 
-static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint8_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
 {
 #ifdef DEBUG_UNASSIGNED
-    printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
+    printf("Unassigned mem read byte " TARGET_FMT_plx "\n", addr);
 #endif
-#ifdef TARGET_SPARC
+#if defined(TARGET_SPARC) | defined(TARGET_CRIS)
     do_unassigned_access(addr, 0, 0, 0);
-#elif TARGET_CRIS
+#endif
+    return 0;
+}
+
+static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, 
uint8_t val)
+{
+#ifdef DEBUG_UNASSIGNED
+    printf("Unassigned mem write byte " TARGET_FMT_plx " = 0x%x\n", addr, val);
+#endif
+#if defined(TARGET_SPARC) | defined(TARGET_CRIS)
+    do_unassigned_access(addr, 1, 0, 0);
+#endif
+}
+
+static uint16_t unassigned_mem_readw(void *opaque, target_phys_addr_t addr)
+{
+#ifdef DEBUG_UNASSIGNED
+    printf("Unassigned mem read word " TARGET_FMT_plx "\n", addr);
+#endif
+#if defined(TARGET_SPARC) | defined(TARGET_CRIS)
     do_unassigned_access(addr, 0, 0, 0);
 #endif
     return 0;
 }
 
-static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, 
uint32_t val)
+static void unassigned_mem_writew(void *opaque, target_phys_addr_t addr, 
uint16_t val)
 {
 #ifdef DEBUG_UNASSIGNED
-    printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);
+    printf("Unassigned mem write word " TARGET_FMT_plx " = 0x%x\n", addr, val);
 #endif
-#ifdef TARGET_SPARC
+#if defined(TARGET_SPARC) | defined(TARGET_CRIS)
     do_unassigned_access(addr, 1, 0, 0);
-#elif TARGET_CRIS
+#endif
+}
+
+static uint32_t unassigned_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+#ifdef DEBUG_UNASSIGNED
+    printf("Unassigned mem read long " TARGET_FMT_plx "\n", addr);
+#endif
+#if defined(TARGET_SPARC) | defined(TARGET_CRIS)
+    do_unassigned_access(addr, 0, 0, 0);
+#endif
+    return 0;
+}
+
+static void unassigned_mem_writel(void *opaque, target_phys_addr_t addr, 
uint32_t val)
+{
+#ifdef DEBUG_UNASSIGNED
+    printf("Unassigned mem write long " TARGET_FMT_plx " = 0x%x\n", addr, val);
+#endif
+#if defined(TARGET_SPARC) | defined(TARGET_CRIS)
     do_unassigned_access(addr, 1, 0, 0);
 #endif
 }
 
-static CPUReadMemoryFunc *unassigned_mem_read[3] = {
-    unassigned_mem_readb,
-    unassigned_mem_readb,
+static uint64_t unassigned_mem_readq(void *opaque, target_phys_addr_t addr)
+{
+#ifdef DEBUG_UNASSIGNED
+    printf("Unassigned mem read quad " TARGET_FMT_plx "\n", addr);
+#endif
+#if defined(TARGET_SPARC) | defined(TARGET_CRIS)
+    do_unassigned_access(addr, 0, 0, 0);
+#endif
+    return 0;
+}
+
+static void unassigned_mem_writeq(void *opaque, target_phys_addr_t addr, 
uint64_t val)
+{
+#ifdef DEBUG_UNASSIGNED
+    printf("Unassigned mem write quad " TARGET_FMT_plx " = 0x%x\n", addr, val);
+#endif
+#if defined(TARGET_SPARC) | defined(TARGET_CRIS)
+    do_unassigned_access(addr, 1, 0, 0);
+#endif
+}
+
+static CPUReadMemoryFuncs unassigned_mem_read = {
     unassigned_mem_readb,
+    unassigned_mem_readw,
+    unassigned_mem_readl,
+    unassigned_mem_readq,
 };
 
-static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
-    unassigned_mem_writeb,
-    unassigned_mem_writeb,
+static CPUWriteMemoryFuncs unassigned_mem_write = {
     unassigned_mem_writeb,
+    unassigned_mem_writew,
+    unassigned_mem_writel,
+    unassigned_mem_writeq,
 };
 
-static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, 
uint32_t val)
+static void notdirty_mem_writeb(void *opaque, target_phys_addr_t addr, uint8_t 
val)
 {
     unsigned long ram_addr;
     int dirty_flags;
@@ -2163,7 +2224,7 @@ static void notdirty_mem_writeb(void *op
         tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
 }
 
-static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, 
uint32_t val)
+static void notdirty_mem_writew(void *opaque, target_phys_addr_t addr, 
uint16_t val)
 {
     unsigned long ram_addr;
     int dirty_flags;
@@ -2215,28 +2276,56 @@ static void notdirty_mem_writel(void *op
         tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
 }
 
-static CPUReadMemoryFunc *error_mem_read[3] = {
+static void notdirty_mem_writeq(void *opaque, target_phys_addr_t addr, 
uint64_t val)
+{
+    unsigned long ram_addr;
+    int dirty_flags;
+    ram_addr = addr - (unsigned long)phys_ram_base;
+    dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+    if (!(dirty_flags & CODE_DIRTY_FLAG)) {
+#if !defined(CONFIG_USER_ONLY)
+        tb_invalidate_phys_page_fast(ram_addr, 4);
+        dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+#endif
+    }
+    stq_p((uint8_t *)(long)addr, val);
+#ifdef USE_KQEMU
+    if (cpu_single_env->kqemu_enabled &&
+        (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
+        kqemu_modify_page(cpu_single_env, ram_addr);
+#endif
+    dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
+    phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
+    /* we remove the notdirty callback only if the code has been
+       flushed */
+    if (dirty_flags == 0xff)
+        tlb_set_dirty(cpu_single_env, addr, cpu_single_env->mem_write_vaddr);
+}
+
+static CPUReadMemoryFuncs error_mem_read = {
+    NULL, /* never used */
     NULL, /* never used */
     NULL, /* never used */
     NULL, /* never used */
 };
 
-static CPUWriteMemoryFunc *notdirty_mem_write[3] = {
+static CPUWriteMemoryFuncs notdirty_mem_write = {
     notdirty_mem_writeb,
     notdirty_mem_writew,
     notdirty_mem_writel,
+    notdirty_mem_writeq,
 };
 
 #if defined(CONFIG_SOFTMMU)
 /* Watchpoint access routines.  Watchpoints are inserted using TLB tricks,
    so these check for a hit then pass through to the normal out-of-line
    phys routines.  */
-static uint32_t watch_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint8_t watch_mem_readb(void *opaque, target_phys_addr_t addr)
 {
     return ldub_phys(addr);
 }
 
-static uint32_t watch_mem_readw(void *opaque, target_phys_addr_t addr)
+static uint16_t watch_mem_readw(void *opaque, target_phys_addr_t addr)
 {
     return lduw_phys(addr);
 }
@@ -2246,6 +2335,11 @@ static uint32_t watch_mem_readl(void *op
     return ldl_phys(addr);
 }
 
+static uint64_t watch_mem_readq(void *opaque, target_phys_addr_t addr)
+{
+    return ldq_phys(addr);
+}
+
 /* Generate a debug exception if a watchpoint has been hit.
    Returns the real physical address of the access.  addr will be a host
    address in case of a RAM location.  */
@@ -2272,14 +2366,14 @@ static target_ulong check_watchpoint(tar
 }
 
 static void watch_mem_writeb(void *opaque, target_phys_addr_t addr,
-                             uint32_t val)
+                             uint8_t val)
 {
     addr = check_watchpoint(addr);
     stb_phys(addr, val);
 }
 
 static void watch_mem_writew(void *opaque, target_phys_addr_t addr,
-                             uint32_t val)
+                             uint16_t val)
 {
     addr = check_watchpoint(addr);
     stw_phys(addr, val);
@@ -2292,23 +2386,32 @@ static void watch_mem_writel(void *opaqu
     stl_phys(addr, val);
 }
 
-static CPUReadMemoryFunc *watch_mem_read[3] = {
+static void watch_mem_writeq(void *opaque, target_phys_addr_t addr,
+                             uint64_t val)
+{
+    addr = check_watchpoint(addr);
+    stq_phys(addr, val);
+}
+
+static CPUReadMemoryFuncs watch_mem_read = {
     watch_mem_readb,
     watch_mem_readw,
     watch_mem_readl,
+    watch_mem_readq,
 };
 
-static CPUWriteMemoryFunc *watch_mem_write[3] = {
+static CPUWriteMemoryFuncs watch_mem_write = {
     watch_mem_writeb,
     watch_mem_writew,
     watch_mem_writel,
+    watch_mem_writeq,
 };
 #endif
 
-static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t 
addr,
-                                 unsigned int len)
+static uint8_t subpage_readb (void *opaque, target_phys_addr_t addr)
 {
-    uint32_t ret;
+    subpage_t *mmio = (subpage_t *)opaque;
+    uint8_t ret;
     unsigned int idx;
 
     idx = SUBPAGE_IDX(addr - mmio->base);
@@ -2316,14 +2419,15 @@ static inline uint32_t subpage_readlen (
     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], addr);
+    ret = (*mmio->mem_read[idx]->b)(mmio->opaque[idx], addr);
 
     return ret;
 }
 
-static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr,
-                              uint32_t value, unsigned int len)
+static void subpage_writeb (void *opaque, target_phys_addr_t addr,
+                            uint8_t value)
 {
+    subpage_t *mmio = (subpage_t *)opaque;
     unsigned int idx;
 
     idx = SUBPAGE_IDX(addr - mmio->base);
@@ -2331,80 +2435,117 @@ static inline void subpage_writelen (sub
     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], addr, value);
+    (*mmio->mem_write[idx]->b)(mmio->opaque[idx], addr, value);
 }
 
-static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr)
+static uint16_t subpage_readw (void *opaque, target_phys_addr_t addr)
 {
+    subpage_t *mmio = (subpage_t *)opaque;
+    uint16_t ret;
+    unsigned int idx;
+
+    idx = SUBPAGE_IDX(addr - mmio->base);
 #if defined(DEBUG_SUBPAGE)
-    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
+    printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
+           mmio, len, addr, idx);
 #endif
+    ret = (*mmio->mem_read[idx]->w)(mmio->opaque[idx], addr);
 
-    return subpage_readlen(opaque, addr, 0);
+    return ret;
 }
 
-static void subpage_writeb (void *opaque, target_phys_addr_t addr,
-                            uint32_t value)
+static void subpage_writew (void *opaque, target_phys_addr_t addr,
+                            uint16_t value)
 {
+    subpage_t *mmio = (subpage_t *)opaque;
+    unsigned int idx;
+
+    idx = SUBPAGE_IDX(addr - mmio->base);
 #if defined(DEBUG_SUBPAGE)
-    printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
+    printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value 
%08x\n", __func__,
+           mmio, len, addr, idx, value);
 #endif
-    subpage_writelen(opaque, addr, value, 0);
+    (*mmio->mem_write[idx]->w)(mmio->opaque[idx], addr, value);
 }
 
-static uint32_t subpage_readw (void *opaque, target_phys_addr_t addr)
+static uint32_t subpage_readl (void *opaque, target_phys_addr_t addr)
 {
+    subpage_t *mmio = (subpage_t *)opaque;
+    uint32_t ret;
+    unsigned int idx;
+
+    idx = SUBPAGE_IDX(addr - mmio->base);
 #if defined(DEBUG_SUBPAGE)
-    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
+    printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
+           mmio, len, addr, idx);
 #endif
+    ret = (*mmio->mem_read[idx]->l)(mmio->opaque[idx], addr);
 
-    return subpage_readlen(opaque, addr, 1);
+    return ret;
 }
 
-static void subpage_writew (void *opaque, target_phys_addr_t addr,
-                            uint32_t value)
+static void subpage_writel (void *opaque,
+                         target_phys_addr_t addr, uint32_t value)
 {
+    subpage_t *mmio = (subpage_t *)opaque;
+    unsigned int idx;
+
+    idx = SUBPAGE_IDX(addr - mmio->base);
 #if defined(DEBUG_SUBPAGE)
-    printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
+    printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value 
%08x\n", __func__,
+           mmio, len, addr, idx, value);
 #endif
-    subpage_writelen(opaque, addr, value, 1);
+    (*mmio->mem_write[idx]->l)(mmio->opaque[idx], addr, value);
 }
 
-static uint32_t subpage_readl (void *opaque, target_phys_addr_t addr)
+static uint64_t subpage_readq (void *opaque, target_phys_addr_t addr)
 {
+    subpage_t *mmio = (subpage_t *)opaque;
+    uint64_t ret;
+    unsigned int idx;
+
+    idx = SUBPAGE_IDX(addr - mmio->base);
 #if defined(DEBUG_SUBPAGE)
-    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
+    printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
+           mmio, len, addr, idx);
 #endif
+    ret = (*mmio->mem_read[idx]->q)(mmio->opaque[idx], addr);
 
-    return subpage_readlen(opaque, addr, 2);
+    return ret;
 }
 
-static void subpage_writel (void *opaque,
-                         target_phys_addr_t addr, uint32_t value)
+static void subpage_writeq (void *opaque,
+                         target_phys_addr_t addr, uint64_t value)
 {
+    subpage_t *mmio = (subpage_t *)opaque;
+    unsigned int idx;
+
+    idx = SUBPAGE_IDX(addr - mmio->base);
 #if defined(DEBUG_SUBPAGE)
-    printf("%s: addr " TARGET_FMT_plx " val %08x\n", __func__, addr, value);
+    printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value 
%08x\n", __func__,
+           mmio, len, addr, idx, value);
 #endif
-    subpage_writelen(opaque, addr, value, 2);
+    (*mmio->mem_write[idx]->q)(mmio->opaque[idx], addr, value);
 }
 
-static CPUReadMemoryFunc *subpage_read[] = {
+static CPUReadMemoryFuncs subpage_read = {
     &subpage_readb,
     &subpage_readw,
     &subpage_readl,
+    &subpage_readq,
 };
 
-static CPUWriteMemoryFunc *subpage_write[] = {
+static CPUWriteMemoryFuncs subpage_write = {
     &subpage_writeb,
     &subpage_writew,
     &subpage_writel,
+    &subpage_writeq,
 };
 
 static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
                              int memory)
 {
     int idx, eidx;
-    unsigned int i;
 
     if (start >= TARGET_PAGE_SIZE || end >= TARGET_PAGE_SIZE)
         return -1;
@@ -2416,12 +2557,8 @@ static int subpage_register (subpage_t *
 #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];
-            if (io_mem_write[memory][i])
-                mmio->mem_write[idx][i] = io_mem_write[memory][i];
-        }
+        mmio->mem_read[idx] = &io_mem_read[memory];
+        mmio->mem_write[idx] = &io_mem_write[memory];
         mmio->opaque[idx] = io_mem_opaque[memory];
     }
 
@@ -2437,7 +2574,7 @@ static void *subpage_init (target_phys_a
     mmio = qemu_mallocz(sizeof(subpage_t));
     if (mmio != NULL) {
         mmio->base = base;
-        subpage_memory = cpu_register_io_memory(0, subpage_read, 
subpage_write, mmio);
+        subpage_memory = cpu_register_io_memory(0, &subpage_read, 
&subpage_write, mmio);
 #if defined(DEBUG_SUBPAGE)
         printf("%s: %p base " TARGET_FMT_plx " len %08x %d\n", __func__,
                mmio, base, TARGET_PAGE_SIZE, subpage_memory);
@@ -2451,14 +2588,14 @@ static void *subpage_init (target_phys_a
 
 static void io_mem_init(void)
 {
-    cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, error_mem_read, 
unassigned_mem_write, NULL);
-    cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, 
unassigned_mem_read, unassigned_mem_write, NULL);
-    cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, error_mem_read, 
notdirty_mem_write, NULL);
+    cpu_register_io_memory(IO_MEM_ROM >> IO_MEM_SHIFT, &error_mem_read, 
&unassigned_mem_write, NULL);
+    cpu_register_io_memory(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, 
&unassigned_mem_read, &unassigned_mem_write, NULL);
+    cpu_register_io_memory(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, &error_mem_read, 
&notdirty_mem_write, NULL);
     io_mem_nb = 5;
 
 #if defined(CONFIG_SOFTMMU)
-    io_mem_watch = cpu_register_io_memory(-1, watch_mem_read,
-                                          watch_mem_write, NULL);
+    io_mem_watch = cpu_register_io_memory(-1, &watch_mem_read,
+                                          &watch_mem_write, NULL);
 #endif
     /* alloc dirty bits array */
     phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS);
@@ -2472,11 +2609,11 @@ static void io_mem_init(void)
    value can be used with cpu_register_physical_memory(). (-1) is
    returned if error. */
 int cpu_register_io_memory(int io_index,
-                           CPUReadMemoryFunc **mem_read,
-                           CPUWriteMemoryFunc **mem_write,
+                           CPUReadMemoryFuncs *mem_read,
+                           CPUWriteMemoryFuncs *mem_write,
                            void *opaque)
 {
-    int i, subwidth = 0;
+    int subwidth = 0;
 
     if (io_index <= 0) {
         if (io_mem_nb >= IO_MEM_NB_ENTRIES)
@@ -2487,24 +2624,21 @@ int cpu_register_io_memory(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];
-    }
+    subwidth = IO_MEM_SUBWIDTH;
+    io_mem_read[io_index] = *mem_read;
+    io_mem_write[io_index] = *mem_write;
     io_mem_opaque[io_index] = opaque;
     return (io_index << IO_MEM_SHIFT) | subwidth;
 }
 
-CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index)
+CPUWriteMemoryFuncs *cpu_get_io_memory_write(int io_index)
 {
-    return io_mem_write[io_index >> IO_MEM_SHIFT];
+    return &io_mem_write[io_index >> IO_MEM_SHIFT];
 }
 
-CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index)
+CPUReadMemoryFuncs *cpu_get_io_memory_read(int io_index)
 {
-    return io_mem_read[io_index >> IO_MEM_SHIFT];
+    return &io_mem_read[io_index >> IO_MEM_SHIFT];
 }
 
 /* physical memory access (slow version, mainly for debug) */
@@ -2556,6 +2690,7 @@ void cpu_physical_memory_rw(target_phys_
     int l, io_index;
     uint8_t *ptr;
     uint32_t val;
+    uint64_t val64;
     target_phys_addr_t page;
     unsigned long pd;
     PhysPageDesc *p;
@@ -2577,20 +2712,25 @@ void cpu_physical_memory_rw(target_phys_
                 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
                 /* XXX: could force cpu_single_env to NULL to avoid
                    potential bugs */
-                if (l >= 4 && ((addr & 3) == 0)) {
+                if (l >= 8 && ((addr & 7) == 0)) {
+                    /* 64 bit write access */
+                    val64 = ldq_p(buf);
+                    io_mem_write[io_index].q(io_mem_opaque[io_index], addr, 
val64);
+                    l = 8;
+                } else if (l >= 4 && ((addr & 3) == 0)) {
                     /* 32 bit write access */
                     val = ldl_p(buf);
-                    io_mem_write[io_index][2](io_mem_opaque[io_index], addr, 
val);
+                    io_mem_write[io_index].l(io_mem_opaque[io_index], addr, 
val);
                     l = 4;
                 } else if (l >= 2 && ((addr & 1) == 0)) {
                     /* 16 bit write access */
                     val = lduw_p(buf);
-                    io_mem_write[io_index][1](io_mem_opaque[io_index], addr, 
val);
+                    io_mem_write[io_index].w(io_mem_opaque[io_index], addr, 
val);
                     l = 2;
                 } else {
                     /* 8 bit write access */
                     val = ldub_p(buf);
-                    io_mem_write[io_index][0](io_mem_opaque[io_index], addr, 
val);
+                    io_mem_write[io_index].b(io_mem_opaque[io_index], addr, 
val);
                     l = 1;
                 }
             } else {
@@ -2612,19 +2752,24 @@ void cpu_physical_memory_rw(target_phys_
                 !(pd & IO_MEM_ROMD)) {
                 /* I/O case */
                 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
-                if (l >= 4 && ((addr & 3) == 0)) {
+                if (l >= 8 && ((addr & 7) == 0)) {
+                    /* 64 bit read access */
+                    val64 = io_mem_read[io_index].q(io_mem_opaque[io_index], 
addr);
+                    stq_p(buf, val64);
+                    l = 8;
+                } else if (l >= 4 && ((addr & 3) == 0)) {
                     /* 32 bit read access */
-                    val = io_mem_read[io_index][2](io_mem_opaque[io_index], 
addr);
+                    val = io_mem_read[io_index].l(io_mem_opaque[io_index], 
addr);
                     stl_p(buf, val);
                     l = 4;
                 } else if (l >= 2 && ((addr & 1) == 0)) {
                     /* 16 bit read access */
-                    val = io_mem_read[io_index][1](io_mem_opaque[io_index], 
addr);
+                    val = io_mem_read[io_index].w(io_mem_opaque[io_index], 
addr);
                     stw_p(buf, val);
                     l = 2;
                 } else {
                     /* 8 bit read access */
-                    val = io_mem_read[io_index][0](io_mem_opaque[io_index], 
addr);
+                    val = io_mem_read[io_index].b(io_mem_opaque[io_index], 
addr);
                     stb_p(buf, val);
                     l = 1;
                 }
@@ -2701,7 +2846,7 @@ uint32_t ldl_phys(target_phys_addr_t add
         !(pd & IO_MEM_ROMD)) {
         /* I/O case */
         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
-        val = io_mem_read[io_index][2](io_mem_opaque[io_index], addr);
+        val = io_mem_read[io_index].l(io_mem_opaque[io_index], addr);
     } else {
         /* RAM case */
         ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
@@ -2731,12 +2876,16 @@ uint64_t ldq_phys(target_phys_addr_t add
         !(pd & IO_MEM_ROMD)) {
         /* I/O case */
         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+#if 0
 #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)io_mem_read[io_index].l(io_mem_opaque[io_index], addr) 
<< 32;
+        val |= io_mem_read[io_index].l(io_mem_opaque[io_index], addr + 4);
+#else
+        val = io_mem_read[io_index].l(io_mem_opaque[io_index], addr);
+        val |= (uint64_t)io_mem_read[io_index].l(io_mem_opaque[io_index], addr 
+ 4) << 32;
+#endif
 #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 = io_mem_read[io_index].q(io_mem_opaque[io_index], addr);
 #endif
     } else {
         /* RAM case */
@@ -2782,7 +2931,7 @@ void stl_phys_notdirty(target_phys_addr_
 
     if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
-        io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
+        io_mem_write[io_index].l(io_mem_opaque[io_index], addr, val);
     } else {
         ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
             (addr & ~TARGET_PAGE_MASK);
@@ -2806,12 +2955,16 @@ void stq_phys_notdirty(target_phys_addr_
 
     if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+#if 0
 #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);
+        io_mem_write[io_index].l(io_mem_opaque[io_index], addr, val >> 32);
+        io_mem_write[io_index].l(io_mem_opaque[io_index], addr + 4, val);
+#else
+        io_mem_write[io_index].l(io_mem_opaque[io_index], addr, val);
+        io_mem_write[io_index].l(io_mem_opaque[io_index], addr + 4, val >> 32);
+#endif
 #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);
+        io_mem_write[io_index].q(io_mem_opaque[io_index], addr, val);
 #endif
     } else {
         ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
@@ -2837,7 +2990,7 @@ void stl_phys(target_phys_addr_t addr, u
 
     if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM) {
         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
-        io_mem_write[io_index][2](io_mem_opaque[io_index], addr, val);
+        io_mem_write[io_index].l(io_mem_opaque[io_index], addr, val);
     } else {
         unsigned long addr1;
         addr1 = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK);
Index: softmmu_template.h
===================================================================
RCS file: /sources/qemu/qemu/softmmu_template.h,v
retrieving revision 1.21
diff -p -u -r1.21 softmmu_template.h
--- softmmu_template.h  17 Nov 2007 12:12:29 -0000      1.21
+++ softmmu_template.h  2 Jan 2008 03:07:03 -0000
@@ -57,17 +57,25 @@ static inline DATA_TYPE glue(io_read, SU
     int index;
 
     index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
-#if SHIFT <= 2
-    res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr);
-#else
+#if SHIFT == 0
+    res = io_mem_read[index].b(io_mem_opaque[index], physaddr);
+#elif SHIFT == 1
+    res = io_mem_read[index].w(io_mem_opaque[index], physaddr);
+#elif SHIFT == 2
+    res = io_mem_read[index].l(io_mem_opaque[index], physaddr);
+#elif SHIFT == 3
+#if 0
 #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)io_mem_read[index].l(io_mem_opaque[index], physaddr) << 32;
+    res |= io_mem_read[index].l(io_mem_opaque[index], physaddr + 4);
+#else
+    res = io_mem_read[index].l(io_mem_opaque[index], physaddr);
+    res |= (uint64_t)io_mem_read[index].l(io_mem_opaque[index], physaddr + 4) 
<< 32;
+#endif
 #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 = io_mem_read[index].q(io_mem_opaque[index], physaddr);
+#endif
 #endif
-#endif /* SHIFT > 2 */
 #ifdef USE_KQEMU
     env->last_io_time = cpu_get_time_fast();
 #endif
@@ -193,17 +201,25 @@ static inline void glue(io_write, SUFFIX
     index = (tlb_addr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
     env->mem_write_vaddr = tlb_addr;
     env->mem_write_pc = (unsigned long)retaddr;
-#if SHIFT <= 2
-    io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val);
-#else
+#if SHIFT == 0
+    io_mem_write[index].b(io_mem_opaque[index], physaddr, val);
+#elif SHIFT == 1
+    io_mem_write[index].w(io_mem_opaque[index], physaddr, val);
+#elif SHIFT == 2
+    io_mem_write[index].l(io_mem_opaque[index], physaddr, val);
+#elif SHIFT == 3
+#if 0
 #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);
+    io_mem_write[index].l(io_mem_opaque[index], physaddr, val >> 32);
+    io_mem_write[index].l(io_mem_opaque[index], physaddr + 4, val);
+#else
+    io_mem_write[index].l(io_mem_opaque[index], physaddr, val);
+    io_mem_write[index].l(io_mem_opaque[index], physaddr + 4, val >> 32);
+#endif
 #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);
+    io_mem_write[index].q(io_mem_opaque[index], physaddr, val);
+#endif
 #endif
-#endif /* SHIFT > 2 */
 #ifdef USE_KQEMU
     env->last_io_time = cpu_get_time_fast();
 #endif
Index: hw/cs4231.c
===================================================================
RCS file: /sources/qemu/qemu/hw/cs4231.c,v
retrieving revision 1.5
diff -p -u -r1.5 cs4231.c
--- hw/cs4231.c 17 Nov 2007 17:14:41 -0000      1.5
+++ hw/cs4231.c 2 Jan 2008 03:07:10 -0000
@@ -127,16 +127,18 @@ static void cs_mem_writel(void *opaque, 
     }
 }
 
-static CPUReadMemoryFunc *cs_mem_read[3] = {
+static CPUReadMemoryFuncs cs_mem_read = {
     cs_mem_readl,
     cs_mem_readl,
     cs_mem_readl,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *cs_mem_write[3] = {
+static CPUWriteMemoryFuncs cs_mem_write = {
     cs_mem_writel,
     cs_mem_writel,
     cs_mem_writel,
+    NULL,
 };
 
 static void cs_save(QEMUFile *f, void *opaque)
@@ -174,7 +176,7 @@ void cs_init(target_phys_addr_t base, in
     if (!s)
         return;
 
-    cs_io_memory = cpu_register_io_memory(0, cs_mem_read, cs_mem_write, s);
+    cs_io_memory = cpu_register_io_memory(0, &cs_mem_read, &cs_mem_write, s);
     cpu_register_physical_memory(base, CS_SIZE, cs_io_memory);
     register_savevm("cs4231", base, 1, cs_save, cs_load, s);
     qemu_register_reset(cs_reset, s);
Index: hw/eccmemctl.c
===================================================================
RCS file: /sources/qemu/qemu/hw/eccmemctl.c,v
retrieving revision 1.2
diff -p -u -r1.2 eccmemctl.c
--- hw/eccmemctl.c      1 Jan 2008 17:06:38 -0000       1.2
+++ hw/eccmemctl.c      2 Jan 2008 03:07:10 -0000
@@ -176,16 +176,18 @@ static uint32_t ecc_mem_readl(void *opaq
     return ret;
 }
 
-static CPUReadMemoryFunc *ecc_mem_read[3] = {
+static CPUReadMemoryFuncs ecc_mem_read = {
     NULL,
     NULL,
     ecc_mem_readl,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *ecc_mem_write[3] = {
+static CPUWriteMemoryFuncs ecc_mem_write = {
     NULL,
     NULL,
     ecc_mem_writel,
+    NULL,
 };
 
 static int ecc_load(QEMUFile *f, void *opaque, int version_id)
@@ -233,7 +235,7 @@ void * ecc_init(target_phys_addr_t base,
 
     s->regs[0] = version;
 
-    ecc_io_memory = cpu_register_io_memory(0, ecc_mem_read, ecc_mem_write, s);
+    ecc_io_memory = cpu_register_io_memory(0, &ecc_mem_read, &ecc_mem_write, 
s);
     cpu_register_physical_memory(base, ECC_SIZE, ecc_io_memory);
     register_savevm("ECC", base, 1, ecc_save, ecc_load, s);
     qemu_register_reset(ecc_reset, s);
Index: hw/esp.c
===================================================================
RCS file: /sources/qemu/qemu/hw/esp.c,v
retrieving revision 1.33
diff -p -u -r1.33 esp.c
--- hw/esp.c    1 Jan 2008 17:06:38 -0000       1.33
+++ hw/esp.c    2 Jan 2008 03:07:11 -0000
@@ -397,7 +397,7 @@ static void parent_esp_reset(void *opaqu
         esp_reset(opaque);
 }
 
-static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint8_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
 {
     ESPState *s = opaque;
     uint32_t saddr;
@@ -433,7 +433,7 @@ static uint32_t esp_mem_readb(void *opaq
     return s->rregs[saddr];
 }
 
-static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
+static void esp_mem_writeb(void *opaque, target_phys_addr_t addr, uint8_t val)
 {
     ESPState *s = opaque;
     uint32_t saddr;
@@ -541,16 +541,18 @@ static void esp_mem_writeb(void *opaque,
     s->wregs[saddr] = val;
 }
 
-static CPUReadMemoryFunc *esp_mem_read[3] = {
+static CPUReadMemoryFuncs esp_mem_read = {
     esp_mem_readb,
     NULL,
     NULL,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *esp_mem_write[3] = {
+static CPUWriteMemoryFuncs esp_mem_write = {
     esp_mem_writeb,
     NULL,
     NULL,
+    NULL,
 };
 
 static void esp_save(QEMUFile *f, void *opaque)
@@ -633,7 +635,7 @@ void *esp_init(target_phys_addr_t espadd
     s->irq = irq;
     s->dma_opaque = dma_opaque;
 
-    esp_io_memory = cpu_register_io_memory(0, esp_mem_read, esp_mem_write, s);
+    esp_io_memory = cpu_register_io_memory(0, &esp_mem_read, &esp_mem_write, 
s);
     cpu_register_physical_memory(espaddr, ESP_SIZE, esp_io_memory);
 
     esp_reset(s);
Index: hw/fdc.c
===================================================================
RCS file: /sources/qemu/qemu/hw/fdc.c,v
retrieving revision 1.37
diff -p -u -r1.37 fdc.c
--- hw/fdc.c    1 Jan 2008 17:06:38 -0000       1.37
+++ hw/fdc.c    2 Jan 2008 03:07:12 -0000
@@ -481,28 +481,32 @@ static void fdctrl_write_mem (void *opaq
     fdctrl_write(opaque, (uint32_t)reg, value);
 }
 
-static CPUReadMemoryFunc *fdctrl_mem_read[3] = {
+static CPUReadMemoryFuncs fdctrl_mem_read = {
     fdctrl_read_mem,
     fdctrl_read_mem,
     fdctrl_read_mem,
+    NULL
 };
 
-static CPUWriteMemoryFunc *fdctrl_mem_write[3] = {
+static CPUWriteMemoryFuncs fdctrl_mem_write = {
     fdctrl_write_mem,
     fdctrl_write_mem,
     fdctrl_write_mem,
+    NULL
 };
 
-static CPUReadMemoryFunc *fdctrl_mem_read_strict[3] = {
+static CPUReadMemoryFuncs fdctrl_mem_read_strict = {
     fdctrl_read_mem,
     NULL,
     NULL,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *fdctrl_mem_write_strict[3] = {
+static CPUWriteMemoryFuncs fdctrl_mem_write_strict = {
     fdctrl_write_mem,
     NULL,
     NULL,
+    NULL,
 };
 
 static void fd_save (QEMUFile *f, fdrive_t *fd)
@@ -653,7 +657,7 @@ fdctrl_t *fdctrl_init (qemu_irq irq, int
 
     fdctrl->sun4m = 0;
     if (mem_mapped) {
-        io_mem = cpu_register_io_memory(0, fdctrl_mem_read, fdctrl_mem_write,
+        io_mem = cpu_register_io_memory(0, &fdctrl_mem_read, &fdctrl_mem_write,
                                         fdctrl);
         cpu_register_physical_memory(io_base, 0x08, io_mem);
     } else {
@@ -678,8 +682,8 @@ fdctrl_t *sun4m_fdctrl_init (qemu_irq ir
 
     fdctrl = fdctrl_init_common(irq, 0, io_base, fds);
     fdctrl->sun4m = 1;
-    io_mem = cpu_register_io_memory(0, fdctrl_mem_read_strict,
-                                    fdctrl_mem_write_strict,
+    io_mem = cpu_register_io_memory(0, &fdctrl_mem_read_strict,
+                                    &fdctrl_mem_write_strict,
                                     fdctrl);
     cpu_register_physical_memory(io_base, 0x08, io_mem);
 
Index: hw/iommu.c
===================================================================
RCS file: /sources/qemu/qemu/hw/iommu.c,v
retrieving revision 1.25
diff -p -u -r1.25 iommu.c
--- hw/iommu.c  1 Jan 2008 17:06:38 -0000       1.25
+++ hw/iommu.c  2 Jan 2008 03:07:15 -0000
@@ -212,16 +212,18 @@ static void iommu_mem_writel(void *opaqu
     }
 }
 
-static CPUReadMemoryFunc *iommu_mem_read[3] = {
+static CPUReadMemoryFuncs iommu_mem_read = {
     NULL,
     NULL,
     iommu_mem_readl,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *iommu_mem_write[3] = {
+static CPUWriteMemoryFuncs iommu_mem_write = {
     NULL,
     NULL,
     iommu_mem_writel,
+    NULL,
 };
 
 static uint32_t iommu_page_get_flags(IOMMUState *s, target_phys_addr_t addr)
@@ -353,8 +355,8 @@ void *iommu_init(target_phys_addr_t addr
     s->version = version;
     s->irq = irq;
 
-    iommu_io_memory = cpu_register_io_memory(0, iommu_mem_read,
-                                             iommu_mem_write, s);
+    iommu_io_memory = cpu_register_io_memory(0, &iommu_mem_read,
+                                             &iommu_mem_write, s);
     cpu_register_physical_memory(addr, IOMMU_NREGS * 4, iommu_io_memory);
 
     register_savevm("iommu", addr, 2, iommu_save, iommu_load, s);
Index: hw/m48t59.c
===================================================================
RCS file: /sources/qemu/qemu/hw/m48t59.c,v
retrieving revision 1.19
diff -p -u -r1.19 m48t59.c
--- hw/m48t59.c 29 Dec 2007 09:05:30 -0000      1.19
+++ hw/m48t59.c 2 Jan 2008 03:07:16 -0000
@@ -539,7 +539,7 @@ static uint32_t NVRAM_readb (void *opaqu
     return retval;
 }
 
-static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t 
value)
+static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint8_t value)
 {
     m48t59_t *NVRAM = opaque;
 
@@ -547,7 +547,7 @@ static void nvram_writeb (void *opaque, 
     m48t59_write(NVRAM, addr, value & 0xff);
 }
 
-static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t 
value)
+static void nvram_writew (void *opaque, target_phys_addr_t addr, uint16_t 
value)
 {
     m48t59_t *NVRAM = opaque;
 
@@ -567,17 +567,32 @@ static void nvram_writel (void *opaque, 
     m48t59_write(NVRAM, addr + 3, value & 0xff);
 }
 
-static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
+static void nvram_writeq (void *opaque, target_phys_addr_t addr, uint64_t 
value)
 {
     m48t59_t *NVRAM = opaque;
-    uint32_t retval;
+
+    addr -= NVRAM->mem_base;
+    m48t59_write(NVRAM, addr + 0, (value >> 56) & 0xff);
+    m48t59_write(NVRAM, addr + 1, (value >> 48) & 0xff);
+    m48t59_write(NVRAM, addr + 2, (value >> 40) & 0xff);
+    m48t59_write(NVRAM, addr + 3, (value >> 32) & 0xff);
+    m48t59_write(NVRAM, addr + 4, (value >> 24) & 0xff);
+    m48t59_write(NVRAM, addr + 5, (value >> 16) & 0xff);
+    m48t59_write(NVRAM, addr + 6, (value >> 8)  & 0xff);
+    m48t59_write(NVRAM, addr + 7, (value >> 0)  & 0xff);
+}
+
+static uint8_t nvram_readb (void *opaque, target_phys_addr_t addr)
+{
+    m48t59_t *NVRAM = opaque;
+    uint16_t retval;
 
     addr -= NVRAM->mem_base;
     retval = m48t59_read(NVRAM, addr);
     return retval;
 }
 
-static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr)
+static uint16_t nvram_readw (void *opaque, target_phys_addr_t addr)
 {
     m48t59_t *NVRAM = opaque;
     uint32_t retval;
@@ -601,16 +616,35 @@ static uint32_t nvram_readl (void *opaqu
     return retval;
 }
 
-static CPUWriteMemoryFunc *nvram_write[] = {
-    &nvram_writeb,
-    &nvram_writew,
-    &nvram_writel,
+static uint64_t nvram_readq (void *opaque, target_phys_addr_t addr)
+{
+    m48t59_t *NVRAM = opaque;
+    uint64_t retval;
+
+    addr -= NVRAM->mem_base;
+    retval  = (uint64_t)m48t59_read(NVRAM, addr + 0) << 56;
+    retval |= (uint64_t)m48t59_read(NVRAM, addr + 1) << 48;
+    retval |= (uint64_t)m48t59_read(NVRAM, addr + 2) << 40;
+    retval |= (uint64_t)m48t59_read(NVRAM, addr + 3) << 32;
+    retval |= (uint64_t)m48t59_read(NVRAM, addr + 4) << 24;
+    retval |= (uint64_t)m48t59_read(NVRAM, addr + 5) << 16;
+    retval |= (uint64_t)m48t59_read(NVRAM, addr + 6) << 8;
+    retval |= (uint64_t)m48t59_read(NVRAM, addr + 7) << 0;
+    return retval;
+}
+
+static CPUWriteMemoryFuncs nvram_write = {
+    nvram_writeb,
+    nvram_writew,
+    nvram_writel,
+    nvram_writeq,
 };
 
-static CPUReadMemoryFunc *nvram_read[] = {
-    &nvram_readb,
-    &nvram_readw,
-    &nvram_readl,
+static CPUReadMemoryFuncs nvram_read = {
+    nvram_readb,
+    nvram_readw,
+    nvram_readl,
+    nvram_readq,
 };
 
 static void m48t59_save(QEMUFile *f, void *opaque)
@@ -674,7 +708,7 @@ m48t59_t *m48t59_init (qemu_irq IRQ, tar
         register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, s);
     }
     if (mem_base != 0) {
-        s->mem_index = cpu_register_io_memory(0, nvram_read, nvram_write, s);
+        s->mem_index = cpu_register_io_memory(0, &nvram_read, &nvram_write, s);
         cpu_register_physical_memory(mem_base, size, s->mem_index);
     }
     if (type == 59) {
Index: hw/pcnet.c
===================================================================
RCS file: /sources/qemu/qemu/hw/pcnet.c,v
retrieving revision 1.23
diff -p -u -r1.23 pcnet.c
--- hw/pcnet.c  1 Jan 2008 17:06:38 -0000       1.23
+++ hw/pcnet.c  2 Jan 2008 03:07:19 -0000
@@ -1740,7 +1740,7 @@ static void pcnet_ioport_map(PCIDevice *
     register_ioport_read(addr + 0x10, 0x10, 4, pcnet_ioport_readl, d);
 }
 
-static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t 
val)
+static void pcnet_mmio_writeb(void *opaque, target_phys_addr_t addr, uint8_t 
val)
 {
     PCNetState *d = opaque;
 #ifdef PCNET_DEBUG_IO
@@ -1750,7 +1750,7 @@ static void pcnet_mmio_writeb(void *opaq
         pcnet_aprom_writeb(d, addr & 0x0f, val);
 }
 
-static uint32_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr)
+static uint8_t pcnet_mmio_readb(void *opaque, target_phys_addr_t addr)
 {
     PCNetState *d = opaque;
     uint32_t val = -1;
@@ -1762,7 +1762,7 @@ static uint32_t pcnet_mmio_readb(void *o
     return val;
 }
 
-static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint32_t 
val)
+static void pcnet_mmio_writew(void *opaque, target_phys_addr_t addr, uint16_t 
val)
 {
     PCNetState *d = opaque;
 #ifdef PCNET_DEBUG_IO
@@ -1777,7 +1777,7 @@ static void pcnet_mmio_writew(void *opaq
     }
 }
 
-static uint32_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr)
+static uint16_t pcnet_mmio_readw(void *opaque, target_phys_addr_t addr)
 {
     PCNetState *d = opaque;
     uint32_t val = -1;
@@ -1922,16 +1922,18 @@ static void pcnet_common_init(PCNetState
 
 /* PCI interface */
 
-static CPUWriteMemoryFunc *pcnet_mmio_write[] = {
-    (CPUWriteMemoryFunc *)&pcnet_mmio_writeb,
-    (CPUWriteMemoryFunc *)&pcnet_mmio_writew,
-    (CPUWriteMemoryFunc *)&pcnet_mmio_writel
+static CPUWriteMemoryFuncs pcnet_mmio_write = {
+    pcnet_mmio_writeb,
+    pcnet_mmio_writew,
+    pcnet_mmio_writel,
+    NULL
 };
 
-static CPUReadMemoryFunc *pcnet_mmio_read[] = {
-    (CPUReadMemoryFunc *)&pcnet_mmio_readb,
-    (CPUReadMemoryFunc *)&pcnet_mmio_readw,
-    (CPUReadMemoryFunc *)&pcnet_mmio_readl
+static CPUReadMemoryFuncs pcnet_mmio_read = {
+    pcnet_mmio_readb,
+    pcnet_mmio_readw,
+    pcnet_mmio_readl,
+    NULL
 };
 
 static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
@@ -1992,7 +1994,7 @@ void pci_pcnet_init(PCIBus *bus, NICInfo
 
     /* Handler for memory-mapped I/O */
     d->mmio_index =
-      cpu_register_io_memory(0, pcnet_mmio_read, pcnet_mmio_write, d);
+      cpu_register_io_memory(0, &pcnet_mmio_read, &pcnet_mmio_write, d);
 
     pci_register_io_region((PCIDevice *)d, 0, PCNET_IOPORT_SIZE,
                            PCI_ADDRESS_SPACE_IO, pcnet_ioport_map);
@@ -2020,7 +2022,7 @@ static void parent_lance_reset(void *opa
 }
 
 static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
-                             uint32_t val)
+                             uint16_t val)
 {
 #ifdef PCNET_DEBUG_IO
     printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
@@ -2029,28 +2031,53 @@ static void lance_mem_writew(void *opaqu
     pcnet_ioport_writew(opaque, addr & 7, val & 0xffff);
 }
 
-static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
+static uint16_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
 {
-    uint32_t val;
+    uint16_t val;
 
     val = pcnet_ioport_readw(opaque, addr & 7);
 #ifdef PCNET_DEBUG_IO
     printf("pcnet_mmio_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
+           val);
+#endif
+
+    return val;
+}
+
+static void lance_mem_writel(void *opaque, target_phys_addr_t addr,
+                             uint32_t val)
+{
+#ifdef PCNET_DEBUG_IO
+    printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
            val & 0xffff);
 #endif
+    pcnet_ioport_writel(opaque, addr & 7, val);
+}
+
+static uint32_t lance_mem_readl(void *opaque, target_phys_addr_t addr)
+{
+    uint32_t val;
+
+    val = pcnet_ioport_readw(opaque, addr & 7);
+#ifdef PCNET_DEBUG_IO
+    printf("pcnet_mmio_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
+           val);
+#endif
 
-    return val & 0xffff;
+    return val;
 }
 
-static CPUReadMemoryFunc *lance_mem_read[3] = {
+static CPUReadMemoryFuncs lance_mem_read = {
     NULL,
     lance_mem_readw,
+    lance_mem_readl,
     NULL,
 };
 
-static CPUWriteMemoryFunc *lance_mem_write[3] = {
+static CPUWriteMemoryFuncs lance_mem_write = {
     NULL,
     lance_mem_writew,
+    lance_mem_writel,
     NULL,
 };
 
@@ -2065,7 +2092,7 @@ void lance_init(NICInfo *nd, target_phys
         return;
 
     lance_io_memory =
-        cpu_register_io_memory(0, lance_mem_read, lance_mem_write, d);
+        cpu_register_io_memory(0, &lance_mem_read, &lance_mem_write, d);
 
     d->dma_opaque = dma_opaque;
 
Index: hw/sbi.c
===================================================================
RCS file: /sources/qemu/qemu/hw/sbi.c,v
retrieving revision 1.2
diff -p -u -r1.2 sbi.c
--- hw/sbi.c    1 Jan 2008 17:06:38 -0000       1.2
+++ hw/sbi.c    2 Jan 2008 03:07:23 -0000
@@ -90,16 +90,18 @@ static void sbi_mem_writel(void *opaque,
     }
 }
 
-static CPUReadMemoryFunc *sbi_mem_read[3] = {
+static CPUReadMemoryFuncs sbi_mem_read = {
     NULL,
     NULL,
     sbi_mem_readl,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *sbi_mem_write[3] = {
+static CPUWriteMemoryFuncs sbi_mem_write = {
     NULL,
     NULL,
     sbi_mem_writel,
+    NULL,
 };
 
 static void sbi_save(QEMUFile *f, void *opaque)
@@ -154,7 +156,7 @@ void *sbi_init(target_phys_addr_t addr, 
         s->cpu_irqs[i] = parent_irq[i];
     }
 
-    sbi_io_memory = cpu_register_io_memory(0, sbi_mem_read, sbi_mem_write, s);
+    sbi_io_memory = cpu_register_io_memory(0, &sbi_mem_read, &sbi_mem_write, 
s);
     cpu_register_physical_memory(addr, SBI_SIZE, sbi_io_memory);
 
     register_savevm("sbi", addr, 1, sbi_save, sbi_load, s);
Index: hw/slavio_intctl.c
===================================================================
RCS file: /sources/qemu/qemu/hw/slavio_intctl.c,v
retrieving revision 1.29
diff -p -u -r1.29 slavio_intctl.c
--- hw/slavio_intctl.c  1 Jan 2008 20:57:25 -0000       1.29
+++ hw/slavio_intctl.c  2 Jan 2008 03:07:24 -0000
@@ -128,16 +128,18 @@ static void slavio_intctl_mem_writel(voi
     }
 }
 
-static CPUReadMemoryFunc *slavio_intctl_mem_read[3] = {
+static CPUReadMemoryFuncs slavio_intctl_mem_read = {
     NULL,
     NULL,
     slavio_intctl_mem_readl,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *slavio_intctl_mem_write[3] = {
+static CPUWriteMemoryFuncs slavio_intctl_mem_write = {
     NULL,
     NULL,
     slavio_intctl_mem_writel,
+    NULL,
 };
 
 // master system interrupt controller
@@ -199,16 +201,18 @@ static void slavio_intctlm_mem_writel(vo
     }
 }
 
-static CPUReadMemoryFunc *slavio_intctlm_mem_read[3] = {
+static CPUReadMemoryFuncs slavio_intctlm_mem_read = {
     NULL,
     NULL,
     slavio_intctlm_mem_readl,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *slavio_intctlm_mem_write[3] = {
+static CPUWriteMemoryFuncs slavio_intctlm_mem_write = {
     NULL,
     NULL,
     slavio_intctlm_mem_writel,
+    NULL,
 };
 
 void slavio_pic_info(void *opaque)
@@ -376,13 +380,13 @@ void *slavio_intctl_init(target_phys_add
 
     s->intbit_to_level = intbit_to_level;
     for (i = 0; i < MAX_CPUS; i++) {
-        slavio_intctl_io_memory = cpu_register_io_memory(0, 
slavio_intctl_mem_read, slavio_intctl_mem_write, s);
+        slavio_intctl_io_memory = cpu_register_io_memory(0, 
&slavio_intctl_mem_read, &slavio_intctl_mem_write, s);
         cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_SIZE,
                                      slavio_intctl_io_memory);
         s->cpu_irqs[i] = parent_irq[i];
     }
 
-    slavio_intctlm_io_memory = cpu_register_io_memory(0, 
slavio_intctlm_mem_read, slavio_intctlm_mem_write, s);
+    slavio_intctlm_io_memory = cpu_register_io_memory(0, 
&slavio_intctlm_mem_read, &slavio_intctlm_mem_write, s);
     cpu_register_physical_memory(addrg, INTCTLM_SIZE, 
slavio_intctlm_io_memory);
 
     register_savevm("slavio_intctl", addr, 1, slavio_intctl_save, 
slavio_intctl_load, s);
Index: hw/slavio_misc.c
===================================================================
RCS file: /sources/qemu/qemu/hw/slavio_misc.c,v
retrieving revision 1.17
diff -p -u -r1.17 slavio_misc.c
--- hw/slavio_misc.c    1 Jan 2008 17:06:38 -0000       1.17
+++ hw/slavio_misc.c    2 Jan 2008 03:07:24 -0000
@@ -112,7 +112,7 @@ void slavio_set_power_fail(void *opaque,
 }
 
 static void slavio_misc_mem_writeb(void *opaque, target_phys_addr_t addr,
-                                   uint32_t val)
+                                   uint8_t val)
 {
     MiscState *s = opaque;
 
@@ -154,10 +154,10 @@ static void slavio_misc_mem_writeb(void 
     }
 }
 
-static uint32_t slavio_misc_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint8_t slavio_misc_mem_readb(void *opaque, target_phys_addr_t addr)
 {
     MiscState *s = opaque;
-    uint32_t ret = 0;
+    uint8_t ret = 0;
 
     switch (addr & MISC_MASK) {
     case MISC_CFG:
@@ -189,16 +189,18 @@ static uint32_t slavio_misc_mem_readb(vo
     return ret;
 }
 
-static CPUReadMemoryFunc *slavio_misc_mem_read[3] = {
+static CPUReadMemoryFuncs slavio_misc_mem_read = {
     slavio_misc_mem_readb,
     NULL,
     NULL,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *slavio_misc_mem_write[3] = {
+static CPUWriteMemoryFuncs slavio_misc_mem_write = {
     slavio_misc_mem_writeb,
     NULL,
     NULL,
+    NULL,
 };
 
 static uint32_t slavio_sysctrl_mem_readl(void *opaque, target_phys_addr_t addr)
@@ -240,22 +242,25 @@ static void slavio_sysctrl_mem_writel(vo
     }
 }
 
-static CPUReadMemoryFunc *slavio_sysctrl_mem_read[3] = {
+static CPUReadMemoryFuncs slavio_sysctrl_mem_read = {
     NULL,
     NULL,
     slavio_sysctrl_mem_readl,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *slavio_sysctrl_mem_write[3] = {
+static CPUWriteMemoryFuncs slavio_sysctrl_mem_write = {
     NULL,
     NULL,
     slavio_sysctrl_mem_writel,
+    NULL,
 };
 
-static uint32_t slavio_led_mem_readw(void *opaque, target_phys_addr_t addr)
+static uint16_t slavio_led_mem_readw(void *opaque, target_phys_addr_t addr)
 {
     MiscState *s = opaque;
-    uint32_t ret = 0, saddr;
+    uint32_t saddr;
+    uint16_t ret = 0;
 
     saddr = addr & LED_MAXADDR;
     switch (saddr) {
@@ -271,7 +276,7 @@ static uint32_t slavio_led_mem_readw(voi
 }
 
 static void slavio_led_mem_writew(void *opaque, target_phys_addr_t addr,
-                                  uint32_t val)
+                                  uint16_t val)
 {
     MiscState *s = opaque;
     uint32_t saddr;
@@ -288,16 +293,18 @@ static void slavio_led_mem_writew(void *
     }
 }
 
-static CPUReadMemoryFunc *slavio_led_mem_read[3] = {
+static CPUReadMemoryFuncs slavio_led_mem_read = {
     NULL,
     slavio_led_mem_readw,
     NULL,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *slavio_led_mem_write[3] = {
+static CPUWriteMemoryFuncs slavio_led_mem_write = {
     NULL,
     slavio_led_mem_writew,
     NULL,
+    NULL,
 };
 
 static void slavio_misc_save(QEMUFile *f, void *opaque)
@@ -348,8 +355,8 @@ void *slavio_misc_init(target_phys_addr_
         return NULL;
 
     /* 8 bit registers */
-    slavio_misc_io_memory = cpu_register_io_memory(0, slavio_misc_mem_read,
-                                                   slavio_misc_mem_write, s);
+    slavio_misc_io_memory = cpu_register_io_memory(0, &slavio_misc_mem_read,
+                                                   &slavio_misc_mem_write, s);
     // Slavio control
     cpu_register_physical_memory(base + MISC_CFG, MISC_SIZE,
                                  slavio_misc_io_memory);
@@ -370,15 +377,15 @@ void *slavio_misc_init(target_phys_addr_
     s->power_base = power_base;
 
     /* 16 bit registers */
-    slavio_misc_io_memory = cpu_register_io_memory(0, slavio_led_mem_read,
-                                                   slavio_led_mem_write, s);
+    slavio_misc_io_memory = cpu_register_io_memory(0, &slavio_led_mem_read,
+                                                   &slavio_led_mem_write, s);
     /* ss600mp diag LEDs */
     cpu_register_physical_memory(base + MISC_LEDS, MISC_SIZE,
                                  slavio_misc_io_memory);
 
     /* 32 bit registers */
-    slavio_misc_io_memory = cpu_register_io_memory(0, slavio_sysctrl_mem_read,
-                                                   slavio_sysctrl_mem_write,
+    slavio_misc_io_memory = cpu_register_io_memory(0, &slavio_sysctrl_mem_read,
+                                                   &slavio_sysctrl_mem_write,
                                                    s);
     // System control
     cpu_register_physical_memory(base + MISC_SYS, SYSCTRL_SIZE,
Index: hw/slavio_serial.c
===================================================================
RCS file: /sources/qemu/qemu/hw/slavio_serial.c,v
retrieving revision 1.32
diff -p -u -r1.32 slavio_serial.c
--- hw/slavio_serial.c  1 Jan 2008 17:06:38 -0000       1.32
+++ hw/slavio_serial.c  2 Jan 2008 03:07:25 -0000
@@ -470,7 +470,7 @@ static void slavio_serial_update_paramet
 }
 
 static void slavio_serial_mem_writeb(void *opaque, target_phys_addr_t addr,
-                                     uint32_t val)
+                                     uint8_t val)
 {
     SerialState *serial = opaque;
     ChannelState *s;
@@ -563,7 +563,7 @@ static void slavio_serial_mem_writeb(voi
     }
 }
 
-static uint32_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint8_t slavio_serial_mem_readb(void *opaque, target_phys_addr_t addr)
 {
     SerialState *serial = opaque;
     ChannelState *s;
@@ -639,16 +639,18 @@ static void serial_event(void *opaque, i
         serial_receive_break(s);
 }
 
-static CPUReadMemoryFunc *slavio_serial_mem_read[3] = {
+static CPUReadMemoryFuncs slavio_serial_mem_read = {
     slavio_serial_mem_readb,
     NULL,
     NULL,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
+static CPUWriteMemoryFuncs slavio_serial_mem_write = {
     slavio_serial_mem_writeb,
     NULL,
     NULL,
+    NULL,
 };
 
 static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
@@ -720,8 +722,8 @@ SerialState *slavio_serial_init(target_p
     if (!s)
         return NULL;
 
-    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read,
-                                                     slavio_serial_mem_write,
+    slavio_serial_io_memory = cpu_register_io_memory(0, 
&slavio_serial_mem_read,
+                                                     &slavio_serial_mem_write,
                                                      s);
     cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
 
@@ -906,8 +908,8 @@ void slavio_serial_ms_kbd_init(target_ph
     s->chn[0].disabled = disabled;
     s->chn[1].disabled = disabled;
 
-    slavio_serial_io_memory = cpu_register_io_memory(0, slavio_serial_mem_read,
-                                                     slavio_serial_mem_write,
+    slavio_serial_io_memory = cpu_register_io_memory(0, 
&slavio_serial_mem_read,
+                                                     &slavio_serial_mem_write,
                                                      s);
     cpu_register_physical_memory(base, SERIAL_SIZE, slavio_serial_io_memory);
 
Index: hw/slavio_timer.c
===================================================================
RCS file: /sources/qemu/qemu/hw/slavio_timer.c,v
retrieving revision 1.28
diff -p -u -r1.28 slavio_timer.c
--- hw/slavio_timer.c   1 Jan 2008 17:06:38 -0000       1.28
+++ hw/slavio_timer.c   2 Jan 2008 03:07:26 -0000
@@ -174,7 +174,34 @@ static uint32_t slavio_timer_mem_readl(v
         ret = 0;
         break;
     }
-    DPRINTF("read " TARGET_FMT_plx " = %08x\n", addr, ret);
+    DPRINTF("read 32 " TARGET_FMT_plx " = %08x\n", addr, ret);
+
+    return ret;
+}
+
+static uint64_t slavio_timer_mem_readq(void *opaque, target_phys_addr_t addr)
+{
+    SLAVIO_TIMERState *s = opaque;
+    uint32_t saddr;
+    uint64_t ret = 0;
+
+    saddr = (addr & TIMER_MAXADDR) >> 2;
+    switch (saddr) {
+    case TIMER_LIMIT:
+        // read limit (system counter mode) or read most signifying
+        // part of counter (user mode)
+        if (slavio_timer_is_user(s)) {
+            // read user timer 
+            slavio_timer_get_out(s);
+            ret = (uint64_t)s->counthigh << 32 | s->count;
+        }
+        break;
+    default:
+        DPRINTF("invalid read address " TARGET_FMT_plx "\n", addr);
+        ret = 0;
+        break;
+    }
+    printf("read 64 " TARGET_FMT_plx " = %016llx\n", addr, ret);
 
     return ret;
 }
@@ -185,7 +212,7 @@ static void slavio_timer_mem_writel(void
     SLAVIO_TIMERState *s = opaque;
     uint32_t saddr;
 
-    DPRINTF("write " TARGET_FMT_plx " %08x\n", addr, val);
+    DPRINTF("write 32 " TARGET_FMT_plx " %08x\n", addr, val);
     saddr = (addr & TIMER_MAXADDR) >> 2;
     switch (saddr) {
     case TIMER_LIMIT:
@@ -275,16 +302,43 @@ static void slavio_timer_mem_writel(void
     }
 }
 
-static CPUReadMemoryFunc *slavio_timer_mem_read[3] = {
+static void slavio_timer_mem_writeq(void *opaque, target_phys_addr_t addr,
+                                    uint64_t val)
+{
+    SLAVIO_TIMERState *s = opaque;
+    uint32_t saddr;
+
+    printf("write 64 " TARGET_FMT_plx " %016llx\n", addr, val);
+    saddr = (addr & TIMER_MAXADDR) >> 2;
+    switch (saddr) {
+    case TIMER_LIMIT:
+        if (slavio_timer_is_user(s)) {
+            // set user counter MSW, reset counter
+            qemu_irq_lower(s->irq);
+            s->limit = TIMER_MAX_COUNT64;
+            DPRINTF("processor %d user timer reset\n", s->slave_index);
+            if (s->timer)
+                ptimer_set_limit(s->timer, LIMIT_TO_PERIODS(s->limit), 1);
+        }
+        break;
+    default:
+        DPRINTF("invalid write address " TARGET_FMT_plx "\n", addr);
+        break;
+    }
+}
+
+static CPUReadMemoryFuncs slavio_timer_mem_read = {
     NULL,
     NULL,
     slavio_timer_mem_readl,
+    slavio_timer_mem_readq,
 };
 
-static CPUWriteMemoryFunc *slavio_timer_mem_write[3] = {
+static CPUWriteMemoryFuncs slavio_timer_mem_write = {
     NULL,
     NULL,
     slavio_timer_mem_writel,
+    slavio_timer_mem_writeq,
 };
 
 static void slavio_timer_save(QEMUFile *f, void *opaque)
@@ -355,8 +409,8 @@ static SLAVIO_TIMERState *slavio_timer_i
         ptimer_set_period(s->timer, TIMER_PERIOD);
     }
 
-    slavio_timer_io_memory = cpu_register_io_memory(0, slavio_timer_mem_read,
-                                                    slavio_timer_mem_write, s);
+    slavio_timer_io_memory = cpu_register_io_memory(0, &slavio_timer_mem_read,
+                                                    &slavio_timer_mem_write, 
s);
     if (master)
         cpu_register_physical_memory(addr, CPU_TIMER_SIZE,
                                      slavio_timer_io_memory);
Index: hw/sparc32_dma.c
===================================================================
RCS file: /sources/qemu/qemu/hw/sparc32_dma.c,v
retrieving revision 1.11
diff -p -u -r1.11 sparc32_dma.c
--- hw/sparc32_dma.c    1 Jan 2008 17:06:38 -0000       1.11
+++ hw/sparc32_dma.c    2 Jan 2008 03:07:26 -0000
@@ -197,16 +197,18 @@ static void dma_mem_writel(void *opaque,
     s->dmaregs[saddr] = val;
 }
 
-static CPUReadMemoryFunc *dma_mem_read[3] = {
+static CPUReadMemoryFuncs dma_mem_read = {
     NULL,
     NULL,
     dma_mem_readl,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *dma_mem_write[3] = {
+static CPUWriteMemoryFuncs dma_mem_write = {
     NULL,
     NULL,
     dma_mem_writel,
+    NULL,
 };
 
 static void dma_reset(void *opaque)
@@ -252,7 +254,7 @@ void *sparc32_dma_init(target_phys_addr_
     s->irq = parent_irq;
     s->iommu = iommu;
 
-    dma_io_memory = cpu_register_io_memory(0, dma_mem_read, dma_mem_write, s);
+    dma_io_memory = cpu_register_io_memory(0, &dma_mem_read, &dma_mem_write, 
s);
     cpu_register_physical_memory(daddr, DMA_SIZE, dma_io_memory);
 
     register_savevm("sparc32_dma", daddr, 2, dma_save, dma_load, s);
Index: hw/sun4c_intctl.c
===================================================================
RCS file: /sources/qemu/qemu/hw/sun4c_intctl.c,v
retrieving revision 1.2
diff -p -u -r1.2 sun4c_intctl.c
--- hw/sun4c_intctl.c   1 Jan 2008 17:06:38 -0000       1.2
+++ hw/sun4c_intctl.c   2 Jan 2008 03:07:26 -0000
@@ -57,7 +57,7 @@ typedef struct Sun4c_INTCTLState {
 
 static void sun4c_check_interrupts(void *opaque);
 
-static uint32_t sun4c_intctl_mem_readb(void *opaque, target_phys_addr_t addr)
+static uint8_t sun4c_intctl_mem_readb(void *opaque, target_phys_addr_t addr)
 {
     Sun4c_INTCTLState *s = opaque;
     uint32_t ret;
@@ -68,7 +68,7 @@ static uint32_t sun4c_intctl_mem_readb(v
     return ret;
 }
 
-static void sun4c_intctl_mem_writeb(void *opaque, target_phys_addr_t addr, 
uint32_t val)
+static void sun4c_intctl_mem_writeb(void *opaque, target_phys_addr_t addr, 
uint8_t val)
 {
     Sun4c_INTCTLState *s = opaque;
 
@@ -78,16 +78,18 @@ static void sun4c_intctl_mem_writeb(void
     sun4c_check_interrupts(s);
 }
 
-static CPUReadMemoryFunc *sun4c_intctl_mem_read[3] = {
+static CPUReadMemoryFuncs sun4c_intctl_mem_read = {
     sun4c_intctl_mem_readb,
     NULL,
     NULL,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *sun4c_intctl_mem_write[3] = {
+static CPUWriteMemoryFuncs sun4c_intctl_mem_write = {
     sun4c_intctl_mem_writeb,
     NULL,
     NULL,
+    NULL,
 };
 
 void sun4c_pic_info(void *opaque)
@@ -206,8 +208,8 @@ void *sun4c_intctl_init(target_phys_addr
     if (!s)
         return NULL;
 
-    sun4c_intctl_io_memory = cpu_register_io_memory(0, sun4c_intctl_mem_read,
-                                                    sun4c_intctl_mem_write, s);
+    sun4c_intctl_io_memory = cpu_register_io_memory(0, &sun4c_intctl_mem_read,
+                                                    &sun4c_intctl_mem_write, 
s);
     cpu_register_physical_memory(addr, INTCTL_SIZE, sun4c_intctl_io_memory);
     s->cpu_irqs = parent_irq;
 
Index: hw/tcx.c
===================================================================
RCS file: /sources/qemu/qemu/hw/tcx.c,v
retrieving revision 1.26
diff -p -u -r1.26 tcx.c
--- hw/tcx.c    1 Jan 2008 17:06:38 -0000       1.26
+++ hw/tcx.c    2 Jan 2008 03:07:26 -0000
@@ -456,16 +456,18 @@ static void tcx_dac_writel(void *opaque,
     return;
 }
 
-static CPUReadMemoryFunc *tcx_dac_read[3] = {
+static CPUReadMemoryFuncs tcx_dac_read = {
     NULL,
     NULL,
     tcx_dac_readl,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *tcx_dac_write[3] = {
+static CPUWriteMemoryFuncs tcx_dac_write = {
     NULL,
     NULL,
     tcx_dac_writel,
+    NULL,
 };
 
 static uint32_t tcx_dummy_readl(void *opaque, target_phys_addr_t addr)
@@ -478,16 +480,18 @@ static void tcx_dummy_writel(void *opaqu
 {
 }
 
-static CPUReadMemoryFunc *tcx_dummy_read[3] = {
+static CPUReadMemoryFuncs tcx_dummy_read = {
     NULL,
     NULL,
     tcx_dummy_readl,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *tcx_dummy_write[3] = {
+static CPUWriteMemoryFuncs tcx_dummy_write = {
     NULL,
     NULL,
     tcx_dummy_writel,
+    NULL,
 };
 
 void tcx_init(DisplayState *ds, target_phys_addr_t addr, uint8_t *vram_base,
@@ -515,10 +519,10 @@ void tcx_init(DisplayState *ds, target_p
     vram_offset += size;
     vram_base += size;
 
-    io_memory = cpu_register_io_memory(0, tcx_dac_read, tcx_dac_write, s);
+    io_memory = cpu_register_io_memory(0, &tcx_dac_read, &tcx_dac_write, s);
     cpu_register_physical_memory(addr + 0x00200000ULL, TCX_DAC_NREGS, 
io_memory);
 
-    dummy_memory = cpu_register_io_memory(0, tcx_dummy_read, tcx_dummy_write,
+    dummy_memory = cpu_register_io_memory(0, &tcx_dummy_read, &tcx_dummy_write,
                                           s);
     cpu_register_physical_memory(addr + 0x00700000ULL, TCX_TEC_NREGS,
                                  dummy_memory);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]