qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [RFC] 64 bit device I/O


From: Robert Reif
Subject: [Qemu-devel] [RFC] 64 bit device I/O
Date: Sat, 21 Feb 2009 10:05:29 -0500
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.19) Gecko/20081204 SeaMonkey/1.1.14

Here is my second proof of concept attempt at supporting
64 bit device I/O.

This attempt doesn't require changing all devices to add a forth
function for 64 bit I/O unless actually needed.  Unfortunately it
does require an ugly cast when 64 bit is required.

This has been tested only on sparc32 and only the slavio_timer
hw device has been converted to support 64 bit I/O.

All other architectures should work as before except when
64 bit I/O is performed.  They will now get an unassigned
access error because there is no 64 bit callback defined by
default.  Adding a 64 bit callback and using
cpu_register_io_memory64 to register the new callback
will fix it.  See slavio_timer.c to to see how the new callback
is registered.

Comments welcome.
Index: softmmu_template.h
===================================================================
--- softmmu_template.h  (revision 6636)
+++ softmmu_template.h  (working copy)
@@ -68,13 +68,7 @@
 #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
+    res = 
((CPUReadMemoryFunc64*)(io_mem_read[index][3]))(io_mem_opaque[index], physaddr);
 #endif /* SHIFT > 2 */
 #ifdef USE_KQEMU
     env->last_io_time = cpu_get_time_fast();
@@ -213,13 +207,7 @@
 #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
+    ((CPUWriteMemoryFunc64*)(io_mem_write[index][3]))(io_mem_opaque[index], 
physaddr, val);
 #endif /* SHIFT > 2 */
 #ifdef USE_KQEMU
     env->last_io_time = cpu_get_time_fast();
Index: exec.c
===================================================================
--- exec.c      (revision 6636)
+++ exec.c      (working copy)
@@ -47,7 +47,7 @@
 //#define DEBUG_TB_INVALIDATE
 //#define DEBUG_FLUSH
 //#define DEBUG_TLB
-//#define DEBUG_UNASSIGNED
+#define DEBUG_UNASSIGNED
 
 /* make various TB consistency checks */
 //#define DEBUG_TB_CHECK
@@ -197,8 +197,8 @@
 #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];
+    CPUReadMemoryFunc *mem_read[TARGET_PAGE_SIZE][4];
+    CPUWriteMemoryFunc *mem_write[TARGET_PAGE_SIZE][4];
     void *opaque[TARGET_PAGE_SIZE][2][4];
     ram_addr_t region_offset[TARGET_PAGE_SIZE][2][4];
 } subpage_t;
@@ -2419,6 +2419,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
@@ -2449,16 +2460,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%llx\n", addr, val);
+#endif
+#if defined(TARGET_SPARC)
+    do_unassigned_access(addr, 1, 0, 0, 8);
+#endif
+}
+
+static CPUReadMemoryFunc *unassigned_mem_read[4] = {
     unassigned_mem_readb,
     unassigned_mem_readw,
     unassigned_mem_readl,
+    (CPUReadMemoryFunc*)unassigned_mem_readq,
 };
 
-static CPUWriteMemoryFunc *unassigned_mem_write[3] = {
+static CPUWriteMemoryFunc *unassigned_mem_write[4] = {
     unassigned_mem_writeb,
     unassigned_mem_writew,
     unassigned_mem_writel,
+    (CPUWriteMemoryFunc*)unassigned_mem_writeq,
 };
 
 static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr,
@@ -2536,16 +2559,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 CPUReadMemoryFunc *error_mem_read[4] = {
     NULL, /* never used */
     NULL, /* never used */
     NULL, /* never used */
+    NULL, /* never used */
 };
 
-static CPUWriteMemoryFunc *notdirty_mem_write[3] = {
+static CPUWriteMemoryFunc *notdirty_mem_write[4] = {
     notdirty_mem_writeb,
     notdirty_mem_writew,
     notdirty_mem_writel,
+    (CPUWriteMemoryFunc*)notdirty_mem_writeq,
 };
 
 /* Generate a debug exception if a watchpoint has been hit.  */
@@ -2614,6 +2664,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)
 {
@@ -2635,16 +2691,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 CPUReadMemoryFunc *watch_mem_read[4] = {
     watch_mem_readb,
     watch_mem_readw,
     watch_mem_readl,
+    (CPUReadMemoryFunc*)watch_mem_readq,
 };
 
-static CPUWriteMemoryFunc *watch_mem_write[3] = {
+static CPUWriteMemoryFunc *watch_mem_write[4] = {
     watch_mem_writeb,
     watch_mem_writew,
     watch_mem_writel,
+    (CPUWriteMemoryFunc*)watch_mem_writeq,
 };
 
 static inline uint32_t subpage_readlen (subpage_t *mmio, target_phys_addr_t 
addr,
@@ -2658,12 +2723,28 @@
     printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
            mmio, len, addr, idx);
 #endif
-    ret = (**mmio->mem_read[idx][len])(mmio->opaque[idx][0][len],
+    ret = mmio->mem_read[idx][len](mmio->opaque[idx][0][len],
                                        addr + 
mmio->region_offset[idx][0][len]);
 
     return ret;
 }
 
+static inline uint64_t subpage_readlen64 (subpage_t *mmio, target_phys_addr_t 
addr)
+{
+    uint32_t ret;
+    unsigned int idx;
+
+    idx = SUBPAGE_IDX(addr);
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: subpage %p addr " TARGET_FMT_plx " idx %d\n", __func__,
+           mmio, addr, idx);
+#endif
+    ret = 
((CPUReadMemoryFunc64*)mmio->mem_read[idx][3])(mmio->opaque[idx][0][3],
+                                       addr + mmio->region_offset[idx][0][3]);
+
+    return ret;
+}
+
 static inline void subpage_writelen (subpage_t *mmio, target_phys_addr_t addr,
                               uint32_t value, unsigned int len)
 {
@@ -2674,11 +2755,26 @@
     printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d value 
%08x\n", __func__,
            mmio, len, addr, idx, value);
 #endif
-    (**mmio->mem_write[idx][len])(mmio->opaque[idx][1][len],
+    mmio->mem_write[idx][len](mmio->opaque[idx][1][len],
                                   addr + mmio->region_offset[idx][1][len],
                                   value);
 }
 
+static inline void subpage_writelen64 (subpage_t *mmio, target_phys_addr_t 
addr,
+                              uint64_t value)
+{
+    unsigned int idx;
+
+    idx = SUBPAGE_IDX(addr);
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: subpage %p addr " TARGET_FMT_plx " idx %d value %016llx\n", 
__func__,
+           mmio, addr, idx, value);
+#endif
+    ((CPUWriteMemoryFunc64*)mmio->mem_write[idx][3])(mmio->opaque[idx][1][3],
+                                  addr + mmio->region_offset[idx][1][3],
+                                  value);
+}
+
 static uint32_t subpage_readb (void *opaque, target_phys_addr_t addr)
 {
 #if defined(DEBUG_SUBPAGE)
@@ -2733,16 +2829,36 @@
     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)
+{
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
+#endif
+
+    return subpage_readlen64(opaque, addr);
+}
+
+static void subpage_writeq (void *opaque,
+                         target_phys_addr_t addr, uint64_t value)
+{
+#if defined(DEBUG_SUBPAGE)
+    printf("%s: addr " TARGET_FMT_plx " val %016llx\n", __func__, addr, value);
+#endif
+    subpage_writelen64(opaque, addr, value);
+}
+
+static CPUReadMemoryFunc *subpage_read[4] = {
+    subpage_readb,
+    subpage_readw,
+    subpage_readl,
+    (CPUReadMemoryFunc*)subpage_readq,
 };
 
-static CPUWriteMemoryFunc *subpage_write[] = {
-    &subpage_writeb,
-    &subpage_writew,
-    &subpage_writel,
+static CPUWriteMemoryFunc *subpage_write[4] = {
+    subpage_writeb,
+    subpage_writew,
+    subpage_writel,
+    (CPUWriteMemoryFunc*)subpage_writeq,
 };
 
 static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
@@ -2763,12 +2879,12 @@
     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->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->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;
             }
@@ -2787,7 +2903,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);
@@ -2816,14 +2932,14 @@
 {
     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);
@@ -2859,10 +2975,38 @@
         io_mem_read[io_index][i] = mem_read[i];
         io_mem_write[io_index][i] = mem_write[i];
     }
+    io_mem_read[io_index][3] = 0;
+    io_mem_write[io_index][3] = 0;
     io_mem_opaque[io_index] = opaque;
     return (io_index << IO_MEM_SHIFT) | subwidth;
 }
 
+int cpu_register_io_memory64(int io_index,
+                             CPUReadMemoryFunc **mem_read,
+                             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;
+    }
+
+    for(i = 0;i < 4; i++) {
+        if (!mem_read[i] || !mem_write[i])
+            subwidth = IO_MEM_SUBWIDTH;
+        io_mem_read[io_index][i] = mem_read[i];
+        io_mem_write[io_index][i] = mem_write[i];
+    }
+    io_mem_opaque[io_index] = opaque;
+    return (io_index << IO_MEM_SHIFT) | subwidth;
+}
+
 void cpu_unregister_io_memory(int io_table_address)
 {
     int i;
@@ -2876,6 +3020,19 @@
     io_mem_used[io_index] = 0;
 }
 
+void cpu_unregister_io_memory64(int io_table_address)
+{
+    int i;
+    int io_index = io_table_address >> IO_MEM_SHIFT;
+
+    for (i=0;i < 4; i++) {
+        io_mem_read[io_index][i] = unassigned_mem_read[i];
+        io_mem_write[io_index][i] = unassigned_mem_write[i];
+    }
+    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];
@@ -2937,6 +3094,7 @@
     int l, io_index;
     uint8_t *ptr;
     uint32_t val;
+    uint64_t val64;
     target_phys_addr_t page;
     unsigned long pd;
     PhysPageDesc *p;
@@ -2961,7 +3119,12 @@
                     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 */
+                    val64 = ldq_p(buf);
+                    
((CPUWriteMemoryFunc64*)(io_mem_write[io_index][3]))(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);
@@ -2999,7 +3162,12 @@
                 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 */
+                    val64 = 
((CPUReadMemoryFunc64*)(io_mem_read[io_index][3]))(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);
                     stl_p(buf, val);
@@ -3264,13 +3432,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 = 
((CPUReadMemoryFunc64*)(io_mem_read[io_index][3]))(io_mem_opaque[io_index], 
addr);
     } else {
         /* RAM case */
         ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
@@ -3353,13 +3515,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
+        
((CPUWriteMemoryFunc64*)(io_mem_write[io_index][3]))(io_mem_opaque[io_index], 
addr, val);
     } else {
         ptr = phys_ram_base + (pd & TARGET_PAGE_MASK) +
             (addr & ~TARGET_PAGE_MASK);
Index: hw/slavio_timer.c
===================================================================
--- hw/slavio_timer.c   (revision 6636)
+++ hw/slavio_timer.c   (working copy)
@@ -177,6 +177,26 @@
     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 >> 2;
+    switch (saddr) {
+    case TIMER_LIMIT:
+        if (slavio_timer_is_user(s)) {
+            slavio_timer_get_out(s);
+            ret = (uint64_t)(s->counthigh | s->reached) << 32 | s->count;
+        }
+        break;
+    }
+    DPRINTF("read " TARGET_FMT_plx " = %016llx\n", addr, ret);
+
+    return ret;
+}
+
 static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
                                     uint32_t val)
 {
@@ -303,16 +323,45 @@
     }
 }
 
-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;
+
+    DPRINTF("write " TARGET_FMT_plx " %016llx\n", addr, val);
+    saddr = addr >> 2;
+    switch (saddr) {
+    case TIMER_LIMIT:
+        if (slavio_timer_is_user(s)) {
+            uint64_t count;
+
+            s->limit = TIMER_MAX_COUNT64;
+            s->count = val;
+            s->counthigh = (val & TIMER_MAX_COUNT64) >> 32;
+            s->reached = 0;
+            count = ((uint64_t)s->counthigh << 32) | s->count;
+            DPRINTF("processor %d user timer set to %016llx\n", s->slave_index,
+                    count);
+            if (s->timer)
+                ptimer_set_count(s->timer, LIMIT_TO_PERIODS(s->limit - count));
+        }
+        break;
+    }
+}
+
+static CPUReadMemoryFunc *slavio_timer_mem_read[4] = {
     NULL,
     NULL,
     slavio_timer_mem_readl,
+    (CPUReadMemoryFunc*)slavio_timer_mem_readq,
 };
 
-static CPUWriteMemoryFunc *slavio_timer_mem_write[3] = {
+static CPUWriteMemoryFunc *slavio_timer_mem_write[4] = {
     NULL,
     NULL,
     slavio_timer_mem_writel,
+    (CPUWriteMemoryFunc*)slavio_timer_mem_writeq,
 };
 
 static void slavio_timer_save(QEMUFile *f, void *opaque)
@@ -381,8 +430,8 @@
         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_memory64(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: cpu-all.h
===================================================================
--- cpu-all.h   (revision 6636)
+++ cpu-all.h   (working copy)
@@ -891,6 +891,9 @@
 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);
+
 void cpu_register_physical_memory_offset(target_phys_addr_t start_addr,
                                          ram_addr_t size,
                                          ram_addr_t phys_offset,
@@ -909,7 +912,12 @@
                            CPUReadMemoryFunc **mem_read,
                            CPUWriteMemoryFunc **mem_write,
                            void *opaque);
+int cpu_register_io_memory64(int io_index,
+                             CPUReadMemoryFunc **mem_read,
+                             CPUWriteMemoryFunc **mem_write,
+                             void *opaque);
 void cpu_unregister_io_memory(int table_address);
+void cpu_unregister_io_memory64(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]