dcavalca / rpms / qemu

Forked from rpms/qemu a year ago
Clone

Blame 0158-ehci-switch-to-new-style-memory-ops.patch

5544c1
From 093374b8c759db877691fde602912a7cafd72a2e Mon Sep 17 00:00:00 2001
Hans de Goede c8dfc6
From: Gerd Hoffmann <kraxel@redhat.com>
Hans de Goede c8dfc6
Date: Thu, 6 Sep 2012 11:24:51 +0200
5544c1
Subject: [PATCH] ehci: switch to new-style memory ops
Hans de Goede c8dfc6
Hans de Goede c8dfc6
Also register different memory regions for capabilities,
Hans de Goede c8dfc6
operational registers and port status registers.  Create
Hans de Goede c8dfc6
separate tracepoints for operational regs and port status
Hans de Goede c8dfc6
regs.  Ditch a bunch of sanity checks because the memory
Hans de Goede c8dfc6
core will do this for us now.
Hans de Goede c8dfc6
Hans de Goede c8dfc6
Offloading the byte, word and dword access handling to the
Hans de Goede c8dfc6
memory core also has the side effect of fixing ehci register
Hans de Goede c8dfc6
access on bigendian hosts.
Hans de Goede c8dfc6
Hans de Goede c8dfc6
Cc: David Gibson <david@gibson.dropbear.id.au>
Hans de Goede c8dfc6
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
5544c1
(cherry picked from commit 3e4f910c8d490a1490409a7e381dbbb229f9d272)
5544c1
5544c1
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Hans de Goede c8dfc6
---
Hans de Goede c8dfc6
 hw/usb/hcd-ehci.c | 173 ++++++++++++++++++++++++++----------------------------
Hans de Goede c8dfc6
 trace-events      |   9 ++-
Hans de Goede c8dfc6
 2 files changed, 90 insertions(+), 92 deletions(-)
Hans de Goede c8dfc6
Hans de Goede c8dfc6
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
Hans de Goede c8dfc6
index 2f3e9c0..f5ba8e1 100644
Hans de Goede c8dfc6
--- a/hw/usb/hcd-ehci.c
Hans de Goede c8dfc6
+++ b/hw/usb/hcd-ehci.c
Hans de Goede c8dfc6
@@ -389,6 +389,9 @@ struct EHCIState {
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_caps;
Hans de Goede c8dfc6
+    MemoryRegion mem_opreg;
Hans de Goede c8dfc6
+    MemoryRegion mem_ports;
Hans de Goede c8dfc6
     int companion_count;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     /* properties */
Hans de Goede c8dfc6
@@ -398,10 +401,10 @@ struct EHCIState {
Hans de Goede c8dfc6
      *  EHCI spec version 1.0 Section 2.3
Hans de Goede c8dfc6
      *  Host Controller Operational Registers
Hans de Goede c8dfc6
      */
Hans de Goede c8dfc6
+    uint8_t caps[OPREGBASE];
Hans de Goede c8dfc6
     union {
Hans de Goede c8dfc6
-        uint8_t mmio[MMIO_SIZE];
Hans de Goede c8dfc6
+        uint32_t opreg[(PORTSC_BEGIN-OPREGBASE)/sizeof(uint32_t)];
Hans de Goede c8dfc6
         struct {
Hans de Goede c8dfc6
-            uint8_t cap[OPREGBASE];
Hans de Goede c8dfc6
             uint32_t usbcmd;
Hans de Goede c8dfc6
             uint32_t usbsts;
Hans de Goede c8dfc6
             uint32_t usbintr;
Hans de Goede c8dfc6
@@ -411,9 +414,9 @@ struct EHCIState {
Hans de Goede c8dfc6
             uint32_t asynclistaddr;
Hans de Goede c8dfc6
             uint32_t notused[9];
Hans de Goede c8dfc6
             uint32_t configflag;
Hans de Goede c8dfc6
-            uint32_t portsc[NB_PORTS];
Hans de Goede c8dfc6
         };
Hans de Goede c8dfc6
     };
Hans de Goede c8dfc6
+    uint32_t portsc[NB_PORTS];
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     /*
Hans de Goede c8dfc6
      *  Internal states, shadow registers, etc
Hans de Goede c8dfc6
@@ -471,22 +474,12 @@ static const char *ehci_state_names[] = {
Hans de Goede c8dfc6
 };
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
 static const char *ehci_mmio_names[] = {
Hans de Goede c8dfc6
-    [CAPLENGTH]         = "CAPLENGTH",
Hans de Goede c8dfc6
-    [HCIVERSION]        = "HCIVERSION",
Hans de Goede c8dfc6
-    [HCSPARAMS]         = "HCSPARAMS",
Hans de Goede c8dfc6
-    [HCCPARAMS]         = "HCCPARAMS",
Hans de Goede c8dfc6
     [USBCMD]            = "USBCMD",
Hans de Goede c8dfc6
     [USBSTS]            = "USBSTS",
Hans de Goede c8dfc6
     [USBINTR]           = "USBINTR",
Hans de Goede c8dfc6
     [FRINDEX]           = "FRINDEX",
Hans de Goede c8dfc6
     [PERIODICLISTBASE]  = "P-LIST BASE",
Hans de Goede c8dfc6
     [ASYNCLISTADDR]     = "A-LIST ADDR",
Hans de Goede c8dfc6
-    [PORTSC_BEGIN]      = "PORTSC #0",
Hans de Goede c8dfc6
-    [PORTSC_BEGIN + 4]  = "PORTSC #1",
Hans de Goede c8dfc6
-    [PORTSC_BEGIN + 8]  = "PORTSC #2",
Hans de Goede c8dfc6
-    [PORTSC_BEGIN + 12] = "PORTSC #3",
Hans de Goede c8dfc6
-    [PORTSC_BEGIN + 16] = "PORTSC #4",
Hans de Goede c8dfc6
-    [PORTSC_BEGIN + 20] = "PORTSC #5",
Hans de Goede c8dfc6
     [CONFIGFLAG]        = "CONFIGFLAG",
Hans de Goede c8dfc6
 };
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
@@ -509,7 +502,8 @@ static const char *state2str(uint32_t state)
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
 static const char *addr2str(target_phys_addr_t addr)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
-    return nr2str(ehci_mmio_names, ARRAY_SIZE(ehci_mmio_names), addr);
Hans de Goede c8dfc6
+    return nr2str(ehci_mmio_names, ARRAY_SIZE(ehci_mmio_names),
Hans de Goede c8dfc6
+                  addr + OPREGBASE);
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
 static void ehci_trace_usbsts(uint32_t mask, int state)
Hans de Goede c8dfc6
@@ -1018,7 +1012,7 @@ static int ehci_register_companion(USBBus *bus, USBPort *ports[],
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     s->companion_count++;
Hans de Goede c8dfc6
-    s->mmio[0x05] = (s->companion_count << 4) | portcount;
Hans de Goede c8dfc6
+    s->caps[0x05] = (s->companion_count << 4) | portcount;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     return 0;
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
@@ -1063,7 +1057,8 @@ static void ehci_reset(void *opaque)
Hans de Goede c8dfc6
         }
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    memset(&s->mmio[OPREGBASE], 0x00, MMIO_SIZE - OPREGBASE);
Hans de Goede c8dfc6
+    memset(&s->opreg, 0x00, sizeof(s->opreg));
Hans de Goede c8dfc6
+    memset(&s->portsc, 0x00, sizeof(s->portsc));
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     s->usbcmd = NB_MAXINTRATE << USBCMD_ITC_SH;
Hans de Goede c8dfc6
     s->usbsts = USBSTS_HALT;
Hans de Goede c8dfc6
@@ -1090,50 +1085,35 @@ static void ehci_reset(void *opaque)
Hans de Goede c8dfc6
     qemu_bh_cancel(s->async_bh);
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-static uint32_t ehci_mem_readb(void *ptr, target_phys_addr_t addr)
Hans de Goede c8dfc6
+static uint64_t ehci_caps_read(void *ptr, target_phys_addr_t addr,
Hans de Goede c8dfc6
+                               unsigned size)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
     EHCIState *s = ptr;
Hans de Goede c8dfc6
-    uint32_t val;
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-    val = s->mmio[addr];
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-    return val;
Hans de Goede c8dfc6
+    return s->caps[addr];
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-static uint32_t ehci_mem_readw(void *ptr, target_phys_addr_t addr)
Hans de Goede c8dfc6
+static uint64_t ehci_opreg_read(void *ptr, target_phys_addr_t addr,
Hans de Goede c8dfc6
+                                unsigned size)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
     EHCIState *s = ptr;
Hans de Goede c8dfc6
     uint32_t val;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    val = s->mmio[addr] | (s->mmio[addr+1] << 8);
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
+    val = s->opreg[addr >> 2];
Hans de Goede c8dfc6
+    trace_usb_ehci_opreg_read(addr + OPREGBASE, addr2str(addr), val);
Hans de Goede c8dfc6
     return val;
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-static uint32_t ehci_mem_readl(void *ptr, target_phys_addr_t addr)
Hans de Goede c8dfc6
+static uint64_t ehci_port_read(void *ptr, target_phys_addr_t addr,
Hans de Goede c8dfc6
+                               unsigned size)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
     EHCIState *s = ptr;
Hans de Goede c8dfc6
     uint32_t val;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    val = s->mmio[addr] | (s->mmio[addr+1] << 8) |
Hans de Goede c8dfc6
-          (s->mmio[addr+2] << 16) | (s->mmio[addr+3] << 24);
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-    trace_usb_ehci_mmio_readl(addr, addr2str(addr), val);
Hans de Goede c8dfc6
+    val = s->portsc[addr >> 2];
Hans de Goede c8dfc6
+    trace_usb_ehci_portsc_read(addr + PORTSC_BEGIN, addr >> 2, val);
Hans de Goede c8dfc6
     return val;
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-static void ehci_mem_writeb(void *ptr, target_phys_addr_t addr, uint32_t val)
Hans de Goede c8dfc6
-{
Hans de Goede c8dfc6
-    fprintf(stderr, "EHCI doesn't handle byte writes to MMIO\n");
Hans de Goede c8dfc6
-    exit(1);
Hans de Goede c8dfc6
-}
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-static void ehci_mem_writew(void *ptr, target_phys_addr_t addr, uint32_t val)
Hans de Goede c8dfc6
-{
Hans de Goede c8dfc6
-    fprintf(stderr, "EHCI doesn't handle 16-bit writes to MMIO\n");
Hans de Goede c8dfc6
-    exit(1);
Hans de Goede c8dfc6
-}
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
 static void handle_port_owner_write(EHCIState *s, int port, uint32_t owner)
Hans de Goede c8dfc6
 {
Hans de Goede c8dfc6
     USBDevice *dev = s->ports[port].dev;
Hans de Goede c8dfc6
@@ -1162,11 +1142,17 @@ static void handle_port_owner_write(EHCIState *s, int port, uint32_t owner)
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-static void handle_port_status_write(EHCIState *s, int port, uint32_t val)
Hans de Goede c8dfc6
+static void ehci_port_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
+    EHCIState *s = ptr;
Hans de Goede c8dfc6
+    int port = addr >> 2;
Hans de Goede c8dfc6
     uint32_t *portsc = &s->portsc[port];
Hans de Goede c8dfc6
+    uint32_t old = *portsc;
Hans de Goede c8dfc6
     USBDevice *dev = s->ports[port].dev;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
+    trace_usb_ehci_portsc_write(addr + PORTSC_BEGIN, addr >> 2, val);
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
     /* Clear rwc bits */
Hans de Goede c8dfc6
     *portsc &= ~(val & PORTSC_RWC_MASK);
Hans de Goede c8dfc6
     /* The guest may clear, but not set the PED bit */
Hans de Goede c8dfc6
@@ -1198,39 +1184,20 @@ static void handle_port_status_write(EHCIState *s, int port, uint32_t val)
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     *portsc &= ~PORTSC_RO_MASK;
Hans de Goede c8dfc6
     *portsc |= val;
Hans de Goede c8dfc6
+    trace_usb_ehci_portsc_change(addr + PORTSC_BEGIN, addr >> 2, *portsc, old);
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
Hans de Goede c8dfc6
+static void ehci_opreg_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
     EHCIState *s = ptr;
Hans de Goede c8dfc6
-    uint32_t *mmio = (uint32_t *)(&s->mmio[addr]);
Hans de Goede c8dfc6
+    uint32_t *mmio = s->opreg + (addr >> 2);
Hans de Goede c8dfc6
     uint32_t old = *mmio;
Hans de Goede c8dfc6
     int i;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    trace_usb_ehci_mmio_writel(addr, addr2str(addr), val);
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-    /* Only aligned reads are allowed on OHCI */
Hans de Goede c8dfc6
-    if (addr & 3) {
Hans de Goede c8dfc6
-        fprintf(stderr, "usb-ehci: Mis-aligned write to addr 0x"
Hans de Goede c8dfc6
-                TARGET_FMT_plx "\n", addr);
Hans de Goede c8dfc6
-        return;
Hans de Goede c8dfc6
-    }
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-    if (addr >= PORTSC && addr < PORTSC + 4 * NB_PORTS) {
Hans de Goede c8dfc6
-        handle_port_status_write(s, (addr-PORTSC)/4, val);
Hans de Goede c8dfc6
-        trace_usb_ehci_mmio_change(addr, addr2str(addr), *mmio, old);
Hans de Goede c8dfc6
-        return;
Hans de Goede c8dfc6
-    }
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
-    if (addr < OPREGBASE) {
Hans de Goede c8dfc6
-        fprintf(stderr, "usb-ehci: write attempt to read-only register"
Hans de Goede c8dfc6
-                TARGET_FMT_plx "\n", addr);
Hans de Goede c8dfc6
-        return;
Hans de Goede c8dfc6
-    }
Hans de Goede c8dfc6
-
Hans de Goede c8dfc6
+    trace_usb_ehci_opreg_write(addr + OPREGBASE, addr2str(addr), val);
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    /* Do any register specific pre-write processing here.  */
Hans de Goede c8dfc6
-    switch(addr) {
Hans de Goede c8dfc6
+    switch (addr + OPREGBASE) {
Hans de Goede c8dfc6
     case USBCMD:
Hans de Goede c8dfc6
         if (val & USBCMD_HCRESET) {
Hans de Goede c8dfc6
             ehci_reset(s);
Hans de Goede c8dfc6
@@ -1241,7 +1208,7 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
Hans de Goede c8dfc6
         /* not supporting dynamic frame list size at the moment */
Hans de Goede c8dfc6
         if ((val & USBCMD_FLS) && !(s->usbcmd & USBCMD_FLS)) {
Hans de Goede c8dfc6
             fprintf(stderr, "attempt to set frame list size -- value %d\n",
Hans de Goede c8dfc6
-                    val & USBCMD_FLS);
Hans de Goede c8dfc6
+                    (int)val & USBCMD_FLS);
Hans de Goede c8dfc6
             val &= ~USBCMD_FLS;
Hans de Goede c8dfc6
         }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
@@ -1308,7 +1275,7 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val)
Hans de Goede c8dfc6
     }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     *mmio = val;
Hans de Goede c8dfc6
-    trace_usb_ehci_mmio_change(addr, addr2str(addr), *mmio, old);
Hans de Goede c8dfc6
+    trace_usb_ehci_opreg_change(addr + OPREGBASE, addr2str(addr), *mmio, old);
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
@@ -2520,11 +2487,28 @@ static void ehci_async_bh(void *opaque)
Hans de Goede c8dfc6
     ehci_advance_async_state(ehci);
Hans de Goede c8dfc6
 }
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-static const MemoryRegionOps ehci_mem_ops = {
Hans de Goede c8dfc6
-    .old_mmio = {
Hans de Goede c8dfc6
-        .read = { ehci_mem_readb, ehci_mem_readw, ehci_mem_readl },
Hans de Goede c8dfc6
-        .write = { ehci_mem_writeb, ehci_mem_writew, ehci_mem_writel },
Hans de Goede c8dfc6
-    },
Hans de Goede c8dfc6
+static const MemoryRegionOps ehci_mmio_caps_ops = {
Hans de Goede c8dfc6
+    .read = ehci_caps_read,
Hans de Goede c8dfc6
+    .valid.min_access_size = 1,
Hans de Goede c8dfc6
+    .valid.max_access_size = 4,
Hans de Goede c8dfc6
+    .impl.min_access_size = 1,
Hans de Goede c8dfc6
+    .impl.max_access_size = 1,
Hans de Goede c8dfc6
+    .endianness = DEVICE_LITTLE_ENDIAN,
Hans de Goede c8dfc6
+};
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
+static const MemoryRegionOps ehci_mmio_opreg_ops = {
Hans de Goede c8dfc6
+    .read = ehci_opreg_read,
Hans de Goede c8dfc6
+    .write = ehci_opreg_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 ehci_mmio_port_ops = {
Hans de Goede c8dfc6
+    .read = ehci_port_read,
Hans de Goede c8dfc6
+    .write = ehci_port_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
@@ -2681,19 +2665,19 @@ static int usb_ehci_initfn(PCIDevice *dev)
Hans de Goede c8dfc6
     pci_conf[0x6e] = 0x00;
Hans de Goede c8dfc6
     pci_conf[0x6f] = 0xc0;  // USBLEFCTLSTS
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    // 2.2 host controller interface version
Hans de Goede c8dfc6
-    s->mmio[0x00] = (uint8_t) OPREGBASE;
Hans de Goede c8dfc6
-    s->mmio[0x01] = 0x00;
Hans de Goede c8dfc6
-    s->mmio[0x02] = 0x00;
Hans de Goede c8dfc6
-    s->mmio[0x03] = 0x01;        // HC version
Hans de Goede c8dfc6
-    s->mmio[0x04] = NB_PORTS;    // Number of downstream ports
Hans de Goede c8dfc6
-    s->mmio[0x05] = 0x00;        // No companion ports at present
Hans de Goede c8dfc6
-    s->mmio[0x06] = 0x00;
Hans de Goede c8dfc6
-    s->mmio[0x07] = 0x00;
Hans de Goede c8dfc6
-    s->mmio[0x08] = 0x80;        // We can cache whole frame, not 64-bit capable
Hans de Goede c8dfc6
-    s->mmio[0x09] = 0x68;        // EECP
Hans de Goede c8dfc6
-    s->mmio[0x0a] = 0x00;
Hans de Goede c8dfc6
-    s->mmio[0x0b] = 0x00;
Hans de Goede c8dfc6
+    /* 2.2 host controller interface version */
Hans de Goede c8dfc6
+    s->caps[0x00] = (uint8_t) OPREGBASE;
Hans de Goede c8dfc6
+    s->caps[0x01] = 0x00;
Hans de Goede c8dfc6
+    s->caps[0x02] = 0x00;
Hans de Goede c8dfc6
+    s->caps[0x03] = 0x01;        /* HC version */
Hans de Goede c8dfc6
+    s->caps[0x04] = NB_PORTS;    /* Number of downstream ports */
Hans de Goede c8dfc6
+    s->caps[0x05] = 0x00;        /* No companion ports at present */
Hans de Goede c8dfc6
+    s->caps[0x06] = 0x00;
Hans de Goede c8dfc6
+    s->caps[0x07] = 0x00;
Hans de Goede c8dfc6
+    s->caps[0x08] = 0x80;        /* We can cache whole frame, no 64-bit */
Hans de Goede c8dfc6
+    s->caps[0x09] = 0x68;        /* EECP */
Hans de Goede c8dfc6
+    s->caps[0x0a] = 0x00;
Hans de Goede c8dfc6
+    s->caps[0x0b] = 0x00;
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     s->irq = s->dev.irq[3];
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
@@ -2712,7 +2696,18 @@ static int usb_ehci_initfn(PCIDevice *dev)
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     qemu_register_reset(ehci_reset, s);
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
-    memory_region_init_io(&s->mem, &ehci_mem_ops, s, "ehci", MMIO_SIZE);
Hans de Goede c8dfc6
+    memory_region_init(&s->mem, "ehci", MMIO_SIZE);
Hans de Goede c8dfc6
+    memory_region_init_io(&s->mem_caps, &ehci_mmio_caps_ops, s,
Hans de Goede c8dfc6
+                          "capabilities", OPREGBASE);
Hans de Goede c8dfc6
+    memory_region_init_io(&s->mem_opreg, &ehci_mmio_opreg_ops, s,
Hans de Goede c8dfc6
+                          "operational", PORTSC_BEGIN - OPREGBASE);
Hans de Goede c8dfc6
+    memory_region_init_io(&s->mem_ports, &ehci_mmio_port_ops, s,
Hans de Goede c8dfc6
+                          "ports", PORTSC_END - PORTSC_BEGIN);
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
+    memory_region_add_subregion(&s->mem, 0,            &s->mem_caps);
Hans de Goede c8dfc6
+    memory_region_add_subregion(&s->mem, OPREGBASE,    &s->mem_opreg);
Hans de Goede c8dfc6
+    memory_region_add_subregion(&s->mem, PORTSC_BEGIN, &s->mem_ports);
Hans de Goede c8dfc6
+
Hans de Goede c8dfc6
     pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mem);
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
     return 0;
Hans de Goede c8dfc6
diff --git a/trace-events b/trace-events
5544c1
index c83d65e..cf05414 100644
Hans de Goede c8dfc6
--- a/trace-events
Hans de Goede c8dfc6
+++ b/trace-events
Hans de Goede c8dfc6
@@ -243,9 +243,12 @@ usb_port_release(int bus, const char *port) "bus %d, port %s"
Hans de Goede c8dfc6
 
Hans de Goede c8dfc6
 # hw/usb/hcd-ehci.c
Hans de Goede c8dfc6
 usb_ehci_reset(void) "=== RESET ==="
Hans de Goede c8dfc6
-usb_ehci_mmio_readl(uint32_t addr, const char *str, uint32_t val) "rd mmio %04x [%s] = %x"
Hans de Goede c8dfc6
-usb_ehci_mmio_writel(uint32_t addr, const char *str, uint32_t val) "wr mmio %04x [%s] = %x"
Hans de Goede c8dfc6
-usb_ehci_mmio_change(uint32_t addr, const char *str, uint32_t new, uint32_t old) "ch mmio %04x [%s] = %x (old: %x)"
Hans de Goede c8dfc6
+usb_ehci_opreg_read(uint32_t addr, const char *str, uint32_t val) "rd mmio %04x [%s] = %x"
Hans de Goede c8dfc6
+usb_ehci_opreg_write(uint32_t addr, const char *str, uint32_t val) "wr mmio %04x [%s] = %x"
Hans de Goede c8dfc6
+usb_ehci_opreg_change(uint32_t addr, const char *str, uint32_t new, uint32_t old) "ch mmio %04x [%s] = %x (old: %x)"
Hans de Goede c8dfc6
+usb_ehci_portsc_read(uint32_t addr, uint32_t port, uint32_t val) "rd mmio %04x [port %d] = %x"
Hans de Goede c8dfc6
+usb_ehci_portsc_write(uint32_t addr, uint32_t port, uint32_t val) "wr mmio %04x [port %d] = %x"
Hans de Goede c8dfc6
+usb_ehci_portsc_change(uint32_t addr, uint32_t port, uint32_t new, uint32_t old) "ch mmio %04x [port %d] = %x (old: %x)"
Hans de Goede c8dfc6
 usb_ehci_usbsts(const char *sts, int state) "usbsts %s %d"
Hans de Goede c8dfc6
 usb_ehci_state(const char *schedule, const char *state) "%s schedule %s"
Hans de Goede c8dfc6
 usb_ehci_qh_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t c_qtd, uint32_t n_qtd, uint32_t a_qtd) "q %p - QH @ %08x: next %08x qtds %08x,%08x,%08x"
Hans de Goede c8dfc6
-- 
5544c1
1.7.12.1
Hans de Goede c8dfc6