|
From: <ge...@op...> - 2017-05-17 14:25:49
|
This is an automated email from Gerrit. Salvador Arroyo (sar...@ya...) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/4137 -- gerrit commit 83df979c596898d3502f9646cb93c9aef54a2217 Author: Salvador Arroyo <sar...@ya...> Date: Wed May 17 15:50:02 2017 +0200 mips32: add mode command to select sync or async mode The scan_delay command now only sets the additonal delay. For low clocked cores a meaningful increase in speed can be achieved when working in sync with pracc. Fasdata transfer works either in async or sync mode with the same scan rate settings. Default scan_delay set to 2uS, enough for a core clocked at 8Mhz with internal memory like pic32. New modes/options can be added without handler modification. Change-Id: I87bdb0ccca3bb68cde34784523105bdc92bc1b4b Signed-off-by: Salvador Arroyo <sar...@ya...> diff --git a/src/target/mips32.c b/src/target/mips32.c index 93fb4e6..7881275 100644 --- a/src/target/mips32.c +++ b/src/target/mips32.c @@ -386,8 +386,8 @@ int mips32_init_arch_info(struct target *target, struct mips32_common *mips32, s mips32->write_core_reg = mips32_write_core_reg; /* if unknown endianness defaults to little endian, 1 */ mips32->ejtag_info.endianness = target->endianness == TARGET_BIG_ENDIAN ? 0 : 1; - mips32->ejtag_info.scan_delay = MIPS32_SCAN_DELAY_LEGACY_MODE; - mips32->ejtag_info.mode = 0; /* Initial default value */ + mips32->ejtag_info.scan_delay = 2000; + mips32->ejtag_info.mode[pa_mode] = opt_sync; /* in sync with pracc */ mips32->ejtag_info.isa = 0; /* isa on debug mips32, updated by poll function */ mips32->ejtag_info.config_regs = 0; /* no config register read */ return ERROR_OK; @@ -977,13 +977,66 @@ COMMAND_HANDLER(mips32_handle_scan_delay_command) return ERROR_COMMAND_SYNTAX_ERROR; command_print(CMD_CTX, "scan delay: %d nsec", ejtag_info->scan_delay); - if (ejtag_info->scan_delay >= MIPS32_SCAN_DELAY_LEGACY_MODE) { - ejtag_info->mode = 0; - command_print(CMD_CTX, "running in legacy mode"); - } else { - ejtag_info->mode = 1; - command_print(CMD_CTX, "running in fast queued mode"); - } + command_print(CMD_CTX, "use mips32 mode command for mode selection"); + return ERROR_OK; +} + +const Jim_Nvp mode_options[] = { + {"sync", (pa_mode << 8) + opt_sync}, + {"async", (pa_mode << 8) + opt_async}, + + {"help", HELP_OPTION}, + + {NULL, -1} +}; + +/* options not added here are not shown */ +const Jim_Nvp mode_messages[] = { + {" mode sync: in sync with pracc (safer)", (pa_mode << 8) + opt_sync}, + {" mode async: in async pracc mode (faster)", (pa_mode << 8) + opt_async}, + + {NULL, -1} +}; + +COMMAND_HANDLER(mips32_handle_mode_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; + + Jim_Nvp *p; + + if (CMD_ARGC == 0) /* print current settings */ + for (unsigned i = 0; i != max_mode; i++) { + p = Jim_Nvp_value2name_simple(mode_messages, ejtag_info->mode[i] + (i << 8)); + if (p->value >= 0) /* mode added */ + command_print(CMD_CTX, "%s", p->name); + } + else + for (unsigned i = 0; i != CMD_ARGC; i++) { + p = Jim_Nvp_name2value_simple(mode_options, CMD_ARGV[i]); + if (p->value >= 0 && p->value < HELP_OPTION) { + + unsigned mode = p->value >> 8; + unsigned option = p->value & 0xff; + if (mode < max_mode) { /* only to be sure */ + ejtag_info->mode[mode] = option; + /* print saved option */ + p = Jim_Nvp_value2name_simple(mode_messages, + (mode << 8) + ejtag_info->mode[mode]); + if (p->value >= 0) + command_print(CMD_CTX, "%s", p->name); + } + + } else if (p->value != HELP_OPTION) + command_print(CMD_CTX, "option not valid: %s", CMD_ARGV[i]); + /* help: print the list of options */ + else { + unsigned j = 0; + while (mode_messages[j].value >= 0) + command_print(CMD_CTX, "%s", mode_messages[j++].name); + } + } return ERROR_OK; } @@ -1003,6 +1056,14 @@ static const struct command_registration mips32_exec_command_handlers[] = { .help = "display/set scan delay in nano seconds", .usage = "[value]", }, + { + .name = "mode", + .handler = mips32_handle_mode_command, + .mode = COMMAND_ANY, + .help = "set or display (without option) several mode options, help for list of options", + .usage = "[option1] [option2] ... [help]: list of options]", + }, + COMMAND_REGISTRATION_DONE }; diff --git a/src/target/mips32.h b/src/target/mips32.h index 928598f..8454980 100644 --- a/src/target/mips32.h +++ b/src/target/mips32.h @@ -42,7 +42,7 @@ /** Returns the kernel segment base of a given address */ #define KSEGX(a) ((a) & 0xe0000000) -/** CP0 CONFIG regites fields */ +/** CP0 CONFIG register fields */ #define MIPS32_CONFIG0_KU_SHIFT 25 #define MIPS32_CONFIG0_KU_MASK (0x7 << MIPS32_CONFIG0_KU_SHIFT) @@ -65,6 +65,7 @@ #define MIPS32_ARCH_REL2 0x1 #define MIPS32_SCAN_DELAY_LEGACY_MODE 2000000 +#define HELP_OPTION 0x10000 /* offsets into mips32 core register cache */ enum { diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c index 7311363..64dd41a 100644 --- a/src/target/mips32_pracc.c +++ b/src/target/mips32_pracc.c @@ -76,7 +76,7 @@ static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, bool read_addr) { int64_t then = timeval_ms(); - + jtag_add_clocks(ejtag_info->clocks); while (1) { mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); ejtag_info->pa_ctrl = ejtag_info->ejtag_ctrl; @@ -364,7 +364,9 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in for (int i = 0; i != ctx->code_count; i++) ctx->pracc_list[i].instr = SWAP16(ctx->pracc_list[i].instr); - if (ejtag_info->mode == 0) + mips_ejtag_update_clocks(ejtag_info); + + if (ejtag_info->mode[pa_mode] == opt_sync) return mips32_pracc_exec(ejtag_info, ctx, buf, check_last); union scan_in { @@ -381,21 +383,18 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in return ERROR_FAIL; } - unsigned num_clocks = - ((uint64_t)(ejtag_info->scan_delay) * jtag_get_speed_khz() + 500000) / 1000000; - uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC; mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ALL); int scan_count = 0; for (int i = 0; i != ctx->code_count; i++) { - jtag_add_clocks(num_clocks); + jtag_add_clocks(ejtag_info->clocks); mips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, ctx->pracc_list[i].instr, scan_in[scan_count++].scan_96); /* Check store address from previous instruction, if not the first */ if (i > 0 && ctx->pracc_list[i - 1].addr) { - jtag_add_clocks(num_clocks); + jtag_add_clocks(ejtag_info->clocks); mips_ejtag_add_scan_96(ejtag_info, ejtag_ctrl, 0, scan_in[scan_count++].scan_96); } } @@ -1011,12 +1010,10 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA); mips_ejtag_fastdata_scan(ejtag_info, 1, &val); - unsigned num_clocks = 0; /* like in legacy code */ - if (ejtag_info->mode != 0) - num_clocks = ((uint64_t)(ejtag_info->scan_delay) * jtag_get_speed_khz() + 500000) / 1000000; + mips_ejtag_update_clocks(ejtag_info); for (int i = 0; i < count; i++) { - jtag_add_clocks(num_clocks); + jtag_add_clocks(ejtag_info->clocks); mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++); } diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h index d637dd4..0bcba02 100644 --- a/src/target/mips_ejtag.h +++ b/src/target/mips_ejtag.h @@ -177,6 +177,11 @@ #define EJTAG_VERSION_41 4 #define EJTAG_VERSION_51 5 +enum working_modes { + pa_mode = 0, + max_mode = 1, +}; + struct mips_ejtag { struct jtag_tap *tap; uint32_t impcode; @@ -189,7 +194,8 @@ struct mips_ejtag { uint32_t reg8; uint32_t reg9; unsigned scan_delay; - int mode; + unsigned clocks; + int mode[max_mode]; uint32_t pa_ctrl; uint32_t pa_addr; unsigned int ejtag_version; @@ -216,6 +222,12 @@ struct mips_ejtag { uint32_t ejtag_dba_step_size; /* size of step till next *DBAn register. */ }; +/* options */ +enum pa_mode_opt { + opt_sync = 0, + opt_async = 1, +}; + void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, uint32_t new_instr); int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info); int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info); @@ -238,4 +250,8 @@ static inline void mips_le_to_h_u32(jtag_callback_data_t arg) *((uint32_t *)arg) = le_to_h_u32(in); } +inline void mips_ejtag_update_clocks(struct mips_ejtag *ejtag_info) +{ + ejtag_info->clocks = ((uint64_t)(ejtag_info->scan_delay) * jtag_get_speed_khz() + 500000) / 1000000; +} #endif /* OPENOCD_TARGET_MIPS_EJTAG_H */ diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index 7d1c06c..2798fdc 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -1401,13 +1401,7 @@ COMMAND_HANDLER(mips_m4k_handle_scan_delay_command) return ERROR_COMMAND_SYNTAX_ERROR; command_print(CMD_CTX, "scan delay: %d nsec", ejtag_info->scan_delay); - if (ejtag_info->scan_delay >= MIPS32_SCAN_DELAY_LEGACY_MODE) { - ejtag_info->mode = 0; - command_print(CMD_CTX, "running in legacy mode"); - } else { - ejtag_info->mode = 1; - command_print(CMD_CTX, "running in fast queued mode"); - } + command_print(CMD_CTX, "use mips32 mode command for mode selection"); return ERROR_OK; } -- |