The capabilities register and operational register offsets can vary from one EHCI implementation to the next. Parameterise accordingly.
Signed-off-by: Peter Crosthwaite <peter.crosthwa...@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(-) 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); -- 1.7.0.4