Blame 0624-xhci-kill-xhci_mem_-read-write-dispatcher-functions.patch

5544c1
From d2efc9f3dc62810ef6075f8759c9856016447c14 Mon Sep 17 00:00:00 2001
c8dfc6
From: Gerd Hoffmann <kraxel@redhat.com>
c8dfc6
Date: Tue, 4 Sep 2012 14:42:20 +0200
5544c1
Subject: [PATCH] xhci: kill xhci_mem_{read,write} dispatcher functions
c8dfc6
c8dfc6
... and register subregions instead, so we offload the dispatching
c8dfc6
to the the memory subsystem which is designed to handle it.
c8dfc6
c8dfc6
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
c8dfc6
---
c8dfc6
 hw/usb/hcd-xhci.c | 140 +++++++++++++++++++++++++++++-------------------------
c8dfc6
 1 file changed, 75 insertions(+), 65 deletions(-)
c8dfc6
c8dfc6
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
5544c1
index 4992705..4ba9464 100644
c8dfc6
--- a/hw/usb/hcd-xhci.c
c8dfc6
+++ b/hw/usb/hcd-xhci.c
c8dfc6
@@ -404,6 +404,10 @@ struct XHCIState {
c8dfc6
     USBBus bus;
c8dfc6
     qemu_irq irq;
c8dfc6
     MemoryRegion mem;
c8dfc6
+    MemoryRegion mem_cap;
c8dfc6
+    MemoryRegion mem_oper;
c8dfc6
+    MemoryRegion mem_runtime;
c8dfc6
+    MemoryRegion mem_doorbell;
c8dfc6
     const char *name;
c8dfc6
     unsigned int devaddr;
c8dfc6
 
5544c1
@@ -2343,8 +2347,9 @@ static void xhci_reset(DeviceState *dev)
c8dfc6
     xhci_mfwrap_update(xhci);
c8dfc6
 }
c8dfc6
 
c8dfc6
-static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
c8dfc6
+static uint64_t xhci_cap_read(void *ptr, target_phys_addr_t reg, unsigned size)
c8dfc6
 {
c8dfc6
+    XHCIState *xhci = ptr;
c8dfc6
     uint32_t ret;
c8dfc6
 
c8dfc6
     switch (reg) {
5544c1
@@ -2401,7 +2406,7 @@ static uint32_t xhci_cap_read(XHCIState *xhci, uint32_t reg)
c8dfc6
         ret = 0x00000000; /* reserved */
c8dfc6
         break;
c8dfc6
     default:
c8dfc6
-        fprintf(stderr, "xhci_cap_read: reg %d unimplemented\n", reg);
c8dfc6
+        fprintf(stderr, "xhci_cap_read: reg %d unimplemented\n", (int)reg);
c8dfc6
         ret = 0;
c8dfc6
     }
c8dfc6
 
5544c1
@@ -2482,8 +2487,9 @@ static void xhci_port_write(XHCIState *xhci, uint32_t reg, uint32_t val)
c8dfc6
     }
c8dfc6
 }
c8dfc6
 
c8dfc6
-static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg)
c8dfc6
+static uint64_t xhci_oper_read(void *ptr, target_phys_addr_t reg, unsigned size)
c8dfc6
 {
c8dfc6
+    XHCIState *xhci = ptr;
c8dfc6
     uint32_t ret;
c8dfc6
 
c8dfc6
     if (reg >= 0x400) {
5544c1
@@ -2519,7 +2525,7 @@ static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg)
c8dfc6
         ret = xhci->config;
c8dfc6
         break;
c8dfc6
     default:
c8dfc6
-        fprintf(stderr, "xhci_oper_read: reg 0x%x unimplemented\n", reg);
c8dfc6
+        fprintf(stderr, "xhci_oper_read: reg 0x%x unimplemented\n", (int)reg);
c8dfc6
         ret = 0;
c8dfc6
     }
c8dfc6
 
5544c1
@@ -2527,8 +2533,11 @@ static uint32_t xhci_oper_read(XHCIState *xhci, uint32_t reg)
c8dfc6
     return ret;
c8dfc6
 }
c8dfc6
 
c8dfc6
-static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
c8dfc6
+static void xhci_oper_write(void *ptr, target_phys_addr_t reg,
c8dfc6
+                            uint64_t val, unsigned size)
c8dfc6
 {
c8dfc6
+    XHCIState *xhci = ptr;
c8dfc6
+
c8dfc6
     if (reg >= 0x400) {
c8dfc6
         xhci_port_write(xhci, reg - 0x400, val);
c8dfc6
         return;
5544c1
@@ -2586,12 +2595,14 @@ static void xhci_oper_write(XHCIState *xhci, uint32_t reg, uint32_t val)
c8dfc6
         xhci->config = val & 0xff;
c8dfc6
         break;
c8dfc6
     default:
c8dfc6
-        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg);
c8dfc6
+        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", (int)reg);
c8dfc6
     }
c8dfc6
 }
c8dfc6
 
c8dfc6
-static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
c8dfc6
+static uint64_t xhci_runtime_read(void *ptr, target_phys_addr_t reg,
c8dfc6
+                                  unsigned size)
c8dfc6
 {
c8dfc6
+    XHCIState *xhci = ptr;
c8dfc6
     uint32_t ret = 0;
c8dfc6
 
c8dfc6
     if (reg < 0x20) {
5544c1
@@ -2600,7 +2611,8 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
c8dfc6
             ret = xhci_mfindex_get(xhci) & 0x3fff;
c8dfc6
             break;
c8dfc6
         default:
c8dfc6
-            fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n", reg);
c8dfc6
+            fprintf(stderr, "xhci_runtime_read: reg 0x%x unimplemented\n",
c8dfc6
+                    (int)reg);
c8dfc6
             break;
c8dfc6
         }
c8dfc6
     } else {
5544c1
@@ -2635,14 +2647,16 @@ static uint32_t xhci_runtime_read(XHCIState *xhci, uint32_t reg)
c8dfc6
     return ret;
c8dfc6
 }
c8dfc6
 
c8dfc6
-static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
c8dfc6
+static void xhci_runtime_write(void *ptr, target_phys_addr_t reg,
c8dfc6
+                               uint64_t val, unsigned size)
c8dfc6
 {
c8dfc6
+    XHCIState *xhci = ptr;
c8dfc6
     int v = (reg - 0x20) / 0x20;
c8dfc6
     XHCIInterrupter *intr = &xhci->intr[v];
c8dfc6
     trace_usb_xhci_runtime_write(reg, val);
c8dfc6
 
c8dfc6
     if (reg < 0x20) {
c8dfc6
-        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg);
c8dfc6
+        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", (int)reg);
c8dfc6
         return;
c8dfc6
     }
c8dfc6
 
5544c1
@@ -2684,19 +2698,24 @@ static void xhci_runtime_write(XHCIState *xhci, uint32_t reg, uint32_t val)
c8dfc6
         xhci_events_update(xhci, v);
c8dfc6
         break;
c8dfc6
     default:
c8dfc6
-        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n", reg);
c8dfc6
+        fprintf(stderr, "xhci_oper_write: reg 0x%x unimplemented\n",
c8dfc6
+                (int)reg);
c8dfc6
     }
c8dfc6
 }
c8dfc6
 
c8dfc6
-static uint32_t xhci_doorbell_read(XHCIState *xhci, uint32_t reg)
c8dfc6
+static uint64_t xhci_doorbell_read(void *ptr, target_phys_addr_t reg,
c8dfc6
+                                   unsigned size)
c8dfc6
 {
c8dfc6
     /* doorbells always read as 0 */
c8dfc6
     trace_usb_xhci_doorbell_read(reg, 0);
c8dfc6
     return 0;
c8dfc6
 }
c8dfc6
 
c8dfc6
-static void xhci_doorbell_write(XHCIState *xhci, uint32_t reg, uint32_t val)
c8dfc6
+static void xhci_doorbell_write(void *ptr, target_phys_addr_t reg,
c8dfc6
+                                uint64_t val, unsigned size)
c8dfc6
 {
c8dfc6
+    XHCIState *xhci = ptr;
c8dfc6
+
c8dfc6
     trace_usb_xhci_doorbell_write(reg, val);
c8dfc6
 
c8dfc6
     if (!xhci_running(xhci)) {
5544c1
@@ -2710,69 +2729,47 @@ static void xhci_doorbell_write(XHCIState *xhci, uint32_t reg, uint32_t val)
c8dfc6
         if (val == 0) {
c8dfc6
             xhci_process_commands(xhci);
c8dfc6
         } else {
c8dfc6
-            fprintf(stderr, "xhci: bad doorbell 0 write: 0x%x\n", val);
c8dfc6
+            fprintf(stderr, "xhci: bad doorbell 0 write: 0x%x\n",
c8dfc6
+                    (uint32_t)val);
c8dfc6
         }
c8dfc6
     } else {
c8dfc6
         if (reg > MAXSLOTS) {
c8dfc6
-            fprintf(stderr, "xhci: bad doorbell %d\n", reg);
c8dfc6
+            fprintf(stderr, "xhci: bad doorbell %d\n", (int)reg);
c8dfc6
         } else if (val > 31) {
c8dfc6
-            fprintf(stderr, "xhci: bad doorbell %d write: 0x%x\n", reg, val);
c8dfc6
+            fprintf(stderr, "xhci: bad doorbell %d write: 0x%x\n",
c8dfc6
+                    (int)reg, (uint32_t)val);
c8dfc6
         } else {
c8dfc6
             xhci_kick_ep(xhci, reg, val);
c8dfc6
         }
c8dfc6
     }
c8dfc6
 }
c8dfc6
 
c8dfc6
-static uint64_t xhci_mem_read(void *ptr, target_phys_addr_t addr,
c8dfc6
-                              unsigned size)
c8dfc6
-{
c8dfc6
-    XHCIState *xhci = ptr;
c8dfc6
-
c8dfc6
-    /* Only aligned reads are allowed on xHCI */
c8dfc6
-    if (addr & 3) {
c8dfc6
-        fprintf(stderr, "xhci_mem_read: Mis-aligned read\n");
c8dfc6
-        return 0;
c8dfc6
-    }
c8dfc6
-
c8dfc6
-    if (addr < LEN_CAP) {
c8dfc6
-        return xhci_cap_read(xhci, addr);
c8dfc6
-    } else if (addr >= OFF_OPER && addr < (OFF_OPER + LEN_OPER)) {
c8dfc6
-        return xhci_oper_read(xhci, addr - OFF_OPER);
c8dfc6
-    } else if (addr >= OFF_RUNTIME && addr < (OFF_RUNTIME + LEN_RUNTIME)) {
c8dfc6
-        return xhci_runtime_read(xhci, addr - OFF_RUNTIME);
c8dfc6
-    } else if (addr >= OFF_DOORBELL && addr < (OFF_DOORBELL + LEN_DOORBELL)) {
c8dfc6
-        return xhci_doorbell_read(xhci, addr - OFF_DOORBELL);
c8dfc6
-    } else {
c8dfc6
-        fprintf(stderr, "xhci_mem_read: Bad offset %x\n", (int)addr);
c8dfc6
-        return 0;
c8dfc6
-    }
c8dfc6
-}
c8dfc6
-
c8dfc6
-static void xhci_mem_write(void *ptr, target_phys_addr_t addr,
c8dfc6
-                           uint64_t val, unsigned size)
c8dfc6
-{
c8dfc6
-    XHCIState *xhci = ptr;
c8dfc6
+static const MemoryRegionOps xhci_cap_ops = {
c8dfc6
+    .read = xhci_cap_read,
c8dfc6
+    .valid.min_access_size = 4,
c8dfc6
+    .valid.max_access_size = 4,
c8dfc6
+    .endianness = DEVICE_LITTLE_ENDIAN,
c8dfc6
+};
c8dfc6
 
c8dfc6
-    /* Only aligned writes are allowed on xHCI */
c8dfc6
-    if (addr & 3) {
c8dfc6
-        fprintf(stderr, "xhci_mem_write: Mis-aligned write\n");
c8dfc6
-        return;
c8dfc6
-    }
c8dfc6
+static const MemoryRegionOps xhci_oper_ops = {
c8dfc6
+    .read = xhci_oper_read,
c8dfc6
+    .write = xhci_oper_write,
c8dfc6
+    .valid.min_access_size = 4,
c8dfc6
+    .valid.max_access_size = 4,
c8dfc6
+    .endianness = DEVICE_LITTLE_ENDIAN,
c8dfc6
+};
c8dfc6
 
c8dfc6
-    if (addr >= OFF_OPER && addr < (OFF_OPER + LEN_OPER)) {
c8dfc6
-        xhci_oper_write(xhci, addr - OFF_OPER, val);
c8dfc6
-    } else if (addr >= OFF_RUNTIME && addr < (OFF_RUNTIME + LEN_RUNTIME)) {
c8dfc6
-        xhci_runtime_write(xhci, addr - OFF_RUNTIME, val);
c8dfc6
-    } else if (addr >= OFF_DOORBELL && addr < (OFF_DOORBELL + LEN_DOORBELL)) {
c8dfc6
-        xhci_doorbell_write(xhci, addr - OFF_DOORBELL, val);
c8dfc6
-    } else {
c8dfc6
-        fprintf(stderr, "xhci_mem_write: Bad offset %x\n", (int)addr);
c8dfc6
-    }
c8dfc6
-}
c8dfc6
+static const MemoryRegionOps xhci_runtime_ops = {
c8dfc6
+    .read = xhci_runtime_read,
c8dfc6
+    .write = xhci_runtime_write,
c8dfc6
+    .valid.min_access_size = 4,
c8dfc6
+    .valid.max_access_size = 4,
c8dfc6
+    .endianness = DEVICE_LITTLE_ENDIAN,
c8dfc6
+};
c8dfc6
 
c8dfc6
-static const MemoryRegionOps xhci_mem_ops = {
c8dfc6
-    .read = xhci_mem_read,
c8dfc6
-    .write = xhci_mem_write,
c8dfc6
+static const MemoryRegionOps xhci_doorbell_ops = {
c8dfc6
+    .read = xhci_doorbell_read,
c8dfc6
+    .write = xhci_doorbell_write,
5544c1
     .valid.min_access_size = 1,
c8dfc6
     .valid.max_access_size = 4,
5544c1
     .impl.min_access_size = 4,
c8dfc6
@@ -2940,8 +2937,21 @@ static int usb_xhci_initfn(struct PCIDevice *dev)
c8dfc6
 
c8dfc6
     xhci->irq = xhci->pci_dev.irq[0];
c8dfc6
 
c8dfc6
-    memory_region_init_io(&xhci->mem, &xhci_mem_ops, xhci,
c8dfc6
-                          "xhci", LEN_REGS);
c8dfc6
+    memory_region_init(&xhci->mem, "xhci", LEN_REGS);
c8dfc6
+    memory_region_init_io(&xhci->mem_cap, &xhci_cap_ops, xhci,
c8dfc6
+                          "capabilities", LEN_CAP);
c8dfc6
+    memory_region_init_io(&xhci->mem_oper, &xhci_oper_ops, xhci,
c8dfc6
+                          "operational", 0x400 + 0x10 * xhci->numports);
c8dfc6
+    memory_region_init_io(&xhci->mem_runtime, &xhci_runtime_ops, xhci,
c8dfc6
+                          "runtime", LEN_RUNTIME);
c8dfc6
+    memory_region_init_io(&xhci->mem_doorbell, &xhci_doorbell_ops, xhci,
c8dfc6
+                          "doorbell", LEN_DOORBELL);
c8dfc6
+
c8dfc6
+    memory_region_add_subregion(&xhci->mem, 0,            &xhci->mem_cap);
c8dfc6
+    memory_region_add_subregion(&xhci->mem, OFF_OPER,     &xhci->mem_oper);
c8dfc6
+    memory_region_add_subregion(&xhci->mem, OFF_RUNTIME,  &xhci->mem_runtime);
c8dfc6
+    memory_region_add_subregion(&xhci->mem, OFF_DOORBELL, &xhci->mem_doorbell);
c8dfc6
+
c8dfc6
     pci_register_bar(&xhci->pci_dev, 0,
c8dfc6
                      PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64,
c8dfc6
                      &xhci->mem);
c8dfc6
-- 
5544c1
1.7.12.1
c8dfc6