diff --git a/tools/sof-ipc4-msg-trace.bt b/tools/sof-ipc4-msg-trace.bt new file mode 100755 index 00000000..f23638ad --- /dev/null +++ b/tools/sof-ipc4-msg-trace.bt @@ -0,0 +1,63 @@ +#!/usr/bin/bpftrace + +struct sof_ipc4_msg { + union { + unsigned long header_u64; + struct { + unsigned int primary; + unsigned int extension; + }; + }; + + unsigned long data_size; + void *data_ptr; +}; + +BEGIN +{ + printf("SOF IPC4 tx message logging. Ctrl-C to end.\n\n"); +} + +/* + * Log the sent IPC4 messages, ignoring the 0x1b060000 notification + * from firmware (trace update) + * The message payload is printed as bytes, arranged by 16 bytes/line + */ +kprobe:sof_ipc4_log_header { + $msg = (struct sof_ipc4_msg *)arg2; + + if ($msg->primary != 0x1b060000 && arg3 == 1 && $msg->data_size != 0) { + printf("%s : 0x%x|0x%x [data size:: %llu]\n", str(arg1), + $msg->primary, $msg->extension, $msg->data_size); + if (!strcontains(str(arg1), "done")) { + $count = (int64) $msg->data_size; + $ptr = (uint8*) $msg->data_ptr; + $line = 0; + + printf("Message payload:\n"); + while ($line < 500) { + if ($count <= 16) { + printf("%rh\n", buf($ptr, $count)); + break; + } + + printf("%rh\n", buf($ptr, 16)); + $count -= 16; + if ($count == 0) { + break; + } + $ptr += 16; + $line++; + } + } else { + printf("\n"); + } + } else if ($msg->primary != 0x1b060000) { + printf("%s : 0x%x|0x%x\n", str(arg1), $msg->primary, + $msg->extension); + if (strcontains(str(arg1), "done")) { + printf("\n"); + } + } +} +