dcavalca / rpms / qemu

Forked from rpms/qemu a year ago
Clone

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

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