qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH] 64 bit I/O v5


From: Robert Reif
Subject: [Qemu-devel] [PATCH] 64 bit I/O v5
Date: Wed, 18 Mar 2009 19:58:06 -0400
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081204 SeaMonkey/1.1.14

This patch adds 64 bit I/O support to QEMU.

This version addresses all comments from previous versions.

This version is mostly a rebase on current svn.  The only changes are
removing the sparc driver changes and adding #define DEBUG_IO64
so code that needs to be converted can be identified.  Unfortunately
physical addresses are no longer used so finding the hardware drivers
that need converting is not straightforward anymore.

Please test it with #define DEBUG_IO64 to find which hardware
drivers need updating.
Index: softmmu_template.h
===================================================================
--- softmmu_template.h  (revision 6858)
+++ softmmu_template.h  (working copy)
@@ -65,17 +65,7 @@
     }
 
     env->mem_io_vaddr = addr;
-#if SHIFT <= 2
-    res = io_mem_read[index][SHIFT](io_mem_opaque[index], physaddr);
-#else
-#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);
-#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;
-#endif
-#endif /* SHIFT > 2 */
+    res = io_mem_read[index].SUFFIX(io_mem_opaque[index], physaddr);
 #ifdef USE_KQEMU
     env->last_io_time = cpu_get_time_fast();
 #endif
@@ -210,17 +200,7 @@
 
     env->mem_io_vaddr = addr;
     env->mem_io_pc = (unsigned long)retaddr;
-#if SHIFT <= 2
-    io_mem_write[index][SHIFT](io_mem_opaque[index], physaddr, val);
-#else
-#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);
-#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);
-#endif
-#endif /* SHIFT > 2 */
+    io_mem_write[index].SUFFIX(io_mem_opaque[index], physaddr, val);
 #ifdef USE_KQEMU
     env->last_io_time = cpu_get_time_fast();
 #endif
Index: exec.c
===================================================================
--- exec.c      (revision 6858)
+++ exec.c      (working copy)
@@ -48,6 +48,7 @@
 //#define DEBUG_FLUSH
 //#define DEBUG_TLB
 //#define DEBUG_UNASSIGNED
+//#define DEBUG_IO64
 
 /* make various TB consistency checks */
 //#define DEBUG_TB_CHECK
@@ -173,8 +174,8 @@
 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];
+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 char io_mem_used[IO_MEM_NB_ENTRIES];
 static int io_mem_watch;
@@ -2441,6 +2442,17 @@
     return 0;
 }
 
+static uint64_t unassigned_mem_readq(void *opaque, target_phys_addr_t addr)
+{
+#ifdef DEBUG_UNASSIGNED
+    printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
+#endif
+#if defined(TARGET_SPARC)
+    do_unassigned_access(addr, 0, 0, 0, 8);
+#endif
+    return 0;
+}
+
 static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, 
uint32_t val)
 {
 #ifdef DEBUG_UNASSIGNED
@@ -2471,16 +2483,28 @@
 #endif
 }
 
-static CPUReadMemoryFunc *unassigned_mem_read[3] = {
+static void unassigned_mem_writeq(void *opaque, target_phys_addr_t addr, 
uint64_t val)
+{
+#ifdef DEBUG_UNASSIGNED
+    printf("Unassigned mem write " TARGET_FMT_plx " = 0x%016llx\n", addr, val);
+#endif
+#if defined(TARGET_SPARC)
+    do_unassigned_access(addr, 1, 0, 0, 8);
+#endif
+}
+
+static CPUReadMemoryFuncs unassigned_mem_read = {
     unassigned_mem_readb,
     unassigned_mem_readw,
     unassigned_mem_readl,
+    unassigned_mem_readq,
 };
 
-static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
+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 ram_addr,
@@ -2558,16 +2582,43 @@
         tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr);
 }
 
-static CPUReadMemoryFunc *error_mem_read[3] = {
+static void notdirty_mem_writeq(void *opaque, target_phys_addr_t ram_addr,
+                                uint64_t val)
+{
+    int dirty_flags;
+    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, 8);
+        dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
+#endif
+    }
+    stq_p(phys_ram_base + ram_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, cpu_single_env->mem_io_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,
 };
 
 /* Generate a debug exception if a watchpoint has been hit.  */
@@ -2636,6 +2687,12 @@
     return ldl_phys(addr);
 }
 
+static uint64_t watch_mem_readq(void *opaque, target_phys_addr_t addr)
+{
+    check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x7, BP_MEM_READ);
+    return ldq_phys(addr);
+}
+
 static void watch_mem_writeb(void *opaque, target_phys_addr_t addr,
                              uint32_t val)
 {
@@ -2657,16 +2714,25 @@
     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)
+{
+    check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x7, BP_MEM_WRITE);
+    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,
 };
 
 static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t 
addr,
@@ -2755,23 +2821,54 @@
     subpage_writelen(opaque, addr, value, 2);
 }
 
-static CPUReadMemoryFunc *subpage_read[] = {
-    &subpage_readb,
-    &subpage_readw,
-    &subpage_readl,
+static uint64_t subpage_readq (void *opaque, target_phys_addr_t addr)
+{
+    subpage_t *mmio = (subpage_t *)opaque;
+    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, 3, addr, idx);
+#endif
+    return 
((CPUReadMemoryFunc64*)(*mmio->mem_read[idx][3]))(mmio->opaque[idx][0][3],
+                                       addr + mmio->region_offset[idx][0][3]);
+}
+
+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);
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value 
%016llx\n", __func__,
+           mmio, 3, addr, idx, value);
+#endif
+    
((CPUWriteMemoryFunc64*)(*mmio->mem_write[idx][3]))(mmio->opaque[idx][1][3],
+                                  addr + mmio->region_offset[idx][1][3],
+                                  value);
+}
+
+static CPUReadMemoryFuncs subpage_read = {
+    subpage_readb,
+    subpage_readw,
+    subpage_readl,
+    subpage_readq,
 };
 
-static CPUWriteMemoryFunc *subpage_write[] = {
-    &subpage_writeb,
-    &subpage_writew,
-    &subpage_writel,
+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,
                              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;
@@ -2783,18 +2880,46 @@
 #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;
-            }
+        if (io_mem_read[memory].b) {
+            mmio->mem_read[idx][0] = &io_mem_read[memory].b;
+            mmio->opaque[idx][0][0] = io_mem_opaque[memory];
+            mmio->region_offset[idx][0][0] = region_offset;
         }
+        if (io_mem_write[memory].b) {
+            mmio->mem_write[idx][0] = &io_mem_write[memory].b;
+            mmio->opaque[idx][1][0] = io_mem_opaque[memory];
+            mmio->region_offset[idx][1][0] = region_offset;
+        }
+        if (io_mem_read[memory].w) {
+            mmio->mem_read[idx][1] = &io_mem_read[memory].w;
+            mmio->opaque[idx][0][1] = io_mem_opaque[memory];
+            mmio->region_offset[idx][0][1] = region_offset;
+        }
+        if (io_mem_write[memory].w) {
+            mmio->mem_write[idx][1] = &io_mem_write[memory].w;
+            mmio->opaque[idx][1][1] = io_mem_opaque[memory];
+            mmio->region_offset[idx][1][1] = region_offset;
+        }
+        if (io_mem_read[memory].l) {
+            mmio->mem_read[idx][2] = &io_mem_read[memory].l;
+            mmio->opaque[idx][0][2] = io_mem_opaque[memory];
+            mmio->region_offset[idx][0][2] = region_offset;
+        }
+        if (io_mem_write[memory].l) {
+            mmio->mem_write[idx][2] = &io_mem_write[memory].l;
+            mmio->opaque[idx][1][2] = io_mem_opaque[memory];
+            mmio->region_offset[idx][1][2] = region_offset;
+        }
+        if (io_mem_read[memory].q) {
+            mmio->mem_read[idx][3] = 
(CPUReadMemoryFunc**)&io_mem_read[memory].q;
+            mmio->opaque[idx][0][3] = io_mem_opaque[memory];
+            mmio->region_offset[idx][0][3] = region_offset;
+        }
+        if (io_mem_write[memory].q) {
+            mmio->mem_write[idx][3] = 
(CPUWriteMemoryFunc**)&io_mem_write[memory].q;
+            mmio->opaque[idx][1][3] = io_mem_opaque[memory];
+            mmio->region_offset[idx][1][3] = region_offset;
+        }
     }
 
     return 0;
@@ -2809,7 +2934,7 @@
     mmio = qemu_mallocz(sizeof(subpage_t));
 
     mmio->base = base;
-    subpage_memory = cpu_register_io_memory(0, subpage_read, subpage_write, 
mmio);
+    subpage_memory = cpu_register_io_memory64(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);
@@ -2838,19 +2963,71 @@
 {
     int i;
 
-    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_memory64(IO_MEM_ROM >> IO_MEM_SHIFT, &error_mem_read, 
&unassigned_mem_write, NULL);
+    cpu_register_io_memory64(IO_MEM_UNASSIGNED >> IO_MEM_SHIFT, 
&unassigned_mem_read, &unassigned_mem_write, NULL);
+    cpu_register_io_memory64(IO_MEM_NOTDIRTY >> IO_MEM_SHIFT, &error_mem_read, 
&notdirty_mem_write, NULL);
     for (i=0; i<5; i++)
         io_mem_used[i] = 1;
 
-    io_mem_watch = cpu_register_io_memory(0, watch_mem_read,
-                                          watch_mem_write, NULL);
+    io_mem_watch = cpu_register_io_memory64(0, &watch_mem_read,
+                                            &watch_mem_write, NULL);
     /* alloc dirty bits array */
     phys_ram_dirty = qemu_vmalloc(phys_ram_size >> TARGET_PAGE_BITS);
     memset(phys_ram_dirty, 0xff, phys_ram_size >> TARGET_PAGE_BITS);
 }
 
+/* mem_readq and mem_writeq are helper functions that are
+   used to emulate 64 bit accesses for hardware devices
+   that are doing 64 bit mmio but have not been converted
+   to use cpu_register_io_memory64.  These functions should
+   only be used until all hardware devices are converted to
+   the new api and then removed because they are not efficient.  */
+static void mem_writeq(void *opaque, target_phys_addr_t addr, uint64_t val)
+{
+    int i;
+
+    for (i = 0; i < IO_MEM_NB_ENTRIES; i++) {
+        if (io_mem_opaque[i] == opaque && io_mem_used[i]) {
+#ifdef TARGET_WORDS_BIGENDIAN
+            io_mem_write[i].l(opaque, addr, val >> 32);
+            io_mem_write[i].l(opaque, addr + 4, val);
+#else
+            io_mem_write[i].l(opaque, addr, val);
+            io_mem_write[i].l(opaque, addr + 4, val >> 32);
+#endif
+#ifdef DEBUG_IO64
+            printf("FIXME: emulating 64 bit I/O using 32 bit I/O.\n");
+#endif
+            return;
+        }
+    }
+}
+
+static uint64_t mem_readq(void *opaque, target_phys_addr_t addr)
+{
+    int i;
+
+    for (i = 0; i < IO_MEM_NB_ENTRIES; i++) {
+        if (io_mem_opaque[i] == opaque && io_mem_used[i]) {
+            uint64_t val;
+
+#ifdef TARGET_WORDS_BIGENDIAN
+            val = (uint64_t)io_mem_read[i].l(opaque, addr) << 32;
+            val |= io_mem_read[i].l(opaque, addr + 4);
+#else
+            val = io_mem_read[i].l(opaque, addr);
+            val |= (uint64_t)io_mem_read[i].l(opaque, addr + 4) << 32;
+#endif
+#ifdef DEBUG_IO64
+            printf("FIXME: emulating 64 bit I/O using 32 bit I/O.\n");
+#endif
+            return val;
+        }
+    }
+
+    return 0;
+}
+
 /* 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. The
@@ -2864,8 +3041,38 @@
                            CPUWriteMemoryFunc **mem_write,
                            void *opaque)
 {
-    int i, subwidth = 0;
+    if (io_index <= 0) {
+        io_index = get_free_io_mem_idx();
+        if (io_index == -1)
+            return io_index;
+    } else {
+        if (io_index >= IO_MEM_NB_ENTRIES)
+            return -1;
+    }
 
+    io_mem_read[io_index].b = mem_read[0];
+    io_mem_write[io_index].b = mem_write[0];
+
+    io_mem_read[io_index].w = mem_read[1];
+    io_mem_write[io_index].w = mem_write[1];
+
+    io_mem_read[io_index].l = mem_read[2];
+    io_mem_write[io_index].l = mem_write[2];
+
+    io_mem_read[io_index].q = mem_readq;
+    io_mem_write[io_index].q = mem_writeq;
+
+    io_mem_opaque[io_index] = opaque;
+    return (io_index << IO_MEM_SHIFT) | IO_MEM_SUBWIDTH;
+}
+
+int cpu_register_io_memory64(int io_index,
+                             CPUReadMemoryFuncs *mem_read,
+                             CPUWriteMemoryFuncs *mem_write,
+                             void *opaque)
+{
+    int subwidth = 0;
+
     if (io_index <= 0) {
         io_index = get_free_io_mem_idx();
         if (io_index == -1)
@@ -2875,37 +3082,36 @@
             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];
-    }
+    if (!mem_read->b || !mem_write->b ||
+        !mem_read->w || !mem_write->w ||
+        !mem_read->l || !mem_write->l ||
+        !mem_read->q || !mem_write->q)
+        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;
 }
 
 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_read[io_index] = unassigned_mem_read;
+    io_mem_write[io_index] = unassigned_mem_write;
     io_mem_opaque[io_index] = NULL;
     io_mem_used[io_index] = 0;
 }
 
 CPUWriteMemoryFunc **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].b;
 }
 
 CPUReadMemoryFunc **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].b;
 }
 
 #endif /* !defined(CONFIG_USER_ONLY) */
@@ -2983,20 +3189,25 @@
                     addr1 = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
                 /* XXX: could force cpu_single_env to NULL to avoid
                    potential bugs */
-                if (l >= 4 && ((addr1 & 3) == 0)) {
+                if (l >= 8 && ((addr1 & 7) == 0)) {
+                    /* 64 bit write access */
+                    uint64_t val64 = ldq_p(buf);
+                    io_mem_write[io_index].q(io_mem_opaque[io_index], addr1, 
val64);
+                    l = 8;
+                } else 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_write[io_index].l(io_mem_opaque[io_index], 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_write[io_index].w(io_mem_opaque[io_index], 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_write[io_index].b(io_mem_opaque[io_index], addr1, 
val);
                     l = 1;
                 }
             } else {
@@ -3021,19 +3232,24 @@
                 io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
                 if (p)
                     addr1 = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
-                if (l >= 4 && ((addr1 & 3) == 0)) {
+                if (l >= 8 && ((addr1 & 7) == 0)) {
+                    /* 64 bit read access */
+                    uint64_t val64 = 
io_mem_read[io_index].q(io_mem_opaque[io_index], addr1);
+                    stq_p(buf, val64);
+                    l = 8;
+                } else 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_read[io_index].l(io_mem_opaque[io_index], 
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_read[io_index].w(io_mem_opaque[io_index], 
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_read[io_index].b(io_mem_opaque[io_index], 
addr1);
                     stb_p(buf, val);
                     l = 1;
                 }
@@ -3254,7 +3470,7 @@
         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_read[io_index].l(io_mem_opaque[io_index], addr);
     } else {
         /* RAM case */
         ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
@@ -3286,13 +3502,7 @@
         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
         if (p)
             addr = (addr & ~TARGET_PAGE_MASK) + p->region_offset;
-#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);
-#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;
-#endif
+        val = io_mem_read[io_index].q(io_mem_opaque[io_index], addr);
     } else {
         /* RAM case */
         ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
@@ -3339,7 +3549,7 @@
         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_write[io_index].l(io_mem_opaque[io_index], addr, val);
     } else {
         unsigned long addr1 = (pd & TARGET_PAGE_MASK) + (addr & 
~TARGET_PAGE_MASK);
         ptr = phys_ram_base + addr1;
@@ -3375,13 +3585,7 @@
         io_index = (pd >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
         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);
-#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);
-#endif
+        io_mem_write[io_index].q(io_mem_opaque[io_index], addr, val);
     } else {
         ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
             (addr & ~TARGET_PAGE_MASK);
@@ -3408,7 +3612,7 @@
         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_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: exec-all.h
===================================================================
--- exec-all.h  (revision 6858)
+++ exec-all.h  (working copy)
@@ -265,8 +265,8 @@
 
 TranslationBlock *tb_find_pc(unsigned long pc_ptr);
 
-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];
 
 #include "qemu-lock.h"
Index: cpu-all.h
===================================================================
--- cpu-all.h   (revision 6858)
+++ cpu-all.h   (working copy)
@@ -892,6 +892,23 @@
 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 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 {
+    CPUWriteMemoryFunc   *b;
+    CPUWriteMemoryFunc   *w;
+    CPUWriteMemoryFunc   *l;
+    CPUWriteMemoryFunc64 *q;
+} CPUWriteMemoryFuncs;
+
+typedef struct CPUReadMemoryFuncs {
+    CPUReadMemoryFunc   *b;
+    CPUReadMemoryFunc   *w;
+    CPUReadMemoryFunc   *l;
+    CPUReadMemoryFunc64 *q;
+} CPUReadMemoryFuncs;
+
 void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
                                          ram_addr_t size,
                                          ram_addr_t phys_offset,
@@ -910,6 +927,10 @@
                            CPUReadMemoryFunc **mem_read,
                            CPUWriteMemoryFunc **mem_write,
                            void *opaque);
+int cpu_register_io_memory64(int io_index,
+                             CPUReadMemoryFuncs *mem_read,
+                             CPUWriteMemoryFuncs *mem_write,
+                             void *opaque);
 void cpu_unregister_io_memory(int table_address);
 CPUWriteMemoryFunc **cpu_get_io_memory_write(int io_index);
 CPUReadMemoryFunc **cpu_get_io_memory_read(int io_index);

reply via email to

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