From 019bf5f83c79353392471529f7cb961c5c603bfd Mon Sep 17 00:00:00 2001 From: Walter Ji Date: Fri, 17 Nov 2023 15:13:55 +0800 Subject: [PATCH] target/mips32: add mips ejtag command Add mips32 ejtag_reg command for inspecting ejtag status. Add description for mips32 ejtag_reg command. Change-Id: Icd173d3397d568b0c004a8cc3f45518d7b48ce43 Signed-off-by: Walter Ji Reviewed-on: https://review.openocd.org/c/openocd/+/7906 Reviewed-by: Oleksij Rempel Reviewed-by: Antonio Borneo Tested-by: jenkins --- doc/openocd.texi | 9 +++++- src/target/mips32.c | 70 +++++++++++++++++++++++++++++++++++++++++ src/target/mips_ejtag.c | 4 +-- src/target/mips_ejtag.h | 19 +++++++++++ 4 files changed, 99 insertions(+), 3 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index a2af45114..e482c43b4 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -11037,10 +11037,17 @@ For common MIPS Coprocessor 0 registers, you can find the definitions of them on MIPS Privileged Resource Architecture Documents(MIPS Document MD00090). For core specific cp0 registers, you can find the definitions of them on Core -Specific Software User's Manual, for example, MIPS M5150 Software User Manual +Specific Software User's Manual(SUM), for example, MIPS M5150 Software User Manual (MD00980). @end deffn +@deffn {Command} {mips32 ejtag_reg} +Reads EJTAG Registers for inspection. + +EJTAG Register Specification could be found in MIPS Document MD00047F, for +core specific EJTAG Register definition, please check Core Specific SUM manual. +@end deffn + @section RISC-V Architecture @uref{http://riscv.org/, RISC-V} is a free and open ISA. OpenOCD supports JTAG diff --git a/src/target/mips32.c b/src/target/mips32.c index 9cebc48f6..b25fae88e 100644 --- a/src/target/mips32.c +++ b/src/target/mips32.c @@ -1707,6 +1707,69 @@ COMMAND_HANDLER(mips32_handle_cpuinfo_command) return ERROR_OK; } +/** + * mips32_handle_ejtag_reg_command - Handler commands related to EJTAG + * @param[in] cmd: Command invocation context + * + * @brief Prints all EJTAG Registers including DCR features. + * + * @return ERROR_OK on success; error code on failure. + */ +COMMAND_HANDLER(mips32_handle_ejtag_reg_command) +{ + struct target *target = get_current_target(CMD_CTX); + struct mips32_common *mips32 = target_to_mips32(target); + struct mips_ejtag *ejtag_info = &mips32->ejtag_info; + + uint32_t ejtag_ctrl; + uint32_t dcr; + int retval; + + retval = mips_ejtag_get_idcode(ejtag_info); + if (retval != ERROR_OK) + command_print(CMD, "Error: Encounter an Error while getting idcode"); + else + command_print(CMD, " idcode: 0x%8.8" PRIx32, ejtag_info->idcode); + + retval = mips_ejtag_get_impcode(ejtag_info); + if (retval != ERROR_OK) + command_print(CMD, "Error: Encounter an Error while getting impcode"); + else + command_print(CMD, " impcode: 0x%8.8" PRIx32, ejtag_info->impcode); + + mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); + ejtag_ctrl = ejtag_info->ejtag_ctrl; + retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); + if (retval != ERROR_OK) + command_print(CMD, "Error: Encounter an Error while executing drscan reading EJTAG Control register"); + else + command_print(CMD, "ejtag control: 0x%8.8" PRIx32, ejtag_ctrl); + + ejtag_main_print_imp(ejtag_info); + + /* Display current DCR */ + retval = target_read_u32(target, EJTAG_DCR, &dcr); + if (retval != ERROR_OK) + command_print(CMD, "Error: Encounter an Error while reading Debug Control Register"); + else + command_print(CMD, " DCR: 0x%8.8" PRIx32, dcr); + + for (unsigned int i = 0; i < EJTAG_DCR_ENTRIES; i++) { + if (dcr & BIT(dcr_features[i].bit)) + command_print(CMD, "%s supported", dcr_features[i].name); + } + + return ERROR_OK; +} + +/** + * mips32_handle_scan_delay_command - Handler command for changing scan delay + * @param[in] cmd: Command invocation context + * + * @brief Changes current scan mode between legacy and fast queued mode. + * + * @return ERROR_OK on success; error code on failure. + */ COMMAND_HANDLER(mips32_handle_scan_delay_command) { struct target *target = get_current_target(CMD_CTX); @@ -1752,6 +1815,13 @@ static const struct command_registration mips32_exec_command_handlers[] = { .help = "display/set scan delay in nano seconds", .usage = "[value]", }, + { + .name = "ejtag_reg", + .handler = mips32_handle_ejtag_reg_command, + .mode = COMMAND_ANY, + .help = "read ejtag registers", + .usage = "", + }, COMMAND_REGISTRATION_DONE }; diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c index 5c92bf9ee..389461cae 100644 --- a/src/target/mips_ejtag.c +++ b/src/target/mips_ejtag.c @@ -47,7 +47,7 @@ int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info) return mips_ejtag_drscan_32(ejtag_info, &ejtag_info->idcode); } -static int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info) +int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info) { mips_ejtag_set_instr(ejtag_info, EJTAG_INST_IMPCODE); @@ -332,7 +332,7 @@ static void ejtag_v26_print_imp(struct mips_ejtag *ejtag_info) EJTAG_IMP_HAS(EJTAG_V26_IMP_DINT) ? " DINT" : ""); } -static void ejtag_main_print_imp(struct mips_ejtag *ejtag_info) +void ejtag_main_print_imp(struct mips_ejtag *ejtag_info) { LOG_DEBUG("EJTAG main: features:%s%s%s%s%s", EJTAG_IMP_HAS(EJTAG_IMP_ASID8) ? " ASID_8" : "", diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h index 852444a51..172ac5955 100644 --- a/src/target/mips_ejtag.h +++ b/src/target/mips_ejtag.h @@ -186,6 +186,22 @@ #define EJTAG64_V25_IBA0 0xFFFFFFFFFF301100ull #define EJTAG64_V25_IBS 0xFFFFFFFFFF301000ull +static const struct dcr_feature { + int bit; + const char *name; +} dcr_features[] = { + {22, "DAS"}, + {18, "FDC"}, + {17, "DataBrk"}, + {16, "InstBrk"}, + {15, "Inverted Data value"}, + {14, "Data value stored"}, + {10, "Complex Breakpoints"}, + { 9, "PC Sampling"}, +}; + +#define EJTAG_DCR_ENTRIES (ARRAY_SIZE(dcr_features)) + struct mips_ejtag { struct jtag_tap *tap; uint32_t impcode; @@ -244,6 +260,9 @@ int mips_ejtag_init(struct mips_ejtag *ejtag_info); int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step); int mips64_ejtag_config_step(struct mips_ejtag *ejtag_info, bool enable_step); +void ejtag_main_print_imp(struct mips_ejtag *ejtag_info); +int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info); + static inline void mips_le_to_h_u32(jtag_callback_data_t arg) { uint8_t *in = (uint8_t *)arg;