From 7e63c5293dd80111cd00f52e2ecb17de2bef15da Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Thu, 7 Jul 2011 15:03:02 -0300 Subject: [RHEL6 qemu-kvm PATCH 090/115] usb-ehci: trace mmio and usbsts usb-ehci: trace mmio and usbsts (v2) RH-Author: Eduardo Habkost Message-id: <20110707150302.GF17131@otherpad.lan.raisama.net> Patchwork-id: 29131 O-Subject: [RHEL6 qemu-kvm PATCH] usb-ehci: trace mmio and usbsts usb-ehci: trace mmio and usbsts (v2) Bugzilla: 561414 632299 645351 711354 RH-Acked-by: Jes Sorensen This simply combines two previously-submitted patches from Gerd. Please ACK. Patch 1: From: Gerd Hoffmann Subject: [RHEL-6.2 kvm PATCH 089/115] usb-ehci: trace mmio and usbsts usb-ehci: trace mmio and usbsts This patch starts adding trace support to ehci. It traces updates of the status register (USBSTS), mmio access and controller reset. It also adds functions to set and clear status register bits and puts them in use everywhere. Some DPRINTF's are dropped in favor of the new tracepoints. No change in behavior. Signed-off-by: Gerd Hoffmann (cherry picked from commit 439a97ccab2dba51e4dad94ba2d347143a0709cc) Conflicts: hw/usb-ehci.c trace-events Patch 2: From: Gerd Hoffmann Subject: [RHEL-6.2 kvm PATCH 094/115] usb-ehci: trace mmio and usbsts FIXUP Signed-off-by: Gerd Hoffmann Signed-off-by: Eduardo Habkost --- hw/usb-ehci.c | 156 ++++++++++++++++++++++++++++++--------------------------- trace-events | 6 ++ 2 files changed, 89 insertions(+), 73 deletions(-) Signed-off-by: Eduardo Habkost --- hw/usb-ehci.c | 156 ++++++++++++++++++++++++++++++--------------------------- trace-events | 6 ++ 2 files changed, 89 insertions(+), 73 deletions(-) diff --git a/hw/usb-ehci.c b/hw/usb-ehci.c index 5c78d23..e1abd8a 100644 --- a/hw/usb-ehci.c +++ b/hw/usb-ehci.c @@ -30,6 +30,7 @@ #include "usb.h" #include "pci.h" #include "monitor.h" +#include "trace.h" #define EHCI_DEBUG 0 #define STATE_DEBUG 0 /* state transitions */ @@ -417,24 +418,23 @@ typedef struct { } while(0) -#if EHCI_DEBUG -static const char *addr2str(unsigned addr) +static const char *addr2str(target_phys_addr_t addr) { - const char *r = " unknown"; + const char *r = "unknown"; const char *n[] = { - [ CAPLENGTH ] = " CAPLENGTH", + [ CAPLENGTH ] = "CAPLENGTH", [ HCIVERSION ] = "HCIVERSION", - [ HCSPARAMS ] = " HCSPARAMS", - [ HCCPARAMS ] = " HCCPARAMS", - [ USBCMD ] = " COMMAND", - [ USBSTS ] = " STATUS", - [ USBINTR ] = " INTERRUPT", - [ FRINDEX ] = " FRAME IDX", + [ HCSPARAMS ] = "HCSPARAMS", + [ HCCPARAMS ] = "HCCPARAMS", + [ USBCMD ] = "USBCMD", + [ USBSTS ] = "USBSTS", + [ USBINTR ] = "USBINTR", + [ FRINDEX ] = "FRINDEX", [ PERIODICLISTBASE ] = "P-LIST BASE", [ ASYNCLISTADDR ] = "A-LIST ADDR", [ PORTSC_BEGIN ... - PORTSC_END ] = "PORT STATUS", - [ CONFIGFLAG ] = "CONFIG FLAG", + PORTSC_END ] = "PORTSC", + [ CONFIGFLAG ] = "CONFIGFLAG", }; if (addr < ARRAY_SIZE(n) && n[addr] != NULL) { @@ -443,8 +443,61 @@ static const char *addr2str(unsigned addr) return r; } } -#endif +static void ehci_trace_usbsts(uint32_t mask, int state) +{ + /* interrupts */ + if (mask & USBSTS_INT) { + trace_usb_ehci_usbsts("INT", state); + } + if (mask & USBSTS_ERRINT) { + trace_usb_ehci_usbsts("ERRINT", state); + } + if (mask & USBSTS_PCD) { + trace_usb_ehci_usbsts("PCD", state); + } + if (mask & USBSTS_FLR) { + trace_usb_ehci_usbsts("FLR", state); + } + if (mask & USBSTS_HSE) { + trace_usb_ehci_usbsts("HSE", state); + } + if (mask & USBSTS_IAA) { + trace_usb_ehci_usbsts("IAA", state); + } + + /* status */ + if (mask & USBSTS_HALT) { + trace_usb_ehci_usbsts("HALT", state); + } + if (mask & USBSTS_REC) { + trace_usb_ehci_usbsts("REC", state); + } + if (mask & USBSTS_PSS) { + trace_usb_ehci_usbsts("PSS", state); + } + if (mask & USBSTS_ASS) { + trace_usb_ehci_usbsts("ASS", state); + } +} + +static inline void ehci_set_usbsts(EHCIState *s, int mask) +{ + if ((s->usbsts & mask) == mask) { + return; + } + ehci_trace_usbsts(mask, 1); + s->usbsts |= mask; +} + +static inline void ehci_clear_usbsts(EHCIState *s, int mask) +{ + if ((s->usbsts & mask) == 0) { + return; + } + ehci_trace_usbsts(mask, 0); + s->usbsts &= ~mask; +} static inline void ehci_set_interrupt(EHCIState *s, int intr) { @@ -452,7 +505,7 @@ static inline void ehci_set_interrupt(EHCIState *s, int intr) // TODO honour interrupt threshold requests - s->usbsts |= intr; + ehci_set_usbsts(s, intr); if ((s->usbsts & USBINTR_MASK) & s->usbintr) { level = 1; @@ -526,6 +579,7 @@ static void ehci_reset(void *opaque) uint8_t *pci_conf; int i; + trace_usb_ehci_reset(); pci_conf = s->dev.config; memset(&s->mmio[OPREGBASE], 0x00, MMIO_SIZE - OPREGBASE); @@ -576,6 +630,7 @@ static uint32_t ehci_mem_readl(void *ptr, target_phys_addr_t addr) val = s->mmio[addr] | (s->mmio[addr+1] << 8) | (s->mmio[addr+2] << 16) | (s->mmio[addr+3] << 24); + trace_usb_ehci_mmio_readl(addr, addr2str(addr), val); return val; } @@ -645,9 +700,9 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) { EHCIState *s = ptr; int i; -#if EHCI_DEBUG - const char *str; -#endif + + trace_usb_ehci_mmio_writel(addr, addr2str(addr), val, + *(uint32_t *)(&s->mmio[addr])); /* Only aligned reads are allowed on OHCI */ if (addr & 3) { @@ -669,30 +724,21 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) /* Do any register specific pre-write processing here. */ -#if EHCI_DEBUG - str = addr2str((unsigned) addr); -#endif switch(addr) { case USBCMD: - DPRINTF("ehci_mem_writel: USBCMD val=0x%08X, current cmd=0x%08X\n", - val, s->usbcmd); - if ((val & USBCMD_RUNSTOP) && !(s->usbcmd & USBCMD_RUNSTOP)) { - DPRINTF("ehci_mem_writel: %s run, clear halt\n", str); qemu_mod_timer(s->frame_timer, qemu_get_clock(vm_clock)); SET_LAST_RUN_CLOCK(s); - s->usbsts &= ~USBSTS_HALT; + ehci_clear_usbsts(s, USBSTS_HALT); } if (!(val & USBCMD_RUNSTOP) && (s->usbcmd & USBCMD_RUNSTOP)) { - DPRINTF(" ** STOP **\n"); qemu_del_timer(s->frame_timer); // TODO - should finish out some stuff before setting halt - s->usbsts |= USBSTS_HALT; + ehci_set_usbsts(s, USBSTS_HALT); } if (val & USBCMD_HCRESET) { - DPRINTF("ehci_mem_writel: %s run, resetting\n", str); ehci_reset(s); val &= ~USBCMD_HCRESET; } @@ -703,56 +749,24 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) val & USBCMD_FLS); val &= ~USBCMD_FLS; } -#if EHCI_DEBUG - if ((val & USBCMD_PSE) && !(s->usbcmd & USBCMD_PSE)) { - DPRINTF("periodic scheduling enabled\n"); - } - if (!(val & USBCMD_PSE) && (s->usbcmd & USBCMD_PSE)) { - DPRINTF("periodic scheduling disabled\n"); - } - if ((val & USBCMD_ASE) && !(s->usbcmd & USBCMD_ASE)) { - DPRINTF("asynchronous scheduling enabled\n"); - } - if (!(val & USBCMD_ASE) && (s->usbcmd & USBCMD_ASE)) { - DPRINTF("asynchronous scheduling disabled\n"); - } - if ((val & USBCMD_IAAD) && !(s->usbcmd & USBCMD_IAAD)) { - DPRINTF("doorbell request received\n"); - } - if ((val & USBCMD_LHCR) && !(s->usbcmd & USBCMD_LHCR)) { - DPRINTF("light host controller reset received\n"); - } - if ((val & USBCMD_ITC) != (s->usbcmd & USBCMD_ITC)) { - DPRINTF("interrupt threshold control set to %x\n", - (val & USBCMD_ITC)>>USBCMD_ITC_SH); - } -#endif break; - case USBSTS: val &= USBSTS_RO_MASK; // bits 6 thru 31 are RO - DPRINTF("ehci_mem_writel: %s RWC set to 0x%08X\n", str, val); - - val = (s->usbsts &= ~val); // bits 0 thru 5 are R/WC - - DPRINTF("ehci_mem_writel: %s updating interrupt condition\n", str); + ehci_clear_usbsts(s, val); // bits 0 thru 5 are R/WC + val = s->usbsts; ehci_set_interrupt(s, 0); break; - case USBINTR: val &= USBINTR_MASK; - DPRINTF("ehci_mem_writel: %s set to 0x%08X\n", str, val); break; case FRINDEX: s->sofv = val >> 3; - DPRINTF("ehci_mem_writel: %s set to 0x%08X\n", str, val); break; case CONFIGFLAG: - DPRINTF("ehci_mem_writel: %s set to 0x%08X\n", str, val); val &= 0x1; if (val) { for(i = 0; i < NB_PORTS; i++) @@ -766,7 +780,6 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) "ehci: PERIODIC list base register set while periodic schedule\n" " is enabled and HC is enabled\n"); } - DPRINTF("ehci_mem_writel: P-LIST BASE set to 0x%08X\n", val); break; case ASYNCLISTADDR: @@ -775,7 +788,6 @@ static void ehci_mem_writel(void *ptr, target_phys_addr_t addr, uint32_t val) "ehci: ASYNC list address register set while async schedule\n" " is enabled and HC is enabled\n"); } - DPRINTF("ehci_mem_writel: A-LIST ADDR set to 0x%08X\n", val); break; } @@ -1227,7 +1239,7 @@ static int ehci_state_waitlisthead(EHCIState *ehci, int async, int *state) /* set reclamation flag at start event (4.8.6) */ if (async) { - ehci->usbsts |= USBSTS_REC; + ehci_set_usbsts(ehci, USBSTS_REC); } /* Find the head of the list (4.9.1.1) */ @@ -1334,7 +1346,7 @@ static int ehci_state_fetchqh(EHCIState *ehci, int async, int *state) /* EHCI spec version 1.0 Section 4.8.3 & 4.10.1 */ if (ehci->usbsts & USBSTS_REC) { - ehci->usbsts &= ~USBSTS_REC; + ehci_clear_usbsts(ehci, USBSTS_REC); } else { DPRINTF("FETCHQH: QH 0x%08x. H-bit set, reclamation status reset" " - done processing\n", ehci->qhaddr); @@ -1534,7 +1546,7 @@ static int ehci_state_execute(EHCIState *ehci, int async, int *state) } if (async) { - ehci->usbsts |= USBSTS_REC; + ehci_set_usbsts(ehci, USBSTS_REC); } ehci->exec_status = ehci_execute(ehci, qh); @@ -1734,13 +1746,13 @@ static void ehci_advance_async_state(EHCIState *ehci) if (!(ehci->usbcmd & USBCMD_ASE)) { break; } - ehci->usbsts |= USBSTS_ASS; + ehci_set_usbsts(ehci, USBSTS_ASS); ehci->astate = EST_ACTIVE; // No break, fall through to ACTIVE case EST_ACTIVE: if ( !(ehci->usbcmd & USBCMD_ASE)) { - ehci->usbsts &= ~USBSTS_ASS; + ehci_clear_usbsts(ehci, USBSTS_ASS); ehci->astate = EST_INACTIVE; break; } @@ -1800,8 +1812,7 @@ static void ehci_advance_periodic_state(EHCIState *ehci) switch(ehci->pstate) { case EST_INACTIVE: if ( !(ehci->frindex & 7) && (ehci->usbcmd & USBCMD_PSE)) { - DPRINTF("PERIODIC going active\n"); - ehci->usbsts |= USBSTS_PSS; + ehci_set_usbsts(ehci, USBSTS_PSS); ehci->pstate = EST_ACTIVE; // No break, fall through to ACTIVE } else @@ -1809,8 +1820,7 @@ static void ehci_advance_periodic_state(EHCIState *ehci) case EST_ACTIVE: if ( !(ehci->frindex & 7) && !(ehci->usbcmd & USBCMD_PSE)) { - DPRINTF("PERIODIC going inactive\n"); - ehci->usbsts &= ~USBSTS_PSS; + ehci_clear_usbsts(ehci, USBSTS_PSS); ehci->pstate = EST_INACTIVE; break; } diff --git a/trace-events b/trace-events index 99cc044..38a2702 100644 --- a/trace-events +++ b/trace-events @@ -82,6 +82,12 @@ disable apic_reset_irq_delivered(int apic_irq_delivered) "old coalescing %d" disable apic_get_irq_delivered(int apic_irq_delivered) "returning coalescing %d" disable apic_set_irq(int apic_irq_delivered) "coalescing %d" +# hw/usb-ehci.c +disable usb_ehci_reset(void) "=== RESET ===" +disable usb_ehci_mmio_readl(uint32_t addr, const char *str, uint32_t val) "rd mmio %04x [%s] = %x" +disable usb_ehci_mmio_writel(uint32_t addr, const char *str, uint32_t val, uint32_t oldval) "wr mmio %04x [%s] = %x (old: %x)" +disable usb_ehci_usbsts(const char *sts, int state) "usbsts %s %d" + # hw/usb-desc.c disable usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d" disable usb_desc_device_qualifier(int addr, int len, int ret) "dev %d query device qualifier, len %d, ret %d" -- 1.7.3.2