diff --git a/include/sys/arch_interface.h b/include/sys/arch_interface.h index f570a72e0fd..ccaedaff701 100644 --- a/include/sys/arch_interface.h +++ b/include/sys/arch_interface.h @@ -819,14 +819,9 @@ static inline void arch_cohere_stacks(struct k_thread *old_thread, * @{ */ -/** - * @def ARCH_GDB_NUM_REGISTERS - * - * ARCH_GDB_NUM_REGISTERS is architecure specific and - * this symbol must be defined in architecure specific header - */ - #ifdef CONFIG_GDBSTUB +struct gdb_ctx; + /** * @brief Architecture layer debug start * @@ -848,6 +843,70 @@ void arch_gdb_continue(void); */ void arch_gdb_step(void); +/** + * @brief Read all registers, and outputs as hexadecimal string. + * + * This reads all CPU registers and outputs as hexadecimal string. + * The output string must be parsable by GDB. + * + * @param ctx GDB context + * @param buf Buffer to output hexadecimal string. + * @param buflen Length of buffer. + * + * @return Length of hexadecimal string written. + * Return 0 if error or not supported. + */ +size_t arch_gdb_reg_readall(struct gdb_ctx *ctx, uint8_t *buf, size_t buflen); + +/** + * @brief Take a hexadecimal string and update all registers. + * + * This takes in a hexadecimal string as presented from GDB, + * and updates all CPU registers with new values. + * + * @param ctx GDB context + * @param hex Input hexadecimal string. + * @param hexlen Length of hexadecimal string. + * + * @return Length of hexadecimal string parsed. + * Return 0 if error or not supported. + */ +size_t arch_gdb_reg_writeall(struct gdb_ctx *ctx, uint8_t *hex, size_t hexlen); + +/** + * @brief Read one register, and outputs as hexadecimal string. + * + * This reads one CPU register and outputs as hexadecimal string. + * The output string must be parsable by GDB. + * + * @param ctx GDB context + * @param buf Buffer to output hexadecimal string. + * @param buflen Length of buffer. + * @param regno Register number + * + * @return Length of hexadecimal string written. + * Return 0 if error or not supported. + */ +size_t arch_gdb_reg_readone(struct gdb_ctx *ctx, uint8_t *buf, size_t buflen, + uint32_t regno); + +/** + * @brief Take a hexadecimal string and update one register. + * + * This takes in a hexadecimal string as presented from GDB, + * and updates one CPU registers with new value. + * + * @param ctx GDB context + * @param hex Input hexadecimal string. + * @param hexlen Length of hexadecimal string. + * @param regno Register number + * + * @return Length of hexadecimal string parsed. + * Return 0 if error or not supported. + */ +size_t arch_gdb_reg_writeone(struct gdb_ctx *ctx, uint8_t *hex, size_t hexlen, + uint32_t regno); + #endif /** @} */ diff --git a/subsys/debug/gdbstub.c b/subsys/debug/gdbstub.c index 80ceda4de3e..6b4f7b03f66 100644 --- a/subsys/debug/gdbstub.c +++ b/subsys/debug/gdbstub.c @@ -344,8 +344,7 @@ int z_gdb_main_loop(struct gdb_ctx *ctx, bool start) * Format: g */ case 'g': - pkt_len = bin2hex((const uint8_t *)&(ctx->registers), - sizeof(ctx->registers), buf, sizeof(buf)); + pkt_len = arch_gdb_reg_readall(ctx, buf, sizeof(buf)); CHECK_FAILURE(pkt_len == 0); gdb_send_packet(buf, pkt_len); break; @@ -355,9 +354,7 @@ int z_gdb_main_loop(struct gdb_ctx *ctx, bool start) * Fromat: G XX... */ case 'G': - pkt_len = hex2bin(ptr, pkt_len - 1, - (uint8_t *)&(ctx->registers), - sizeof(ctx->registers)); + pkt_len = arch_gdb_reg_writeall(ctx, ptr, pkt_len - 1); CHECK_FAILURE(pkt_len == 0); gdb_send_packet("OK", 2); break; @@ -368,13 +365,9 @@ int z_gdb_main_loop(struct gdb_ctx *ctx, bool start) */ case 'p': CHECK_INT(addr); - CHECK_FAILURE(addr >= ARCH_GDB_NUM_REGISTERS); /* Read Register */ - pkt_len = bin2hex( - (const uint8_t *)&(ctx->registers[addr]), - sizeof(ctx->registers[addr]), - buf, sizeof(buf)); + pkt_len = arch_gdb_reg_readone(ctx, buf, sizeof(buf), addr); CHECK_FAILURE(pkt_len == 0); gdb_send_packet(buf, pkt_len); break; @@ -393,12 +386,8 @@ int z_gdb_main_loop(struct gdb_ctx *ctx, bool start) * return "E01" gdb will stop. So, we just * send "OK" and ignore it. */ - if (addr < ARCH_GDB_NUM_REGISTERS) { - pkt_len = hex2bin(ptr, strlen(ptr), - (uint8_t *)&(ctx->registers[addr]), - sizeof(ctx->registers[addr])); - CHECK_FAILURE(pkt_len == 0); - } + pkt_len = arch_gdb_reg_writeone(ctx, ptr, strlen(ptr), addr); + CHECK_FAILURE(pkt_len == 0); gdb_send_packet("OK", 2); break;