All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing
@ 2017-08-29 20:49 John Snow
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 1/9] IDE: replace DEBUG_IDE with tracing system John Snow
                   ` (10 more replies)
  0 siblings, 11 replies; 22+ messages in thread
From: John Snow @ 2017-08-29 20:49 UTC (permalink / raw)
  To: qemu-block; +Cc: eblake, qemu-devel, f4bug, John Snow

Wherever possible, replace all printfs with proper tracing.
In most places I've tried to do a straight replacement, but
forthcoming patches may calibrate the tracing to be a little nicer.

For now, it's nice to just remove the all-or-nothing tracing.

For V2, I opted to leave in the nearly redundant tracers for now
with their individual names so that they can be targeted individually.

Key:
[----] : patches are identical
[####] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively

001/9:[0020] [FC] 'IDE: replace DEBUG_IDE with tracing system'
002/9:[0004] [FC] 'IDE: Add register hints to tracing'
003/9:[0005] [FC] 'IDE: add tracing for data ports'
004/9:[0004] [FC] 'ATAPI: Replace DEBUG_IDE_ATAPI with tracing events'
005/9:[0013] [FC] 'IDE: replace DEBUG_AIO with trace events'
006/9:[0007] [FC] 'AHCI: Replace DPRINTF with trace-events'
007/9:[----] [--] 'AHCI: Rework IRQ constants'
008/9:[0001] [FC] 'AHCI: pretty-print FIS to buffer instead of stderr'
009/9:[----] [--] 'AHCI: remove DPRINTF macro'

===
v2:
===

01: Rehabilitate commit message.
    Fix switch () statement spacing. (Eric)
    Adjust spacing in ide-tracing file to maintain columns.
    Change filename orderings in trace-events. (Eric)
    Fixed newline issue in trace-events. (Eric)

02: Context / Added R-B.

03: Added trace-events items to appropriate patch (removed from 04) (Eric)
    Added a verbose warning for data tracers (Eric)

04: Shifted items to 03 (Eric)
    Fixed newline issue (Eric)

05: Changed __END to __COUNT (Philippe)
    Removed __BEGIN enumerator (Philippe)

06: Added more information to unknown write (Philippe)

08: Context (Entropy)

John Snow (9):
  IDE: replace DEBUG_IDE with tracing system
  IDE: Add register hints to tracing
  IDE: add tracing for data ports
  ATAPI: Replace DEBUG_IDE_ATAPI with tracing events
  IDE: replace DEBUG_AIO with trace events
  AHCI: Replace DPRINTF with trace-events
  AHCI: Rework IRQ constants
  AHCI: pretty-print FIS to buffer instead of stderr
  AHCI: remove DPRINTF macro

 Makefile.objs             |   1 +
 hw/ide/ahci.c             | 269 ++++++++++++++++++++++++++--------------------
 hw/ide/ahci_internal.h    |  44 ++++++--
 hw/ide/atapi.c            |  69 +++++-------
 hw/ide/cmd646.c           |  10 +-
 hw/ide/core.c             | 178 +++++++++++++++++++-----------
 hw/ide/pci.c              |  17 +--
 hw/ide/piix.c             |  11 +-
 hw/ide/trace-events       | 111 +++++++++++++++++++
 hw/ide/via.c              |  10 +-
 include/hw/ide/internal.h |   8 +-
 11 files changed, 456 insertions(+), 272 deletions(-)
 create mode 100644 hw/ide/trace-events

-- 
2.9.5

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 1/9] IDE: replace DEBUG_IDE with tracing system
  2017-08-29 20:49 [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing John Snow
@ 2017-08-29 20:49 ` John Snow
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 2/9] IDE: Add register hints to tracing John Snow
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: John Snow @ 2017-08-29 20:49 UTC (permalink / raw)
  To: qemu-block; +Cc: eblake, qemu-devel, f4bug, John Snow

Remove the DEBUG_IDE preprocessor definition with something more
appropriately flexible, using the trace-events subsystem.

This will be less prone to bitrot and will more effectively allow
us to target just the functions we care about.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 Makefile.objs             |  1 +
 hw/ide/cmd646.c           | 10 +++-----
 hw/ide/core.c             | 65 +++++++++++++++++++----------------------------
 hw/ide/pci.c              | 17 ++++---------
 hw/ide/piix.c             | 11 ++++----
 hw/ide/trace-events       | 35 +++++++++++++++++++++++++
 hw/ide/via.c              | 10 +++-----
 include/hw/ide/internal.h |  1 -
 8 files changed, 80 insertions(+), 70 deletions(-)
 create mode 100644 hw/ide/trace-events

diff --git a/Makefile.objs b/Makefile.objs
index 24a4ea0..967c092 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -153,6 +153,7 @@ trace-events-subdirs += hw/acpi
 trace-events-subdirs += hw/arm
 trace-events-subdirs += hw/alpha
 trace-events-subdirs += hw/xen
+trace-events-subdirs += hw/ide
 trace-events-subdirs += ui
 trace-events-subdirs += audio
 trace-events-subdirs += net
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 9ebb8d4..86b2a8f 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -32,6 +32,7 @@
 #include "sysemu/dma.h"
 
 #include "hw/ide/pci.h"
+#include "trace.h"
 
 /* CMD646 specific */
 #define CFR		0x50
@@ -195,9 +196,8 @@ static uint64_t bmdma_read(void *opaque, hwaddr addr,
         val = 0xff;
         break;
     }
-#ifdef DEBUG_IDE
-    printf("bmdma: readb " TARGET_FMT_plx " : 0x%02x\n", addr, val);
-#endif
+
+    trace_bmdma_read_cmd646(addr, val);
     return val;
 }
 
@@ -211,9 +211,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
         return;
     }
 
-#ifdef DEBUG_IDE
-    printf("bmdma: writeb " TARGET_FMT_plx " : 0x%" PRIx64 "\n", addr, val);
-#endif
+    trace_bmdma_write_cmd646(addr, val);
     switch(addr & 3) {
     case 0:
         bmdma_cmd_writeb(bm, val);
diff --git a/hw/ide/core.c b/hw/ide/core.c
index bea3953..31fd593 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -36,6 +36,7 @@
 #include "qemu/cutils.h"
 
 #include "hw/ide/internal.h"
+#include "trace.h"
 
 /* These values were based on a Seagate ST3500418AS but have been modified
    to make more sense in QEMU */
@@ -656,10 +657,7 @@ void ide_cancel_dma_sync(IDEState *s)
      * write requests) pending and we can avoid to drain. */
     QLIST_FOREACH(req, &s->buffered_requests, list) {
         if (!req->orphaned) {
-#ifdef DEBUG_IDE
-            printf("%s: invoking cb %p of buffered request %p with"
-                   " -ECANCELED\n", __func__, req->original_cb, req);
-#endif
+            trace_ide_cancel_dma_sync_buffered(req->original_cb, req);
             req->original_cb(req->original_opaque, -ECANCELED);
         }
         req->orphaned = true;
@@ -678,9 +676,7 @@ void ide_cancel_dma_sync(IDEState *s)
      * aio operation with preadv/pwritev.
      */
     if (s->bus->dma->aiocb) {
-#ifdef DEBUG_IDE
-        printf("%s: draining all remaining requests", __func__);
-#endif
+        trace_ide_cancel_dma_sync_remaining();
         blk_drain(s->blk);
         assert(s->bus->dma->aiocb == NULL);
     }
@@ -741,9 +737,7 @@ static void ide_sector_read(IDEState *s)
         n = s->req_nb_sectors;
     }
 
-#if defined(DEBUG_IDE)
-    printf("sector=%" PRId64 "\n", sector_num);
-#endif
+    trace_ide_sector_read(sector_num, n);
 
     if (!ide_sect_range_ok(s, sector_num, n)) {
         ide_rw_error(s);
@@ -1005,14 +999,14 @@ static void ide_sector_write(IDEState *s)
 
     s->status = READY_STAT | SEEK_STAT | BUSY_STAT;
     sector_num = ide_get_sector(s);
-#if defined(DEBUG_IDE)
-    printf("sector=%" PRId64 "\n", sector_num);
-#endif
+
     n = s->nsector;
     if (n > s->req_nb_sectors) {
         n = s->req_nb_sectors;
     }
 
+    trace_ide_sector_write(sector_num, n);
+
     if (!ide_sect_range_ok(s, sector_num, n)) {
         ide_rw_error(s);
         block_acct_invalid(blk_get_stats(s->blk), BLOCK_ACCT_WRITE);
@@ -1194,18 +1188,17 @@ static void ide_clear_hob(IDEBus *bus)
 void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
     IDEBus *bus = opaque;
+    IDEState *s = idebus_active_if(bus);
+    int reg_num = addr & 7;
 
-#ifdef DEBUG_IDE
-    printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
-#endif
-
-    addr &= 7;
+    trace_ide_ioport_write(addr, val, bus, s);
 
     /* ignore writes to command block while busy with previous command */
-    if (addr != 7 && (idebus_active_if(bus)->status & (BUSY_STAT|DRQ_STAT)))
+    if (reg_num != 7 && (s->status & (BUSY_STAT|DRQ_STAT))) {
         return;
+    }
 
-    switch(addr) {
+    switch (reg_num) {
     case 0:
         break;
     case 1:
@@ -1261,9 +1254,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 
 static void ide_reset(IDEState *s)
 {
-#ifdef DEBUG_IDE
-    printf("ide: reset\n");
-#endif
+    trace_ide_reset(s);
 
     if (s->pio_aiocb) {
         blk_aio_cancel(s->pio_aiocb);
@@ -2021,10 +2012,9 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
     IDEState *s;
     bool complete;
 
-#if defined(DEBUG_IDE)
-    printf("ide: CMD=%02x\n", val);
-#endif
     s = idebus_active_if(bus);
+    trace_ide_exec_cmd(bus, s, val);
+
     /* ignore commands to non existent slave */
     if (s != bus->ifs && !s->blk) {
         return;
@@ -2062,18 +2052,18 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
     }
 }
 
-uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
+uint32_t ide_ioport_read(void *opaque, uint32_t addr)
 {
     IDEBus *bus = opaque;
     IDEState *s = idebus_active_if(bus);
-    uint32_t addr;
+    uint32_t reg_num;
     int ret, hob;
 
-    addr = addr1 & 7;
+    reg_num = addr & 7;
     /* FIXME: HOB readback uses bit 7, but it's always set right now */
     //hob = s->select & (1 << 7);
     hob = 0;
-    switch(addr) {
+    switch (reg_num) {
     case 0:
         ret = 0xff;
         break;
@@ -2141,9 +2131,8 @@ uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
         qemu_irq_lower(bus->irq);
         break;
     }
-#ifdef DEBUG_IDE
-    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);
-#endif
+
+    trace_ide_ioport_read(addr, ret, bus, s);
     return ret;
 }
 
@@ -2159,9 +2148,8 @@ uint32_t ide_status_read(void *opaque, uint32_t addr)
     } else {
         ret = s->status;
     }
-#ifdef DEBUG_IDE
-    printf("ide: read status addr=0x%x val=%02x\n", addr, ret);
-#endif
+
+    trace_ide_status_read(addr, ret, bus, s);
     return ret;
 }
 
@@ -2171,9 +2159,8 @@ void ide_cmd_write(void *opaque, uint32_t addr, uint32_t val)
     IDEState *s;
     int i;
 
-#ifdef DEBUG_IDE
-    printf("ide: write control addr=0x%x val=%02x\n", addr, val);
-#endif
+    trace_ide_cmd_write(addr, val, bus);
+
     /* common for both drives */
     if (!(bus->cmd & IDE_CMD_RESET) &&
         (val & IDE_CMD_RESET)) {
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 3cfb510..f2dcc0e 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -31,6 +31,7 @@
 #include "sysemu/dma.h"
 #include "qemu/error-report.h"
 #include "hw/ide/pci.h"
+#include "trace.h"
 
 #define BMDMA_PAGE_SIZE 4096
 
@@ -196,9 +197,7 @@ static void bmdma_reset(IDEDMA *dma)
 {
     BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
 
-#ifdef DEBUG_IDE
-    printf("ide: dma_reset\n");
-#endif
+    trace_bmdma_reset();
     bmdma_cancel(bm);
     bm->cmd = 0;
     bm->status = 0;
@@ -227,9 +226,7 @@ static void bmdma_irq(void *opaque, int n, int level)
 
 void bmdma_cmd_writeb(BMDMAState *bm, uint32_t val)
 {
-#ifdef DEBUG_IDE
-    printf("%s: 0x%08x\n", __func__, val);
-#endif
+    trace_bmdma_cmd_writeb(val);
 
     /* Ignore writes to SSBM if it keeps the old value */
     if ((val & BM_CMD_START) != (bm->cmd & BM_CMD_START)) {
@@ -258,9 +255,7 @@ static uint64_t bmdma_addr_read(void *opaque, hwaddr addr,
     uint64_t data;
 
     data = (bm->addr >> (addr * 8)) & mask;
-#ifdef DEBUG_IDE
-    printf("%s: 0x%08x\n", __func__, (unsigned)data);
-#endif
+    trace_bmdma_addr_read(data);
     return data;
 }
 
@@ -271,9 +266,7 @@ static void bmdma_addr_write(void *opaque, hwaddr addr,
     int shift = addr * 8;
     uint32_t mask = (1ULL << (width * 8)) - 1;
 
-#ifdef DEBUG_IDE
-    printf("%s: 0x%08x\n", __func__, (unsigned)data);
-#endif
+    trace_bmdma_addr_write(data);
     bm->addr &= ~(mask << shift);
     bm->addr |= ((data & mask) << shift) & ~3;
 }
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index 7e2d767..dfb21f6 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -33,6 +33,7 @@
 #include "sysemu/dma.h"
 
 #include "hw/ide/pci.h"
+#include "trace.h"
 
 static uint64_t bmdma_read(void *opaque, hwaddr addr, unsigned size)
 {
@@ -54,9 +55,8 @@ static uint64_t bmdma_read(void *opaque, hwaddr addr, unsigned size)
         val = 0xff;
         break;
     }
-#ifdef DEBUG_IDE
-    printf("bmdma: readb 0x%02x : 0x%02x\n", (uint8_t)addr, val);
-#endif
+
+    trace_bmdma_read(addr, val);
     return val;
 }
 
@@ -69,9 +69,8 @@ static void bmdma_write(void *opaque, hwaddr addr,
         return;
     }
 
-#ifdef DEBUG_IDE
-    printf("bmdma: writeb 0x%02x : 0x%02x\n", (uint8_t)addr, (uint8_t)val);
-#endif
+    trace_bmdma_write(addr, val);
+
     switch(addr & 3) {
     case 0:
         bmdma_cmd_writeb(bm, val);
diff --git a/hw/ide/trace-events b/hw/ide/trace-events
new file mode 100644
index 0000000..b9792812
--- /dev/null
+++ b/hw/ide/trace-events
@@ -0,0 +1,35 @@
+# See docs/devel/tracing.txt for syntax documentation.
+
+# hw/ide/core.c
+# portio
+ide_ioport_read(uint32_t addr, uint32_t val, void *bus, void *s)  "IDE PIO rd @ 0x%"PRIx32"; val 0x%02"PRIx32"; bus %p IDEState %p"
+ide_ioport_write(uint32_t addr, uint32_t val, void *bus, void *s) "IDE PIO wr @ 0x%"PRIx32"; val 0x%02"PRIx32"; bus %p IDEState %p"
+ide_status_read(uint32_t addr, uint32_t val, void *bus, void *s)  "IDE PIO rd @ 0x%"PRIx32" (Alt Status); val 0x%02"PRIx32"; bus %p; IDEState %p"
+ide_cmd_write(uint32_t addr, uint32_t val, void *bus)             "IDE PIO wr @ 0x%"PRIx32" (Device Control); val 0x%02"PRIx32"; bus %p"
+# misc
+ide_exec_cmd(void *bus, void *state, uint32_t cmd) "IDE exec cmd: bus %p; state %p; cmd 0x%02x"
+ide_cancel_dma_sync_buffered(void *fn, void *req) "invoking cb %p of buffered request %p with -ECANCELED"
+ide_cancel_dma_sync_remaining(void) "draining all remaining requests"
+ide_sector_read(int64_t sector_num, int nsectors) "sector=%"PRId64" nsectors=%d"
+ide_sector_write(int64_t sector_num, int nsectors) "sector=%"PRId64" nsectors=%d"
+ide_reset(void *s) "IDEstate %p"
+
+# BMDMA HBAs:
+
+# hw/ide/cmd646.c
+bmdma_read_cmd646(uint64_t addr, uint32_t val) "bmdma: readb 0x%"PRIx64" : 0x%02x"
+bmdma_write_cmd646(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%02"PRIx64
+
+# hw/ide/pci.c
+bmdma_reset(void) ""
+bmdma_cmd_writeb(uint32_t val) "val: 0x%08x"
+bmdma_addr_read(uint64_t data) "data: 0x%016"PRIx64
+bmdma_addr_write(uint64_t data) "data: 0x%016"PRIx64
+
+# hw/ide/piix.c
+bmdma_read(uint64_t addr, uint8_t val) "bmdma: readb 0x%"PRIx64" : 0x%02x"
+bmdma_write(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%02"PRIx64
+
+# hw/ide/via.c
+bmdma_read_via(uint64_t addr, uint32_t val) "bmdma: readb 0x%"PRIx64" : 0x%02x"
+bmdma_write_via(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%02"PRIx64
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 5b32ecb..35c3059 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -33,6 +33,7 @@
 #include "sysemu/dma.h"
 
 #include "hw/ide/pci.h"
+#include "trace.h"
 
 static uint64_t bmdma_read(void *opaque, hwaddr addr,
                            unsigned size)
@@ -55,9 +56,8 @@ static uint64_t bmdma_read(void *opaque, hwaddr addr,
         val = 0xff;
         break;
     }
-#ifdef DEBUG_IDE
-    printf("bmdma: readb 0x%02x : 0x%02x\n", addr, val);
-#endif
+
+    trace_bmdma_read_via(addr, val);
     return val;
 }
 
@@ -70,9 +70,7 @@ static void bmdma_write(void *opaque, hwaddr addr,
         return;
     }
 
-#ifdef DEBUG_IDE
-    printf("bmdma: writeb 0x%02x : 0x%02x\n", addr, val);
-#endif
+    trace_bmdma_write_via(addr, val);
     switch (addr & 3) {
     case 0:
         bmdma_cmd_writeb(bm, val);
diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
index 482a951..4a92f0a 100644
--- a/include/hw/ide/internal.h
+++ b/include/hw/ide/internal.h
@@ -14,7 +14,6 @@
 #include "block/scsi.h"
 
 /* debug IDE devices */
-//#define DEBUG_IDE
 //#define DEBUG_IDE_ATAPI
 //#define DEBUG_AIO
 #define USE_DMA_CDROM
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 2/9] IDE: Add register hints to tracing
  2017-08-29 20:49 [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing John Snow
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 1/9] IDE: replace DEBUG_IDE with tracing system John Snow
@ 2017-08-29 20:49 ` John Snow
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 3/9] IDE: add tracing for data ports John Snow
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: John Snow @ 2017-08-29 20:49 UTC (permalink / raw)
  To: qemu-block; +Cc: eblake, qemu-devel, f4bug, John Snow

Name the registers for tracing purposes.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 hw/ide/core.c       | 88 +++++++++++++++++++++++++++++++++++++++++------------
 hw/ide/trace-events |  8 ++---
 2 files changed, 72 insertions(+), 24 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 31fd593..cb250e6 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -1185,13 +1185,37 @@ static void ide_clear_hob(IDEBus *bus)
     bus->ifs[1].select &= ~(1 << 7);
 }
 
+/* IOport [W]rite [R]egisters */
+enum ATA_IOPORT_WR {
+    ATA_IOPORT_WR_DATA = 0,
+    ATA_IOPORT_WR_FEATURES = 1,
+    ATA_IOPORT_WR_SECTOR_COUNT = 2,
+    ATA_IOPORT_WR_SECTOR_NUMBER = 3,
+    ATA_IOPORT_WR_CYLINDER_LOW = 4,
+    ATA_IOPORT_WR_CYLINDER_HIGH = 5,
+    ATA_IOPORT_WR_DEVICE_HEAD = 6,
+    ATA_IOPORT_WR_COMMAND = 7,
+    ATA_IOPORT_WR_NUM_REGISTERS,
+};
+
+const char *ATA_IOPORT_WR_lookup[ATA_IOPORT_WR_NUM_REGISTERS] = {
+    [ATA_IOPORT_WR_DATA] = "Data",
+    [ATA_IOPORT_WR_FEATURES] = "Features",
+    [ATA_IOPORT_WR_SECTOR_COUNT] = "Sector Count",
+    [ATA_IOPORT_WR_SECTOR_NUMBER] = "Sector Number",
+    [ATA_IOPORT_WR_CYLINDER_LOW] = "Cylinder Low",
+    [ATA_IOPORT_WR_CYLINDER_HIGH] = "Cylinder High",
+    [ATA_IOPORT_WR_DEVICE_HEAD] = "Device/Head",
+    [ATA_IOPORT_WR_COMMAND] = "Command"
+};
+
 void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 {
     IDEBus *bus = opaque;
     IDEState *s = idebus_active_if(bus);
     int reg_num = addr & 7;
 
-    trace_ide_ioport_write(addr, val, bus, s);
+    trace_ide_ioport_write(addr, ATA_IOPORT_WR_lookup[reg_num], val, bus, s);
 
     /* ignore writes to command block while busy with previous command */
     if (reg_num != 7 && (s->status & (BUSY_STAT|DRQ_STAT))) {
@@ -1201,43 +1225,43 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
     switch (reg_num) {
     case 0:
         break;
-    case 1:
-	ide_clear_hob(bus);
+    case ATA_IOPORT_WR_FEATURES:
+        ide_clear_hob(bus);
         /* NOTE: data is written to the two drives */
-	bus->ifs[0].hob_feature = bus->ifs[0].feature;
-	bus->ifs[1].hob_feature = bus->ifs[1].feature;
+        bus->ifs[0].hob_feature = bus->ifs[0].feature;
+        bus->ifs[1].hob_feature = bus->ifs[1].feature;
         bus->ifs[0].feature = val;
         bus->ifs[1].feature = val;
         break;
-    case 2:
+    case ATA_IOPORT_WR_SECTOR_COUNT:
 	ide_clear_hob(bus);
 	bus->ifs[0].hob_nsector = bus->ifs[0].nsector;
 	bus->ifs[1].hob_nsector = bus->ifs[1].nsector;
         bus->ifs[0].nsector = val;
         bus->ifs[1].nsector = val;
         break;
-    case 3:
+    case ATA_IOPORT_WR_SECTOR_NUMBER:
 	ide_clear_hob(bus);
 	bus->ifs[0].hob_sector = bus->ifs[0].sector;
 	bus->ifs[1].hob_sector = bus->ifs[1].sector;
         bus->ifs[0].sector = val;
         bus->ifs[1].sector = val;
         break;
-    case 4:
+    case ATA_IOPORT_WR_CYLINDER_LOW:
 	ide_clear_hob(bus);
 	bus->ifs[0].hob_lcyl = bus->ifs[0].lcyl;
 	bus->ifs[1].hob_lcyl = bus->ifs[1].lcyl;
         bus->ifs[0].lcyl = val;
         bus->ifs[1].lcyl = val;
         break;
-    case 5:
+    case ATA_IOPORT_WR_CYLINDER_HIGH:
 	ide_clear_hob(bus);
 	bus->ifs[0].hob_hcyl = bus->ifs[0].hcyl;
 	bus->ifs[1].hob_hcyl = bus->ifs[1].hcyl;
         bus->ifs[0].hcyl = val;
         bus->ifs[1].hcyl = val;
         break;
-    case 6:
+    case ATA_IOPORT_WR_DEVICE_HEAD:
 	/* FIXME: HOB readback uses bit 7 */
         bus->ifs[0].select = (val & ~0x10) | 0xa0;
         bus->ifs[1].select = (val | 0x10) | 0xa0;
@@ -1245,7 +1269,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
         bus->unit = (val >> 4) & 1;
         break;
     default:
-    case 7:
+    case ATA_IOPORT_WR_COMMAND:
         /* command */
         ide_exec_cmd(bus, val);
         break;
@@ -2052,6 +2076,30 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
     }
 }
 
+/* IOport [R]ead [R]egisters */
+enum ATA_IOPORT_RR {
+    ATA_IOPORT_RR_DATA = 0,
+    ATA_IOPORT_RR_ERROR = 1,
+    ATA_IOPORT_RR_SECTOR_COUNT = 2,
+    ATA_IOPORT_RR_SECTOR_NUMBER = 3,
+    ATA_IOPORT_RR_CYLINDER_LOW = 4,
+    ATA_IOPORT_RR_CYLINDER_HIGH = 5,
+    ATA_IOPORT_RR_DEVICE_HEAD = 6,
+    ATA_IOPORT_RR_STATUS = 7,
+    ATA_IOPORT_RR_NUM_REGISTERS,
+};
+
+const char *ATA_IOPORT_RR_lookup[ATA_IOPORT_RR_NUM_REGISTERS] = {
+    [ATA_IOPORT_RR_DATA] = "Data",
+    [ATA_IOPORT_RR_ERROR] = "Error",
+    [ATA_IOPORT_RR_SECTOR_COUNT] = "Sector Count",
+    [ATA_IOPORT_RR_SECTOR_NUMBER] = "Sector Number",
+    [ATA_IOPORT_RR_CYLINDER_LOW] = "Cylinder Low",
+    [ATA_IOPORT_RR_CYLINDER_HIGH] = "Cylinder High",
+    [ATA_IOPORT_RR_DEVICE_HEAD] = "Device/Head",
+    [ATA_IOPORT_RR_STATUS] = "Status"
+};
+
 uint32_t ide_ioport_read(void *opaque, uint32_t addr)
 {
     IDEBus *bus = opaque;
@@ -2064,10 +2112,10 @@ uint32_t ide_ioport_read(void *opaque, uint32_t addr)
     //hob = s->select & (1 << 7);
     hob = 0;
     switch (reg_num) {
-    case 0:
+    case ATA_IOPORT_RR_DATA:
         ret = 0xff;
         break;
-    case 1:
+    case ATA_IOPORT_RR_ERROR:
         if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
             (s != bus->ifs && !s->blk)) {
             ret = 0;
@@ -2077,7 +2125,7 @@ uint32_t ide_ioport_read(void *opaque, uint32_t addr)
 	    ret = s->hob_feature;
         }
         break;
-    case 2:
+    case ATA_IOPORT_RR_SECTOR_COUNT:
         if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
             ret = 0;
         } else if (!hob) {
@@ -2086,7 +2134,7 @@ uint32_t ide_ioport_read(void *opaque, uint32_t addr)
 	    ret = s->hob_nsector;
         }
         break;
-    case 3:
+    case ATA_IOPORT_RR_SECTOR_NUMBER:
         if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
             ret = 0;
         } else if (!hob) {
@@ -2095,7 +2143,7 @@ uint32_t ide_ioport_read(void *opaque, uint32_t addr)
 	    ret = s->hob_sector;
         }
         break;
-    case 4:
+    case ATA_IOPORT_RR_CYLINDER_LOW:
         if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
             ret = 0;
         } else if (!hob) {
@@ -2104,7 +2152,7 @@ uint32_t ide_ioport_read(void *opaque, uint32_t addr)
 	    ret = s->hob_lcyl;
         }
         break;
-    case 5:
+    case ATA_IOPORT_RR_CYLINDER_HIGH:
         if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
             ret = 0;
         } else if (!hob) {
@@ -2113,7 +2161,7 @@ uint32_t ide_ioport_read(void *opaque, uint32_t addr)
 	    ret = s->hob_hcyl;
         }
         break;
-    case 6:
+    case ATA_IOPORT_RR_DEVICE_HEAD:
         if (!bus->ifs[0].blk && !bus->ifs[1].blk) {
             ret = 0;
         } else {
@@ -2121,7 +2169,7 @@ uint32_t ide_ioport_read(void *opaque, uint32_t addr)
         }
         break;
     default:
-    case 7:
+    case ATA_IOPORT_RR_STATUS:
         if ((!bus->ifs[0].blk && !bus->ifs[1].blk) ||
             (s != bus->ifs && !s->blk)) {
             ret = 0;
@@ -2132,7 +2180,7 @@ uint32_t ide_ioport_read(void *opaque, uint32_t addr)
         break;
     }
 
-    trace_ide_ioport_read(addr, ret, bus, s);
+    trace_ide_ioport_read(addr, ATA_IOPORT_RR_lookup[reg_num], ret, bus, s);
     return ret;
 }
 
diff --git a/hw/ide/trace-events b/hw/ide/trace-events
index b9792812..bff8f39 100644
--- a/hw/ide/trace-events
+++ b/hw/ide/trace-events
@@ -2,10 +2,10 @@
 
 # hw/ide/core.c
 # portio
-ide_ioport_read(uint32_t addr, uint32_t val, void *bus, void *s)  "IDE PIO rd @ 0x%"PRIx32"; val 0x%02"PRIx32"; bus %p IDEState %p"
-ide_ioport_write(uint32_t addr, uint32_t val, void *bus, void *s) "IDE PIO wr @ 0x%"PRIx32"; val 0x%02"PRIx32"; bus %p IDEState %p"
-ide_status_read(uint32_t addr, uint32_t val, void *bus, void *s)  "IDE PIO rd @ 0x%"PRIx32" (Alt Status); val 0x%02"PRIx32"; bus %p; IDEState %p"
-ide_cmd_write(uint32_t addr, uint32_t val, void *bus)             "IDE PIO wr @ 0x%"PRIx32" (Device Control); val 0x%02"PRIx32"; bus %p"
+ide_ioport_read(uint32_t addr, const char *reg, uint32_t val, void *bus, void *s)  "IDE PIO rd @ 0x%"PRIx32" (%s); val 0x%02"PRIx32"; bus %p IDEState %p"
+ide_ioport_write(uint32_t addr, const char *reg, uint32_t val, void *bus, void *s) "IDE PIO wr @ 0x%"PRIx32" (%s); val 0x%02"PRIx32"; bus %p IDEState %p"
+ide_status_read(uint32_t addr, uint32_t val, void *bus, void *s)                   "IDE PIO rd @ 0x%"PRIx32" (Alt Status); val 0x%02"PRIx32"; bus %p; IDEState %p"
+ide_cmd_write(uint32_t addr, uint32_t val, void *bus)                              "IDE PIO wr @ 0x%"PRIx32" (Device Control); val 0x%02"PRIx32"; bus %p"
 # misc
 ide_exec_cmd(void *bus, void *state, uint32_t cmd) "IDE exec cmd: bus %p; state %p; cmd 0x%02x"
 ide_cancel_dma_sync_buffered(void *fn, void *req) "invoking cb %p of buffered request %p with -ECANCELED"
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 3/9] IDE: add tracing for data ports
  2017-08-29 20:49 [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing John Snow
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 1/9] IDE: replace DEBUG_IDE with tracing system John Snow
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 2/9] IDE: Add register hints to tracing John Snow
@ 2017-08-29 20:49 ` John Snow
  2017-08-29 22:20   ` Philippe Mathieu-Daudé
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 4/9] ATAPI: Replace DEBUG_IDE_ATAPI with tracing events John Snow
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: John Snow @ 2017-08-29 20:49 UTC (permalink / raw)
  To: qemu-block; +Cc: eblake, qemu-devel, f4bug, John Snow

To be used sparingly, but still interesting in the case of small
firmwares designed to reproduce bugs in QEMU IDE.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 hw/ide/core.c       | 12 +++++++++++-
 hw/ide/trace-events |  5 +++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index cb250e6..82a19b1 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2259,6 +2259,8 @@ void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
     IDEState *s = idebus_active_if(bus);
     uint8_t *p;
 
+    trace_ide_data_writew(addr, val, bus, s);
+
     /* PIO data access allowed only when DRQ bit is set. The result of a write
      * during PIO out is indeterminate, just ignore it. */
     if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
@@ -2304,6 +2306,8 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr)
         s->status &= ~DRQ_STAT;
         s->end_transfer_func(s);
     }
+
+    trace_ide_data_readw(addr, ret, bus, s);
     return ret;
 }
 
@@ -2313,6 +2317,8 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
     IDEState *s = idebus_active_if(bus);
     uint8_t *p;
 
+    trace_ide_data_writel(addr, val, bus, s);
+
     /* PIO data access allowed only when DRQ bit is set. The result of a write
      * during PIO out is indeterminate, just ignore it. */
     if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
@@ -2343,7 +2349,8 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr)
     /* PIO data access allowed only when DRQ bit is set. The result of a read
      * during PIO in is indeterminate, return 0 and don't move forward. */
     if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
-        return 0;
+        ret = 0;
+        goto out;
     }
 
     p = s->data_ptr;
@@ -2358,6 +2365,9 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr)
         s->status &= ~DRQ_STAT;
         s->end_transfer_func(s);
     }
+
+out:
+    trace_ide_data_readl(addr, ret, bus, s);
     return ret;
 }
 
diff --git a/hw/ide/trace-events b/hw/ide/trace-events
index bff8f39..17bc6f1 100644
--- a/hw/ide/trace-events
+++ b/hw/ide/trace-events
@@ -6,6 +6,11 @@ ide_ioport_read(uint32_t addr, const char *reg, uint32_t val, void *bus, void *s
 ide_ioport_write(uint32_t addr, const char *reg, uint32_t val, void *bus, void *s) "IDE PIO wr @ 0x%"PRIx32" (%s); val 0x%02"PRIx32"; bus %p IDEState %p"
 ide_status_read(uint32_t addr, uint32_t val, void *bus, void *s)                   "IDE PIO rd @ 0x%"PRIx32" (Alt Status); val 0x%02"PRIx32"; bus %p; IDEState %p"
 ide_cmd_write(uint32_t addr, uint32_t val, void *bus)                              "IDE PIO wr @ 0x%"PRIx32" (Device Control); val 0x%02"PRIx32"; bus %p"
+# Warning: verbose
+ide_data_readw(uint32_t addr, uint32_t val, void *bus, void *s)                    "IDE PIO rd @ 0x%"PRIx32" (Data: Word); val 0x%04"PRIx32"; bus %p; IDEState %p"
+ide_data_writew(uint32_t addr, uint32_t val, void *bus, void *s)                   "IDE PIO wr @ 0x%"PRIx32" (Data: Word); val 0x%04"PRIx32"; bus %p; IDEState %p"
+ide_data_readl(uint32_t addr, uint32_t val, void *bus, void *s)                    "IDE PIO rd @ 0x%"PRIx32" (Data: Long); val 0x%08"PRIx32"; bus %p; IDEState %p"
+ide_data_writel(uint32_t addr, uint32_t val, void *bus, void *s)                   "IDE PIO wr @ 0x%"PRIx32" (Data: Long); val 0x%08"PRIx32"; bus %p; IDEState %p"
 # misc
 ide_exec_cmd(void *bus, void *state, uint32_t cmd) "IDE exec cmd: bus %p; state %p; cmd 0x%02x"
 ide_cancel_dma_sync_buffered(void *fn, void *req) "invoking cb %p of buffered request %p with -ECANCELED"
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 4/9] ATAPI: Replace DEBUG_IDE_ATAPI with tracing events
  2017-08-29 20:49 [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing John Snow
                   ` (2 preceding siblings ...)
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 3/9] IDE: add tracing for data ports John Snow
@ 2017-08-29 20:49 ` John Snow
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 5/9] IDE: replace DEBUG_AIO with trace events John Snow
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 22+ messages in thread
From: John Snow @ 2017-08-29 20:49 UTC (permalink / raw)
  To: qemu-block; +Cc: eblake, qemu-devel, f4bug, John Snow

Goodbye, printfs.
Hello, fancy printfs.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 hw/ide/atapi.c            | 64 +++++++++++++++++------------------------------
 hw/ide/trace-events       | 15 +++++++++++
 include/hw/ide/internal.h |  1 -
 3 files changed, 38 insertions(+), 42 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index fc1d19c..37fa699 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -27,6 +27,7 @@
 #include "hw/ide/internal.h"
 #include "hw/scsi/scsi.h"
 #include "sysemu/block-backend.h"
+#include "trace.h"
 
 #define ATAPI_SECTOR_BITS (2 + BDRV_SECTOR_BITS)
 #define ATAPI_SECTOR_SIZE (1 << ATAPI_SECTOR_BITS)
@@ -116,9 +117,7 @@ cd_read_sector_sync(IDEState *s)
     block_acct_start(blk_get_stats(s->blk), &s->acct,
                      ATAPI_SECTOR_SIZE, BLOCK_ACCT_READ);
 
-#ifdef DEBUG_IDE_ATAPI
-    printf("cd_read_sector_sync: lba=%d\n", s->lba);
-#endif
+    trace_cd_read_sector_sync(s->lba);
 
     switch (s->cd_sector_size) {
     case 2048:
@@ -152,9 +151,7 @@ static void cd_read_sector_cb(void *opaque, int ret)
 {
     IDEState *s = opaque;
 
-#ifdef DEBUG_IDE_ATAPI
-    printf("cd_read_sector_cb: lba=%d ret=%d\n", s->lba, ret);
-#endif
+    trace_cd_read_sector_cb(s->lba, ret);
 
     if (ret < 0) {
         block_acct_failed(blk_get_stats(s->blk), &s->acct);
@@ -188,9 +185,7 @@ static int cd_read_sector(IDEState *s)
     s->iov.iov_len = ATAPI_SECTOR_SIZE;
     qemu_iovec_init_external(&s->qiov, &s->iov, 1);
 
-#ifdef DEBUG_IDE_ATAPI
-    printf("cd_read_sector: lba=%d\n", s->lba);
-#endif
+    trace_cd_read_sector(s->lba);
 
     block_acct_start(blk_get_stats(s->blk), &s->acct,
                      ATAPI_SECTOR_SIZE, BLOCK_ACCT_READ);
@@ -213,9 +208,7 @@ void ide_atapi_cmd_ok(IDEState *s)
 
 void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc)
 {
-#ifdef DEBUG_IDE_ATAPI
-    printf("atapi_cmd_error: sense=0x%x asc=0x%x\n", sense_key, asc);
-#endif
+    trace_ide_atapi_cmd_error(s, sense_key, asc);
     s->error = sense_key << 4;
     s->status = READY_STAT | ERR_STAT;
     s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO | ATAPI_INT_REASON_CD;
@@ -252,19 +245,14 @@ static uint16_t atapi_byte_count_limit(IDEState *s)
 void ide_atapi_cmd_reply_end(IDEState *s)
 {
     int byte_count_limit, size, ret;
-#ifdef DEBUG_IDE_ATAPI
-    printf("reply: tx_size=%d elem_tx_size=%d index=%d\n",
-           s->packet_transfer_size,
-           s->elementary_transfer_size,
-           s->io_buffer_index);
-#endif
+    trace_ide_atapi_cmd_reply_end(s, s->packet_transfer_size,
+                                  s->elementary_transfer_size,
+                                  s->io_buffer_index);
     if (s->packet_transfer_size <= 0) {
         /* end of transfer */
         ide_atapi_cmd_ok(s);
         ide_set_irq(s->bus);
-#ifdef DEBUG_IDE_ATAPI
-        printf("end of transfer, status=0x%x\n", s->status);
-#endif
+        trace_ide_atapi_cmd_reply_end_eot(s, s->status);
     } else {
         /* see if a new sector must be read */
         if (s->lba != -1 && s->io_buffer_index >= s->cd_sector_size) {
@@ -300,9 +288,7 @@ void ide_atapi_cmd_reply_end(IDEState *s)
             /* a new transfer is needed */
             s->nsector = (s->nsector & ~7) | ATAPI_INT_REASON_IO;
             byte_count_limit = atapi_byte_count_limit(s);
-#ifdef DEBUG_IDE_ATAPI
-            printf("byte_count_limit=%d\n", byte_count_limit);
-#endif
+            trace_ide_atapi_cmd_reply_end_bcl(s, byte_count_limit);
             size = s->packet_transfer_size;
             if (size > byte_count_limit) {
                 /* byte count limit must be even if this case */
@@ -324,9 +310,7 @@ void ide_atapi_cmd_reply_end(IDEState *s)
             ide_transfer_start(s, s->io_buffer + s->io_buffer_index - size,
                                size, ide_atapi_cmd_reply_end);
             ide_set_irq(s->bus);
-#ifdef DEBUG_IDE_ATAPI
-            printf("status=0x%x\n", s->status);
-#endif
+            trace_ide_atapi_cmd_reply_end_new(s, s->status);
         }
     }
 }
@@ -368,9 +352,7 @@ static void ide_atapi_cmd_read_pio(IDEState *s, int lba, int nb_sectors,
 
 static void ide_atapi_cmd_check_status(IDEState *s)
 {
-#ifdef DEBUG_IDE_ATAPI
-    printf("atapi_cmd_check_status\n");
-#endif
+    trace_ide_atapi_cmd_check_status(s);
     s->error = MC_ERR | (UNIT_ATTENTION << 4);
     s->status = ERR_STAT;
     s->nsector = 0;
@@ -477,10 +459,8 @@ static void ide_atapi_cmd_read_dma(IDEState *s, int lba, int nb_sectors,
 static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
                                int sector_size)
 {
-#ifdef DEBUG_IDE_ATAPI
-    printf("read %s: LBA=%d nb_sectors=%d\n", s->atapi_dma ? "dma" : "pio",
-        lba, nb_sectors);
-#endif
+    trace_ide_atapi_cmd_read(s, s->atapi_dma ? "dma" : "pio",
+                             lba, nb_sectors);
     if (s->atapi_dma) {
         ide_atapi_cmd_read_dma(s, lba, nb_sectors, sector_size);
     } else {
@@ -1330,16 +1310,18 @@ void ide_atapi_cmd(IDEState *s)
     uint8_t *buf = s->io_buffer;
     const struct AtapiCmd *cmd = &atapi_cmd_table[s->io_buffer[0]];
 
-#ifdef DEBUG_IDE_ATAPI
-    {
+    trace_ide_atapi_cmd(s, s->io_buffer[0]);
+
+    if (TRACE_IDE_ATAPI_CMD_PACKET_ENABLED) {
+        /* Each pretty-printed byte needs two bytes and a space; */
+        char *ppacket = g_malloc(ATAPI_PACKET_SIZE * 3 + 1);
         int i;
-        printf("ATAPI limit=0x%x packet:", s->lcyl | (s->hcyl << 8));
-        for(i = 0; i < ATAPI_PACKET_SIZE; i++) {
-            printf(" %02x", buf[i]);
+        for (i = 0; i < ATAPI_PACKET_SIZE; i++) {
+            sprintf(ppacket + (i * 3), "%02x ", buf[i]);
         }
-        printf("\n");
+        trace_ide_atapi_cmd_packet(s, s->lcyl | (s->hcyl << 8), ppacket);
+        g_free(ppacket);
     }
-#endif
 
     /*
      * If there's a UNIT_ATTENTION condition pending, only command flagged with
diff --git a/hw/ide/trace-events b/hw/ide/trace-events
index 17bc6f1..8c79a6c 100644
--- a/hw/ide/trace-events
+++ b/hw/ide/trace-events
@@ -38,3 +38,18 @@ bmdma_write(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%02"PRIx
 # hw/ide/via.c
 bmdma_read_via(uint64_t addr, uint32_t val) "bmdma: readb 0x%"PRIx64" : 0x%02x"
 bmdma_write_via(uint64_t addr, uint64_t val) "bmdma: writeb 0x%"PRIx64" : 0x%02"PRIx64
+
+# hw/ide/atapi.c
+cd_read_sector_sync(int lba) "lba=%d"
+cd_read_sector_cb(int lba, int ret) "lba=%d ret=%d"
+cd_read_sector(int lba) "lba=%d"
+ide_atapi_cmd_error(void *s, int sense_key, int asc) "IDEState: %p; sense=0x%x asc=0x%x"
+ide_atapi_cmd_reply_end(void *s, int tx_size, int elem_tx_size, int32_t index) "IDEState %p; reply: tx_size=%d elem_tx_size=%d index=%"PRId32
+ide_atapi_cmd_reply_end_eot(void *s, int status) "IDEState: %p; end of transfer, status=0x%x"
+ide_atapi_cmd_reply_end_bcl(void *s, int bcl) "IDEState: %p; byte_count_limit=%d"
+ide_atapi_cmd_reply_end_new(void *s, int status) "IDEState: %p; new transfer started, status=0x%x"
+ide_atapi_cmd_check_status(void *s) "IDEState: %p"
+ide_atapi_cmd_read(void *s, const char *method, int lba, int nb_sectors) "IDEState: %p; read %s: LBA=%d nb_sectors=%d"
+ide_atapi_cmd(void *s, uint8_t cmd) "IDEState: %p; cmd: 0x%02x"
+# Warning: Verbose
+ide_atapi_cmd_packet(void *s, uint16_t limit, const char *packet) "IDEState: %p; limit=0x%x packet: %s"
diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
index 4a92f0a..74efe8a 100644
--- a/include/hw/ide/internal.h
+++ b/include/hw/ide/internal.h
@@ -14,7 +14,6 @@
 #include "block/scsi.h"
 
 /* debug IDE devices */
-//#define DEBUG_IDE_ATAPI
 //#define DEBUG_AIO
 #define USE_DMA_CDROM
 
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 5/9] IDE: replace DEBUG_AIO with trace events
  2017-08-29 20:49 [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing John Snow
                   ` (3 preceding siblings ...)
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 4/9] ATAPI: Replace DEBUG_IDE_ATAPI with tracing events John Snow
@ 2017-08-29 20:49 ` John Snow
  2017-08-30  3:14   ` Philippe Mathieu-Daudé
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 6/9] AHCI: Replace DPRINTF with trace-events John Snow
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: John Snow @ 2017-08-29 20:49 UTC (permalink / raw)
  To: qemu-block; +Cc: eblake, qemu-devel, f4bug, John Snow

Signed-off-by: John Snow <jsnow@redhat.com>
---
 hw/ide/atapi.c            |  5 +----
 hw/ide/core.c             | 17 ++++++++++-------
 hw/ide/trace-events       |  3 +++
 include/hw/ide/internal.h |  6 ++++--
 4 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 37fa699..b8fc51e 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -416,10 +416,7 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
         s->io_buffer_size = n * 2048;
         data_offset = 0;
     }
-#ifdef DEBUG_AIO
-    printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
-#endif
-
+    trace_ide_atapi_cmd_read_dma_cb_aio(s, s->lba, n);
     s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
     s->bus->dma->iov.iov_len = n * ATAPI_SECTOR_SIZE;
     qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 82a19b1..a1c90e9 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -58,6 +58,13 @@ static const int smart_attributes[][12] = {
     { 190,  0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x32},
 };
 
+const char *IDE_DMA_CMD_lookup[IDE_DMA__COUNT] = {
+    [IDE_DMA_READ] = "DMA READ",
+    [IDE_DMA_WRITE] = "DMA WRITE",
+    [IDE_DMA_TRIM] = "DMA TRIM",
+    [IDE_DMA_ATAPI] = "DMA ATAPI"
+};
+
 static void ide_dummy_transfer_stop(IDEState *s);
 
 static void padstr(char *str, const char *src, int len)
@@ -860,10 +867,8 @@ static void ide_dma_cb(void *opaque, int ret)
         goto eot;
     }
 
-#ifdef DEBUG_AIO
-    printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, cmd_cmd=%d\n",
-           sector_num, n, s->dma_cmd);
-#endif
+    trace_ide_dma_cb(s, sector_num, n,
+                     IDE_DMA_CMD_lookup[s->dma_cmd]);
 
     if ((s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) &&
         !ide_sect_range_ok(s, sector_num, n)) {
@@ -2391,9 +2396,7 @@ void ide_bus_reset(IDEBus *bus)
 
     /* pending async DMA */
     if (bus->dma->aiocb) {
-#ifdef DEBUG_AIO
-        printf("aio_cancel\n");
-#endif
+        trace_ide_bus_reset_aio();
         blk_aio_cancel(bus->dma->aiocb);
         bus->dma->aiocb = NULL;
     }
diff --git a/hw/ide/trace-events b/hw/ide/trace-events
index 8c79a6c..cc8949c 100644
--- a/hw/ide/trace-events
+++ b/hw/ide/trace-events
@@ -18,6 +18,8 @@ ide_cancel_dma_sync_remaining(void) "draining all remaining requests"
 ide_sector_read(int64_t sector_num, int nsectors) "sector=%"PRId64" nsectors=%d"
 ide_sector_write(int64_t sector_num, int nsectors) "sector=%"PRId64" nsectors=%d"
 ide_reset(void *s) "IDEstate %p"
+ide_bus_reset_aio(void) "aio_cancel"
+ide_dma_cb(void *s, int64_t sector_num, int n, const char *dma) "IDEState %p; sector_num=%"PRId64" n=%d cmd=%s"
 
 # BMDMA HBAs:
 
@@ -51,5 +53,6 @@ ide_atapi_cmd_reply_end_new(void *s, int status) "IDEState: %p; new transfer sta
 ide_atapi_cmd_check_status(void *s) "IDEState: %p"
 ide_atapi_cmd_read(void *s, const char *method, int lba, int nb_sectors) "IDEState: %p; read %s: LBA=%d nb_sectors=%d"
 ide_atapi_cmd(void *s, uint8_t cmd) "IDEState: %p; cmd: 0x%02x"
+ide_atapi_cmd_read_dma_cb_aio(void *s, int lba, int n) "IDEState: %p; aio read: lba=%d n=%d"
 # Warning: Verbose
 ide_atapi_cmd_packet(void *s, uint16_t limit, const char *packet) "IDEState: %p; limit=0x%x packet: %s"
diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
index 74efe8a..db9fde0 100644
--- a/include/hw/ide/internal.h
+++ b/include/hw/ide/internal.h
@@ -14,7 +14,6 @@
 #include "block/scsi.h"
 
 /* debug IDE devices */
-//#define DEBUG_AIO
 #define USE_DMA_CDROM
 
 typedef struct IDEBus IDEBus;
@@ -333,12 +332,15 @@ struct unreported_events {
 };
 
 enum ide_dma_cmd {
-    IDE_DMA_READ,
+    IDE_DMA_READ = 0,
     IDE_DMA_WRITE,
     IDE_DMA_TRIM,
     IDE_DMA_ATAPI,
+    IDE_DMA__COUNT
 };
 
+extern const char *IDE_DMA_CMD_lookup[IDE_DMA__COUNT];
+
 #define ide_cmd_is_read(s) \
 	((s)->dma_cmd == IDE_DMA_READ)
 
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 6/9] AHCI: Replace DPRINTF with trace-events
  2017-08-29 20:49 [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing John Snow
                   ` (4 preceding siblings ...)
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 5/9] IDE: replace DEBUG_AIO with trace events John Snow
@ 2017-08-29 20:49 ` John Snow
  2017-08-29 22:22   ` Philippe Mathieu-Daudé
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 7/9] AHCI: Rework IRQ constants John Snow
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: John Snow @ 2017-08-29 20:49 UTC (permalink / raw)
  To: qemu-block; +Cc: eblake, qemu-devel, f4bug, John Snow

There are a few hangers-on that will be dealt with individually
in forthcoming patches.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 hw/ide/ahci.c       | 157 +++++++++++++++++++++++-----------------------------
 hw/ide/trace-events |  49 ++++++++++++++++
 2 files changed, 117 insertions(+), 89 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 406a1b5..c60a000 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -35,6 +35,7 @@
 #include "hw/ide/ahci_internal.h"
 
 #define DEBUG_AHCI 0
+#include "trace.h"
 
 #define DPRINTF(port, fmt, ...) \
 do { \
@@ -114,9 +115,9 @@ static uint32_t  ahci_port_read(AHCIState *s, int port, int offset)
     default:
         val = 0;
     }
-    DPRINTF(port, "offset: 0x%x val: 0x%x\n", offset, val);
-    return val;
 
+    trace_ahci_port_read(s, port, offset, val);
+    return val;
 }
 
 static void ahci_irq_raise(AHCIState *s, AHCIDevice *dev)
@@ -125,7 +126,7 @@ static void ahci_irq_raise(AHCIState *s, AHCIDevice *dev)
     PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state),
                                                            TYPE_PCI_DEVICE);
 
-    DPRINTF(0, "raise irq\n");
+    trace_ahci_irq_raise(s);
 
     if (pci_dev && msi_enabled(pci_dev)) {
         msi_notify(pci_dev, 0);
@@ -140,7 +141,7 @@ static void ahci_irq_lower(AHCIState *s, AHCIDevice *dev)
     PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state),
                                                            TYPE_PCI_DEVICE);
 
-    DPRINTF(0, "lower irq\n");
+    trace_ahci_irq_lower(s);
 
     if (!pci_dev || !msi_enabled(pci_dev)) {
         qemu_irq_lower(s->irq);
@@ -150,8 +151,7 @@ static void ahci_irq_lower(AHCIState *s, AHCIDevice *dev)
 static void ahci_check_irq(AHCIState *s)
 {
     int i;
-
-    DPRINTF(-1, "check irq %#x\n", s->control_regs.irqstatus);
+    uint32_t old_irq = s->control_regs.irqstatus;
 
     s->control_regs.irqstatus = 0;
     for (i = 0; i < s->ports; i++) {
@@ -160,7 +160,7 @@ static void ahci_check_irq(AHCIState *s)
             s->control_regs.irqstatus |= (1 << i);
         }
     }
-
+    trace_ahci_check_irq(s, old_irq, s->control_regs.irqstatus);
     if (s->control_regs.irqstatus &&
         (s->control_regs.ghc & HOST_CTL_IRQ_EN)) {
             ahci_irq_raise(s, NULL);
@@ -240,7 +240,7 @@ static void  ahci_port_write(AHCIState *s, int port, int offset, uint32_t val)
 {
     AHCIPortRegs *pr = &s->dev[port].port_regs;
 
-    DPRINTF(port, "offset: 0x%x val: 0x%x\n", offset, val);
+    trace_ahci_port_write(s, port, offset, val);
     switch (offset) {
         case PORT_LST_ADDR:
             pr->lst_addr = val;
@@ -341,8 +341,6 @@ static uint64_t ahci_mem_read_32(void *opaque, hwaddr addr)
             val = s->control_regs.version;
             break;
         }
-
-        DPRINTF(-1, "(addr 0x%08X), val 0x%08X\n", (unsigned) addr, val);
     } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
                (addr < (AHCI_PORT_REGS_START_ADDR +
                 (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) {
@@ -350,6 +348,7 @@ static uint64_t ahci_mem_read_32(void *opaque, hwaddr addr)
                              addr & AHCI_PORT_ADDR_OFFSET_MASK);
     }
 
+    trace_ahci_mem_read_32(s, addr, val);
     return val;
 }
 
@@ -379,8 +378,7 @@ static uint64_t ahci_mem_read(void *opaque, hwaddr addr, unsigned size)
         val = (hi << 32 | lo) >> (ofst * 8);
     }
 
-    DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
-            addr, val, size);
+    trace_ahci_mem_read(opaque, size, addr, val);
     return val;
 }
 
@@ -390,8 +388,7 @@ static void ahci_mem_write(void *opaque, hwaddr addr,
 {
     AHCIState *s = opaque;
 
-    DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
-            addr, val, size);
+    trace_ahci_mem_write(s, size, addr, val);
 
     /* Only aligned reads are allowed on AHCI */
     if (addr & 3) {
@@ -401,15 +398,12 @@ static void ahci_mem_write(void *opaque, hwaddr addr,
     }
 
     if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
-        DPRINTF(-1, "(addr 0x%08X), val 0x%08"PRIX64"\n", (unsigned) addr, val);
-
         switch (addr) {
             case HOST_CAP: /* R/WO, RO */
                 /* FIXME handle R/WO */
                 break;
             case HOST_CTL: /* R/W */
                 if (val & HOST_CTL_RESET) {
-                    DPRINTF(-1, "HBA Reset\n");
                     ahci_reset(s);
                 } else {
                     s->control_regs.ghc = (val & 0x3) | HOST_CTL_AHCI_EN;
@@ -427,7 +421,7 @@ static void ahci_mem_write(void *opaque, hwaddr addr,
                 /* FIXME report write? */
                 break;
             default:
-                DPRINTF(-1, "write to unknown register 0x%x\n", (unsigned)addr);
+                trace_ahci_mem_write_unknown(s, size, addr, val);
         }
     } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
                (addr < (AHCI_PORT_REGS_START_ADDR +
@@ -559,7 +553,8 @@ static void ahci_set_signature(AHCIDevice *ad, uint32_t sig)
     s->sector = sig >> 8 & 0xFF;
     s->nsector = sig & 0xFF;
 
-    DPRINTF(ad->port_no, "set hcyl:lcyl:sect:nsect = 0x%08x\n", sig);
+    trace_ahci_set_signature(ad->hba, ad->port_no, s->nsector, s->sector,
+                             s->lcyl, s->hcyl, sig);
 }
 
 static void ahci_reset_port(AHCIState *s, int port)
@@ -569,7 +564,7 @@ static void ahci_reset_port(AHCIState *s, int port)
     IDEState *ide_state = &d->port.ifs[0];
     int i;
 
-    DPRINTF(port, "reset port\n");
+    trace_ahci_reset_port(s, port);
 
     ide_bus_reset(&d->port);
     ide_state->ncq_queues = AHCI_MAX_CMDS;
@@ -655,7 +650,7 @@ static bool ahci_map_fis_address(AHCIDevice *ad)
 static void ahci_unmap_fis_address(AHCIDevice *ad)
 {
     if (ad->res_fis == NULL) {
-        DPRINTF(ad->port_no, "Attempt to unmap NULL FIS address\n");
+        trace_ahci_unmap_fis_address_null(ad->hba, ad->port_no);
         return;
     }
     ad->port_regs.cmd &= ~PORT_CMD_FIS_ON;
@@ -682,7 +677,7 @@ static bool ahci_map_clb_address(AHCIDevice *ad)
 static void ahci_unmap_clb_address(AHCIDevice *ad)
 {
     if (ad->lst == NULL) {
-        DPRINTF(ad->port_no, "Attempt to unmap NULL CLB address\n");
+        trace_ahci_unmap_clb_address_null(ad->hba, ad->port_no);
         return;
     }
     ad->port_regs.cmd &= ~PORT_CMD_LIST_ON;
@@ -854,20 +849,22 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist,
     IDEBus *bus = &ad->port;
     BusState *qbus = BUS(bus);
 
+    trace_ahci_populate_sglist(ad->hba, ad->port_no);
+
     if (!prdtl) {
-        DPRINTF(ad->port_no, "no sg list given by guest: 0x%08x\n", opts);
+        trace_ahci_populate_sglist_no_prdtl(ad->hba, ad->port_no, opts);
         return -1;
     }
 
     /* map PRDT */
     if (!(prdt = dma_memory_map(ad->hba->as, prdt_addr, &prdt_len,
                                 DMA_DIRECTION_TO_DEVICE))){
-        DPRINTF(ad->port_no, "map failed\n");
+        trace_ahci_populate_sglist_no_map(ad->hba, ad->port_no);
         return -1;
     }
 
     if (prdt_len < real_prdt_len) {
-        DPRINTF(ad->port_no, "mapped less than expected\n");
+        trace_ahci_populate_sglist_short_map(ad->hba, ad->port_no);
         r = -1;
         goto out;
     }
@@ -886,9 +883,8 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist,
             sum += tbl_entry_size;
         }
         if ((off_idx == -1) || (off_pos < 0) || (off_pos > tbl_entry_size)) {
-            DPRINTF(ad->port_no, "%s: Incorrect offset! "
-                            "off_idx: %d, off_pos: %"PRId64"\n",
-                            __func__, off_idx, off_pos);
+            trace_ahci_populate_sglist_bad_offset(ad->hba, ad->port_no,
+                                                  off_idx, off_pos);
             r = -1;
             goto out;
         }
@@ -934,8 +930,8 @@ static void ncq_finish(NCQTransferState *ncq_tfs)
 
     ahci_write_fis_sdb(ncq_tfs->drive->hba, ncq_tfs);
 
-    DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n",
-            ncq_tfs->tag);
+    trace_ncq_finish(ncq_tfs->drive->hba, ncq_tfs->drive->port_no,
+                     ncq_tfs->tag);
 
     block_acct_done(blk_get_stats(ncq_tfs->drive->port.ifs[0].blk),
                     &ncq_tfs->acct);
@@ -999,12 +995,8 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
 
     switch (ncq_tfs->cmd) {
     case READ_FPDMA_QUEUED:
-        DPRINTF(port, "NCQ reading %d sectors from LBA %"PRId64", tag %d\n",
-                ncq_tfs->sector_count, ncq_tfs->lba, ncq_tfs->tag);
-
-        DPRINTF(port, "tag %d aio read %"PRId64"\n",
-                ncq_tfs->tag, ncq_tfs->lba);
-
+        trace_execute_ncq_command_read(ad->hba, port, ncq_tfs->tag,
+                                       ncq_tfs->sector_count, ncq_tfs->lba);
         dma_acct_start(ide_state->blk, &ncq_tfs->acct,
                        &ncq_tfs->sglist, BLOCK_ACCT_READ);
         ncq_tfs->aiocb = dma_blk_read(ide_state->blk, &ncq_tfs->sglist,
@@ -1013,12 +1005,8 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
                                       ncq_cb, ncq_tfs);
         break;
     case WRITE_FPDMA_QUEUED:
-        DPRINTF(port, "NCQ writing %d sectors to LBA %"PRId64", tag %d\n",
-                ncq_tfs->sector_count, ncq_tfs->lba, ncq_tfs->tag);
-
-        DPRINTF(port, "tag %d aio write %"PRId64"\n",
-                ncq_tfs->tag, ncq_tfs->lba);
-
+        trace_execute_ncq_command_read(ad->hba, port, ncq_tfs->tag,
+                                       ncq_tfs->sector_count, ncq_tfs->lba);
         dma_acct_start(ide_state->blk, &ncq_tfs->acct,
                        &ncq_tfs->sglist, BLOCK_ACCT_WRITE);
         ncq_tfs->aiocb = dma_blk_write(ide_state->blk, &ncq_tfs->sglist,
@@ -1027,8 +1015,8 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
                                        ncq_cb, ncq_tfs);
         break;
     default:
-        DPRINTF(port, "error: unsupported NCQ command (0x%02x) received\n",
-                ncq_tfs->cmd);
+        trace_execute_ncq_command_unsup(ad->hba, port,
+                                        ncq_tfs->tag, ncq_tfs->cmd);
         ncq_err(ncq_tfs);
     }
 }
@@ -1038,7 +1026,6 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
                                 uint8_t slot)
 {
     AHCIDevice *ad = &s->dev[port];
-    IDEState *ide_state = &ad->port.ifs[0];
     NCQFrame *ncq_fis = (NCQFrame*)cmd_fis;
     uint8_t tag = ncq_fis->tag >> 3;
     NCQTransferState *ncq_tfs = &ad->ncq_tfs[tag];
@@ -1066,21 +1053,20 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
 
     /* Sanity-check the NCQ packet */
     if (tag != slot) {
-        DPRINTF(port, "Warn: NCQ slot (%d) did not match the given tag (%d)\n",
-                slot, tag);
+        trace_process_ncq_command_mismatch(s, port, tag, slot);
     }
 
     if (ncq_fis->aux0 || ncq_fis->aux1 || ncq_fis->aux2 || ncq_fis->aux3) {
-        DPRINTF(port, "Warn: Attempt to use NCQ auxiliary fields.\n");
+        trace_process_ncq_command_aux(s, port, tag);
     }
     if (ncq_fis->prio || ncq_fis->icc) {
-        DPRINTF(port, "Warn: Unsupported attempt to use PRIO/ICC fields\n");
+        trace_process_ncq_command_prioicc(s, port, tag);
     }
     if (ncq_fis->fua & NCQ_FIS_FUA_MASK) {
-        DPRINTF(port, "Warn: Unsupported attempt to use Force Unit Access\n");
+        trace_process_ncq_command_fua(s, port, tag);
     }
     if (ncq_fis->tag & NCQ_FIS_RARC_MASK) {
-        DPRINTF(port, "Warn: Unsupported attempt to use Rebuild Assist\n");
+        trace_process_ncq_command_rarc(s, port, tag);
     }
 
     ncq_tfs->sector_count = ((ncq_fis->sector_count_high << 8) |
@@ -1099,16 +1085,14 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
         ahci_trigger_irq(ad->hba, ad, PORT_IRQ_OVERFLOW);
         return;
     } else if (ncq_tfs->sglist.size != size) {
-        DPRINTF(port, "Warn: PRDTL (0x%zx)"
-                " does not match requested size (0x%zx)",
-                ncq_tfs->sglist.size, size);
+        trace_process_ncq_command_large(s, port, tag,
+                                        ncq_tfs->sglist.size, size);
     }
 
-    DPRINTF(port, "NCQ transfer LBA from %"PRId64" to %"PRId64", "
-            "drive max %"PRId64"\n",
-            ncq_tfs->lba, ncq_tfs->lba + ncq_tfs->sector_count - 1,
-            ide_state->nb_sectors - 1);
-
+    trace_process_ncq_command(s, port, tag,
+                              ncq_fis->command,
+                              ncq_tfs->lba,
+                              ncq_tfs->lba + ncq_tfs->sector_count - 1);
     execute_ncq_command(ncq_tfs);
 }
 
@@ -1129,16 +1113,14 @@ static void handle_reg_h2d_fis(AHCIState *s, int port,
     uint16_t opts = le16_to_cpu(cmd->opts);
 
     if (cmd_fis[1] & 0x0F) {
-        DPRINTF(port, "Port Multiplier not supported."
-                " cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
-                cmd_fis[0], cmd_fis[1], cmd_fis[2]);
+        trace_handle_reg_h2d_fis_pmp(s, port, cmd_fis[1],
+                                     cmd_fis[2], cmd_fis[3]);
         return;
     }
 
     if (cmd_fis[1] & 0x70) {
-        DPRINTF(port, "Reserved flags set in H2D Register FIS."
-                " cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
-                cmd_fis[0], cmd_fis[1], cmd_fis[2]);
+        trace_handle_reg_h2d_fis_res(s, port, cmd_fis[1],
+                                     cmd_fis[2], cmd_fis[3]);
         return;
     }
 
@@ -1216,12 +1198,12 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
 
     if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
         /* Engine currently busy, try again later */
-        DPRINTF(port, "engine busy\n");
+        trace_handle_cmd_busy(s, port);
         return -1;
     }
 
     if (!s->dev[port].lst) {
-        DPRINTF(port, "error: lst not given but cmd handled");
+        trace_handle_cmd_nolist(s, port);
         return -1;
     }
     cmd = get_cmd_header(s, port, slot);
@@ -1231,7 +1213,7 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
     /* The device we are working for */
     ide_state = &s->dev[port].port.ifs[0];
     if (!ide_state->blk) {
-        DPRINTF(port, "error: guest accessed unused port");
+        trace_handle_cmd_badport(s, port);
         return -1;
     }
 
@@ -1240,13 +1222,11 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
     cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
                              DMA_DIRECTION_FROM_DEVICE);
     if (!cmd_fis) {
-        DPRINTF(port, "error: guest passed us an invalid cmd fis\n");
+        trace_handle_cmd_badfis(s, port);
         return -1;
     } else if (cmd_len != 0x80) {
         ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_HBUS_ERR);
-        DPRINTF(port, "error: dma_memory_map failed: "
-                "(len(%02"PRIx64") != 0x80)\n",
-                cmd_len);
+        trace_handle_cmd_badmap(s, port, cmd_len);
         goto out;
     }
     debug_print_fis(cmd_fis, 0x80);
@@ -1256,9 +1236,8 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
             handle_reg_h2d_fis(s, port, slot, cmd_fis);
             break;
         default:
-            DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
-                          "cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
-                          cmd_fis[2]);
+            trace_handle_cmd_unhandled_fis(s, port,
+                                           cmd_fis[0], cmd_fis[1], cmd_fis[2]);
             break;
     }
 
@@ -1299,9 +1278,9 @@ static void ahci_start_transfer(IDEDMA *dma)
         has_sglist = 1;
     }
 
-    DPRINTF(ad->port_no, "%sing %d bytes on %s w/%s sglist\n",
-            is_write ? "writ" : "read", size, is_atapi ? "atapi" : "ata",
-            has_sglist ? "" : "o");
+    trace_ahci_start_transfer(ad->hba, ad->port_no, is_write ? "writ" : "read",
+                              size, is_atapi ? "atapi" : "ata",
+                              has_sglist ? "" : "o");
 
     if (has_sglist && size) {
         if (is_write) {
@@ -1330,7 +1309,7 @@ static void ahci_start_dma(IDEDMA *dma, IDEState *s,
                            BlockCompletionFunc *dma_cb)
 {
     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
-    DPRINTF(ad->port_no, "\n");
+    trace_ahci_start_dma(ad->hba, ad->port_no);
     s->io_buffer_offset = 0;
     dma_cb(s, 0);
 }
@@ -1368,12 +1347,12 @@ static int32_t ahci_dma_prepare_buf(IDEDMA *dma, int32_t limit)
 
     if (ahci_populate_sglist(ad, &s->sg, ad->cur_cmd,
                              limit, s->io_buffer_offset) == -1) {
-        DPRINTF(ad->port_no, "ahci_dma_prepare_buf failed.\n");
+        trace_ahci_dma_prepare_buf_fail(ad->hba, ad->port_no);
         return -1;
     }
     s->io_buffer_size = s->sg.size;
 
-    DPRINTF(ad->port_no, "len=%#x\n", s->io_buffer_size);
+    trace_ahci_dma_prepare_buf(ad->hba, ad->port_no, limit, s->io_buffer_size);
     return s->io_buffer_size;
 }
 
@@ -1409,11 +1388,9 @@ static int ahci_dma_rw_buf(IDEDMA *dma, int is_write)
 
     /* free sglist, update byte count */
     dma_buf_commit(s, l);
-
     s->io_buffer_index += l;
 
-    DPRINTF(ad->port_no, "len=%#x\n", l);
-
+    trace_ahci_dma_rw_buf(ad->hba, ad->port_no, l);
     return 1;
 }
 
@@ -1421,7 +1398,7 @@ static void ahci_cmd_done(IDEDMA *dma)
 {
     AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
 
-    DPRINTF(ad->port_no, "cmd done\n");
+    trace_ahci_cmd_done(ad->hba, ad->port_no);
 
     /* update d2h status */
     ahci_write_fis_d2h(ad);
@@ -1505,6 +1482,8 @@ void ahci_reset(AHCIState *s)
     AHCIPortRegs *pr;
     int i;
 
+    trace_ahci_reset(s);
+
     s->control_regs.irqstatus = 0;
     /* AHCI Enable (AE)
      * The implementation of this bit is dependent upon the value of the
@@ -1755,6 +1734,7 @@ static uint64_t allwinner_ahci_mem_read(void *opaque, hwaddr addr,
                                         unsigned size)
 {
     AllwinnerAHCIState *a = opaque;
+    AHCIState *s = &(SYSBUS_AHCI(a)->ahci);
     uint64_t val = a->regs[addr/4];
 
     switch (addr / 4) {
@@ -1765,8 +1745,7 @@ static uint64_t allwinner_ahci_mem_read(void *opaque, hwaddr addr,
         val &= ~(0x1 << 24);
         break;
     }
-    DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
-            addr, val, size);
+    trace_allwinner_ahci_mem_read(s, a, addr, val, size);
     return  val;
 }
 
@@ -1774,9 +1753,9 @@ static void allwinner_ahci_mem_write(void *opaque, hwaddr addr,
                                      uint64_t val, unsigned size)
 {
     AllwinnerAHCIState *a = opaque;
+    AHCIState *s = &(SYSBUS_AHCI(a)->ahci);
 
-    DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
-            addr, val, size);
+    trace_allwinner_ahci_mem_write(s, a, addr, val, size);
     a->regs[addr/4] = val;
 }
 
diff --git a/hw/ide/trace-events b/hw/ide/trace-events
index cc8949c..0b61c5d 100644
--- a/hw/ide/trace-events
+++ b/hw/ide/trace-events
@@ -56,3 +56,52 @@ ide_atapi_cmd(void *s, uint8_t cmd) "IDEState: %p; cmd: 0x%02x"
 ide_atapi_cmd_read_dma_cb_aio(void *s, int lba, int n) "IDEState: %p; aio read: lba=%d n=%d"
 # Warning: Verbose
 ide_atapi_cmd_packet(void *s, uint16_t limit, const char *packet) "IDEState: %p; limit=0x%x packet: %s"
+
+# hw/ide/ahci.c
+ahci_port_read(void *s, int port, int offset, uint32_t ret) "ahci(%p)[%d]: port read @ 0x%x: 0x%08x"
+ahci_irq_raise(void *s) "ahci(%p): raise irq"
+ahci_irq_lower(void *s) "ahci(%p): lower irq"
+ahci_check_irq(void *s, uint32_t old, uint32_t new) "ahci(%p): check irq 0x%08x --> 0x%08x"
+
+ahci_port_write(void *s, int port, int offset, uint32_t val) "ahci(%p)[%d]: port write @ 0x%x: 0x%08x"
+ahci_mem_read_32(void *s, uint64_t addr, uint32_t val) "ahci(%p): mem read @ 0x%"PRIx64": 0x%08x"
+ahci_mem_read(void *s, unsigned size, uint64_t addr, uint64_t val) "ahci(%p): read%u @ 0x%"PRIx64": 0x%016"PRIx64
+ahci_mem_write(void *s, unsigned size, uint64_t addr, uint64_t val) "ahci(%p): write%u @ 0x%"PRIx64": 0x%016"PRIx64
+ahci_mem_write_unknown(void *s, unsigned size, uint64_t addr, uint64_t val) "ahci(%p): write%u to unknown register 0x%"PRIx64": 0x%016"PRIx64
+ahci_set_signature(void *s, int port, uint8_t nsector, uint8_t sector, uint8_t lcyl, uint8_t hcyl, uint32_t sig) "ahci(%p)[%d]: set signature sector:0x%02x nsector:0x%02x lcyl:0x%02x hcyl:0x%02x (cumulatively: 0x%08x)"
+ahci_reset_port(void *s, int port) "ahci(%p)[%d]: reset port"
+ahci_unmap_fis_address_null(void *s, int port) "ahci(%p)[%d]: Attempt to unmap NULL FIS address"
+ahci_unmap_clb_address_null(void *s, int port) "ahci(%p)[%d]: Attempt to unmap NULL CLB address"
+ahci_populate_sglist(void *s, int port) "ahci(%p)[%d]"
+ahci_populate_sglist_no_prdtl(void *s, int port, uint16_t opts) "ahci(%p)[%d]: no sg list given by guest: 0x%04x"
+ahci_populate_sglist_no_map(void *s, int port) "ahci(%p)[%d]: DMA mapping failed"
+ahci_populate_sglist_short_map(void *s, int port) "ahci(%p)[%d]: mapped less than expected"
+ahci_populate_sglist_bad_offset(void *s, int port, int off_idx, int64_t off_pos) "ahci(%p)[%d]: Incorrect offset! off_idx: %d, off_pos: %"PRId64
+ncq_finish(void *s, int port, uint8_t tag) "ahci(%p)[%d][tag:%d]: NCQ transfer finished"
+execute_ncq_command_read(void *s, int port, uint8_t tag, int count, int64_t lba) "ahci(%p)[%d][tag:%d]: NCQ reading %d sectors from LBA %"PRId64
+execute_ncq_command_write(void *s, int port, uint8_t tag, int count, int64_t lba) "ahci(%p)[%d][tag:%d]: NCQ writing %d sectors to LBA %"PRId64
+execute_ncq_command_unsup(void *s, int port, uint8_t tag, uint8_t cmd) "ahci(%p)[%d][tag:%d]: error: unsupported NCQ command (0x%02x) received"
+process_ncq_command_mismatch(void *s, int port, uint8_t tag, uint8_t slot) "ahci(%p)[%d][tag:%d]: Warning: NCQ slot (%d) did not match the given tag"
+process_ncq_command_aux(void *s, int port, uint8_t tag) "ahci(%p)[%d][tag:%d]: Warn: Attempt to use NCQ auxiliary fields"
+process_ncq_command_prioicc(void *s, int port, uint8_t tag) "ahci(%p)[%d][tag:%d]: Warn: Unsupported attempt to use PRIO/ICC fields"
+process_ncq_command_fua(void *s, int port, uint8_t tag) "ahci(%p)[%d][tag:%d]: Warn: Unsupported attempt to use Force Unit Access"
+process_ncq_command_rarc(void *s, int port, uint8_t tag) "ahci(%p)[%d][tag:%d]: Warn: Unsupported attempt to use Rebuild Assist"
+process_ncq_command_large(void *s, int port, uint8_t tag, size_t prdtl, size_t size) "ahci(%p)[%d][tag:%d]: Warn: PRDTL (0x%zx) does not match requested size (0x%zx)"
+process_ncq_command(void *s, int port, uint8_t tag, uint8_t cmd, uint64_t lba, uint64_t end) "ahci(%p)[%d][tag:%d]: NCQ op 0x%02x on sectors [%"PRId64",%"PRId64"]"
+handle_reg_h2d_fis_pmp(void *s, int port, char b0, char b1, char b2) "ahci(%p)[%d]: Port Multiplier not supported, FIS: 0x%02x-%02x-%02x"
+handle_reg_h2d_fis_res(void *s, int port, char b0, char b1, char b2) "ahci(%p)[%d]: Reserved flags set in H2D Register FIS, FIS: 0x%02x-%02x-%02x"
+handle_cmd_busy(void *s, int port) "ahci(%p)[%d]: engine busy"
+handle_cmd_nolist(void *s, int port) "ahci(%p)[%d]: handle_cmd called without s->dev[port].lst"
+handle_cmd_badport(void *s, int port) "ahci(%p)[%d]: guest accessed unused port"
+handle_cmd_badfis(void *s, int port) "ahci(%p)[%d]: guest provided an invalid cmd FIS"
+handle_cmd_badmap(void *s, int port, uint64_t len) "ahci(%p)[%d]: dma_memory_map failed, 0x%02"PRIx64" != 0x80"
+handle_cmd_unhandled_fis(void *s, int port, uint8_t b0, uint8_t b1, uint8_t b2) "ahci(%p)[%d]: unhandled FIS type. cmd_fis: 0x%02x-%02x-%02x"
+ahci_start_transfer(void *s, int port, const char *rw, uint32_t size, const char *tgt, const char *sgl) "ahci(%p)[%d]: %sing %d bytes on %s w/%s sglist"
+ahci_start_dma(void *s, int port) "ahci(%p)[%d]: start dma"
+ahci_dma_prepare_buf(void *s, int port, int32_t io_buffer_size, int32_t limit) "ahci(%p)[%d]: prepare buf limit=%"PRId32" prepared=%"PRId32
+ahci_dma_prepare_buf_fail(void *s, int port) "ahci(%p)[%d]: sglist population failed"
+ahci_dma_rw_buf(void *s, int port, int l) "ahci(%p)[%d] len=0x%x"
+ahci_cmd_done(void *s, int port) "ahci(%p)[%d]: cmd done"
+ahci_reset(void *s) "ahci(%p): HBA reset"
+allwinner_ahci_mem_read(void *s, void *a, uint64_t addr, uint64_t val, unsigned size) "ahci(%p): read a=%p addr=0x%"HWADDR_PRIx" val=0x%"PRIx64", size=%d"
+allwinner_ahci_mem_write(void *s, void *a, uint64_t addr, uint64_t val, unsigned size) "ahci(%p): write a=%p addr=0x%"HWADDR_PRIx" val=0x%"PRIx64", size=%d"
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 7/9] AHCI: Rework IRQ constants
  2017-08-29 20:49 [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing John Snow
                   ` (5 preceding siblings ...)
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 6/9] AHCI: Replace DPRINTF with trace-events John Snow
@ 2017-08-29 20:49 ` John Snow
  2017-08-30  3:54   ` Philippe Mathieu-Daudé
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 8/9] AHCI: pretty-print FIS to buffer instead of stderr John Snow
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: John Snow @ 2017-08-29 20:49 UTC (permalink / raw)
  To: qemu-block; +Cc: eblake, qemu-devel, f4bug, John Snow

Create a new enum so that we can name the IRQ bits, which will make debugging
them a little nicer if we can print them out. Not handled in this patch, but
this will make it possible to get a nice debug printf detailing exactly which
status bits are set, as it can be multiple at any given time.

As a consequence of this patch, it is no longer possible to set multiple IRQ
codes at once, but nothing was utilizing this ability anyway.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 hw/ide/ahci.c          | 49 ++++++++++++++++++++++++++++++++++++++-----------
 hw/ide/ahci_internal.h | 44 +++++++++++++++++++++++++++++++++++---------
 hw/ide/trace-events    |  2 +-
 3 files changed, 74 insertions(+), 21 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index c60a000..a0a4dd6 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -56,6 +56,27 @@ static bool ahci_map_fis_address(AHCIDevice *ad);
 static void ahci_unmap_clb_address(AHCIDevice *ad);
 static void ahci_unmap_fis_address(AHCIDevice *ad);
 
+static const char *AHCIPortIRQ_lookup[AHCI_PORT_IRQ__END] = {
+    [AHCI_PORT_IRQ_BIT_DHRS] = "DHRS",
+    [AHCI_PORT_IRQ_BIT_PSS]  = "PSS",
+    [AHCI_PORT_IRQ_BIT_DSS]  = "DSS",
+    [AHCI_PORT_IRQ_BIT_SDBS] = "SDBS",
+    [AHCI_PORT_IRQ_BIT_UFS]  = "UFS",
+    [AHCI_PORT_IRQ_BIT_DPS]  = "DPS",
+    [AHCI_PORT_IRQ_BIT_PCS]  = "PCS",
+    [AHCI_PORT_IRQ_BIT_DMPS] = "DMPS",
+    [8 ... 21]               = "RESERVED",
+    [AHCI_PORT_IRQ_BIT_PRCS] = "PRCS",
+    [AHCI_PORT_IRQ_BIT_IPMS] = "IPMS",
+    [AHCI_PORT_IRQ_BIT_OFS]  = "OFS",
+    [25]                     = "RESERVED",
+    [AHCI_PORT_IRQ_BIT_INFS] = "INFS",
+    [AHCI_PORT_IRQ_BIT_IFS]  = "IFS",
+    [AHCI_PORT_IRQ_BIT_HBDS] = "HBDS",
+    [AHCI_PORT_IRQ_BIT_HBFS] = "HBFS",
+    [AHCI_PORT_IRQ_BIT_TFES] = "TFES",
+    [AHCI_PORT_IRQ_BIT_CPDS] = "CPDS"
+};
 
 static uint32_t  ahci_port_read(AHCIState *s, int port, int offset)
 {
@@ -170,12 +191,18 @@ static void ahci_check_irq(AHCIState *s)
 }
 
 static void ahci_trigger_irq(AHCIState *s, AHCIDevice *d,
-                             int irq_type)
+                             enum AHCIPortIRQ irqbit)
 {
-    DPRINTF(d->port_no, "trigger irq %#x -> %x\n",
-            irq_type, d->port_regs.irq_mask & irq_type);
+    g_assert(irqbit >= 0 && irqbit < 32);
+    uint32_t irq = 1U << irqbit;
+    uint32_t irqstat = d->port_regs.irq_stat | irq;
 
-    d->port_regs.irq_stat |= irq_type;
+    trace_ahci_trigger_irq(s, d->port_no,
+                           AHCIPortIRQ_lookup[irqbit], irq,
+                           d->port_regs.irq_stat, irqstat,
+                           irqstat & d->port_regs.irq_mask);
+
+    d->port_regs.irq_stat = irqstat;
     ahci_check_irq(s);
 }
 
@@ -718,7 +745,7 @@ static void ahci_write_fis_sdb(AHCIState *s, NCQTransferState *ncq_tfs)
 
     /* Trigger IRQ if interrupt bit is set (which currently, it always is) */
     if (sdb_fis->flags & 0x40) {
-        ahci_trigger_irq(s, ad, PORT_IRQ_SDB_FIS);
+        ahci_trigger_irq(s, ad, AHCI_PORT_IRQ_BIT_SDBS);
     }
 }
 
@@ -761,10 +788,10 @@ static void ahci_write_fis_pio(AHCIDevice *ad, uint16_t len)
         ad->port.ifs[0].status;
 
     if (pio_fis[2] & ERR_STAT) {
-        ahci_trigger_irq(ad->hba, ad, PORT_IRQ_TF_ERR);
+        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES);
     }
 
-    ahci_trigger_irq(ad->hba, ad, PORT_IRQ_PIOS_FIS);
+    ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_PSS);
 }
 
 static bool ahci_write_fis_d2h(AHCIDevice *ad)
@@ -804,10 +831,10 @@ static bool ahci_write_fis_d2h(AHCIDevice *ad)
         ad->port.ifs[0].status;
 
     if (d2h_fis[2] & ERR_STAT) {
-        ahci_trigger_irq(ad->hba, ad, PORT_IRQ_TF_ERR);
+        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES);
     }
 
-    ahci_trigger_irq(ad->hba, ad, PORT_IRQ_D2H_REG_FIS);
+    ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_DHRS);
     return true;
 }
 
@@ -1082,7 +1109,7 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
                      "is smaller than the requested size (0x%zx)",
                      ncq_tfs->sglist.size, size);
         ncq_err(ncq_tfs);
-        ahci_trigger_irq(ad->hba, ad, PORT_IRQ_OVERFLOW);
+        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_OFS);
         return;
     } else if (ncq_tfs->sglist.size != size) {
         trace_process_ncq_command_large(s, port, tag,
@@ -1225,7 +1252,7 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
         trace_handle_cmd_badfis(s, port);
         return -1;
     } else if (cmd_len != 0x80) {
-        ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_HBUS_ERR);
+        ahci_trigger_irq(s, &s->dev[port], AHCI_PORT_IRQ_BIT_HBFS);
         trace_handle_cmd_badmap(s, port, cmd_len);
         goto out;
     }
diff --git a/hw/ide/ahci_internal.h b/hw/ide/ahci_internal.h
index 1e21169..7e67add 100644
--- a/hw/ide/ahci_internal.h
+++ b/hw/ide/ahci_internal.h
@@ -91,6 +91,31 @@
 #define PORT_CMD_ISSUE            0x38 /* command issue */
 #define PORT_RESERVED             0x3c /* reserved */
 
+/* Port interrupt bit descriptors */
+enum AHCIPortIRQ {
+    AHCI_PORT_IRQ_BIT_DHRS = 0,
+    AHCI_PORT_IRQ_BIT_PSS  = 1,
+    AHCI_PORT_IRQ_BIT_DSS  = 2,
+    AHCI_PORT_IRQ_BIT_SDBS = 3,
+    AHCI_PORT_IRQ_BIT_UFS  = 4,
+    AHCI_PORT_IRQ_BIT_DPS  = 5,
+    AHCI_PORT_IRQ_BIT_PCS  = 6,
+    AHCI_PORT_IRQ_BIT_DMPS = 7,
+    /* RESERVED */
+    AHCI_PORT_IRQ_BIT_PRCS = 22,
+    AHCI_PORT_IRQ_BIT_IPMS = 23,
+    AHCI_PORT_IRQ_BIT_OFS  = 24,
+    /* RESERVED */
+    AHCI_PORT_IRQ_BIT_INFS = 26,
+    AHCI_PORT_IRQ_BIT_IFS  = 27,
+    AHCI_PORT_IRQ_BIT_HBDS = 28,
+    AHCI_PORT_IRQ_BIT_HBFS = 29,
+    AHCI_PORT_IRQ_BIT_TFES = 30,
+    AHCI_PORT_IRQ_BIT_CPDS = 31,
+    AHCI_PORT_IRQ__END     = 32
+};
+
+
 /* PORT_IRQ_{STAT,MASK} bits */
 #define PORT_IRQ_COLD_PRES        (1U << 31) /* cold presence detect */
 #define PORT_IRQ_TF_ERR           (1 << 30) /* task file error */
@@ -98,18 +123,19 @@
 #define PORT_IRQ_HBUS_DATA_ERR    (1 << 28) /* host bus data error */
 #define PORT_IRQ_IF_ERR           (1 << 27) /* interface fatal error */
 #define PORT_IRQ_IF_NONFATAL      (1 << 26) /* interface non-fatal error */
+                                            /* reserved */
 #define PORT_IRQ_OVERFLOW         (1 << 24) /* xfer exhausted available S/G */
 #define PORT_IRQ_BAD_PMP          (1 << 23) /* incorrect port multiplier */
-
 #define PORT_IRQ_PHYRDY           (1 << 22) /* PhyRdy changed */
-#define PORT_IRQ_DEV_ILCK         (1 << 7) /* device interlock */
-#define PORT_IRQ_CONNECT          (1 << 6) /* port connect change status */
-#define PORT_IRQ_SG_DONE          (1 << 5) /* descriptor processed */
-#define PORT_IRQ_UNK_FIS          (1 << 4) /* unknown FIS rx'd */
-#define PORT_IRQ_SDB_FIS          (1 << 3) /* Set Device Bits FIS rx'd */
-#define PORT_IRQ_DMAS_FIS         (1 << 2) /* DMA Setup FIS rx'd */
-#define PORT_IRQ_PIOS_FIS         (1 << 1) /* PIO Setup FIS rx'd */
-#define PORT_IRQ_D2H_REG_FIS      (1 << 0) /* D2H Register FIS rx'd */
+                                            /* reserved */
+#define PORT_IRQ_DEV_ILCK         (1 << 7)  /* device interlock */
+#define PORT_IRQ_CONNECT          (1 << 6)  /* port connect change status */
+#define PORT_IRQ_SG_DONE          (1 << 5)  /* descriptor processed */
+#define PORT_IRQ_UNK_FIS          (1 << 4)  /* unknown FIS rx'd */
+#define PORT_IRQ_SDB_FIS          (1 << 3)  /* Set Device Bits FIS rx'd */
+#define PORT_IRQ_DMAS_FIS         (1 << 2)  /* DMA Setup FIS rx'd */
+#define PORT_IRQ_PIOS_FIS         (1 << 1)  /* PIO Setup FIS rx'd */
+#define PORT_IRQ_D2H_REG_FIS      (1 << 0)  /* D2H Register FIS rx'd */
 
 #define PORT_IRQ_FREEZE           (PORT_IRQ_HBUS_ERR | PORT_IRQ_IF_ERR |   \
                                    PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY |    \
diff --git a/hw/ide/trace-events b/hw/ide/trace-events
index 0b61c5d..e15fd77 100644
--- a/hw/ide/trace-events
+++ b/hw/ide/trace-events
@@ -62,7 +62,7 @@ ahci_port_read(void *s, int port, int offset, uint32_t ret) "ahci(%p)[%d]: port
 ahci_irq_raise(void *s) "ahci(%p): raise irq"
 ahci_irq_lower(void *s) "ahci(%p): lower irq"
 ahci_check_irq(void *s, uint32_t old, uint32_t new) "ahci(%p): check irq 0x%08x --> 0x%08x"
-
+ahci_trigger_irq(void *s, int port, const char *name, uint32_t val, uint32_t old, uint32_t new, uint32_t effective) "ahci(%p)[%d]: trigger irq +%s (0x%08x); irqstat: 0x%08x --> 0x%08x; effective: 0x%08x"
 ahci_port_write(void *s, int port, int offset, uint32_t val) "ahci(%p)[%d]: port write @ 0x%x: 0x%08x"
 ahci_mem_read_32(void *s, uint64_t addr, uint32_t val) "ahci(%p): mem read @ 0x%"PRIx64": 0x%08x"
 ahci_mem_read(void *s, unsigned size, uint64_t addr, uint64_t val) "ahci(%p): read%u @ 0x%"PRIx64": 0x%016"PRIx64
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 8/9] AHCI: pretty-print FIS to buffer instead of stderr
  2017-08-29 20:49 [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing John Snow
                   ` (6 preceding siblings ...)
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 7/9] AHCI: Rework IRQ constants John Snow
@ 2017-08-29 20:49 ` John Snow
  2017-08-30  9:17   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 9/9] AHCI: remove DPRINTF macro John Snow
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 22+ messages in thread
From: John Snow @ 2017-08-29 20:49 UTC (permalink / raw)
  To: qemu-block; +Cc: eblake, qemu-devel, f4bug, John Snow

The current FIS printing routines dump the FIS to screen. adjust this
such that it dumps to buffer instead, then use this ability to have
FIS dump mechanisms via trace-events instead of compiled defines.

Signed-off-by: John Snow <jsnow@redhat.com>
---
 hw/ide/ahci.c       | 54 +++++++++++++++++++++++++++++++++++++++++++----------
 hw/ide/trace-events |  4 ++++
 2 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index a0a4dd6..2e75f9b 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -644,20 +644,45 @@ static void ahci_reset_port(AHCIState *s, int port)
     ahci_init_d2h(d);
 }
 
-static void debug_print_fis(uint8_t *fis, int cmd_len)
+/* Buffer pretty output based on a raw FIS structure. */
+static void ahci_pretty_buffer_fis(uint8_t *fis, int cmd_len, char **out)
 {
-#if DEBUG_AHCI
+    size_t bufsize;
+    char *pbuf;
+    char *pptr;
+    size_t lines = DIV_ROUND_UP(cmd_len, 16);
+    const char *preamble = "FIS:";
     int i;
 
-    fprintf(stderr, "fis:");
+    /* Total amount of memory to store FISes in HBA memory */
+    g_assert_cmpint(cmd_len, <=, 0x100);
+    g_assert(out);
+
+    /* Printed like:
+     * FIS:\n
+     * 0x00: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee \n
+     * 0x10: ff \n
+     * \0
+     *
+     * Four bytes for the preamble, seven for each line prefix (including a
+     * newline to start a new line), three bytes for each source byte,
+     * a trailing newline and a terminal null byte.
+     */
+
+    bufsize = strlen(preamble) + ((6 + 1) * lines) + (3 * cmd_len) + 1 + 1;
+    pbuf = g_malloc(bufsize);
+    pptr = pbuf;
+    pptr += sprintf(pptr, "%s", preamble);
     for (i = 0; i < cmd_len; i++) {
         if ((i & 0xf) == 0) {
-            fprintf(stderr, "\n%02x:",i);
+            pptr += sprintf(pptr, "\n0x%02x: ", i);
         }
-        fprintf(stderr, "%02x ",fis[i]);
+        pptr += sprintf(pptr, "%02x ", fis[i]);
     }
-    fprintf(stderr, "\n");
-#endif
+    pptr += sprintf(pptr, "\n");
+    pptr += 1; /* \0 */
+    g_assert(pbuf + bufsize == pptr);
+    *out = pbuf;
 }
 
 static bool ahci_map_fis_address(AHCIDevice *ad)
@@ -1201,7 +1226,12 @@ static void handle_reg_h2d_fis(AHCIState *s, int port,
      * table to ide_state->io_buffer */
     if (opts & AHCI_CMD_ATAPI) {
         memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10);
-        debug_print_fis(ide_state->io_buffer, 0x10);
+        if (TRACE_HANDLE_REG_H2D_FIS_DUMP_ENABLED) {
+            char *pretty_fis;
+            ahci_pretty_buffer_fis(ide_state->io_buffer, 0x10, &pretty_fis);
+            trace_handle_reg_h2d_fis_dump(s, port, pretty_fis);
+            g_free(pretty_fis);
+        }
         s->dev[port].done_atapi_packet = false;
         /* XXX send PIO setup FIS */
     }
@@ -1256,8 +1286,12 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
         trace_handle_cmd_badmap(s, port, cmd_len);
         goto out;
     }
-    debug_print_fis(cmd_fis, 0x80);
-
+    if (TRACE_HANDLE_CMD_FIS_DUMP_ENABLED) {
+        char *pretty_fis;
+        ahci_pretty_buffer_fis(cmd_fis, 0x80, &pretty_fis);
+        trace_handle_cmd_fis_dump(s, port, pretty_fis);
+        g_free(pretty_fis);
+    }
     switch (cmd_fis[0]) {
         case SATA_FIS_TYPE_REGISTER_H2D:
             handle_reg_h2d_fis(s, port, slot, cmd_fis);
diff --git a/hw/ide/trace-events b/hw/ide/trace-events
index e15fd77..77ed3c1 100644
--- a/hw/ide/trace-events
+++ b/hw/ide/trace-events
@@ -105,3 +105,7 @@ ahci_cmd_done(void *s, int port) "ahci(%p)[%d]: cmd done"
 ahci_reset(void *s) "ahci(%p): HBA reset"
 allwinner_ahci_mem_read(void *s, void *a, uint64_t addr, uint64_t val, unsigned size) "ahci(%p): read a=%p addr=0x%"HWADDR_PRIx" val=0x%"PRIx64", size=%d"
 allwinner_ahci_mem_write(void *s, void *a, uint64_t addr, uint64_t val, unsigned size) "ahci(%p): write a=%p addr=0x%"HWADDR_PRIx" val=0x%"PRIx64", size=%d"
+
+# Warning: Verbose
+handle_reg_h2d_fis_dump(void *s, int port, char *fis) "ahci(%p)[%d]: %s"
+handle_cmd_fis_dump(void *s, int port, char *fis) "ahci(%p)[%d]: %s"
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [Qemu-devel] [PATCH v2 9/9] AHCI: remove DPRINTF macro
  2017-08-29 20:49 [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing John Snow
                   ` (7 preceding siblings ...)
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 8/9] AHCI: pretty-print FIS to buffer instead of stderr John Snow
@ 2017-08-29 20:49 ` John Snow
  2017-08-29 22:24   ` Philippe Mathieu-Daudé
  2017-08-29 21:14 ` [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing no-reply
  2017-08-30  9:21 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
  10 siblings, 1 reply; 22+ messages in thread
From: John Snow @ 2017-08-29 20:49 UTC (permalink / raw)
  To: qemu-block; +Cc: eblake, qemu-devel, f4bug, John Snow

Signed-off-by: John Snow <jsnow@redhat.com>
---
 hw/ide/ahci.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 2e75f9b..57bb59d 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -34,17 +34,8 @@
 #include "hw/ide/pci.h"
 #include "hw/ide/ahci_internal.h"
 
-#define DEBUG_AHCI 0
 #include "trace.h"
 
-#define DPRINTF(port, fmt, ...) \
-do { \
-    if (DEBUG_AHCI) { \
-        fprintf(stderr, "ahci: %s: [%d] ", __func__, port); \
-        fprintf(stderr, fmt, ## __VA_ARGS__); \
-    } \
-} while (0)
-
 static void check_cmd(AHCIState *s, int port);
 static int handle_cmd(AHCIState *s, int port, uint8_t slot);
 static void ahci_reset_port(AHCIState *s, int port);
-- 
2.9.5

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing
  2017-08-29 20:49 [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing John Snow
                   ` (8 preceding siblings ...)
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 9/9] AHCI: remove DPRINTF macro John Snow
@ 2017-08-29 21:14 ` no-reply
  2017-08-30  9:21 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
  10 siblings, 0 replies; 22+ messages in thread
From: no-reply @ 2017-08-29 21:14 UTC (permalink / raw)
  To: jsnow; +Cc: famz, qemu-block, qemu-devel, f4bug

Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: 20170829204934.9039-1-jsnow@redhat.com
Subject: [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
    echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
    if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
        failed=1
        echo
    fi
    n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]               patchew/20170829204934.9039-1-jsnow@redhat.com -> patchew/20170829204934.9039-1-jsnow@redhat.com
Switched to a new branch 'test'
317562672d AHCI: remove DPRINTF macro
5111f245b5 AHCI: pretty-print FIS to buffer instead of stderr
fd94464a09 AHCI: Rework IRQ constants
a2cbc7a1b9 AHCI: Replace DPRINTF with trace-events
7617a100a4 IDE: replace DEBUG_AIO with trace events
d0ab9d9ae8 ATAPI: Replace DEBUG_IDE_ATAPI with tracing events
ec07b9f487 IDE: add tracing for data ports
ad50ebd27b IDE: Add register hints to tracing
99af2ced97 IDE: replace DEBUG_IDE with tracing system

=== OUTPUT BEGIN ===
Checking PATCH 1/9: IDE: replace DEBUG_IDE with tracing system...
ERROR: spaces required around that '|' (ctx:VxV)
#143: FILE: hw/ide/core.c:1197:
+    if (reg_num != 7 && (s->status & (BUSY_STAT|DRQ_STAT))) {
                                                ^

total: 1 errors, 0 warnings, 337 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 2/9: IDE: Add register hints to tracing...
Checking PATCH 3/9: IDE: add tracing for data ports...
Checking PATCH 4/9: ATAPI: Replace DEBUG_IDE_ATAPI with tracing events...
Checking PATCH 5/9: IDE: replace DEBUG_AIO with trace events...
Checking PATCH 6/9: AHCI: Replace DPRINTF with trace-events...
ERROR: Hex numbers must be prefixed with '0x'
#540: FILE: hw/ide/trace-events:91:
+handle_reg_h2d_fis_pmp(void *s, int port, char b0, char b1, char b2) "ahci(%p)[%d]: Port Multiplier not supported, FIS: 0x%02x-%02x-%02x"

ERROR: Hex numbers must be prefixed with '0x'
#541: FILE: hw/ide/trace-events:92:
+handle_reg_h2d_fis_res(void *s, int port, char b0, char b1, char b2) "ahci(%p)[%d]: Reserved flags set in H2D Register FIS, FIS: 0x%02x-%02x-%02x"

ERROR: Hex numbers must be prefixed with '0x'
#547: FILE: hw/ide/trace-events:98:
+handle_cmd_unhandled_fis(void *s, int port, uint8_t b0, uint8_t b1, uint8_t b2) "ahci(%p)[%d]: unhandled FIS type. cmd_fis: 0x%02x-%02x-%02x"

total: 3 errors, 0 warnings, 496 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 7/9: AHCI: Rework IRQ constants...
Checking PATCH 8/9: AHCI: pretty-print FIS to buffer instead of stderr...
ERROR: Use g_assert or g_assert_not_reached
#35: FILE: hw/ide/ahci.c:658:
+    g_assert_cmpint(cmd_len, <=, 0x100);

total: 1 errors, 0 warnings, 86 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 9/9: AHCI: remove DPRINTF macro...
=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/9] IDE: add tracing for data ports
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 3/9] IDE: add tracing for data ports John Snow
@ 2017-08-29 22:20   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-08-29 22:20 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: eblake, qemu-devel

On 08/29/2017 05:49 PM, John Snow wrote:
> To be used sparingly, but still interesting in the case of small
> firmwares designed to reproduce bugs in QEMU IDE.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>   hw/ide/core.c       | 12 +++++++++++-
>   hw/ide/trace-events |  5 +++++
>   2 files changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/ide/core.c b/hw/ide/core.c
> index cb250e6..82a19b1 100644
> --- a/hw/ide/core.c
> +++ b/hw/ide/core.c
> @@ -2259,6 +2259,8 @@ void ide_data_writew(void *opaque, uint32_t addr, uint32_t val)
>       IDEState *s = idebus_active_if(bus);
>       uint8_t *p;
>   
> +    trace_ide_data_writew(addr, val, bus, s);
> +
>       /* PIO data access allowed only when DRQ bit is set. The result of a write
>        * during PIO out is indeterminate, just ignore it. */
>       if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
> @@ -2304,6 +2306,8 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr)
>           s->status &= ~DRQ_STAT;
>           s->end_transfer_func(s);
>       }
> +
> +    trace_ide_data_readw(addr, ret, bus, s);
>       return ret;
>   }
>   
> @@ -2313,6 +2317,8 @@ void ide_data_writel(void *opaque, uint32_t addr, uint32_t val)
>       IDEState *s = idebus_active_if(bus);
>       uint8_t *p;
>   
> +    trace_ide_data_writel(addr, val, bus, s);
> +
>       /* PIO data access allowed only when DRQ bit is set. The result of a write
>        * during PIO out is indeterminate, just ignore it. */
>       if (!(s->status & DRQ_STAT) || ide_is_pio_out(s)) {
> @@ -2343,7 +2349,8 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr)
>       /* PIO data access allowed only when DRQ bit is set. The result of a read
>        * during PIO in is indeterminate, return 0 and don't move forward. */
>       if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {
> -        return 0;
> +        ret = 0;
> +        goto out;
>       }
>   
>       p = s->data_ptr;
> @@ -2358,6 +2365,9 @@ uint32_t ide_data_readl(void *opaque, uint32_t addr)
>           s->status &= ~DRQ_STAT;
>           s->end_transfer_func(s);
>       }
> +
> +out:
> +    trace_ide_data_readl(addr, ret, bus, s);
>       return ret;
>   }
>   
> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
> index bff8f39..17bc6f1 100644
> --- a/hw/ide/trace-events
> +++ b/hw/ide/trace-events
> @@ -6,6 +6,11 @@ ide_ioport_read(uint32_t addr, const char *reg, uint32_t val, void *bus, void *s
>   ide_ioport_write(uint32_t addr, const char *reg, uint32_t val, void *bus, void *s) "IDE PIO wr @ 0x%"PRIx32" (%s); val 0x%02"PRIx32"; bus %p IDEState %p"
>   ide_status_read(uint32_t addr, uint32_t val, void *bus, void *s)                   "IDE PIO rd @ 0x%"PRIx32" (Alt Status); val 0x%02"PRIx32"; bus %p; IDEState %p"
>   ide_cmd_write(uint32_t addr, uint32_t val, void *bus)                              "IDE PIO wr @ 0x%"PRIx32" (Device Control); val 0x%02"PRIx32"; bus %p"
> +# Warning: verbose
> +ide_data_readw(uint32_t addr, uint32_t val, void *bus, void *s)                    "IDE PIO rd @ 0x%"PRIx32" (Data: Word); val 0x%04"PRIx32"; bus %p; IDEState %p"
> +ide_data_writew(uint32_t addr, uint32_t val, void *bus, void *s)                   "IDE PIO wr @ 0x%"PRIx32" (Data: Word); val 0x%04"PRIx32"; bus %p; IDEState %p"
> +ide_data_readl(uint32_t addr, uint32_t val, void *bus, void *s)                    "IDE PIO rd @ 0x%"PRIx32" (Data: Long); val 0x%08"PRIx32"; bus %p; IDEState %p"
> +ide_data_writel(uint32_t addr, uint32_t val, void *bus, void *s)                   "IDE PIO wr @ 0x%"PRIx32" (Data: Long); val 0x%08"PRIx32"; bus %p; IDEState %p"
>   # misc
>   ide_exec_cmd(void *bus, void *state, uint32_t cmd) "IDE exec cmd: bus %p; state %p; cmd 0x%02x"
>   ide_cancel_dma_sync_buffered(void *fn, void *req) "invoking cb %p of buffered request %p with -ECANCELED"
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 6/9] AHCI: Replace DPRINTF with trace-events
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 6/9] AHCI: Replace DPRINTF with trace-events John Snow
@ 2017-08-29 22:22   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-08-29 22:22 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: eblake, qemu-devel

On 08/29/2017 05:49 PM, John Snow wrote:
> There are a few hangers-on that will be dealt with individually
> in forthcoming patches.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>   hw/ide/ahci.c       | 157 +++++++++++++++++++++++-----------------------------
>   hw/ide/trace-events |  49 ++++++++++++++++
>   2 files changed, 117 insertions(+), 89 deletions(-)
> 
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 406a1b5..c60a000 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -35,6 +35,7 @@
>   #include "hw/ide/ahci_internal.h"
>   
>   #define DEBUG_AHCI 0
> +#include "trace.h"
>   
>   #define DPRINTF(port, fmt, ...) \
>   do { \
> @@ -114,9 +115,9 @@ static uint32_t  ahci_port_read(AHCIState *s, int port, int offset)
>       default:
>           val = 0;
>       }
> -    DPRINTF(port, "offset: 0x%x val: 0x%x\n", offset, val);
> -    return val;
>   
> +    trace_ahci_port_read(s, port, offset, val);
> +    return val;
>   }
>   
>   static void ahci_irq_raise(AHCIState *s, AHCIDevice *dev)
> @@ -125,7 +126,7 @@ static void ahci_irq_raise(AHCIState *s, AHCIDevice *dev)
>       PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state),
>                                                              TYPE_PCI_DEVICE);
>   
> -    DPRINTF(0, "raise irq\n");
> +    trace_ahci_irq_raise(s);
>   
>       if (pci_dev && msi_enabled(pci_dev)) {
>           msi_notify(pci_dev, 0);
> @@ -140,7 +141,7 @@ static void ahci_irq_lower(AHCIState *s, AHCIDevice *dev)
>       PCIDevice *pci_dev = (PCIDevice *) object_dynamic_cast(OBJECT(dev_state),
>                                                              TYPE_PCI_DEVICE);
>   
> -    DPRINTF(0, "lower irq\n");
> +    trace_ahci_irq_lower(s);
>   
>       if (!pci_dev || !msi_enabled(pci_dev)) {
>           qemu_irq_lower(s->irq);
> @@ -150,8 +151,7 @@ static void ahci_irq_lower(AHCIState *s, AHCIDevice *dev)
>   static void ahci_check_irq(AHCIState *s)
>   {
>       int i;
> -
> -    DPRINTF(-1, "check irq %#x\n", s->control_regs.irqstatus);
> +    uint32_t old_irq = s->control_regs.irqstatus;
>   
>       s->control_regs.irqstatus = 0;
>       for (i = 0; i < s->ports; i++) {
> @@ -160,7 +160,7 @@ static void ahci_check_irq(AHCIState *s)
>               s->control_regs.irqstatus |= (1 << i);
>           }
>       }
> -
> +    trace_ahci_check_irq(s, old_irq, s->control_regs.irqstatus);
>       if (s->control_regs.irqstatus &&
>           (s->control_regs.ghc & HOST_CTL_IRQ_EN)) {
>               ahci_irq_raise(s, NULL);
> @@ -240,7 +240,7 @@ static void  ahci_port_write(AHCIState *s, int port, int offset, uint32_t val)
>   {
>       AHCIPortRegs *pr = &s->dev[port].port_regs;
>   
> -    DPRINTF(port, "offset: 0x%x val: 0x%x\n", offset, val);
> +    trace_ahci_port_write(s, port, offset, val);
>       switch (offset) {
>           case PORT_LST_ADDR:
>               pr->lst_addr = val;
> @@ -341,8 +341,6 @@ static uint64_t ahci_mem_read_32(void *opaque, hwaddr addr)
>               val = s->control_regs.version;
>               break;
>           }
> -
> -        DPRINTF(-1, "(addr 0x%08X), val 0x%08X\n", (unsigned) addr, val);
>       } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
>                  (addr < (AHCI_PORT_REGS_START_ADDR +
>                   (s->ports * AHCI_PORT_ADDR_OFFSET_LEN)))) {
> @@ -350,6 +348,7 @@ static uint64_t ahci_mem_read_32(void *opaque, hwaddr addr)
>                                addr & AHCI_PORT_ADDR_OFFSET_MASK);
>       }
>   
> +    trace_ahci_mem_read_32(s, addr, val);
>       return val;
>   }
>   
> @@ -379,8 +378,7 @@ static uint64_t ahci_mem_read(void *opaque, hwaddr addr, unsigned size)
>           val = (hi << 32 | lo) >> (ofst * 8);
>       }
>   
> -    DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
> -            addr, val, size);
> +    trace_ahci_mem_read(opaque, size, addr, val);
>       return val;
>   }
>   
> @@ -390,8 +388,7 @@ static void ahci_mem_write(void *opaque, hwaddr addr,
>   {
>       AHCIState *s = opaque;
>   
> -    DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
> -            addr, val, size);
> +    trace_ahci_mem_write(s, size, addr, val);
>   
>       /* Only aligned reads are allowed on AHCI */
>       if (addr & 3) {
> @@ -401,15 +398,12 @@ static void ahci_mem_write(void *opaque, hwaddr addr,
>       }
>   
>       if (addr < AHCI_GENERIC_HOST_CONTROL_REGS_MAX_ADDR) {
> -        DPRINTF(-1, "(addr 0x%08X), val 0x%08"PRIX64"\n", (unsigned) addr, val);
> -
>           switch (addr) {
>               case HOST_CAP: /* R/WO, RO */
>                   /* FIXME handle R/WO */
>                   break;
>               case HOST_CTL: /* R/W */
>                   if (val & HOST_CTL_RESET) {
> -                    DPRINTF(-1, "HBA Reset\n");
>                       ahci_reset(s);
>                   } else {
>                       s->control_regs.ghc = (val & 0x3) | HOST_CTL_AHCI_EN;
> @@ -427,7 +421,7 @@ static void ahci_mem_write(void *opaque, hwaddr addr,
>                   /* FIXME report write? */
>                   break;
>               default:
> -                DPRINTF(-1, "write to unknown register 0x%x\n", (unsigned)addr);
> +                trace_ahci_mem_write_unknown(s, size, addr, val);
>           }
>       } else if ((addr >= AHCI_PORT_REGS_START_ADDR) &&
>                  (addr < (AHCI_PORT_REGS_START_ADDR +
> @@ -559,7 +553,8 @@ static void ahci_set_signature(AHCIDevice *ad, uint32_t sig)
>       s->sector = sig >> 8 & 0xFF;
>       s->nsector = sig & 0xFF;
>   
> -    DPRINTF(ad->port_no, "set hcyl:lcyl:sect:nsect = 0x%08x\n", sig);
> +    trace_ahci_set_signature(ad->hba, ad->port_no, s->nsector, s->sector,
> +                             s->lcyl, s->hcyl, sig);
>   }
>   
>   static void ahci_reset_port(AHCIState *s, int port)
> @@ -569,7 +564,7 @@ static void ahci_reset_port(AHCIState *s, int port)
>       IDEState *ide_state = &d->port.ifs[0];
>       int i;
>   
> -    DPRINTF(port, "reset port\n");
> +    trace_ahci_reset_port(s, port);
>   
>       ide_bus_reset(&d->port);
>       ide_state->ncq_queues = AHCI_MAX_CMDS;
> @@ -655,7 +650,7 @@ static bool ahci_map_fis_address(AHCIDevice *ad)
>   static void ahci_unmap_fis_address(AHCIDevice *ad)
>   {
>       if (ad->res_fis == NULL) {
> -        DPRINTF(ad->port_no, "Attempt to unmap NULL FIS address\n");
> +        trace_ahci_unmap_fis_address_null(ad->hba, ad->port_no);
>           return;
>       }
>       ad->port_regs.cmd &= ~PORT_CMD_FIS_ON;
> @@ -682,7 +677,7 @@ static bool ahci_map_clb_address(AHCIDevice *ad)
>   static void ahci_unmap_clb_address(AHCIDevice *ad)
>   {
>       if (ad->lst == NULL) {
> -        DPRINTF(ad->port_no, "Attempt to unmap NULL CLB address\n");
> +        trace_ahci_unmap_clb_address_null(ad->hba, ad->port_no);
>           return;
>       }
>       ad->port_regs.cmd &= ~PORT_CMD_LIST_ON;
> @@ -854,20 +849,22 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist,
>       IDEBus *bus = &ad->port;
>       BusState *qbus = BUS(bus);
>   
> +    trace_ahci_populate_sglist(ad->hba, ad->port_no);
> +
>       if (!prdtl) {
> -        DPRINTF(ad->port_no, "no sg list given by guest: 0x%08x\n", opts);
> +        trace_ahci_populate_sglist_no_prdtl(ad->hba, ad->port_no, opts);
>           return -1;
>       }
>   
>       /* map PRDT */
>       if (!(prdt = dma_memory_map(ad->hba->as, prdt_addr, &prdt_len,
>                                   DMA_DIRECTION_TO_DEVICE))){
> -        DPRINTF(ad->port_no, "map failed\n");
> +        trace_ahci_populate_sglist_no_map(ad->hba, ad->port_no);
>           return -1;
>       }
>   
>       if (prdt_len < real_prdt_len) {
> -        DPRINTF(ad->port_no, "mapped less than expected\n");
> +        trace_ahci_populate_sglist_short_map(ad->hba, ad->port_no);
>           r = -1;
>           goto out;
>       }
> @@ -886,9 +883,8 @@ static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist,
>               sum += tbl_entry_size;
>           }
>           if ((off_idx == -1) || (off_pos < 0) || (off_pos > tbl_entry_size)) {
> -            DPRINTF(ad->port_no, "%s: Incorrect offset! "
> -                            "off_idx: %d, off_pos: %"PRId64"\n",
> -                            __func__, off_idx, off_pos);
> +            trace_ahci_populate_sglist_bad_offset(ad->hba, ad->port_no,
> +                                                  off_idx, off_pos);
>               r = -1;
>               goto out;
>           }
> @@ -934,8 +930,8 @@ static void ncq_finish(NCQTransferState *ncq_tfs)
>   
>       ahci_write_fis_sdb(ncq_tfs->drive->hba, ncq_tfs);
>   
> -    DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n",
> -            ncq_tfs->tag);
> +    trace_ncq_finish(ncq_tfs->drive->hba, ncq_tfs->drive->port_no,
> +                     ncq_tfs->tag);
>   
>       block_acct_done(blk_get_stats(ncq_tfs->drive->port.ifs[0].blk),
>                       &ncq_tfs->acct);
> @@ -999,12 +995,8 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
>   
>       switch (ncq_tfs->cmd) {
>       case READ_FPDMA_QUEUED:
> -        DPRINTF(port, "NCQ reading %d sectors from LBA %"PRId64", tag %d\n",
> -                ncq_tfs->sector_count, ncq_tfs->lba, ncq_tfs->tag);
> -
> -        DPRINTF(port, "tag %d aio read %"PRId64"\n",
> -                ncq_tfs->tag, ncq_tfs->lba);
> -
> +        trace_execute_ncq_command_read(ad->hba, port, ncq_tfs->tag,
> +                                       ncq_tfs->sector_count, ncq_tfs->lba);
>           dma_acct_start(ide_state->blk, &ncq_tfs->acct,
>                          &ncq_tfs->sglist, BLOCK_ACCT_READ);
>           ncq_tfs->aiocb = dma_blk_read(ide_state->blk, &ncq_tfs->sglist,
> @@ -1013,12 +1005,8 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
>                                         ncq_cb, ncq_tfs);
>           break;
>       case WRITE_FPDMA_QUEUED:
> -        DPRINTF(port, "NCQ writing %d sectors to LBA %"PRId64", tag %d\n",
> -                ncq_tfs->sector_count, ncq_tfs->lba, ncq_tfs->tag);
> -
> -        DPRINTF(port, "tag %d aio write %"PRId64"\n",
> -                ncq_tfs->tag, ncq_tfs->lba);
> -
> +        trace_execute_ncq_command_read(ad->hba, port, ncq_tfs->tag,
> +                                       ncq_tfs->sector_count, ncq_tfs->lba);
>           dma_acct_start(ide_state->blk, &ncq_tfs->acct,
>                          &ncq_tfs->sglist, BLOCK_ACCT_WRITE);
>           ncq_tfs->aiocb = dma_blk_write(ide_state->blk, &ncq_tfs->sglist,
> @@ -1027,8 +1015,8 @@ static void execute_ncq_command(NCQTransferState *ncq_tfs)
>                                          ncq_cb, ncq_tfs);
>           break;
>       default:
> -        DPRINTF(port, "error: unsupported NCQ command (0x%02x) received\n",
> -                ncq_tfs->cmd);
> +        trace_execute_ncq_command_unsup(ad->hba, port,
> +                                        ncq_tfs->tag, ncq_tfs->cmd);
>           ncq_err(ncq_tfs);
>       }
>   }
> @@ -1038,7 +1026,6 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
>                                   uint8_t slot)
>   {
>       AHCIDevice *ad = &s->dev[port];
> -    IDEState *ide_state = &ad->port.ifs[0];
>       NCQFrame *ncq_fis = (NCQFrame*)cmd_fis;
>       uint8_t tag = ncq_fis->tag >> 3;
>       NCQTransferState *ncq_tfs = &ad->ncq_tfs[tag];
> @@ -1066,21 +1053,20 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
>   
>       /* Sanity-check the NCQ packet */
>       if (tag != slot) {
> -        DPRINTF(port, "Warn: NCQ slot (%d) did not match the given tag (%d)\n",
> -                slot, tag);
> +        trace_process_ncq_command_mismatch(s, port, tag, slot);
>       }
>   
>       if (ncq_fis->aux0 || ncq_fis->aux1 || ncq_fis->aux2 || ncq_fis->aux3) {
> -        DPRINTF(port, "Warn: Attempt to use NCQ auxiliary fields.\n");
> +        trace_process_ncq_command_aux(s, port, tag);
>       }
>       if (ncq_fis->prio || ncq_fis->icc) {
> -        DPRINTF(port, "Warn: Unsupported attempt to use PRIO/ICC fields\n");
> +        trace_process_ncq_command_prioicc(s, port, tag);
>       }
>       if (ncq_fis->fua & NCQ_FIS_FUA_MASK) {
> -        DPRINTF(port, "Warn: Unsupported attempt to use Force Unit Access\n");
> +        trace_process_ncq_command_fua(s, port, tag);
>       }
>       if (ncq_fis->tag & NCQ_FIS_RARC_MASK) {
> -        DPRINTF(port, "Warn: Unsupported attempt to use Rebuild Assist\n");
> +        trace_process_ncq_command_rarc(s, port, tag);
>       }
>   
>       ncq_tfs->sector_count = ((ncq_fis->sector_count_high << 8) |
> @@ -1099,16 +1085,14 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
>           ahci_trigger_irq(ad->hba, ad, PORT_IRQ_OVERFLOW);
>           return;
>       } else if (ncq_tfs->sglist.size != size) {
> -        DPRINTF(port, "Warn: PRDTL (0x%zx)"
> -                " does not match requested size (0x%zx)",
> -                ncq_tfs->sglist.size, size);
> +        trace_process_ncq_command_large(s, port, tag,
> +                                        ncq_tfs->sglist.size, size);
>       }
>   
> -    DPRINTF(port, "NCQ transfer LBA from %"PRId64" to %"PRId64", "
> -            "drive max %"PRId64"\n",
> -            ncq_tfs->lba, ncq_tfs->lba + ncq_tfs->sector_count - 1,
> -            ide_state->nb_sectors - 1);
> -
> +    trace_process_ncq_command(s, port, tag,
> +                              ncq_fis->command,
> +                              ncq_tfs->lba,
> +                              ncq_tfs->lba + ncq_tfs->sector_count - 1);
>       execute_ncq_command(ncq_tfs);
>   }
>   
> @@ -1129,16 +1113,14 @@ static void handle_reg_h2d_fis(AHCIState *s, int port,
>       uint16_t opts = le16_to_cpu(cmd->opts);
>   
>       if (cmd_fis[1] & 0x0F) {
> -        DPRINTF(port, "Port Multiplier not supported."
> -                " cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
> -                cmd_fis[0], cmd_fis[1], cmd_fis[2]);
> +        trace_handle_reg_h2d_fis_pmp(s, port, cmd_fis[1],
> +                                     cmd_fis[2], cmd_fis[3]);
>           return;
>       }
>   
>       if (cmd_fis[1] & 0x70) {
> -        DPRINTF(port, "Reserved flags set in H2D Register FIS."
> -                " cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
> -                cmd_fis[0], cmd_fis[1], cmd_fis[2]);
> +        trace_handle_reg_h2d_fis_res(s, port, cmd_fis[1],
> +                                     cmd_fis[2], cmd_fis[3]);
>           return;
>       }
>   
> @@ -1216,12 +1198,12 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
>   
>       if (s->dev[port].port.ifs[0].status & (BUSY_STAT|DRQ_STAT)) {
>           /* Engine currently busy, try again later */
> -        DPRINTF(port, "engine busy\n");
> +        trace_handle_cmd_busy(s, port);
>           return -1;
>       }
>   
>       if (!s->dev[port].lst) {
> -        DPRINTF(port, "error: lst not given but cmd handled");
> +        trace_handle_cmd_nolist(s, port);
>           return -1;
>       }
>       cmd = get_cmd_header(s, port, slot);
> @@ -1231,7 +1213,7 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
>       /* The device we are working for */
>       ide_state = &s->dev[port].port.ifs[0];
>       if (!ide_state->blk) {
> -        DPRINTF(port, "error: guest accessed unused port");
> +        trace_handle_cmd_badport(s, port);
>           return -1;
>       }
>   
> @@ -1240,13 +1222,11 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
>       cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
>                                DMA_DIRECTION_FROM_DEVICE);
>       if (!cmd_fis) {
> -        DPRINTF(port, "error: guest passed us an invalid cmd fis\n");
> +        trace_handle_cmd_badfis(s, port);
>           return -1;
>       } else if (cmd_len != 0x80) {
>           ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_HBUS_ERR);
> -        DPRINTF(port, "error: dma_memory_map failed: "
> -                "(len(%02"PRIx64") != 0x80)\n",
> -                cmd_len);
> +        trace_handle_cmd_badmap(s, port, cmd_len);
>           goto out;
>       }
>       debug_print_fis(cmd_fis, 0x80);
> @@ -1256,9 +1236,8 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
>               handle_reg_h2d_fis(s, port, slot, cmd_fis);
>               break;
>           default:
> -            DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
> -                          "cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
> -                          cmd_fis[2]);
> +            trace_handle_cmd_unhandled_fis(s, port,
> +                                           cmd_fis[0], cmd_fis[1], cmd_fis[2]);
>               break;
>       }
>   
> @@ -1299,9 +1278,9 @@ static void ahci_start_transfer(IDEDMA *dma)
>           has_sglist = 1;
>       }
>   
> -    DPRINTF(ad->port_no, "%sing %d bytes on %s w/%s sglist\n",
> -            is_write ? "writ" : "read", size, is_atapi ? "atapi" : "ata",
> -            has_sglist ? "" : "o");
> +    trace_ahci_start_transfer(ad->hba, ad->port_no, is_write ? "writ" : "read",
> +                              size, is_atapi ? "atapi" : "ata",
> +                              has_sglist ? "" : "o");
>   
>       if (has_sglist && size) {
>           if (is_write) {
> @@ -1330,7 +1309,7 @@ static void ahci_start_dma(IDEDMA *dma, IDEState *s,
>                              BlockCompletionFunc *dma_cb)
>   {
>       AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
> -    DPRINTF(ad->port_no, "\n");
> +    trace_ahci_start_dma(ad->hba, ad->port_no);
>       s->io_buffer_offset = 0;
>       dma_cb(s, 0);
>   }
> @@ -1368,12 +1347,12 @@ static int32_t ahci_dma_prepare_buf(IDEDMA *dma, int32_t limit)
>   
>       if (ahci_populate_sglist(ad, &s->sg, ad->cur_cmd,
>                                limit, s->io_buffer_offset) == -1) {
> -        DPRINTF(ad->port_no, "ahci_dma_prepare_buf failed.\n");
> +        trace_ahci_dma_prepare_buf_fail(ad->hba, ad->port_no);
>           return -1;
>       }
>       s->io_buffer_size = s->sg.size;
>   
> -    DPRINTF(ad->port_no, "len=%#x\n", s->io_buffer_size);
> +    trace_ahci_dma_prepare_buf(ad->hba, ad->port_no, limit, s->io_buffer_size);
>       return s->io_buffer_size;
>   }
>   
> @@ -1409,11 +1388,9 @@ static int ahci_dma_rw_buf(IDEDMA *dma, int is_write)
>   
>       /* free sglist, update byte count */
>       dma_buf_commit(s, l);
> -
>       s->io_buffer_index += l;
>   
> -    DPRINTF(ad->port_no, "len=%#x\n", l);
> -
> +    trace_ahci_dma_rw_buf(ad->hba, ad->port_no, l);
>       return 1;
>   }
>   
> @@ -1421,7 +1398,7 @@ static void ahci_cmd_done(IDEDMA *dma)
>   {
>       AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
>   
> -    DPRINTF(ad->port_no, "cmd done\n");
> +    trace_ahci_cmd_done(ad->hba, ad->port_no);
>   
>       /* update d2h status */
>       ahci_write_fis_d2h(ad);
> @@ -1505,6 +1482,8 @@ void ahci_reset(AHCIState *s)
>       AHCIPortRegs *pr;
>       int i;
>   
> +    trace_ahci_reset(s);
> +
>       s->control_regs.irqstatus = 0;
>       /* AHCI Enable (AE)
>        * The implementation of this bit is dependent upon the value of the
> @@ -1755,6 +1734,7 @@ static uint64_t allwinner_ahci_mem_read(void *opaque, hwaddr addr,
>                                           unsigned size)
>   {
>       AllwinnerAHCIState *a = opaque;
> +    AHCIState *s = &(SYSBUS_AHCI(a)->ahci);
>       uint64_t val = a->regs[addr/4];
>   
>       switch (addr / 4) {
> @@ -1765,8 +1745,7 @@ static uint64_t allwinner_ahci_mem_read(void *opaque, hwaddr addr,
>           val &= ~(0x1 << 24);
>           break;
>       }
> -    DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
> -            addr, val, size);
> +    trace_allwinner_ahci_mem_read(s, a, addr, val, size);
>       return  val;
>   }
>   
> @@ -1774,9 +1753,9 @@ static void allwinner_ahci_mem_write(void *opaque, hwaddr addr,
>                                        uint64_t val, unsigned size)
>   {
>       AllwinnerAHCIState *a = opaque;
> +    AHCIState *s = &(SYSBUS_AHCI(a)->ahci);
>   
> -    DPRINTF(-1, "addr=0x%" HWADDR_PRIx " val=0x%" PRIx64 ", size=%d\n",
> -            addr, val, size);
> +    trace_allwinner_ahci_mem_write(s, a, addr, val, size);
>       a->regs[addr/4] = val;
>   }
>   
> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
> index cc8949c..0b61c5d 100644
> --- a/hw/ide/trace-events
> +++ b/hw/ide/trace-events
> @@ -56,3 +56,52 @@ ide_atapi_cmd(void *s, uint8_t cmd) "IDEState: %p; cmd: 0x%02x"
>   ide_atapi_cmd_read_dma_cb_aio(void *s, int lba, int n) "IDEState: %p; aio read: lba=%d n=%d"
>   # Warning: Verbose
>   ide_atapi_cmd_packet(void *s, uint16_t limit, const char *packet) "IDEState: %p; limit=0x%x packet: %s"
> +
> +# hw/ide/ahci.c
> +ahci_port_read(void *s, int port, int offset, uint32_t ret) "ahci(%p)[%d]: port read @ 0x%x: 0x%08x"
> +ahci_irq_raise(void *s) "ahci(%p): raise irq"
> +ahci_irq_lower(void *s) "ahci(%p): lower irq"
> +ahci_check_irq(void *s, uint32_t old, uint32_t new) "ahci(%p): check irq 0x%08x --> 0x%08x"
> +
> +ahci_port_write(void *s, int port, int offset, uint32_t val) "ahci(%p)[%d]: port write @ 0x%x: 0x%08x"
> +ahci_mem_read_32(void *s, uint64_t addr, uint32_t val) "ahci(%p): mem read @ 0x%"PRIx64": 0x%08x"
> +ahci_mem_read(void *s, unsigned size, uint64_t addr, uint64_t val) "ahci(%p): read%u @ 0x%"PRIx64": 0x%016"PRIx64
> +ahci_mem_write(void *s, unsigned size, uint64_t addr, uint64_t val) "ahci(%p): write%u @ 0x%"PRIx64": 0x%016"PRIx64
> +ahci_mem_write_unknown(void *s, unsigned size, uint64_t addr, uint64_t val) "ahci(%p): write%u to unknown register 0x%"PRIx64": 0x%016"PRIx64
> +ahci_set_signature(void *s, int port, uint8_t nsector, uint8_t sector, uint8_t lcyl, uint8_t hcyl, uint32_t sig) "ahci(%p)[%d]: set signature sector:0x%02x nsector:0x%02x lcyl:0x%02x hcyl:0x%02x (cumulatively: 0x%08x)"
> +ahci_reset_port(void *s, int port) "ahci(%p)[%d]: reset port"
> +ahci_unmap_fis_address_null(void *s, int port) "ahci(%p)[%d]: Attempt to unmap NULL FIS address"
> +ahci_unmap_clb_address_null(void *s, int port) "ahci(%p)[%d]: Attempt to unmap NULL CLB address"
> +ahci_populate_sglist(void *s, int port) "ahci(%p)[%d]"
> +ahci_populate_sglist_no_prdtl(void *s, int port, uint16_t opts) "ahci(%p)[%d]: no sg list given by guest: 0x%04x"
> +ahci_populate_sglist_no_map(void *s, int port) "ahci(%p)[%d]: DMA mapping failed"
> +ahci_populate_sglist_short_map(void *s, int port) "ahci(%p)[%d]: mapped less than expected"
> +ahci_populate_sglist_bad_offset(void *s, int port, int off_idx, int64_t off_pos) "ahci(%p)[%d]: Incorrect offset! off_idx: %d, off_pos: %"PRId64
> +ncq_finish(void *s, int port, uint8_t tag) "ahci(%p)[%d][tag:%d]: NCQ transfer finished"
> +execute_ncq_command_read(void *s, int port, uint8_t tag, int count, int64_t lba) "ahci(%p)[%d][tag:%d]: NCQ reading %d sectors from LBA %"PRId64
> +execute_ncq_command_write(void *s, int port, uint8_t tag, int count, int64_t lba) "ahci(%p)[%d][tag:%d]: NCQ writing %d sectors to LBA %"PRId64
> +execute_ncq_command_unsup(void *s, int port, uint8_t tag, uint8_t cmd) "ahci(%p)[%d][tag:%d]: error: unsupported NCQ command (0x%02x) received"
> +process_ncq_command_mismatch(void *s, int port, uint8_t tag, uint8_t slot) "ahci(%p)[%d][tag:%d]: Warning: NCQ slot (%d) did not match the given tag"
> +process_ncq_command_aux(void *s, int port, uint8_t tag) "ahci(%p)[%d][tag:%d]: Warn: Attempt to use NCQ auxiliary fields"
> +process_ncq_command_prioicc(void *s, int port, uint8_t tag) "ahci(%p)[%d][tag:%d]: Warn: Unsupported attempt to use PRIO/ICC fields"
> +process_ncq_command_fua(void *s, int port, uint8_t tag) "ahci(%p)[%d][tag:%d]: Warn: Unsupported attempt to use Force Unit Access"
> +process_ncq_command_rarc(void *s, int port, uint8_t tag) "ahci(%p)[%d][tag:%d]: Warn: Unsupported attempt to use Rebuild Assist"
> +process_ncq_command_large(void *s, int port, uint8_t tag, size_t prdtl, size_t size) "ahci(%p)[%d][tag:%d]: Warn: PRDTL (0x%zx) does not match requested size (0x%zx)"
> +process_ncq_command(void *s, int port, uint8_t tag, uint8_t cmd, uint64_t lba, uint64_t end) "ahci(%p)[%d][tag:%d]: NCQ op 0x%02x on sectors [%"PRId64",%"PRId64"]"
> +handle_reg_h2d_fis_pmp(void *s, int port, char b0, char b1, char b2) "ahci(%p)[%d]: Port Multiplier not supported, FIS: 0x%02x-%02x-%02x"
> +handle_reg_h2d_fis_res(void *s, int port, char b0, char b1, char b2) "ahci(%p)[%d]: Reserved flags set in H2D Register FIS, FIS: 0x%02x-%02x-%02x"
> +handle_cmd_busy(void *s, int port) "ahci(%p)[%d]: engine busy"
> +handle_cmd_nolist(void *s, int port) "ahci(%p)[%d]: handle_cmd called without s->dev[port].lst"
> +handle_cmd_badport(void *s, int port) "ahci(%p)[%d]: guest accessed unused port"
> +handle_cmd_badfis(void *s, int port) "ahci(%p)[%d]: guest provided an invalid cmd FIS"
> +handle_cmd_badmap(void *s, int port, uint64_t len) "ahci(%p)[%d]: dma_memory_map failed, 0x%02"PRIx64" != 0x80"
> +handle_cmd_unhandled_fis(void *s, int port, uint8_t b0, uint8_t b1, uint8_t b2) "ahci(%p)[%d]: unhandled FIS type. cmd_fis: 0x%02x-%02x-%02x"
> +ahci_start_transfer(void *s, int port, const char *rw, uint32_t size, const char *tgt, const char *sgl) "ahci(%p)[%d]: %sing %d bytes on %s w/%s sglist"
> +ahci_start_dma(void *s, int port) "ahci(%p)[%d]: start dma"
> +ahci_dma_prepare_buf(void *s, int port, int32_t io_buffer_size, int32_t limit) "ahci(%p)[%d]: prepare buf limit=%"PRId32" prepared=%"PRId32
> +ahci_dma_prepare_buf_fail(void *s, int port) "ahci(%p)[%d]: sglist population failed"
> +ahci_dma_rw_buf(void *s, int port, int l) "ahci(%p)[%d] len=0x%x"
> +ahci_cmd_done(void *s, int port) "ahci(%p)[%d]: cmd done"
> +ahci_reset(void *s) "ahci(%p): HBA reset"
> +allwinner_ahci_mem_read(void *s, void *a, uint64_t addr, uint64_t val, unsigned size) "ahci(%p): read a=%p addr=0x%"HWADDR_PRIx" val=0x%"PRIx64", size=%d"
> +allwinner_ahci_mem_write(void *s, void *a, uint64_t addr, uint64_t val, unsigned size) "ahci(%p): write a=%p addr=0x%"HWADDR_PRIx" val=0x%"PRIx64", size=%d"
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 9/9] AHCI: remove DPRINTF macro
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 9/9] AHCI: remove DPRINTF macro John Snow
@ 2017-08-29 22:24   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-08-29 22:24 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: eblake, qemu-devel

On 08/29/2017 05:49 PM, John Snow wrote:
> Signed-off-by: John Snow <jsnow@redhat.com>

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> ---
>   hw/ide/ahci.c | 9 ---------
>   1 file changed, 9 deletions(-)
> 
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index 2e75f9b..57bb59d 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -34,17 +34,8 @@
>   #include "hw/ide/pci.h"
>   #include "hw/ide/ahci_internal.h"
>   
> -#define DEBUG_AHCI 0
>   #include "trace.h"
>   
> -#define DPRINTF(port, fmt, ...) \
> -do { \
> -    if (DEBUG_AHCI) { \
> -        fprintf(stderr, "ahci: %s: [%d] ", __func__, port); \
> -        fprintf(stderr, fmt, ## __VA_ARGS__); \
> -    } \
> -} while (0)
> -
>   static void check_cmd(AHCIState *s, int port);
>   static int handle_cmd(AHCIState *s, int port, uint8_t slot);
>   static void ahci_reset_port(AHCIState *s, int port);
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 5/9] IDE: replace DEBUG_AIO with trace events
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 5/9] IDE: replace DEBUG_AIO with trace events John Snow
@ 2017-08-30  3:14   ` Philippe Mathieu-Daudé
  2017-08-30 23:25     ` John Snow
  0 siblings, 1 reply; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-08-30  3:14 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: eblake, qemu-devel

Hi John,

On 08/29/2017 05:49 PM, John Snow wrote:
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   hw/ide/atapi.c            |  5 +----
>   hw/ide/core.c             | 17 ++++++++++-------
>   hw/ide/trace-events       |  3 +++
>   include/hw/ide/internal.h |  6 ++++--
>   4 files changed, 18 insertions(+), 13 deletions(-)
> 
> diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
> index 37fa699..b8fc51e 100644
> --- a/hw/ide/atapi.c
> +++ b/hw/ide/atapi.c
> @@ -416,10 +416,7 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
>           s->io_buffer_size = n * 2048;
>           data_offset = 0;
>       }
> -#ifdef DEBUG_AIO
> -    printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
> -#endif
> -
> +    trace_ide_atapi_cmd_read_dma_cb_aio(s, s->lba, n);
>       s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
>       s->bus->dma->iov.iov_len = n * ATAPI_SECTOR_SIZE;
>       qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
> diff --git a/hw/ide/core.c b/hw/ide/core.c
> index 82a19b1..a1c90e9 100644
> --- a/hw/ide/core.c
> +++ b/hw/ide/core.c
> @@ -58,6 +58,13 @@ static const int smart_attributes[][12] = {
>       { 190,  0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x32},
>   };
>   
> +const char *IDE_DMA_CMD_lookup[IDE_DMA__COUNT] = {
> +    [IDE_DMA_READ] = "DMA READ",
> +    [IDE_DMA_WRITE] = "DMA WRITE",
> +    [IDE_DMA_TRIM] = "DMA TRIM",
> +    [IDE_DMA_ATAPI] = "DMA ATAPI"
> +};
> +
>   static void ide_dummy_transfer_stop(IDEState *s);
>   
>   static void padstr(char *str, const char *src, int len)
> @@ -860,10 +867,8 @@ static void ide_dma_cb(void *opaque, int ret)
>           goto eot;
>       }
>   
> -#ifdef DEBUG_AIO
> -    printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, cmd_cmd=%d\n",
> -           sector_num, n, s->dma_cmd);
> -#endif
> +    trace_ide_dma_cb(s, sector_num, n,
> +                     IDE_DMA_CMD_lookup[s->dma_cmd]);
>   
>       if ((s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) &&
>           !ide_sect_range_ok(s, sector_num, n)) {
> @@ -2391,9 +2396,7 @@ void ide_bus_reset(IDEBus *bus)
>   
>       /* pending async DMA */
>       if (bus->dma->aiocb) {
> -#ifdef DEBUG_AIO
> -        printf("aio_cancel\n");
> -#endif
> +        trace_ide_bus_reset_aio();
>           blk_aio_cancel(bus->dma->aiocb);
>           bus->dma->aiocb = NULL;
>       }
> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
> index 8c79a6c..cc8949c 100644
> --- a/hw/ide/trace-events
> +++ b/hw/ide/trace-events
> @@ -18,6 +18,8 @@ ide_cancel_dma_sync_remaining(void) "draining all remaining requests"
>   ide_sector_read(int64_t sector_num, int nsectors) "sector=%"PRId64" nsectors=%d"
>   ide_sector_write(int64_t sector_num, int nsectors) "sector=%"PRId64" nsectors=%d"
>   ide_reset(void *s) "IDEstate %p"
> +ide_bus_reset_aio(void) "aio_cancel"
> +ide_dma_cb(void *s, int64_t sector_num, int n, const char *dma) "IDEState %p; sector_num=%"PRId64" n=%d cmd=%s"
>   
>   # BMDMA HBAs:
>   
> @@ -51,5 +53,6 @@ ide_atapi_cmd_reply_end_new(void *s, int status) "IDEState: %p; new transfer sta
>   ide_atapi_cmd_check_status(void *s) "IDEState: %p"
>   ide_atapi_cmd_read(void *s, const char *method, int lba, int nb_sectors) "IDEState: %p; read %s: LBA=%d nb_sectors=%d"
>   ide_atapi_cmd(void *s, uint8_t cmd) "IDEState: %p; cmd: 0x%02x"
> +ide_atapi_cmd_read_dma_cb_aio(void *s, int lba, int n) "IDEState: %p; aio read: lba=%d n=%d"
>   # Warning: Verbose
>   ide_atapi_cmd_packet(void *s, uint16_t limit, const char *packet) "IDEState: %p; limit=0x%x packet: %s"
> diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
> index 74efe8a..db9fde0 100644
> --- a/include/hw/ide/internal.h
> +++ b/include/hw/ide/internal.h
> @@ -14,7 +14,6 @@
>   #include "block/scsi.h"
>   
>   /* debug IDE devices */
> -//#define DEBUG_AIO
>   #define USE_DMA_CDROM
>   
>   typedef struct IDEBus IDEBus;
> @@ -333,12 +332,15 @@ struct unreported_events {
>   };
>   
>   enum ide_dma_cmd {
> -    IDE_DMA_READ,
> +    IDE_DMA_READ = 0,
>       IDE_DMA_WRITE,
>       IDE_DMA_TRIM,
>       IDE_DMA_ATAPI,
> +    IDE_DMA__COUNT
>   };
>   
> +extern const char *IDE_DMA_CMD_lookup[IDE_DMA__COUNT];

I recommend you to avoid this declaring extern const array with size, I 
remember some compilers (old GCC?) ignoring array size in extern. Eric 
will correct me!

It is much safer to use a getter:

const char *IDE_DMA_CMD_lookup(enum ide_dma_cmd cmd)
{
     static const char *IDE_DMA_CMD_name[IDE_DMA__COUNT] = {
         [IDE_DMA_READ] = "DMA READ",
         [IDE_DMA_WRITE] = "DMA WRITE",
         [IDE_DMA_TRIM] = "DMA TRIM",
         [IDE_DMA_ATAPI] = "DMA ATAPI"
     };

     return IDE_DMA_CMD_name[cmd];
};

If you agree:
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> +
>   #define ide_cmd_is_read(s) \
>   	((s)->dma_cmd == IDE_DMA_READ)
>   
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] AHCI: Rework IRQ constants
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 7/9] AHCI: Rework IRQ constants John Snow
@ 2017-08-30  3:54   ` Philippe Mathieu-Daudé
  2017-08-30 23:28     ` John Snow
  0 siblings, 1 reply; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2017-08-30  3:54 UTC (permalink / raw)
  To: John Snow, qemu-block; +Cc: eblake, qemu-devel

On 08/29/2017 05:49 PM, John Snow wrote:
> Create a new enum so that we can name the IRQ bits, which will make debugging
> them a little nicer if we can print them out. Not handled in this patch, but
> this will make it possible to get a nice debug printf detailing exactly which
> status bits are set, as it can be multiple at any given time.
> 
> As a consequence of this patch, it is no longer possible to set multiple IRQ
> codes at once, but nothing was utilizing this ability anyway.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>   hw/ide/ahci.c          | 49 ++++++++++++++++++++++++++++++++++++++-----------
>   hw/ide/ahci_internal.h | 44 +++++++++++++++++++++++++++++++++++---------
>   hw/ide/trace-events    |  2 +-
>   3 files changed, 74 insertions(+), 21 deletions(-)
> 
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index c60a000..a0a4dd6 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -56,6 +56,27 @@ static bool ahci_map_fis_address(AHCIDevice *ad);
>   static void ahci_unmap_clb_address(AHCIDevice *ad);
>   static void ahci_unmap_fis_address(AHCIDevice *ad);
>   
> +static const char *AHCIPortIRQ_lookup[AHCI_PORT_IRQ__END] = {
> +    [AHCI_PORT_IRQ_BIT_DHRS] = "DHRS",
> +    [AHCI_PORT_IRQ_BIT_PSS]  = "PSS",
> +    [AHCI_PORT_IRQ_BIT_DSS]  = "DSS",
> +    [AHCI_PORT_IRQ_BIT_SDBS] = "SDBS",
> +    [AHCI_PORT_IRQ_BIT_UFS]  = "UFS",
> +    [AHCI_PORT_IRQ_BIT_DPS]  = "DPS",
> +    [AHCI_PORT_IRQ_BIT_PCS]  = "PCS",
> +    [AHCI_PORT_IRQ_BIT_DMPS] = "DMPS",
> +    [8 ... 21]               = "RESERVED",
> +    [AHCI_PORT_IRQ_BIT_PRCS] = "PRCS",
> +    [AHCI_PORT_IRQ_BIT_IPMS] = "IPMS",
> +    [AHCI_PORT_IRQ_BIT_OFS]  = "OFS",
> +    [25]                     = "RESERVED",
> +    [AHCI_PORT_IRQ_BIT_INFS] = "INFS",
> +    [AHCI_PORT_IRQ_BIT_IFS]  = "IFS",
> +    [AHCI_PORT_IRQ_BIT_HBDS] = "HBDS",
> +    [AHCI_PORT_IRQ_BIT_HBFS] = "HBFS",
> +    [AHCI_PORT_IRQ_BIT_TFES] = "TFES",
> +    [AHCI_PORT_IRQ_BIT_CPDS] = "CPDS"
> +};
>   
>   static uint32_t  ahci_port_read(AHCIState *s, int port, int offset)
>   {
> @@ -170,12 +191,18 @@ static void ahci_check_irq(AHCIState *s)
>   }
>   
>   static void ahci_trigger_irq(AHCIState *s, AHCIDevice *d,
> -                             int irq_type)
> +                             enum AHCIPortIRQ irqbit)
>   {
> -    DPRINTF(d->port_no, "trigger irq %#x -> %x\n",
> -            irq_type, d->port_regs.irq_mask & irq_type);
> +    g_assert(irqbit >= 0 && irqbit < 32);

I still think this assert is superfluous, anyway (and having hard time 
reading C99 statement before declarations - I need to grow):

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> +    uint32_t irq = 1U << irqbit;
> +    uint32_t irqstat = d->port_regs.irq_stat | irq;
>   
> -    d->port_regs.irq_stat |= irq_type;
> +    trace_ahci_trigger_irq(s, d->port_no,
> +                           AHCIPortIRQ_lookup[irqbit], irq,
> +                           d->port_regs.irq_stat, irqstat,
> +                           irqstat & d->port_regs.irq_mask);
> +
> +    d->port_regs.irq_stat = irqstat;
>       ahci_check_irq(s);
>   }
>   
> @@ -718,7 +745,7 @@ static void ahci_write_fis_sdb(AHCIState *s, NCQTransferState *ncq_tfs)
>   
>       /* Trigger IRQ if interrupt bit is set (which currently, it always is) */
>       if (sdb_fis->flags & 0x40) {
> -        ahci_trigger_irq(s, ad, PORT_IRQ_SDB_FIS);
> +        ahci_trigger_irq(s, ad, AHCI_PORT_IRQ_BIT_SDBS);
>       }
>   }
>   
> @@ -761,10 +788,10 @@ static void ahci_write_fis_pio(AHCIDevice *ad, uint16_t len)
>           ad->port.ifs[0].status;
>   
>       if (pio_fis[2] & ERR_STAT) {
> -        ahci_trigger_irq(ad->hba, ad, PORT_IRQ_TF_ERR);
> +        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES);
>       }
>   
> -    ahci_trigger_irq(ad->hba, ad, PORT_IRQ_PIOS_FIS);
> +    ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_PSS);
>   }
>   
>   static bool ahci_write_fis_d2h(AHCIDevice *ad)
> @@ -804,10 +831,10 @@ static bool ahci_write_fis_d2h(AHCIDevice *ad)
>           ad->port.ifs[0].status;
>   
>       if (d2h_fis[2] & ERR_STAT) {
> -        ahci_trigger_irq(ad->hba, ad, PORT_IRQ_TF_ERR);
> +        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_TFES);
>       }
>   
> -    ahci_trigger_irq(ad->hba, ad, PORT_IRQ_D2H_REG_FIS);
> +    ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_DHRS);
>       return true;
>   }
>   
> @@ -1082,7 +1109,7 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
>                        "is smaller than the requested size (0x%zx)",
>                        ncq_tfs->sglist.size, size);
>           ncq_err(ncq_tfs);
> -        ahci_trigger_irq(ad->hba, ad, PORT_IRQ_OVERFLOW);
> +        ahci_trigger_irq(ad->hba, ad, AHCI_PORT_IRQ_BIT_OFS);
>           return;
>       } else if (ncq_tfs->sglist.size != size) {
>           trace_process_ncq_command_large(s, port, tag,
> @@ -1225,7 +1252,7 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
>           trace_handle_cmd_badfis(s, port);
>           return -1;
>       } else if (cmd_len != 0x80) {
> -        ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_HBUS_ERR);
> +        ahci_trigger_irq(s, &s->dev[port], AHCI_PORT_IRQ_BIT_HBFS);
>           trace_handle_cmd_badmap(s, port, cmd_len);
>           goto out;
>       }
> diff --git a/hw/ide/ahci_internal.h b/hw/ide/ahci_internal.h
> index 1e21169..7e67add 100644
> --- a/hw/ide/ahci_internal.h
> +++ b/hw/ide/ahci_internal.h
> @@ -91,6 +91,31 @@
>   #define PORT_CMD_ISSUE            0x38 /* command issue */
>   #define PORT_RESERVED             0x3c /* reserved */
>   
> +/* Port interrupt bit descriptors */
> +enum AHCIPortIRQ {
> +    AHCI_PORT_IRQ_BIT_DHRS = 0,
> +    AHCI_PORT_IRQ_BIT_PSS  = 1,
> +    AHCI_PORT_IRQ_BIT_DSS  = 2,
> +    AHCI_PORT_IRQ_BIT_SDBS = 3,
> +    AHCI_PORT_IRQ_BIT_UFS  = 4,
> +    AHCI_PORT_IRQ_BIT_DPS  = 5,
> +    AHCI_PORT_IRQ_BIT_PCS  = 6,
> +    AHCI_PORT_IRQ_BIT_DMPS = 7,
> +    /* RESERVED */
> +    AHCI_PORT_IRQ_BIT_PRCS = 22,
> +    AHCI_PORT_IRQ_BIT_IPMS = 23,
> +    AHCI_PORT_IRQ_BIT_OFS  = 24,
> +    /* RESERVED */
> +    AHCI_PORT_IRQ_BIT_INFS = 26,
> +    AHCI_PORT_IRQ_BIT_IFS  = 27,
> +    AHCI_PORT_IRQ_BIT_HBDS = 28,
> +    AHCI_PORT_IRQ_BIT_HBFS = 29,
> +    AHCI_PORT_IRQ_BIT_TFES = 30,
> +    AHCI_PORT_IRQ_BIT_CPDS = 31,
> +    AHCI_PORT_IRQ__END     = 32
> +};
> +
> +
>   /* PORT_IRQ_{STAT,MASK} bits */
>   #define PORT_IRQ_COLD_PRES        (1U << 31) /* cold presence detect */
>   #define PORT_IRQ_TF_ERR           (1 << 30) /* task file error */
> @@ -98,18 +123,19 @@
>   #define PORT_IRQ_HBUS_DATA_ERR    (1 << 28) /* host bus data error */
>   #define PORT_IRQ_IF_ERR           (1 << 27) /* interface fatal error */
>   #define PORT_IRQ_IF_NONFATAL      (1 << 26) /* interface non-fatal error */
> +                                            /* reserved */
>   #define PORT_IRQ_OVERFLOW         (1 << 24) /* xfer exhausted available S/G */
>   #define PORT_IRQ_BAD_PMP          (1 << 23) /* incorrect port multiplier */
> -
>   #define PORT_IRQ_PHYRDY           (1 << 22) /* PhyRdy changed */
> -#define PORT_IRQ_DEV_ILCK         (1 << 7) /* device interlock */
> -#define PORT_IRQ_CONNECT          (1 << 6) /* port connect change status */
> -#define PORT_IRQ_SG_DONE          (1 << 5) /* descriptor processed */
> -#define PORT_IRQ_UNK_FIS          (1 << 4) /* unknown FIS rx'd */
> -#define PORT_IRQ_SDB_FIS          (1 << 3) /* Set Device Bits FIS rx'd */
> -#define PORT_IRQ_DMAS_FIS         (1 << 2) /* DMA Setup FIS rx'd */
> -#define PORT_IRQ_PIOS_FIS         (1 << 1) /* PIO Setup FIS rx'd */
> -#define PORT_IRQ_D2H_REG_FIS      (1 << 0) /* D2H Register FIS rx'd */
> +                                            /* reserved */
> +#define PORT_IRQ_DEV_ILCK         (1 << 7)  /* device interlock */
> +#define PORT_IRQ_CONNECT          (1 << 6)  /* port connect change status */
> +#define PORT_IRQ_SG_DONE          (1 << 5)  /* descriptor processed */
> +#define PORT_IRQ_UNK_FIS          (1 << 4)  /* unknown FIS rx'd */
> +#define PORT_IRQ_SDB_FIS          (1 << 3)  /* Set Device Bits FIS rx'd */
> +#define PORT_IRQ_DMAS_FIS         (1 << 2)  /* DMA Setup FIS rx'd */
> +#define PORT_IRQ_PIOS_FIS         (1 << 1)  /* PIO Setup FIS rx'd */
> +#define PORT_IRQ_D2H_REG_FIS      (1 << 0)  /* D2H Register FIS rx'd */
>   
>   #define PORT_IRQ_FREEZE           (PORT_IRQ_HBUS_ERR | PORT_IRQ_IF_ERR |   \
>                                      PORT_IRQ_CONNECT | PORT_IRQ_PHYRDY |    \
> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
> index 0b61c5d..e15fd77 100644
> --- a/hw/ide/trace-events
> +++ b/hw/ide/trace-events
> @@ -62,7 +62,7 @@ ahci_port_read(void *s, int port, int offset, uint32_t ret) "ahci(%p)[%d]: port
>   ahci_irq_raise(void *s) "ahci(%p): raise irq"
>   ahci_irq_lower(void *s) "ahci(%p): lower irq"
>   ahci_check_irq(void *s, uint32_t old, uint32_t new) "ahci(%p): check irq 0x%08x --> 0x%08x"
> -
> +ahci_trigger_irq(void *s, int port, const char *name, uint32_t val, uint32_t old, uint32_t new, uint32_t effective) "ahci(%p)[%d]: trigger irq +%s (0x%08x); irqstat: 0x%08x --> 0x%08x; effective: 0x%08x"
>   ahci_port_write(void *s, int port, int offset, uint32_t val) "ahci(%p)[%d]: port write @ 0x%x: 0x%08x"
>   ahci_mem_read_32(void *s, uint64_t addr, uint32_t val) "ahci(%p): mem read @ 0x%"PRIx64": 0x%08x"
>   ahci_mem_read(void *s, unsigned size, uint64_t addr, uint64_t val) "ahci(%p): read%u @ 0x%"PRIx64": 0x%016"PRIx64
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH v2 8/9] AHCI: pretty-print FIS to buffer instead of stderr
  2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 8/9] AHCI: pretty-print FIS to buffer instead of stderr John Snow
@ 2017-08-30  9:17   ` Stefan Hajnoczi
  2017-08-30 22:50     ` John Snow
  0 siblings, 1 reply; 22+ messages in thread
From: Stefan Hajnoczi @ 2017-08-30  9:17 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, qemu-devel, f4bug

On Tue, Aug 29, 2017 at 04:49:33PM -0400, John Snow wrote:
> The current FIS printing routines dump the FIS to screen. adjust this
> such that it dumps to buffer instead, then use this ability to have
> FIS dump mechanisms via trace-events instead of compiled defines.
> 
> Signed-off-by: John Snow <jsnow@redhat.com>
> ---
>  hw/ide/ahci.c       | 54 +++++++++++++++++++++++++++++++++++++++++++----------
>  hw/ide/trace-events |  4 ++++
>  2 files changed, 48 insertions(+), 10 deletions(-)
> 
> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
> index a0a4dd6..2e75f9b 100644
> --- a/hw/ide/ahci.c
> +++ b/hw/ide/ahci.c
> @@ -644,20 +644,45 @@ static void ahci_reset_port(AHCIState *s, int port)
>      ahci_init_d2h(d);
>  }
>  
> -static void debug_print_fis(uint8_t *fis, int cmd_len)
> +/* Buffer pretty output based on a raw FIS structure. */
> +static void ahci_pretty_buffer_fis(uint8_t *fis, int cmd_len, char **out)

Simplified function using GString:

  static char *ahci_pretty_buffer_fis(const uint8_t *fis, int cmd_len)
  {
      GString *s = g_string_new("FIS:");
      int i;

      for (i = 0; i < cmd_len; i++) {
          if (i % 16 == 0) {
              g_string_append_printf(s, "\n0x%02x:", i);
	  }

          g_string_append_printf(s, " %02x", fis[i]);
      }

      g_string_append_c('\n');
      return g_string_free(s, FALSE);
  }

It's less efficient due to extra mallocs but a lot easier to read.

>  {
> -#if DEBUG_AHCI
> +    size_t bufsize;
> +    char *pbuf;
> +    char *pptr;
> +    size_t lines = DIV_ROUND_UP(cmd_len, 16);
> +    const char *preamble = "FIS:";
>      int i;
>  
> -    fprintf(stderr, "fis:");
> +    /* Total amount of memory to store FISes in HBA memory */
> +    g_assert_cmpint(cmd_len, <=, 0x100);
> +    g_assert(out);
> +
> +    /* Printed like:
> +     * FIS:\n
> +     * 0x00: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee \n
> +     * 0x10: ff \n
> +     * \0
> +     *
> +     * Four bytes for the preamble, seven for each line prefix (including a
> +     * newline to start a new line), three bytes for each source byte,
> +     * a trailing newline and a terminal null byte.
> +     */
> +
> +    bufsize = strlen(preamble) + ((6 + 1) * lines) + (3 * cmd_len) + 1 + 1;
> +    pbuf = g_malloc(bufsize);
> +    pptr = pbuf;
> +    pptr += sprintf(pptr, "%s", preamble);
>      for (i = 0; i < cmd_len; i++) {
>          if ((i & 0xf) == 0) {
> -            fprintf(stderr, "\n%02x:",i);
> +            pptr += sprintf(pptr, "\n0x%02x: ", i);
>          }
> -        fprintf(stderr, "%02x ",fis[i]);
> +        pptr += sprintf(pptr, "%02x ", fis[i]);
>      }
> -    fprintf(stderr, "\n");
> -#endif
> +    pptr += sprintf(pptr, "\n");
> +    pptr += 1; /* \0 */
> +    g_assert(pbuf + bufsize == pptr);
> +    *out = pbuf;
>  }
>  
>  static bool ahci_map_fis_address(AHCIDevice *ad)
> @@ -1201,7 +1226,12 @@ static void handle_reg_h2d_fis(AHCIState *s, int port,
>       * table to ide_state->io_buffer */
>      if (opts & AHCI_CMD_ATAPI) {
>          memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10);
> -        debug_print_fis(ide_state->io_buffer, 0x10);
> +        if (TRACE_HANDLE_REG_H2D_FIS_DUMP_ENABLED) {

This should probably be:

  if (trace_event_get_state_backends(TRACE_HANDLE_REG_H2D_FIS_DUMP)) {

The difference is that TRACE_HANDLE_REG_H2D_FIS_DUMP_ENABLED is set at
compile time while trace_event_get_state_backends() checks if the event
is enabled at run-time.

Therefore TRACE_HANDLE_REG_H2D_FIS_DUMP_ENABLED causes the trace event
to fire even when the user hasn't enabled the trace event yet.  That
would be a waste of CPU.

> +            char *pretty_fis;
> +            ahci_pretty_buffer_fis(ide_state->io_buffer, 0x10, &pretty_fis);
> +            trace_handle_reg_h2d_fis_dump(s, port, pretty_fis);
> +            g_free(pretty_fis);
> +        }
>          s->dev[port].done_atapi_packet = false;
>          /* XXX send PIO setup FIS */
>      }
> @@ -1256,8 +1286,12 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
>          trace_handle_cmd_badmap(s, port, cmd_len);
>          goto out;
>      }
> -    debug_print_fis(cmd_fis, 0x80);
> -
> +    if (TRACE_HANDLE_CMD_FIS_DUMP_ENABLED) {

Same here.

> +        char *pretty_fis;
> +        ahci_pretty_buffer_fis(cmd_fis, 0x80, &pretty_fis);
> +        trace_handle_cmd_fis_dump(s, port, pretty_fis);
> +        g_free(pretty_fis);
> +    }
>      switch (cmd_fis[0]) {
>          case SATA_FIS_TYPE_REGISTER_H2D:
>              handle_reg_h2d_fis(s, port, slot, cmd_fis);
> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
> index e15fd77..77ed3c1 100644
> --- a/hw/ide/trace-events
> +++ b/hw/ide/trace-events
> @@ -105,3 +105,7 @@ ahci_cmd_done(void *s, int port) "ahci(%p)[%d]: cmd done"
>  ahci_reset(void *s) "ahci(%p): HBA reset"
>  allwinner_ahci_mem_read(void *s, void *a, uint64_t addr, uint64_t val, unsigned size) "ahci(%p): read a=%p addr=0x%"HWADDR_PRIx" val=0x%"PRIx64", size=%d"
>  allwinner_ahci_mem_write(void *s, void *a, uint64_t addr, uint64_t val, unsigned size) "ahci(%p): write a=%p addr=0x%"HWADDR_PRIx" val=0x%"PRIx64", size=%d"
> +
> +# Warning: Verbose
> +handle_reg_h2d_fis_dump(void *s, int port, char *fis) "ahci(%p)[%d]: %s"

const char *fis

> +handle_cmd_fis_dump(void *s, int port, char *fis) "ahci(%p)[%d]: %s"

const char *fis

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH v2 0/9] IDE: replace printfs with tracing
  2017-08-29 20:49 [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing John Snow
                   ` (9 preceding siblings ...)
  2017-08-29 21:14 ` [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing no-reply
@ 2017-08-30  9:21 ` Stefan Hajnoczi
  10 siblings, 0 replies; 22+ messages in thread
From: Stefan Hajnoczi @ 2017-08-30  9:21 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, qemu-devel, f4bug

On Tue, Aug 29, 2017 at 04:49:25PM -0400, John Snow wrote:
> Wherever possible, replace all printfs with proper tracing.
> In most places I've tried to do a straight replacement, but
> forthcoming patches may calibrate the tracing to be a little nicer.
> 
> For now, it's nice to just remove the all-or-nothing tracing.
> 
> For V2, I opted to leave in the nearly redundant tracers for now
> with their individual names so that they can be targeted individually.

Looks good.  I left a comment on one patch.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [Qemu-block] [PATCH v2 8/9] AHCI: pretty-print FIS to buffer instead of stderr
  2017-08-30  9:17   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
@ 2017-08-30 22:50     ` John Snow
  0 siblings, 0 replies; 22+ messages in thread
From: John Snow @ 2017-08-30 22:50 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: qemu-devel, qemu-block, f4bug



On 08/30/2017 05:17 AM, Stefan Hajnoczi wrote:
> On Tue, Aug 29, 2017 at 04:49:33PM -0400, John Snow wrote:
>> The current FIS printing routines dump the FIS to screen. adjust this
>> such that it dumps to buffer instead, then use this ability to have
>> FIS dump mechanisms via trace-events instead of compiled defines.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>  hw/ide/ahci.c       | 54 +++++++++++++++++++++++++++++++++++++++++++----------
>>  hw/ide/trace-events |  4 ++++
>>  2 files changed, 48 insertions(+), 10 deletions(-)
>>
>> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
>> index a0a4dd6..2e75f9b 100644
>> --- a/hw/ide/ahci.c
>> +++ b/hw/ide/ahci.c
>> @@ -644,20 +644,45 @@ static void ahci_reset_port(AHCIState *s, int port)
>>      ahci_init_d2h(d);
>>  }
>>  
>> -static void debug_print_fis(uint8_t *fis, int cmd_len)
>> +/* Buffer pretty output based on a raw FIS structure. */
>> +static void ahci_pretty_buffer_fis(uint8_t *fis, int cmd_len, char **out)
> 
> Simplified function using GString:
> 
>   static char *ahci_pretty_buffer_fis(const uint8_t *fis, int cmd_len)
>   {
>       GString *s = g_string_new("FIS:");
>       int i;
> 
>       for (i = 0; i < cmd_len; i++) {
>           if (i % 16 == 0) {
>               g_string_append_printf(s, "\n0x%02x:", i);
> 	  }
> 
>           g_string_append_printf(s, " %02x", fis[i]);
>       }
> 
>       g_string_append_c('\n');
>       return g_string_free(s, FALSE);
>   }
> 
> It's less efficient due to extra mallocs but a lot easier to read.
> 

eeeyyyyeahhhh I guess I don't need to be bleedingly efficient with debug
printfs...

And in this example I don't need to worry about the math being precisely
correct. I'll make the change :(

>>  {
>> -#if DEBUG_AHCI
>> +    size_t bufsize;
>> +    char *pbuf;
>> +    char *pptr;
>> +    size_t lines = DIV_ROUND_UP(cmd_len, 16);
>> +    const char *preamble = "FIS:";
>>      int i;
>>  
>> -    fprintf(stderr, "fis:");
>> +    /* Total amount of memory to store FISes in HBA memory */
>> +    g_assert_cmpint(cmd_len, <=, 0x100);
>> +    g_assert(out);
>> +
>> +    /* Printed like:
>> +     * FIS:\n
>> +     * 0x00: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee \n
>> +     * 0x10: ff \n
>> +     * \0
>> +     *
>> +     * Four bytes for the preamble, seven for each line prefix (including a
>> +     * newline to start a new line), three bytes for each source byte,
>> +     * a trailing newline and a terminal null byte.
>> +     */
>> +
>> +    bufsize = strlen(preamble) + ((6 + 1) * lines) + (3 * cmd_len) + 1 + 1;
>> +    pbuf = g_malloc(bufsize);
>> +    pptr = pbuf;
>> +    pptr += sprintf(pptr, "%s", preamble);
>>      for (i = 0; i < cmd_len; i++) {
>>          if ((i & 0xf) == 0) {
>> -            fprintf(stderr, "\n%02x:",i);
>> +            pptr += sprintf(pptr, "\n0x%02x: ", i);
>>          }
>> -        fprintf(stderr, "%02x ",fis[i]);
>> +        pptr += sprintf(pptr, "%02x ", fis[i]);
>>      }
>> -    fprintf(stderr, "\n");
>> -#endif
>> +    pptr += sprintf(pptr, "\n");
>> +    pptr += 1; /* \0 */
>> +    g_assert(pbuf + bufsize == pptr);
>> +    *out = pbuf;
>>  }
>>  
>>  static bool ahci_map_fis_address(AHCIDevice *ad)
>> @@ -1201,7 +1226,12 @@ static void handle_reg_h2d_fis(AHCIState *s, int port,
>>       * table to ide_state->io_buffer */
>>      if (opts & AHCI_CMD_ATAPI) {
>>          memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10);
>> -        debug_print_fis(ide_state->io_buffer, 0x10);
>> +        if (TRACE_HANDLE_REG_H2D_FIS_DUMP_ENABLED) {
> 
> This should probably be:
> 
>   if (trace_event_get_state_backends(TRACE_HANDLE_REG_H2D_FIS_DUMP)) {
> 
> The difference is that TRACE_HANDLE_REG_H2D_FIS_DUMP_ENABLED is set at
> compile time while trace_event_get_state_backends() checks if the event
> is enabled at run-time.
> 
> Therefore TRACE_HANDLE_REG_H2D_FIS_DUMP_ENABLED causes the trace event
> to fire even when the user hasn't enabled the trace event yet.  That
> would be a waste of CPU.
> 

Oh, cool! Nice tip!

>> +            char *pretty_fis;
>> +            ahci_pretty_buffer_fis(ide_state->io_buffer, 0x10, &pretty_fis);
>> +            trace_handle_reg_h2d_fis_dump(s, port, pretty_fis);
>> +            g_free(pretty_fis);
>> +        }
>>          s->dev[port].done_atapi_packet = false;
>>          /* XXX send PIO setup FIS */
>>      }
>> @@ -1256,8 +1286,12 @@ static int handle_cmd(AHCIState *s, int port, uint8_t slot)
>>          trace_handle_cmd_badmap(s, port, cmd_len);
>>          goto out;
>>      }
>> -    debug_print_fis(cmd_fis, 0x80);
>> -
>> +    if (TRACE_HANDLE_CMD_FIS_DUMP_ENABLED) {
> 
> Same here.
> 

Sure thing. There's probably a block in ATAPI that needs this treatment,
too.

>> +        char *pretty_fis;
>> +        ahci_pretty_buffer_fis(cmd_fis, 0x80, &pretty_fis);
>> +        trace_handle_cmd_fis_dump(s, port, pretty_fis);
>> +        g_free(pretty_fis);
>> +    }
>>      switch (cmd_fis[0]) {
>>          case SATA_FIS_TYPE_REGISTER_H2D:
>>              handle_reg_h2d_fis(s, port, slot, cmd_fis);
>> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
>> index e15fd77..77ed3c1 100644
>> --- a/hw/ide/trace-events
>> +++ b/hw/ide/trace-events
>> @@ -105,3 +105,7 @@ ahci_cmd_done(void *s, int port) "ahci(%p)[%d]: cmd done"
>>  ahci_reset(void *s) "ahci(%p): HBA reset"
>>  allwinner_ahci_mem_read(void *s, void *a, uint64_t addr, uint64_t val, unsigned size) "ahci(%p): read a=%p addr=0x%"HWADDR_PRIx" val=0x%"PRIx64", size=%d"
>>  allwinner_ahci_mem_write(void *s, void *a, uint64_t addr, uint64_t val, unsigned size) "ahci(%p): write a=%p addr=0x%"HWADDR_PRIx" val=0x%"PRIx64", size=%d"
>> +
>> +# Warning: Verbose
>> +handle_reg_h2d_fis_dump(void *s, int port, char *fis) "ahci(%p)[%d]: %s"
> 
> const char *fis
> 
>> +handle_cmd_fis_dump(void *s, int port, char *fis) "ahci(%p)[%d]: %s"
> 
> const char *fis
> 

Thanks for the 👀

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 5/9] IDE: replace DEBUG_AIO with trace events
  2017-08-30  3:14   ` Philippe Mathieu-Daudé
@ 2017-08-30 23:25     ` John Snow
  2017-08-31 16:19       ` Laszlo Ersek
  0 siblings, 1 reply; 22+ messages in thread
From: John Snow @ 2017-08-30 23:25 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-block
  Cc: qemu-devel, Eric Blake, Laszlo Ersek

CCing Laszlo Ersek literally just for laughs, as he is the most
entertaining language lawyer I know of.

Laszlo, please feel free to ignore this if you don't care :P

On 08/29/2017 11:14 PM, Philippe Mathieu-Daudé wrote:
> Hi John,
> 
> On 08/29/2017 05:49 PM, John Snow wrote:
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>   hw/ide/atapi.c            |  5 +----
>>   hw/ide/core.c             | 17 ++++++++++-------
>>   hw/ide/trace-events       |  3 +++
>>   include/hw/ide/internal.h |  6 ++++--
>>   4 files changed, 18 insertions(+), 13 deletions(-)
>>
>> diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
>> index 37fa699..b8fc51e 100644
>> --- a/hw/ide/atapi.c
>> +++ b/hw/ide/atapi.c
>> @@ -416,10 +416,7 @@ static void ide_atapi_cmd_read_dma_cb(void
>> *opaque, int ret)
>>           s->io_buffer_size = n * 2048;
>>           data_offset = 0;
>>       }
>> -#ifdef DEBUG_AIO
>> -    printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
>> -#endif
>> -
>> +    trace_ide_atapi_cmd_read_dma_cb_aio(s, s->lba, n);
>>       s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
>>       s->bus->dma->iov.iov_len = n * ATAPI_SECTOR_SIZE;
>>       qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
>> diff --git a/hw/ide/core.c b/hw/ide/core.c
>> index 82a19b1..a1c90e9 100644
>> --- a/hw/ide/core.c
>> +++ b/hw/ide/core.c
>> @@ -58,6 +58,13 @@ static const int smart_attributes[][12] = {
>>       { 190,  0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00,
>> 0x00, 0x32},
>>   };
>>   +const char *IDE_DMA_CMD_lookup[IDE_DMA__COUNT] = {
>> +    [IDE_DMA_READ] = "DMA READ",
>> +    [IDE_DMA_WRITE] = "DMA WRITE",
>> +    [IDE_DMA_TRIM] = "DMA TRIM",
>> +    [IDE_DMA_ATAPI] = "DMA ATAPI"
>> +};
>> +
>>   static void ide_dummy_transfer_stop(IDEState *s);
>>     static void padstr(char *str, const char *src, int len)
>> @@ -860,10 +867,8 @@ static void ide_dma_cb(void *opaque, int ret)
>>           goto eot;
>>       }
>>   -#ifdef DEBUG_AIO
>> -    printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, cmd_cmd=%d\n",
>> -           sector_num, n, s->dma_cmd);
>> -#endif
>> +    trace_ide_dma_cb(s, sector_num, n,
>> +                     IDE_DMA_CMD_lookup[s->dma_cmd]);
>>         if ((s->dma_cmd == IDE_DMA_READ || s->dma_cmd ==
>> IDE_DMA_WRITE) &&
>>           !ide_sect_range_ok(s, sector_num, n)) {
>> @@ -2391,9 +2396,7 @@ void ide_bus_reset(IDEBus *bus)
>>         /* pending async DMA */
>>       if (bus->dma->aiocb) {
>> -#ifdef DEBUG_AIO
>> -        printf("aio_cancel\n");
>> -#endif
>> +        trace_ide_bus_reset_aio();
>>           blk_aio_cancel(bus->dma->aiocb);
>>           bus->dma->aiocb = NULL;
>>       }
>> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
>> index 8c79a6c..cc8949c 100644
>> --- a/hw/ide/trace-events
>> +++ b/hw/ide/trace-events
>> @@ -18,6 +18,8 @@ ide_cancel_dma_sync_remaining(void) "draining all
>> remaining requests"
>>   ide_sector_read(int64_t sector_num, int nsectors) "sector=%"PRId64"
>> nsectors=%d"
>>   ide_sector_write(int64_t sector_num, int nsectors) "sector=%"PRId64"
>> nsectors=%d"
>>   ide_reset(void *s) "IDEstate %p"
>> +ide_bus_reset_aio(void) "aio_cancel"
>> +ide_dma_cb(void *s, int64_t sector_num, int n, const char *dma)
>> "IDEState %p; sector_num=%"PRId64" n=%d cmd=%s"
>>     # BMDMA HBAs:
>>   @@ -51,5 +53,6 @@ ide_atapi_cmd_reply_end_new(void *s, int status)
>> "IDEState: %p; new transfer sta
>>   ide_atapi_cmd_check_status(void *s) "IDEState: %p"
>>   ide_atapi_cmd_read(void *s, const char *method, int lba, int
>> nb_sectors) "IDEState: %p; read %s: LBA=%d nb_sectors=%d"
>>   ide_atapi_cmd(void *s, uint8_t cmd) "IDEState: %p; cmd: 0x%02x"
>> +ide_atapi_cmd_read_dma_cb_aio(void *s, int lba, int n) "IDEState: %p;
>> aio read: lba=%d n=%d"
>>   # Warning: Verbose
>>   ide_atapi_cmd_packet(void *s, uint16_t limit, const char *packet)
>> "IDEState: %p; limit=0x%x packet: %s"
>> diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
>> index 74efe8a..db9fde0 100644
>> --- a/include/hw/ide/internal.h
>> +++ b/include/hw/ide/internal.h
>> @@ -14,7 +14,6 @@
>>   #include "block/scsi.h"
>>     /* debug IDE devices */
>> -//#define DEBUG_AIO
>>   #define USE_DMA_CDROM
>>     typedef struct IDEBus IDEBus;
>> @@ -333,12 +332,15 @@ struct unreported_events {
>>   };
>>     enum ide_dma_cmd {
>> -    IDE_DMA_READ,
>> +    IDE_DMA_READ = 0,
>>       IDE_DMA_WRITE,
>>       IDE_DMA_TRIM,
>>       IDE_DMA_ATAPI,
>> +    IDE_DMA__COUNT
>>   };
>>   +extern const char *IDE_DMA_CMD_lookup[IDE_DMA__COUNT];
> 
> I recommend you to avoid this declaring extern const array with size, I
> remember some compilers (old GCC?) ignoring array size in extern. Eric
> will correct me!
> 
> It is much safer to use a getter:
> 

Well, whether or not the compiler ignores it, you're right that it's
safer to use a getter. I don't think the width being declared HURTS any
compiler though, does it?

> const char *IDE_DMA_CMD_lookup(enum ide_dma_cmd cmd)
> {
>     static const char *IDE_DMA_CMD_name[IDE_DMA__COUNT] = {
>         [IDE_DMA_READ] = "DMA READ",
>         [IDE_DMA_WRITE] = "DMA WRITE",
>         [IDE_DMA_TRIM] = "DMA TRIM",
>         [IDE_DMA_ATAPI] = "DMA ATAPI"
>     };
> 
>     return IDE_DMA_CMD_name[cmd];
> };
> 

Why is this safer...?

Here's my opinion of enums:

jhuston@probe ~/s/scratch> cat enum.c
enum foo {
    FOO_A = 0,
    FOO_B
};

int fn(enum foo in)
{
    switch (in) {
    case FOO_A:
    case FOO_B:
        return 0;
    default:
        return 1;
    }
}

int main(int argc, char *argv[])
{
    return fn(2);
}


jhuston@probe ~/s/scratch> gcc -ansi -Wall -pedantic -o enum enum.c
jhuston@probe ~/s/scratch> ./enum
jhuston@probe ~/s/scratch> echo $status
1


No warnings, no messages, it just happily takes a value outside the
domain and in this case it doesn't explode because I caught it, but,
take a look:

jhuston@probe ~/s/scratch> cat enum.c
#include <stdio.h>

enum foo {
    FOO_A = 0,
    FOO_B,
    FOO__COUNT
};

const char *table[FOO__COUNT] = {"FOO_A", "FOO_B"};

int fn(enum foo in)
{
    fprintf(stderr, "%s\n", table[in]);
    switch (in) {
    case FOO_A:
    case FOO_B:
        return 0;
    default:
        return 1;
    }
}

int main(int argc, char *argv[])
{
    return fn(2);
}

Similar program, let's compile it:

jhuston@probe ~/s/scratch> gcc -ansi -Wall -pedantic -o enum enum.c
jhuston@probe ~/s/scratch> ./enum
� �


Ah, dang.

This is why I prefer to have my assertions and don't trust enums to be
checked rigorously.

For anyone playing along at home, yes, if you specify at least -O1 here
it will catch it:

jhuston@probe ~/s/scratch> gcc -ansi -Wall -pedantic -O3 -o enum enum.c
enum.c: In function ‘main’:
enum.c:13:5: warning: array subscript is above array bounds [-Warray-bounds]
     fprintf(stderr, "%s\n", table[in]);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Oh no, what the hell is clang up to, though?

jhuston@probe ~/s/scratch> clang -ansi -Wall -pedantic -O3 -o enum enum.c
jhuston@probe ~/s/scratch>


Oh no...

http://i.imgur.com/uRvorq3.jpg

> If you agree:
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> 

Somewhat. I will write a getter that does bounds checking. It _is_ safer
that way, though I don't think we'll ever run into a situation where it
would come up.

>> +
>>   #define ide_cmd_is_read(s) \
>>       ((s)->dma_cmd == IDE_DMA_READ)
>>  
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 7/9] AHCI: Rework IRQ constants
  2017-08-30  3:54   ` Philippe Mathieu-Daudé
@ 2017-08-30 23:28     ` John Snow
  0 siblings, 0 replies; 22+ messages in thread
From: John Snow @ 2017-08-30 23:28 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-block; +Cc: qemu-devel



On 08/29/2017 11:54 PM, Philippe Mathieu-Daudé wrote:
> On 08/29/2017 05:49 PM, John Snow wrote:
>> Create a new enum so that we can name the IRQ bits, which will make
>> debugging
>> them a little nicer if we can print them out. Not handled in this
>> patch, but
>> this will make it possible to get a nice debug printf detailing
>> exactly which
>> status bits are set, as it can be multiple at any given time.
>>
>> As a consequence of this patch, it is no longer possible to set
>> multiple IRQ
>> codes at once, but nothing was utilizing this ability anyway.
>>
>> Signed-off-by: John Snow <jsnow@redhat.com>
>> ---
>>   hw/ide/ahci.c          | 49
>> ++++++++++++++++++++++++++++++++++++++-----------
>>   hw/ide/ahci_internal.h | 44
>> +++++++++++++++++++++++++++++++++++---------
>>   hw/ide/trace-events    |  2 +-
>>   3 files changed, 74 insertions(+), 21 deletions(-)
>>
>> diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
>> index c60a000..a0a4dd6 100644
>> --- a/hw/ide/ahci.c
>> +++ b/hw/ide/ahci.c
>> @@ -56,6 +56,27 @@ static bool ahci_map_fis_address(AHCIDevice *ad);
>>   static void ahci_unmap_clb_address(AHCIDevice *ad);
>>   static void ahci_unmap_fis_address(AHCIDevice *ad);
>>   +static const char *AHCIPortIRQ_lookup[AHCI_PORT_IRQ__END] = {
>> +    [AHCI_PORT_IRQ_BIT_DHRS] = "DHRS",
>> +    [AHCI_PORT_IRQ_BIT_PSS]  = "PSS",
>> +    [AHCI_PORT_IRQ_BIT_DSS]  = "DSS",
>> +    [AHCI_PORT_IRQ_BIT_SDBS] = "SDBS",
>> +    [AHCI_PORT_IRQ_BIT_UFS]  = "UFS",
>> +    [AHCI_PORT_IRQ_BIT_DPS]  = "DPS",
>> +    [AHCI_PORT_IRQ_BIT_PCS]  = "PCS",
>> +    [AHCI_PORT_IRQ_BIT_DMPS] = "DMPS",
>> +    [8 ... 21]               = "RESERVED",
>> +    [AHCI_PORT_IRQ_BIT_PRCS] = "PRCS",
>> +    [AHCI_PORT_IRQ_BIT_IPMS] = "IPMS",
>> +    [AHCI_PORT_IRQ_BIT_OFS]  = "OFS",
>> +    [25]                     = "RESERVED",
>> +    [AHCI_PORT_IRQ_BIT_INFS] = "INFS",
>> +    [AHCI_PORT_IRQ_BIT_IFS]  = "IFS",
>> +    [AHCI_PORT_IRQ_BIT_HBDS] = "HBDS",
>> +    [AHCI_PORT_IRQ_BIT_HBFS] = "HBFS",
>> +    [AHCI_PORT_IRQ_BIT_TFES] = "TFES",
>> +    [AHCI_PORT_IRQ_BIT_CPDS] = "CPDS"
>> +};
>>     static uint32_t  ahci_port_read(AHCIState *s, int port, int offset)
>>   {
>> @@ -170,12 +191,18 @@ static void ahci_check_irq(AHCIState *s)
>>   }
>>     static void ahci_trigger_irq(AHCIState *s, AHCIDevice *d,
>> -                             int irq_type)
>> +                             enum AHCIPortIRQ irqbit)
>>   {
>> -    DPRINTF(d->port_no, "trigger irq %#x -> %x\n",
>> -            irq_type, d->port_regs.irq_mask & irq_type);
>> +    g_assert(irqbit >= 0 && irqbit < 32);
> 
> I still think this assert is superfluous, anyway (and having hard time
> reading C99 statement before declarations - I need to grow):
> 
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> 

Left in because of my distrust of compilers as explained in my reply to
#05. We'll get to the bottom of it ;)

Thank you for the reviews.

--js

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH v2 5/9] IDE: replace DEBUG_AIO with trace events
  2017-08-30 23:25     ` John Snow
@ 2017-08-31 16:19       ` Laszlo Ersek
  0 siblings, 0 replies; 22+ messages in thread
From: Laszlo Ersek @ 2017-08-31 16:19 UTC (permalink / raw)
  To: John Snow, Philippe Mathieu-Daudé, qemu-block; +Cc: qemu-devel, Eric Blake

On 08/31/17 01:25, John Snow wrote:
> CCing Laszlo Ersek literally just for laughs, as he is the most
> entertaining language lawyer I know of.
> 
> Laszlo, please feel free to ignore this if you don't care :P
> 
> On 08/29/2017 11:14 PM, Philippe Mathieu-Daudé wrote:
>> Hi John,
>>
>> On 08/29/2017 05:49 PM, John Snow wrote:
>>> Signed-off-by: John Snow <jsnow@redhat.com>
>>> ---
>>>   hw/ide/atapi.c            |  5 +----
>>>   hw/ide/core.c             | 17 ++++++++++-------
>>>   hw/ide/trace-events       |  3 +++
>>>   include/hw/ide/internal.h |  6 ++++--
>>>   4 files changed, 18 insertions(+), 13 deletions(-)
>>>
>>> diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
>>> index 37fa699..b8fc51e 100644
>>> --- a/hw/ide/atapi.c
>>> +++ b/hw/ide/atapi.c
>>> @@ -416,10 +416,7 @@ static void ide_atapi_cmd_read_dma_cb(void
>>> *opaque, int ret)
>>>           s->io_buffer_size = n * 2048;
>>>           data_offset = 0;
>>>       }
>>> -#ifdef DEBUG_AIO
>>> -    printf("aio_read_cd: lba=%u n=%d\n", s->lba, n);
>>> -#endif
>>> -
>>> +    trace_ide_atapi_cmd_read_dma_cb_aio(s, s->lba, n);
>>>       s->bus->dma->iov.iov_base = (void *)(s->io_buffer + data_offset);
>>>       s->bus->dma->iov.iov_len = n * ATAPI_SECTOR_SIZE;
>>>       qemu_iovec_init_external(&s->bus->dma->qiov, &s->bus->dma->iov, 1);
>>> diff --git a/hw/ide/core.c b/hw/ide/core.c
>>> index 82a19b1..a1c90e9 100644
>>> --- a/hw/ide/core.c
>>> +++ b/hw/ide/core.c
>>> @@ -58,6 +58,13 @@ static const int smart_attributes[][12] = {
>>>       { 190,  0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00,
>>> 0x00, 0x32},
>>>   };
>>>   +const char *IDE_DMA_CMD_lookup[IDE_DMA__COUNT] = {
>>> +    [IDE_DMA_READ] = "DMA READ",
>>> +    [IDE_DMA_WRITE] = "DMA WRITE",
>>> +    [IDE_DMA_TRIM] = "DMA TRIM",
>>> +    [IDE_DMA_ATAPI] = "DMA ATAPI"
>>> +};
>>> +
>>>   static void ide_dummy_transfer_stop(IDEState *s);
>>>     static void padstr(char *str, const char *src, int len)
>>> @@ -860,10 +867,8 @@ static void ide_dma_cb(void *opaque, int ret)
>>>           goto eot;
>>>       }
>>>   -#ifdef DEBUG_AIO
>>> -    printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, cmd_cmd=%d\n",
>>> -           sector_num, n, s->dma_cmd);
>>> -#endif
>>> +    trace_ide_dma_cb(s, sector_num, n,
>>> +                     IDE_DMA_CMD_lookup[s->dma_cmd]);
>>>         if ((s->dma_cmd == IDE_DMA_READ || s->dma_cmd ==
>>> IDE_DMA_WRITE) &&
>>>           !ide_sect_range_ok(s, sector_num, n)) {
>>> @@ -2391,9 +2396,7 @@ void ide_bus_reset(IDEBus *bus)
>>>         /* pending async DMA */
>>>       if (bus->dma->aiocb) {
>>> -#ifdef DEBUG_AIO
>>> -        printf("aio_cancel\n");
>>> -#endif
>>> +        trace_ide_bus_reset_aio();
>>>           blk_aio_cancel(bus->dma->aiocb);
>>>           bus->dma->aiocb = NULL;
>>>       }
>>> diff --git a/hw/ide/trace-events b/hw/ide/trace-events
>>> index 8c79a6c..cc8949c 100644
>>> --- a/hw/ide/trace-events
>>> +++ b/hw/ide/trace-events
>>> @@ -18,6 +18,8 @@ ide_cancel_dma_sync_remaining(void) "draining all
>>> remaining requests"
>>>   ide_sector_read(int64_t sector_num, int nsectors) "sector=%"PRId64"
>>> nsectors=%d"
>>>   ide_sector_write(int64_t sector_num, int nsectors) "sector=%"PRId64"
>>> nsectors=%d"
>>>   ide_reset(void *s) "IDEstate %p"
>>> +ide_bus_reset_aio(void) "aio_cancel"
>>> +ide_dma_cb(void *s, int64_t sector_num, int n, const char *dma)
>>> "IDEState %p; sector_num=%"PRId64" n=%d cmd=%s"
>>>     # BMDMA HBAs:
>>>   @@ -51,5 +53,6 @@ ide_atapi_cmd_reply_end_new(void *s, int status)
>>> "IDEState: %p; new transfer sta
>>>   ide_atapi_cmd_check_status(void *s) "IDEState: %p"
>>>   ide_atapi_cmd_read(void *s, const char *method, int lba, int
>>> nb_sectors) "IDEState: %p; read %s: LBA=%d nb_sectors=%d"
>>>   ide_atapi_cmd(void *s, uint8_t cmd) "IDEState: %p; cmd: 0x%02x"
>>> +ide_atapi_cmd_read_dma_cb_aio(void *s, int lba, int n) "IDEState: %p;
>>> aio read: lba=%d n=%d"
>>>   # Warning: Verbose
>>>   ide_atapi_cmd_packet(void *s, uint16_t limit, const char *packet)
>>> "IDEState: %p; limit=0x%x packet: %s"
>>> diff --git a/include/hw/ide/internal.h b/include/hw/ide/internal.h
>>> index 74efe8a..db9fde0 100644
>>> --- a/include/hw/ide/internal.h
>>> +++ b/include/hw/ide/internal.h
>>> @@ -14,7 +14,6 @@
>>>   #include "block/scsi.h"
>>>     /* debug IDE devices */
>>> -//#define DEBUG_AIO
>>>   #define USE_DMA_CDROM
>>>     typedef struct IDEBus IDEBus;
>>> @@ -333,12 +332,15 @@ struct unreported_events {
>>>   };
>>>     enum ide_dma_cmd {
>>> -    IDE_DMA_READ,
>>> +    IDE_DMA_READ = 0,
>>>       IDE_DMA_WRITE,
>>>       IDE_DMA_TRIM,
>>>       IDE_DMA_ATAPI,
>>> +    IDE_DMA__COUNT
>>>   };
>>>   +extern const char *IDE_DMA_CMD_lookup[IDE_DMA__COUNT];
>>
>> I recommend you to avoid this declaring extern const array with size, I
>> remember some compilers (old GCC?) ignoring array size in extern. Eric
>> will correct me!
>>
>> It is much safer to use a getter:
>>
> 
> Well, whether or not the compiler ignores it, you're right that it's
> safer to use a getter. I don't think the width being declared HURTS any
> compiler though, does it?

If, in the above declaration, you say

extern const char *IDE_DMA_CMD_lookup[];

then the "IDE_DMA_CMD_lookup" will have "incomplete array type". In a
translation unit that includes this declaration, but doesn't actually
*define* the array (thereby completing its type), you can e.g. subscript
the array like this:

  IDE_CMD_DMA_lookup[IDE_DMA_WRITE]

but you cannot do anything with it that would require it to have a
complete type, such as:

  sizeof IDE_CMD_DMA_lookup


If you declare the array as quoted above, then the type will be complete
for all translation units that include the declaration, not just for the
one that defines the array.

Which one I'd recommend depends on the use case. If it's OK to expose
the size of the array to all consumers (or the IDE_DMA__COUNT
enumeration constant), then I'd go with the complete type in the
declaration. It communicates the intent.

And no, the compiler is not required to catch your out-of-bounds access
in either case; but that's not the point. The point is that the human
that looks at the declaration will know how to bounds-check the access.

If you write a getter function, then either declaration will work just
fine, but in that case, you don't even need the array. Just add a switch
statement to your getter, and return the addresses of open-coded string
literals.

> 
>> const char *IDE_DMA_CMD_lookup(enum ide_dma_cmd cmd)
>> {
>>     static const char *IDE_DMA_CMD_name[IDE_DMA__COUNT] = {
>>         [IDE_DMA_READ] = "DMA READ",
>>         [IDE_DMA_WRITE] = "DMA WRITE",
>>         [IDE_DMA_TRIM] = "DMA TRIM",
>>         [IDE_DMA_ATAPI] = "DMA ATAPI"
>>     };
>>
>>     return IDE_DMA_CMD_name[cmd];
>> };
>>
> 
> Why is this safer...?
> 
> Here's my opinion of enums:
> 
> jhuston@probe ~/s/scratch> cat enum.c
> enum foo {
>     FOO_A = 0,
>     FOO_B
> };
> 
> int fn(enum foo in)
> {
>     switch (in) {
>     case FOO_A:
>     case FOO_B:
>         return 0;
>     default:
>         return 1;
>     }
> }
> 
> int main(int argc, char *argv[])
> {
>     return fn(2);
> }
> 
> 
> jhuston@probe ~/s/scratch> gcc -ansi -Wall -pedantic -o enum enum.c
> jhuston@probe ~/s/scratch> ./enum
> jhuston@probe ~/s/scratch> echo $status
> 1
> 
> 
> No warnings, no messages, it just happily takes a value outside the
> domain and in this case it doesn't explode because I caught it, but,
> take a look:
> 
> jhuston@probe ~/s/scratch> cat enum.c
> #include <stdio.h>
> 
> enum foo {
>     FOO_A = 0,
>     FOO_B,
>     FOO__COUNT
> };
> 
> const char *table[FOO__COUNT] = {"FOO_A", "FOO_B"};
> 
> int fn(enum foo in)
> {
>     fprintf(stderr, "%s\n", table[in]);
>     switch (in) {
>     case FOO_A:
>     case FOO_B:
>         return 0;
>     default:
>         return 1;
>     }
> }
> 
> int main(int argc, char *argv[])
> {
>     return fn(2);
> }
> 
> Similar program, let's compile it:
> 
> jhuston@probe ~/s/scratch> gcc -ansi -Wall -pedantic -o enum enum.c
> jhuston@probe ~/s/scratch> ./enum
> � �
> 
> 
> Ah, dang.
> 
> This is why I prefer to have my assertions and don't trust enums to be
> checked rigorously.
> 
> For anyone playing along at home, yes, if you specify at least -O1 here
> it will catch it:
> 
> jhuston@probe ~/s/scratch> gcc -ansi -Wall -pedantic -O3 -o enum enum.c
> enum.c: In function ‘main’:
> enum.c:13:5: warning: array subscript is above array bounds [-Warray-bounds]
>      fprintf(stderr, "%s\n", table[in]);
>      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> Oh no, what the hell is clang up to, though?
> 
> jhuston@probe ~/s/scratch> clang -ansi -Wall -pedantic -O3 -o enum enum.c
> jhuston@probe ~/s/scratch>
> 
> 
> Oh no...
> 
> http://i.imgur.com/uRvorq3.jpg

I wouldn't like to quote all the standardese related to enums. My point
here is that the compiler might choose "signed char", for example, for
representing the "enum foo" type. Let's say the range of "signed char"
is -128..127 inclusive.

Now assume you pass value 128 (of type "int") to a function that takes
"enum foo", such as your fn(). The argument is converted as in an
assignment, and the following applies:

  6.3 Conversions
  6.3.1 Arithmetic operands
  6.3.1.1 Boolean, characters, and integers
    1 [...]
       - The rank of any enumerated type shall equal the rank of the
         compatible integer type (see 6.7.2.2).
    [...]
  6.3.1.3 Signed and unsigned integers
    [...]
    3 Otherwise, the new type is signed and the value cannot be
      represented in it; either the result is implementation-defined or
      an implementation-defined signal is raised.

Dependent on what the docs for your C language implementation say, you
could get total garbage in fn(), or you could get a signal before your
code in fn() is reached.

IOW, if you cannot guarantee *before* the function call that the value
you pass to fn() -- or convert to "enum foo" otherwise -- will nicely
fit in "enum foo"'s represenative integer type, then catching it in fn()
is too late.

I suggest assigning to "enum foo" only
- another "enum foo" object,
- a matching enumeration constant (which has type "int", but will fit of
  course),
- any integer value that has been range-checked explicitly.

The last point does encourage that your getter function should take,
say, "unsigned int" rather than "enum foo"; it handles incorrect calls
more portably.

... I'm unsure if this wall of text is relevant *at all* here, but I've
had to live up to past entertainment! ;)

Laszlo

> 
>> If you agree:
>> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
>>
> 
> Somewhat. I will write a getter that does bounds checking. It _is_ safer
> that way, though I don't think we'll ever run into a situation where it
> would come up.
> 
>>> +
>>>   #define ide_cmd_is_read(s) \
>>>       ((s)->dma_cmd == IDE_DMA_READ)
>>>  
>>
> 

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2017-08-31 16:19 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-29 20:49 [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing John Snow
2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 1/9] IDE: replace DEBUG_IDE with tracing system John Snow
2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 2/9] IDE: Add register hints to tracing John Snow
2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 3/9] IDE: add tracing for data ports John Snow
2017-08-29 22:20   ` Philippe Mathieu-Daudé
2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 4/9] ATAPI: Replace DEBUG_IDE_ATAPI with tracing events John Snow
2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 5/9] IDE: replace DEBUG_AIO with trace events John Snow
2017-08-30  3:14   ` Philippe Mathieu-Daudé
2017-08-30 23:25     ` John Snow
2017-08-31 16:19       ` Laszlo Ersek
2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 6/9] AHCI: Replace DPRINTF with trace-events John Snow
2017-08-29 22:22   ` Philippe Mathieu-Daudé
2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 7/9] AHCI: Rework IRQ constants John Snow
2017-08-30  3:54   ` Philippe Mathieu-Daudé
2017-08-30 23:28     ` John Snow
2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 8/9] AHCI: pretty-print FIS to buffer instead of stderr John Snow
2017-08-30  9:17   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2017-08-30 22:50     ` John Snow
2017-08-29 20:49 ` [Qemu-devel] [PATCH v2 9/9] AHCI: remove DPRINTF macro John Snow
2017-08-29 22:24   ` Philippe Mathieu-Daudé
2017-08-29 21:14 ` [Qemu-devel] [PATCH v2 0/9] IDE: replace printfs with tracing no-reply
2017-08-30  9:21 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.