Patchwork [v3,3/8] usb/ehci: parameterise the register region offsets

login
register
mail settings
Submitter Peter Crosthwaite
Date Oct. 29, 2012, 1:34 a.m.
Message ID <41d979dd1828b024d9615eca8a8a3e2bc516d36d.1351473902.git.peter.crosthwaite@xilinx.com>
Download mbox | patch
Permalink /patch/194784/
State New
Headers show

Comments

Peter Crosthwaite - Oct. 29, 2012, 1:34 a.m.
The capabilities register and operational register offsets can vary from one
EHCI implementation to the next. Parameterise accordingly.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
---
changed from v2:
Added strcut EHCIInfo to hold these two properties and added struct to
class definition. This struct can be passed around instead of the class to
share init functionailty (rather than the union apporach in prev revision)
changed from v1:
Moved opregbase and capregbase to class_data (Gerd Review)
Fixed capa regs to 16 bytes in length (Gerd Review)
Removed C++ comments touched by this patch (Checkpatch)

 hw/usb/hcd-ehci.c |   78 +++++++++++++++++++++++++++++++---------------------
 1 files changed, 46 insertions(+), 32 deletions(-)

Patch

diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 274225b..2519484 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -48,20 +48,18 @@ 
 #define USB_RET_PROCERR   (-99)
 
 #define MMIO_SIZE        0x1000
+#define CAPA_SIZE        0x10
 
 /* Capability Registers Base Address - section 2.2 */
-#define CAPREGBASE       0x0000
-#define CAPLENGTH        CAPREGBASE + 0x0000  // 1-byte, 0x0001 reserved
-#define HCIVERSION       CAPREGBASE + 0x0002  // 2-bytes, i/f version #
-#define HCSPARAMS        CAPREGBASE + 0x0004  // 4-bytes, structural params
-#define HCCPARAMS        CAPREGBASE + 0x0008  // 4-bytes, capability params
+#define CAPLENGTH        0x0000  /* 1-byte, 0x0001 reserved */
+#define HCIVERSION       0x0002  /* 2-bytes, i/f version # */
+#define HCSPARAMS        0x0004  /* 4-bytes, structural params */
+#define HCCPARAMS        0x0008  /* 4-bytes, capability params */
 #define EECP             HCCPARAMS + 1
-#define HCSPPORTROUTE1   CAPREGBASE + 0x000c
-#define HCSPPORTROUTE2   CAPREGBASE + 0x0010
+#define HCSPPORTROUTE1   0x000c
+#define HCSPPORTROUTE2   0x0010
 
-#define OPREGBASE        0x0020        // Operational Registers Base Address
-
-#define USBCMD           OPREGBASE + 0x0000
+#define USBCMD           0x0000
 #define USBCMD_RUNSTOP   (1 << 0)      // run / Stop
 #define USBCMD_HCRESET   (1 << 1)      // HC Reset
 #define USBCMD_FLS       (3 << 2)      // Frame List Size
@@ -75,7 +73,7 @@ 
 #define USBCMD_ITC       (0x7f << 16)  // Int Threshold Control
 #define USBCMD_ITC_SH    16            // Int Threshold Control Shift
 
-#define USBSTS           OPREGBASE + 0x0004
+#define USBSTS           0x0004
 #define USBSTS_RO_MASK   0x0000003f
 #define USBSTS_INT       (1 << 0)      // USB Interrupt
 #define USBSTS_ERRINT    (1 << 1)      // Error Interrupt
@@ -92,18 +90,18 @@ 
  *  Interrupt enable bits correspond to the interrupt active bits in USBSTS
  *  so no need to redefine here.
  */
-#define USBINTR              OPREGBASE + 0x0008
+#define USBINTR              0x0008
 #define USBINTR_MASK         0x0000003f
 
-#define FRINDEX              OPREGBASE + 0x000c
-#define CTRLDSSEGMENT        OPREGBASE + 0x0010
-#define PERIODICLISTBASE     OPREGBASE + 0x0014
-#define ASYNCLISTADDR        OPREGBASE + 0x0018
+#define FRINDEX              0x000c
+#define CTRLDSSEGMENT        0x0010
+#define PERIODICLISTBASE     0x0014
+#define ASYNCLISTADDR        0x0018
 #define ASYNCLISTADDR_MASK   0xffffffe0
 
-#define CONFIGFLAG           OPREGBASE + 0x0040
+#define CONFIGFLAG           0x0040
 
-#define PORTSC               (OPREGBASE + 0x0044)
+#define PORTSC               0x0044
 #define PORTSC_BEGIN         PORTSC
 #define PORTSC_END           (PORTSC + 4 * NB_PORTS)
 /*
@@ -399,14 +397,15 @@  struct EHCIState {
 
     /* properties */
     uint32_t maxframes;
+    uint16_t opregbase;
 
     /*
      *  EHCI spec version 1.0 Section 2.3
      *  Host Controller Operational Registers
      */
-    uint8_t caps[OPREGBASE];
+    uint8_t caps[CAPA_SIZE];
     union {
-        uint32_t opreg[(PORTSC_BEGIN-OPREGBASE)/sizeof(uint32_t)];
+        uint32_t opreg[PORTSC_BEGIN/sizeof(uint32_t)];
         struct {
             uint32_t usbcmd;
             uint32_t usbsts;
@@ -505,8 +504,7 @@  static const char *state2str(uint32_t state)
 
 static const char *addr2str(hwaddr addr)
 {
-    return nr2str(ehci_mmio_names, ARRAY_SIZE(ehci_mmio_names),
-                  addr + OPREGBASE);
+    return nr2str(ehci_mmio_names, ARRAY_SIZE(ehci_mmio_names), addr);
 }
 
 static void ehci_trace_usbsts(uint32_t mask, int state)
@@ -1114,7 +1112,7 @@  static uint64_t ehci_opreg_read(void *ptr, hwaddr addr,
     uint32_t val;
 
     val = s->opreg[addr >> 2];
-    trace_usb_ehci_opreg_read(addr + OPREGBASE, addr2str(addr), val);
+    trace_usb_ehci_opreg_read(addr + s->opregbase, addr2str(addr), val);
     return val;
 }
 
@@ -1210,9 +1208,9 @@  static void ehci_opreg_write(void *ptr, hwaddr addr,
     uint32_t old = *mmio;
     int i;
 
-    trace_usb_ehci_opreg_write(addr + OPREGBASE, addr2str(addr), val);
+    trace_usb_ehci_opreg_write(addr + s->opregbase, addr2str(addr), val);
 
-    switch (addr + OPREGBASE) {
+    switch (addr) {
     case USBCMD:
         if (val & USBCMD_HCRESET) {
             ehci_reset(s);
@@ -1290,7 +1288,8 @@  static void ehci_opreg_write(void *ptr, hwaddr addr,
     }
 
     *mmio = val;
-    trace_usb_ehci_opreg_change(addr + OPREGBASE, addr2str(addr), *mmio, old);
+    trace_usb_ehci_opreg_change(addr + s->opregbase, addr2str(addr),
+                                *mmio, old);
 }
 
 
@@ -2641,8 +2640,14 @@  static Property ehci_properties[] = {
     DEFINE_PROP_END_OF_LIST(),
 };
 
+typedef struct EHCIInfo {
+    uint16_t capabase;
+    uint16_t opregbase;
+} EHCIInfo;
+
 typedef struct EHCIPCIClass {
     PCIDeviceClass pci;
+    EHCIInfo ehci;
 } EHCIPCIClass;
 
 static void ehci_class_init(ObjectClass *klass, void *data)
@@ -2656,6 +2661,7 @@  static void ehci_class_init(ObjectClass *klass, void *data)
     k->pci.device_id = template->pci.device_id; /* ich4 */
     k->pci.revision = template->pci.revision;
     k->pci.class_id = PCI_CLASS_SERIAL_USB;
+    k->ehci = template->ehci;
     dc->vmsd = &vmstate_ehci;
     dc->props = ehci_properties;
 }
@@ -2671,6 +2677,8 @@  static TypeInfo ehci_info[] = {
             .pci.vendor_id = PCI_VENDOR_ID_INTEL,
             .pci.device_id = PCI_DEVICE_ID_INTEL_82801D,
             .pci.revision  = 0x10,
+            .ehci.capabase  = 0x0,
+            .ehci.opregbase = 0x20,
         } }
     }, {
         .name          = "ich9-usb-ehci1",
@@ -2682,6 +2690,8 @@  static TypeInfo ehci_info[] = {
             .pci.vendor_id = PCI_VENDOR_ID_INTEL,
             .pci.device_id = PCI_DEVICE_ID_INTEL_82801I_EHCI1,
             .pci.revision  = 0x03,
+            .ehci.capabase  = 0x0,
+            .ehci.opregbase = 0x20,
         } }
     },
 };
@@ -2689,6 +2699,7 @@  static TypeInfo ehci_info[] = {
 static int usb_ehci_initfn(PCIDevice *dev)
 {
     EHCIState *s = DO_UPCAST(EHCIState, dev, dev);
+    EHCIPCIClass *c = (EHCIPCIClass *)object_get_class(OBJECT(dev));
     uint8_t *pci_conf = s->dev.config;
     int i;
 
@@ -2721,8 +2732,10 @@  static int usb_ehci_initfn(PCIDevice *dev)
     pci_conf[0x6e] = 0x00;
     pci_conf[0x6f] = 0xc0;  // USBLEFCTLSTS
 
+    s->opregbase = c->ehci.opregbase;
+
     /* 2.2 host controller interface version */
-    s->caps[0x00] = (uint8_t) OPREGBASE;
+    s->caps[0x00] = (uint8_t)(s->opregbase - c->ehci.capabase);
     s->caps[0x01] = 0x00;
     s->caps[0x02] = 0x00;
     s->caps[0x03] = 0x01;        /* HC version */
@@ -2755,15 +2768,16 @@  static int usb_ehci_initfn(PCIDevice *dev)
 
     memory_region_init(&s->mem, "ehci", MMIO_SIZE);
     memory_region_init_io(&s->mem_caps, &ehci_mmio_caps_ops, s,
-                          "capabilities", OPREGBASE);
+                          "capabilities", CAPA_SIZE);
     memory_region_init_io(&s->mem_opreg, &ehci_mmio_opreg_ops, s,
-                          "operational", PORTSC_BEGIN - OPREGBASE);
+                          "operational", PORTSC_BEGIN);
     memory_region_init_io(&s->mem_ports, &ehci_mmio_port_ops, s,
                           "ports", PORTSC_END - PORTSC_BEGIN);
 
-    memory_region_add_subregion(&s->mem, 0,            &s->mem_caps);
-    memory_region_add_subregion(&s->mem, OPREGBASE,    &s->mem_opreg);
-    memory_region_add_subregion(&s->mem, PORTSC_BEGIN, &s->mem_ports);
+    memory_region_add_subregion(&s->mem, c->ehci.capabase, &s->mem_caps);
+    memory_region_add_subregion(&s->mem, s->opregbase, &s->mem_opreg);
+    memory_region_add_subregion(&s->mem, s->opregbase + PORTSC_BEGIN,
+                                &s->mem_ports);
 
     pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);