The device only offered the compile-time DEBUG_SMC fprintf() macro for introspection. Add trace events for the command and data port transactions: the incoming command byte and whether it was accepted or rejected, each four-character key as it is assembled, key lookups that miss, and every data byte handed back. The SMC conversation a guest performs can then be observed at runtime, for example with -trace 'applesmc*', which is helpful for understanding which keys and commands a macOS guest actually issues.
Signed-off-by: Daniel Golle <[email protected]> --- hw/misc/applesmc.c | 13 +++++++++++++ hw/misc/trace-events | 9 +++++++++ 2 files changed, 22 insertions(+) diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c index d004e8b443..6f9d0a590d 100644 --- a/hw/misc/applesmc.c +++ b/hw/misc/applesmc.c @@ -39,6 +39,7 @@ #include "qemu/timer.h" #include "qom/object.h" #include "hw/acpi/acpi_aml_interface.h" +#include "trace.h" /* #define DEBUG_SMC */ @@ -123,6 +124,7 @@ static void applesmc_io_cmd_write(void *opaque, hwaddr addr, uint64_t val, AppleSMCState *s = opaque; uint8_t status = s->status & 0x0f; + trace_applesmc_cmd_write((uint8_t)val, s->status); smc_debug("CMD received: 0x%02x\n", (uint8_t)val); switch (val) { case APPLESMC_READ_CMD: @@ -130,6 +132,7 @@ static void applesmc_io_cmd_write(void *opaque, hwaddr addr, uint64_t val, if (status == APPLESMC_ST_CMD_DONE || status == APPLESMC_ST_NEW_CMD) { s->cmd = val; s->status = APPLESMC_ST_NEW_CMD | APPLESMC_ST_ACK; + trace_applesmc_cmd_accepted((uint8_t)val); } else { smc_debug("ERROR: previous command interrupted!\n"); s->status = APPLESMC_ST_NEW_CMD; @@ -140,6 +143,7 @@ static void applesmc_io_cmd_write(void *opaque, hwaddr addr, uint64_t val, smc_debug("UNEXPECTED CMD 0x%02x\n", (uint8_t)val); s->status = APPLESMC_ST_NEW_CMD; s->status_1e = APPLESMC_ST_1E_BAD_CMD; + trace_applesmc_cmd_rejected((uint8_t)val, s->status_1e); } s->read_pos = 0; s->data_pos = 0; @@ -164,6 +168,7 @@ static void applesmc_io_data_write(void *opaque, hwaddr addr, uint64_t val, const struct AppleSMCData *d; smc_debug("DATA received: 0x%02x\n", (uint8_t)val); + trace_applesmc_data_write(s->cmd, s->read_pos, (uint8_t)val); switch (s->cmd) { case APPLESMC_READ_CMD: if ((s->status & 0x0f) == APPLESMC_ST_CMD_DONE) { @@ -172,6 +177,10 @@ static void applesmc_io_data_write(void *opaque, hwaddr addr, uint64_t val, if (s->read_pos < 4) { s->key[s->read_pos] = val; s->status = APPLESMC_ST_ACK; + if (s->read_pos == 3) { + trace_applesmc_key_selected(s->key[0], s->key[1], + s->key[2], s->key[3]); + } } else if (s->read_pos == 4) { d = applesmc_find_key(s); if (d != NULL) { @@ -183,6 +192,8 @@ static void applesmc_io_data_write(void *opaque, hwaddr addr, uint64_t val, } else { smc_debug("READ_CMD: key '%c%c%c%c' not found!\n", s->key[0], s->key[1], s->key[2], s->key[3]); + trace_applesmc_key_not_found(s->key[0], s->key[1], + s->key[2], s->key[3]); s->status = APPLESMC_ST_CMD_DONE; s->status_1e = APPLESMC_ST_1E_NOEXIST; } @@ -213,6 +224,8 @@ static uint64_t applesmc_io_data_read(void *opaque, hwaddr addr, unsigned size) } if (s->data_pos < s->data_len) { s->last_ret = s->data[s->data_pos]; + trace_applesmc_data_read(s->key[0], s->key[1], s->key[2], + s->key[3], s->data_pos, s->last_ret); smc_debug("READ '%c%c%c%c'[%d] = %02x\n", s->key[0], s->key[1], s->key[2], s->key[3], s->data_pos, s->last_ret); diff --git a/hw/misc/trace-events b/hw/misc/trace-events index c9a868b3ef..b924b4398e 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -37,6 +37,15 @@ allwinner_sid_write(uint64_t offset, uint64_t data, unsigned size) "offset 0x%" allwinner_sramc_read(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64 allwinner_sramc_write(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64 +# applesmc.c +applesmc_cmd_write(uint8_t cmd, uint8_t status) "cmd 0x%02x (status 0x%02x)" +applesmc_cmd_accepted(uint8_t cmd) "cmd 0x%02x accepted" +applesmc_cmd_rejected(uint8_t cmd, uint8_t status_1e) "cmd 0x%02x rejected (status_1e 0x%02x)" +applesmc_data_write(uint8_t cmd, uint8_t pos, uint8_t val) "cmd 0x%02x pos %u data 0x%02x" +applesmc_key_selected(uint8_t c0, uint8_t c1, uint8_t c2, uint8_t c3) "key %c%c%c%c" +applesmc_key_not_found(uint8_t c0, uint8_t c1, uint8_t c2, uint8_t c3) "key %c%c%c%c not found" +applesmc_data_read(uint8_t c0, uint8_t c1, uint8_t c2, uint8_t c3, uint8_t pos, uint8_t val) "read key %c%c%c%c [%u] 0x%02x" + # avr_power.c avr_power_read(uint8_t value) "power_reduc read value:%u" avr_power_write(uint8_t value) "power_reduc write value:%u" -- 2.55.0
