qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH] 64 bit I/O support v7


From: Robert Reif
Subject: Re: [Qemu-devel] [PATCH] 64 bit I/O support v7
Date: Fri, 01 May 2009 10:39:53 -0400
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.21) Gecko/20090303 SeaMonkey/1.1.15 (Ubuntu-1.1.15+nobinonly-0ubuntu2)

Paul Brook wrote:
The right way to do this is to convert the whole tree at once
so we don't need the helper functions and two versions of
cpu_register_io_memory.
95% of the hardware drivers could be trivially converted and
work fine.

I think you're missing my point. It's the 95% of drivers that I don't want to have to "convert". I'm working on the assumption that devices that actually implement 64-bit transfers are the exception rather than the rule.

So we have three options:

1) Omit the 64-bit handler for most devices. This will trigger the subwith code and associated overhead for no good reason[1]. 2) Implement a 64-bit handler for every single device. 90% of these are going to be identical trivial wrappers round the 32-bit function. Maybe 5% actually need 64-bit accesses, and 5% are broken because someone messed up a copy/paste. 3) Implement splitting of 64-bit accesses in generic code. Devices that actually care about 64-bit accesses can install a handler. Everything else indicates that it wants accesses split, either by a magic handler or a different registration function.

Your current patch implements a broken version of (3), with a vague hope that we'll switch to (2) at some time in the future.

I'm suggesting we implement (3) properly from the start.

Paul

[1] I still don't understand why the subwidth code exists, It's seems rather unlikely we'll have two different devices responding to different types of access the same address range. That's a separate argument though.

Here is a patch for most of the sparc32 hardware drivers.  It's
a very trivial and mechanical process for these drivers.  The one
driver that does 64 bit accesses just adds 64 bit access functions
because it's broken now and has no workaround to remove.  I don't
think converting most other drivers will be much harder.
Index: hw/sparc32_dma.c
===================================================================
--- hw/sparc32_dma.c    (revision 7191)
+++ hw/sparc32_dma.c    (working copy)
@@ -199,16 +199,18 @@
     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 @@
     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_memory64(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/slavio_intctl.c
===================================================================
--- hw/slavio_intctl.c  (revision 7191)
+++ hw/slavio_intctl.c  (working copy)
@@ -132,16 +132,18 @@
     }
 }
 
-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
@@ -206,16 +208,18 @@
     }
 }
 
-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(Monitor *mon, void *opaque)
@@ -388,10 +392,10 @@
         slave->cpu = i;
         slave->master = s;
 
-        slavio_intctl_io_memory = cpu_register_io_memory(0,
-                                                         
slavio_intctl_mem_read,
-                                                         
slavio_intctl_mem_write,
-                                                         slave);
+        slavio_intctl_io_memory = cpu_register_io_memory64(0,
+                                                           
&slavio_intctl_mem_read,
+                                                           
&slavio_intctl_mem_write,
+                                                           slave);
         cpu_register_physical_memory(addr + i * TARGET_PAGE_SIZE, INTCTL_SIZE,
                                      slavio_intctl_io_memory);
 
@@ -399,10 +403,10 @@
         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_memory64(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,
Index: hw/tcx.c
===================================================================
--- hw/tcx.c    (revision 7191)
+++ hw/tcx.c    (working copy)
@@ -463,16 +463,18 @@
     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)
@@ -485,16 +487,18 @@
 {
 }
 
-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(target_phys_addr_t addr, int vram_size, int width, int height,
@@ -523,12 +527,12 @@
     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_memory64(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,
-                                          s);
+    dummy_memory = cpu_register_io_memory64(0, &tcx_dummy_read,
+                                            &tcx_dummy_write, s);
     cpu_register_physical_memory(addr + 0x00700000ULL, TCX_TEC_NREGS,
                                  dummy_memory);
     if (depth == 24) {
Index: hw/iommu.c
===================================================================
--- hw/iommu.c  (revision 7191)
+++ hw/iommu.c  (working copy)
@@ -236,16 +236,18 @@
     }
 }
 
-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)
@@ -375,8 +377,8 @@
     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_memory64(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/esp.c
===================================================================
--- hw/esp.c    (revision 7191)
+++ hw/esp.c    (working copy)
@@ -563,16 +563,18 @@
     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,
     esp_mem_writeb,
+    NULL,
 };
 
 static void esp_save(QEMUFile *f, void *opaque)
@@ -660,7 +662,8 @@
     s->dma_memory_write = dma_memory_write;
     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_memory64(0, &esp_mem_read, &esp_mem_write,
+                                             s);
     cpu_register_physical_memory(espaddr, ESP_REGS << it_shift, esp_io_memory);
 
     esp_reset(s);
Index: hw/m48t59.c
===================================================================
--- hw/m48t59.c (revision 7191)
+++ hw/m48t59.c (working copy)
@@ -565,16 +565,18 @@
     return retval;
 }
 
-static CPUWriteMemoryFunc *nvram_write[] = {
-    &nvram_writeb,
-    &nvram_writew,
-    &nvram_writel,
+static CPUWriteMemoryFuncs nvram_write = {
+    nvram_writeb,
+    nvram_writew,
+    nvram_writel,
+    NULL,
 };
 
-static CPUReadMemoryFunc *nvram_read[] = {
-    &nvram_readb,
-    &nvram_readw,
-    &nvram_readl,
+static CPUReadMemoryFuncs nvram_read = {
+    nvram_readb,
+    nvram_readw,
+    nvram_readl,
+    NULL,
 };
 
 static void m48t59_save(QEMUFile *f, void *opaque)
@@ -632,7 +634,8 @@
         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_memory64(0, &nvram_read, &nvram_write,
+                                                s);
         cpu_register_physical_memory(mem_base, size, s->mem_index);
     }
     if (type == 59) {
Index: hw/slavio_misc.c
===================================================================
--- hw/slavio_misc.c    (revision 7191)
+++ hw/slavio_misc.c    (working copy)
@@ -128,16 +128,18 @@
     return ret;
 }
 
-static CPUReadMemoryFunc *slavio_cfg_mem_read[3] = {
+static CPUReadMemoryFuncs slavio_cfg_mem_read = {
     slavio_cfg_mem_readb,
     NULL,
     NULL,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *slavio_cfg_mem_write[3] = {
+static CPUWriteMemoryFuncs slavio_cfg_mem_write = {
     slavio_cfg_mem_writeb,
     NULL,
     NULL,
+    NULL,
 };
 
 static void slavio_diag_mem_writeb(void *opaque, target_phys_addr_t addr,
@@ -159,16 +161,18 @@
     return ret;
 }
 
-static CPUReadMemoryFunc *slavio_diag_mem_read[3] = {
+static CPUReadMemoryFuncs slavio_diag_mem_read = {
     slavio_diag_mem_readb,
     NULL,
     NULL,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *slavio_diag_mem_write[3] = {
+static CPUWriteMemoryFuncs slavio_diag_mem_write = {
     slavio_diag_mem_writeb,
     NULL,
     NULL,
+    NULL,
 };
 
 static void slavio_mdm_mem_writeb(void *opaque, target_phys_addr_t addr,
@@ -190,16 +194,18 @@
     return ret;
 }
 
-static CPUReadMemoryFunc *slavio_mdm_mem_read[3] = {
+static CPUReadMemoryFuncs slavio_mdm_mem_read = {
     slavio_mdm_mem_readb,
     NULL,
     NULL,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *slavio_mdm_mem_write[3] = {
+static CPUWriteMemoryFuncs slavio_mdm_mem_write = {
     slavio_mdm_mem_writeb,
     NULL,
     NULL,
+    NULL,
 };
 
 static void slavio_aux1_mem_writeb(void *opaque, target_phys_addr_t addr,
@@ -230,16 +236,18 @@
     return ret;
 }
 
-static CPUReadMemoryFunc *slavio_aux1_mem_read[3] = {
+static CPUReadMemoryFuncs slavio_aux1_mem_read = {
     slavio_aux1_mem_readb,
     NULL,
     NULL,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *slavio_aux1_mem_write[3] = {
+static CPUWriteMemoryFuncs slavio_aux1_mem_write = {
     slavio_aux1_mem_writeb,
     NULL,
     NULL,
+    NULL,
 };
 
 static void slavio_aux2_mem_writeb(void *opaque, target_phys_addr_t addr,
@@ -269,16 +277,18 @@
     return ret;
 }
 
-static CPUReadMemoryFunc *slavio_aux2_mem_read[3] = {
+static CPUReadMemoryFuncs slavio_aux2_mem_read = {
     slavio_aux2_mem_readb,
     NULL,
     NULL,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *slavio_aux2_mem_write[3] = {
+static CPUWriteMemoryFuncs slavio_aux2_mem_write = {
     slavio_aux2_mem_writeb,
     NULL,
     NULL,
+    NULL,
 };
 
 static void apc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
@@ -297,16 +307,18 @@
     return ret;
 }
 
-static CPUReadMemoryFunc *apc_mem_read[3] = {
+static CPUReadMemoryFuncs apc_mem_read = {
     apc_mem_readb,
     NULL,
     NULL,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *apc_mem_write[3] = {
+static CPUWriteMemoryFuncs apc_mem_write = {
     apc_mem_writeb,
     NULL,
     NULL,
+    NULL,
 };
 
 static uint32_t slavio_sysctrl_mem_readl(void *opaque, target_phys_addr_t addr)
@@ -343,16 +355,18 @@
     }
 }
 
-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)
@@ -386,16 +400,18 @@
     }
 }
 
-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)
@@ -448,50 +464,50 @@
         /* 8 bit registers */
 
         // Slavio control
-        io = cpu_register_io_memory(0, slavio_cfg_mem_read,
-                                    slavio_cfg_mem_write, s);
+        io = cpu_register_io_memory64(0, &slavio_cfg_mem_read,
+                                      &slavio_cfg_mem_write, s);
         cpu_register_physical_memory(base + MISC_CFG, MISC_SIZE, io);
 
         // Diagnostics
-        io = cpu_register_io_memory(0, slavio_diag_mem_read,
-                                    slavio_diag_mem_write, s);
+        io = cpu_register_io_memory64(0, &slavio_diag_mem_read,
+                                      &slavio_diag_mem_write, s);
         cpu_register_physical_memory(base + MISC_DIAG, MISC_SIZE, io);
 
         // Modem control
-        io = cpu_register_io_memory(0, slavio_mdm_mem_read,
-                                    slavio_mdm_mem_write, s);
+        io = cpu_register_io_memory64(0, &slavio_mdm_mem_read,
+                                      &slavio_mdm_mem_write, s);
         cpu_register_physical_memory(base + MISC_MDM, MISC_SIZE, io);
 
         /* 16 bit registers */
-        io = cpu_register_io_memory(0, slavio_led_mem_read,
-                                    slavio_led_mem_write, s);
+        io = cpu_register_io_memory64(0, &slavio_led_mem_read,
+                                      &slavio_led_mem_write, s);
         /* ss600mp diag LEDs */
         cpu_register_physical_memory(base + MISC_LEDS, MISC_SIZE, io);
 
         /* 32 bit registers */
-        io = cpu_register_io_memory(0, slavio_sysctrl_mem_read,
-                                    slavio_sysctrl_mem_write, s);
+        io = cpu_register_io_memory64(0, &slavio_sysctrl_mem_read,
+                                      &slavio_sysctrl_mem_write, s);
         // System control
         cpu_register_physical_memory(base + MISC_SYS, SYSCTRL_SIZE, io);
     }
 
     // AUX 1 (Misc System Functions)
     if (aux1_base) {
-        io = cpu_register_io_memory(0, slavio_aux1_mem_read,
-                                    slavio_aux1_mem_write, s);
+        io = cpu_register_io_memory64(0, &slavio_aux1_mem_read,
+                                      &slavio_aux1_mem_write, s);
         cpu_register_physical_memory(aux1_base, MISC_SIZE, io);
     }
 
     // AUX 2 (Software Powerdown Control)
     if (aux2_base) {
-        io = cpu_register_io_memory(0, slavio_aux2_mem_read,
-                                    slavio_aux2_mem_write, s);
+        io = cpu_register_io_memory64(0, &slavio_aux2_mem_read,
+                                      &slavio_aux2_mem_write, s);
         cpu_register_physical_memory(aux2_base, MISC_SIZE, io);
     }
 
     // Power management (APC) XXX: not a Slavio device
     if (power_base) {
-        io = cpu_register_io_memory(0, apc_mem_read, apc_mem_write, s);
+        io = cpu_register_io_memory64(0, &apc_mem_read, &apc_mem_write, s);
         cpu_register_physical_memory(power_base, MISC_SIZE, io);
     }
 
Index: hw/eccmemctl.c
===================================================================
--- hw/eccmemctl.c      (revision 7191)
+++ hw/eccmemctl.c      (working copy)
@@ -220,16 +220,18 @@
     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 void ecc_diag_mem_writeb(void *opaque, target_phys_addr_t addr,
@@ -250,16 +252,18 @@
     return ret;
 }
 
-static CPUReadMemoryFunc *ecc_diag_mem_read[3] = {
+static CPUReadMemoryFuncs ecc_diag_mem_read = {
     ecc_diag_mem_readb,
     NULL,
     NULL,
+    NULL,
 };
 
-static CPUWriteMemoryFunc *ecc_diag_mem_write[3] = {
+static CPUWriteMemoryFuncs ecc_diag_mem_write = {
     ecc_diag_mem_writeb,
     NULL,
     NULL,
+    NULL,
 };
 
 static int ecc_load(QEMUFile *f, void *opaque, int version_id)
@@ -325,11 +329,12 @@
     s->regs[0] = version;
     s->irq = irq;
 
-    ecc_io_memory = cpu_register_io_memory(0, ecc_mem_read, ecc_mem_write, s);
+    ecc_io_memory = cpu_register_io_memory64(0, &ecc_mem_read, &ecc_mem_write,
+                                             s);
     cpu_register_physical_memory(base, ECC_SIZE, ecc_io_memory);
     if (version == ECC_MCC) { // SS-600MP only
-        ecc_io_memory = cpu_register_io_memory(0, ecc_diag_mem_read,
-                                               ecc_diag_mem_write, s);
+        ecc_io_memory = cpu_register_io_memory64(0, &ecc_diag_mem_read,
+                                                 &ecc_diag_mem_write, s);
         cpu_register_physical_memory(base + 0x1000, ECC_DIAG_SIZE,
                                      ecc_io_memory);
     }
Index: hw/slavio_timer.c
===================================================================
--- hw/slavio_timer.c   (revision 7190)
+++ hw/slavio_timer.c   (working copy)
@@ -137,9 +137,17 @@
         // read limit (system counter mode) or read most signifying
         // part of counter (user mode)
         if (slavio_timer_is_user(s)) {
+            uint64_t last_count = (uint64_t)(s->counthigh) << 32 | s->count;
             // read user timer MSW
             slavio_timer_get_out(s);
             ret = s->counthigh | s->reached;
+            if (last_count == TIMER_MAX_COUNT64) { 
+                uint64_t new_count = (uint64_t)ret << 32 | s->count;
+                if (new_count != last_count) {
+                    s->reached = TIMER_REACHED;
+                    ret |= TIMER_REACHED;
+                }
+            }  
         } else {
             // read limit
             // clear irq
@@ -177,6 +185,31 @@
     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)) {
+            uint64_t last_count = (uint64_t)(s->counthigh) << 32 | s->count;
+            slavio_timer_get_out(s);
+            ret = (uint64_t)(s->counthigh | s->reached) << 32 | s->count;
+            if (last_count == TIMER_MAX_COUNT64 && ret != last_count) {
+                s->reached = TIMER_REACHED;
+                ret |= ((uint64_t)TIMER_REACHED << 32);
+            }  
+        }
+        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 +336,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 & TIMER_MAX_COUNT64;
+            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 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)
@@ -381,8 +443,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);

reply via email to

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