From 6ef75352f1e4a86f66bf98e1792a68345c77f9a7 Mon Sep 17 00:00:00 2001 From: Marek Vrbka Date: Tue, 30 May 2023 15:36:12 +0200 Subject: semihosting: improve semihosting opcode debug messages This patch introduces function semihosting_opcode_to_str() which converts semihosting opcodes to strings. This function is then used in debug messages to improve log analysis and troubleshooting. Change-Id: Iffea49dae13d6a626ae0db40d379cba3c9ea5bd3 Signed-off-by: Marek Vrbka Reviewed-on: https://review.openocd.org/c/openocd/+/7726 Tested-by: jenkins Reviewed-by: Antonio Borneo Reviewed-by: Jan Matyas --- src/target/semihosting_common.c | 70 ++++++++++++++++++++++++++++++++++++++--- src/target/semihosting_common.h | 9 ++++++ 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c index 6c91876..107b6d3 100644 --- a/src/target/semihosting_common.c +++ b/src/target/semihosting_common.c @@ -294,6 +294,66 @@ static inline int semihosting_getchar(struct semihosting *semihosting, int fd) */ static char *semihosting_user_op_params; +const char *semihosting_opcode_to_str(const uint64_t opcode) +{ + switch (opcode) { + case SEMIHOSTING_SYS_CLOSE: + return "CLOSE"; + case SEMIHOSTING_SYS_CLOCK: + return "CLOCK"; + case SEMIHOSTING_SYS_ELAPSED: + return "ELAPSED"; + case SEMIHOSTING_SYS_ERRNO: + return "ERRNO"; + case SEMIHOSTING_SYS_EXIT: + return "EXIT"; + case SEMIHOSTING_SYS_EXIT_EXTENDED: + return "EXIT_EXTENDED"; + case SEMIHOSTING_SYS_FLEN: + return "FLEN"; + case SEMIHOSTING_SYS_GET_CMDLINE: + return "GET_CMDLINE"; + case SEMIHOSTING_SYS_HEAPINFO: + return "HEAPINFO"; + case SEMIHOSTING_SYS_ISERROR: + return "ISERROR"; + case SEMIHOSTING_SYS_ISTTY: + return "ISTTY"; + case SEMIHOSTING_SYS_OPEN: + return "OPEN"; + case SEMIHOSTING_SYS_READ: + return "READ"; + case SEMIHOSTING_SYS_READC: + return "READC"; + case SEMIHOSTING_SYS_REMOVE: + return "REMOVE"; + case SEMIHOSTING_SYS_RENAME: + return "RENAME"; + case SEMIHOSTING_SYS_SEEK: + return "SEEK"; + case SEMIHOSTING_SYS_SYSTEM: + return "SYSTEM"; + case SEMIHOSTING_SYS_TICKFREQ: + return "TICKFREQ"; + case SEMIHOSTING_SYS_TIME: + return "TIME"; + case SEMIHOSTING_SYS_TMPNAM: + return "TMPNAM"; + case SEMIHOSTING_SYS_WRITE: + return "WRITE"; + case SEMIHOSTING_SYS_WRITEC: + return "WRITEC"; + case SEMIHOSTING_SYS_WRITE0: + return "WRITE0"; + case SEMIHOSTING_USER_CMD_0X100 ... SEMIHOSTING_USER_CMD_0X1FF: + return "USER_CMD"; + case SEMIHOSTING_ARM_RESERVED_START ... SEMIHOSTING_ARM_RESERVED_END: + return "ARM_RESERVED_CMD"; + default: + return ""; + } +} + /** * Portable implementation of ARM semihosting calls. * Performs the currently pending semihosting operation @@ -323,8 +383,9 @@ int semihosting_common(struct target *target) /* Enough space to hold 4 long words. */ uint8_t fields[4*8]; - LOG_DEBUG("op=0x%x, param=0x%" PRIx64, semihosting->op, - semihosting->param); + LOG_DEBUG("op=0x%x (%s), param=0x%" PRIx64, semihosting->op, + semihosting_opcode_to_str(semihosting->op), + semihosting->param); switch (semihosting->op) { @@ -1470,8 +1531,9 @@ int semihosting_common(struct target *target) retval = target_read_buffer(target, addr, len, (uint8_t *)(semihosting_user_op_params)); if (retval != ERROR_OK) { - LOG_ERROR("Failed to read from target, semihosting op=0x%x", - semihosting->op); + LOG_ERROR("Failed to read from target, semihosting op=0x%x (%s)", + semihosting->op, + semihosting_opcode_to_str(semihosting->op)); free(semihosting_user_op_params); semihosting_user_op_params = NULL; return retval; diff --git a/src/target/semihosting_common.h b/src/target/semihosting_common.h index 7c5f748..a1848b4 100644 --- a/src/target/semihosting_common.h +++ b/src/target/semihosting_common.h @@ -65,6 +65,8 @@ enum semihosting_operation_numbers { SEMIHOSTING_SYS_WRITE = 0x05, SEMIHOSTING_SYS_WRITEC = 0x03, SEMIHOSTING_SYS_WRITE0 = 0x04, + SEMIHOSTING_ARM_RESERVED_START = 0x32, + SEMIHOSTING_ARM_RESERVED_END = 0xFF, SEMIHOSTING_USER_CMD_0X100 = 0x100, /* First user cmd op code */ SEMIHOSTING_USER_CMD_0X107 = 0x107, /* Last supported user cmd op code */ SEMIHOSTING_USER_CMD_0X1FF = 0x1FF, /* Last user cmd op code */ @@ -186,6 +188,13 @@ struct semihosting { int (*post_result)(struct target *target); }; +/** + * @brief Convert the syscall opcode to a human-readable string + * @param[in] opcode Syscall opcode + * @return String representation of syscall opcode + */ +const char *semihosting_opcode_to_str(uint64_t opcode); + int semihosting_common_init(struct target *target, void *setup, void *post_result); int semihosting_common(struct target *target); -- cgit v1.1