qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: Gerd Hoffmann <kraxel@redhat.com>
Subject: [Qemu-devel] [PATCH 02/31] usb-ehci: trace mmio and usbsts
Date: Mon,  6 Jun 2011 14:38:53 +0200	[thread overview]
Message-ID: <1307363962-27223-3-git-send-email-kraxel@redhat.com> (raw)
In-Reply-To: <1307363962-27223-1-git-send-email-kraxel@redhat.com>

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 <kraxel@redhat.com>
---
 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 f63519e..16fbca6 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_ns(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 e0e9574..c87a86e 100644
--- a/trace-events
+++ b/trace-events
@@ -194,6 +194,12 @@ disable sun4m_iommu_page_get_flags(uint64_t pa, uint64_t iopte, uint32_t ret) "g
 disable sun4m_iommu_translate_pa(uint64_t addr, uint64_t pa, uint32_t iopte) "xlate dva %"PRIx64" => pa %"PRIx64" iopte = %x"
 disable sun4m_iommu_bad_addr(uint64_t addr) "bad addr %"PRIx64""
 
+# 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.1

  parent reply	other threads:[~2011-06-06 12:39 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-06 12:38 [Qemu-devel] [PATCH 00/31] usb patch queue Gerd Hoffmann
2011-06-06 12:38 ` [Qemu-devel] [PATCH 01/31] usb-linux: catch ENODEV in more places Gerd Hoffmann
2011-06-06 12:38 ` Gerd Hoffmann [this message]
2011-06-06 12:38 ` [Qemu-devel] [PATCH 03/31] usb-ehci: trace state machine changes Gerd Hoffmann
2011-06-06 12:38 ` [Qemu-devel] [PATCH 04/31] usb-ehci: trace port state Gerd Hoffmann
2011-06-06 12:38 ` [Qemu-devel] [PATCH 05/31] usb-ehci: improve mmio tracing Gerd Hoffmann
2011-06-06 12:38 ` [Qemu-devel] [PATCH 06/31] usb-ehci: trace buffer copy Gerd Hoffmann
2011-06-06 12:38 ` [Qemu-devel] [PATCH 07/31] usb-ehci: add queue data struct Gerd Hoffmann
2011-06-06 12:38 ` [Qemu-devel] [PATCH 08/31] usb-ehci: multiqueue support Gerd Hoffmann
2011-06-06 14:50   ` David Ahern
2011-06-07  7:30     ` Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 09/31] usb-ehci: fix offset writeback in ehci_buffer_rw Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 10/31] usb-ehci: fix error handling Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 11/31] ehci: fix a number of unused-but-set-variable warnings (new with gcc-4.6) Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 12/31] usb: cancel async packets on unplug Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 13/31] usb-ehci: drop EXECUTING checks Gerd Hoffmann
2011-06-06 13:34   ` David Ahern
2011-06-06 13:57     ` David Ahern
2011-06-06 14:25       ` Gerd Hoffmann
2011-06-06 14:51         ` David Ahern
2011-06-06 12:39 ` [Qemu-devel] [PATCH 14/31] Fix USB mouse Set_Protocol behavior Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 15/31] The USB tablet should not claim boot protocol support Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 16/31] usb-ehci: itd handling fixes Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 17/31] usb-ehci: split trace calls to handle arg count limits Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 18/31] usb: documentation update Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 19/31] usb-linux: Get speed from sysfs rather then from the connectinfo ioctl Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 20/31] usb-linux: Teach about super speed Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 21/31] usb-linux: Don't do perror when errno is not set Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 22/31] usb-linux: Ensure devep != 0 Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 23/31] usb-linux: Don't try to open the same device twice Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 24/31] usb-linux: only cleanup in host_close when host_open was successful Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 25/31] usb: don't call usb_host_device_open from vl.c Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 26/31] usb-linux: Enlarge buffer for descriptors to 8192 bytes Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 27/31] usb-bus: Add knowledge of USB_SPEED_SUPER to usb_speed helper Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 28/31] usb-bus: Don't detach non attached devices on device exit Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 29/31] usb: Add defines for USB Serial Bus Release Number register Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 30/31] usb: Use defines for serial bus release number register for UHCI Gerd Hoffmann
2011-06-06 12:39 ` [Qemu-devel] [PATCH 31/31] usb: Use defines for serial bus release number register for EHCI Gerd Hoffmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1307363962-27223-3-git-send-email-kraxel@redhat.com \
    --to=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).