gerrit
2017-05-17 14:25:41 UTC
This is an automated email from Gerrit.
Salvador Arroyo (***@yahoo.es) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/4137
-- gerrit
commit 83df979c596898d3502f9646cb93c9aef54a2217
Author: Salvador Arroyo <***@yahoo.es>
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 <***@yahoo.es>
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;
}
--
Salvador Arroyo (***@yahoo.es) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/4137
-- gerrit
commit 83df979c596898d3502f9646cb93c9aef54a2217
Author: Salvador Arroyo <***@yahoo.es>
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 <***@yahoo.es>
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;
}
--