hw/sd: Update trace events for buf+len data
After switching sdbuf and sdcard over to use buf+len instead of single byte operation, the trace events need to be updated. This patch updates sdbus_{read,write} and sdcard_write_data to output the buffer that is worked on. sdcard_read_data is left unchanged, as it did not print the read byte before anyways. Signed-off-by: Christian Speich <c.speich@avm.de> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20260417-sdcard-performance-b4-v4-7-119e66be10c2@avm.de> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Christian Speich committed
Apr 17, 2026 at 11:51 UTC
d7f3ab9d5a186b3ca44a7abcc975e59164fece62
3 files changed
+43
-8
hw/sd/core.c
+25
-2
@@ -24,6 +24,7 @@
24
#include "hw/sd/sd.h"
25
#include "qemu/module.h"
26
#include "qapi/error.h"
27
+#include "qemu/cutils.h"
28
#include "sdmmc-internal.h"
29
#include "trace.h"
30
@@ -43,6 +44,26 @@ static SDState *get_card(SDBus *sdbus)
44
return SDMMC_COMMON(kid->child);
45
}
46
47
+static void sdbus_write_dump(const char *bus_name, const void *buf, size_t len)
48
+{
49
+ g_autoptr(GString) str = NULL;
50
+
51
+ if (trace_event_get_state_backends(TRACE_SDBUS_WRITE)) {
52
+ str = qemu_hexdump_line(NULL, buf, len, 8, 0);
53
+ trace_sdbus_write(bus_name, str->str);
54
+ }
55
+}
56
+
57
+static void sdbus_read_dump(const char *bus_name, const void *buf, size_t len)
58
+{
59
+ g_autoptr(GString) str = NULL;
60
+
61
+ if (trace_event_get_state_backends(TRACE_SDBUS_READ)) {
62
+ str = qemu_hexdump_line(NULL, buf, len, 8, 0);
63
+ trace_sdbus_read(bus_name, str->str);
64
+ }
65
+}
66
+
67
uint8_t sdbus_get_dat_lines(SDBus *sdbus)
68
{
69
SDState *slave = get_card(sdbus);
@@ -109,7 +130,7 @@ void sdbus_write_byte(SDBus *sdbus, uint8_t value)
130
{
131
SDState *card = get_card(sdbus);
132
112
- trace_sdbus_write(sdbus_name(sdbus), value);
133
+ sdbus_write_dump(sdbus_name(sdbus), &value, 1);
134
if (card) {
135
SDCardClass *sc = SDMMC_COMMON_GET_CLASS(card);
136
@@ -121,6 +142,7 @@ void sdbus_write_data(SDBus *sdbus, const void *buf, size_t length)
142
{
143
SDState *card = get_card(sdbus);
144
145
+ sdbus_write_dump(sdbus_name(sdbus), buf, length);
146
if (card) {
147
SDCardClass *sc = SDMMC_COMMON_GET_CLASS(card);
148
@@ -145,7 +167,7 @@ uint8_t sdbus_read_byte(SDBus *sdbus)
167
168
sc->read_data(card, &value, 1);
169
}
148
- trace_sdbus_read(sdbus_name(sdbus), value);
170
+ sdbus_read_dump(sdbus_name(sdbus), &value, 1);
171
172
return value;
173
}
@@ -166,6 +188,7 @@ void sdbus_read_data(SDBus *sdbus, void *buf, size_t length)
188
length -= read;
189
}
190
}
191
+ sdbus_read_dump(sdbus_name(sdbus), buf, length);
192
}
193
194
bool sdbus_receive_ready(SDBus *sdbus)
hw/sd/sd.c
+15
-3
@@ -2647,6 +2647,18 @@ static bool sd_generic_read_data(SDState *sd, void *buf, size_t *len)
2647
return false;
2648
}
2649
2650
+static void sdcard_write_data_dump(const char *proto, const char *cmd_desc,
2651
+ uint8_t cmd, uint32_t offset,
2652
+ const void *buf, size_t len)
2653
+{
2654
+ g_autoptr(GString) str = NULL;
2655
+
2656
+ if (trace_event_get_state_backends(TRACE_SDCARD_WRITE_DATA)) {
2657
+ str = qemu_hexdump_line(NULL, buf, len, 8, 0);
2658
+ trace_sdcard_write_data(proto, cmd_desc, cmd, offset, str->str);
2659
+ }
2660
+}
2661
+
2662
static size_t sd_write_data(SDState *sd, const void *buf, size_t length)
2663
{
2664
unsigned int partition_access;
@@ -2666,9 +2678,9 @@ static size_t sd_write_data(SDState *sd, const void *buf, size_t length)
2678
if (sd->card_status & (ADDRESS_ERROR | WP_VIOLATION))
2679
return length;
2680
2669
- trace_sdcard_write_data(sd->proto->name,
2670
- sd->last_cmd_name,
2671
- sd->current_cmd, sd->data_offset, value[0]);
2681
+ sdcard_write_data_dump(sd->proto->name,
2682
+ sd->last_cmd_name,
2683
+ sd->current_cmd, sd->data_offset, buf, length);
2684
switch (sd->current_cmd) {
2685
case 24: /* CMD24: WRITE_SINGLE_BLOCK */
2686
if (sd_generic_write_data(sd, buf, &length)) {
hw/sd/trace-events
+3
-3
@@ -15,8 +15,8 @@ bcm2835_sdhost_update_irq(uint32_t irq) "IRQ bits 0x%x"
15
16
# core.c
17
sdbus_command(const char *bus_name, uint8_t cmd, uint32_t arg) "@%s CMD%02d arg 0x%08x"
18
-sdbus_read(const char *bus_name, uint8_t value) "@%s value 0x%02x"
19
-sdbus_write(const char *bus_name, uint8_t value) "@%s value 0x%02x"
18
+sdbus_read(const char *bus_name, const char *hexdump) "@%s data %s"
19
+sdbus_write(const char *bus_name, const char *hexdump) "@%s data %s"
20
sdbus_set_voltage(const char *bus_name, uint16_t millivolts) "@%s %u (mV)"
21
sdbus_get_dat_lines(const char *bus_name, uint8_t dat_lines) "@%s dat_lines: %u"
22
sdbus_get_cmd_line(const char *bus_name, bool cmd_line) "@%s cmd_line: %u"
@@ -54,7 +54,7 @@ sdcard_unlock(void) ""
54
sdcard_req_addr(uint32_t req_arg, uint64_t addr) "req 0x%" PRIx32 " addr 0x%" PRIx64
55
sdcard_read_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
56
sdcard_write_block(uint64_t addr, uint32_t len) "addr 0x%" PRIx64 " size 0x%x"
57
-sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint32_t offset, uint8_t value) "%s %20s/ CMD%02d ofs %"PRIu32" value 0x%02x"
57
+sdcard_write_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint32_t offset, const char *hexdump) "%s %20s/ CMD%02d ofs %"PRIu32" data %s"
58
sdcard_read_data(const char *proto, const char *cmd_desc, uint8_t cmd, uint32_t offset, uint64_t size, uint32_t blklen) "%s %20s/ CMD%02d ofs %"PRIu32" size %"PRIu64" blklen %" PRIu32
59
sdcard_set_voltage(uint16_t millivolts) "%u mV"
60
sdcard_ext_csd_update(unsigned index, uint8_t oval, uint8_t nval) "index %u: 0x%02x -> 0x%02x"