This is an automated email from Gerrit. Daniel Glöckner ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/4247
-- gerrit commit 92cf5778644b2c3c9c9d63afc35055773325541d Author: Daniel Glöckner <[email protected]> Date: Sun Oct 8 11:48:33 2017 +0200 mips32: allow Ingenic XBurst BTB to be disabled in debug mode On Ingenic JZ4730 the branch target buffer also affects dmseg. It remembers unconditional branches executed from dmseg and will do the same branches on following code snippets executed from there regardless of the actual instruction at that address. So on affected processors we must disable the BTB before we execute the first branch (i.e. before mips32_pracc_read_regs ends) and restore it after the last branch done in debug mode (i.e. in the same snipped that executes DRET). The old value of the enable bit is cached and changes to it are deferred. A configuration stage command is added to enable the workaround. Later JZ47xx processors also have a BTB that is controlled with this bit, but it is unknown if it affects dmseg/debug mode there. Change-Id: I6f1a48382b3f6d36cabfa40f05d61c7a8328fef2 Signed-off-by: Daniel Glöckner <[email protected]> diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c index 790c8dc..e9433d1 100644 --- a/src/target/mips32_pracc.c +++ b/src/target/mips32_pracc.c @@ -571,6 +571,10 @@ int mips32_cp0_read(struct mips_ejtag *ejtag_info, uint32_t *val, uint32_t cp0_r ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, val, 1); pracc_queue_free(&ctx); + + if (cp0_reg == 16 && cp0_sel == 7 && ejtag_info->xburst_btb_on) + *val &= ~1; + return ctx.retval; } @@ -579,6 +583,11 @@ int mips32_cp0_write(struct mips_ejtag *ejtag_info, uint32_t val, uint32_t cp0_r struct pracc_queue_info ctx = {.ejtag_info = ejtag_info}; pracc_queue_init(&ctx); + if (cp0_reg == 16 && cp0_sel == 7 && ejtag_info->has_xburst_btb) { + ejtag_info->xburst_btb_on = !(val & 1); + val |= 1; + } + pracc_add_li32(&ctx, 15, val, 0); /* Load val to $15 */ pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 15, cp0_reg, cp0_sel)); /* write $15 to cp0 reg / sel */ @@ -890,6 +899,14 @@ int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs) pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + (i * 4), MIPS32_SW(ctx.isa, i, PRACC_OUT_OFFSET + (i * 4), 1)); + if (ejtag_info->has_xburst_btb) { + pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, 16, 7)); /* move config7 to $8 */ + pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT, /* store config7 value from $8 to param out */ + MIPS32_SW(ctx.isa, 8, PRACC_OUT_OFFSET, 1)); + pracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 8, 1)); /* set BTBE to disable branch target buffer */ + pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 8, 16, 7)); /* store $8 in config7 */ + } + for (int i = 0; i != 6; i++) { pracc_add(&ctx, 0, cp0_read_code[i]); /* load COP0 needed registers to $8 */ pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + (i + 32) * 4, /* store $8 at PARAM OUT */ @@ -907,6 +924,11 @@ int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs) ejtag_info->reg8 = regs[8]; /* reg8 is saved but not restored, next called function should restore it */ ejtag_info->reg9 = regs[9]; + + if (ejtag_info->has_xburst_btb) + ejtag_info->xburst_btb_on = !(regs[0] & 1); + + regs[0] = 0; pracc_queue_free(&ctx); return ctx.retval; } diff --git a/src/target/mips_ejtag.c b/src/target/mips_ejtag.c index f4c40e4..a732cfe 100644 --- a/src/target/mips_ejtag.c +++ b/src/target/mips_ejtag.c @@ -235,11 +235,23 @@ error: int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info) { - pa_list pracc_list = {.instr = MIPS32_DRET(ejtag_info->isa), .addr = 0}; - struct pracc_queue_info ctx = {.max_code = 1, .pracc_list = &pracc_list, .code_count = 1, .store_count = 0}; + struct pracc_queue_info ctx = {.ejtag_info = ejtag_info}; + pracc_queue_init(&ctx); + + if (ejtag_info->xburst_btb_on) { + pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 8, 31, 0)); /* move $8 to COP0 DeSave */ + pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, 16, 7)); /* move config7 to $8 */ + pracc_add(&ctx, 0, MIPS32_SRL(ctx.isa, 8, 8, 1)); /* clear the lowest bit */ + pracc_add(&ctx, 0, MIPS32_SLL(ctx.isa, 8, 8, 1)); + pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 8, 16, 7)); /* store $8 in config7 */ + pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, 31, 0)); /* move DeSave to $8 */ + } + + pracc_add(&ctx, 0, MIPS32_DRET(ejtag_info->isa)); /* execute our dret instruction */ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 0); /* shift out instr, omit last check */ + pracc_queue_free(&ctx); /* pic32mx workaround, false pending at low core clock */ jtag_add_sleep(1000); diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h index 71f5c1b..c93757b 100644 --- a/src/target/mips_ejtag.h +++ b/src/target/mips_ejtag.h @@ -185,6 +185,8 @@ struct mips_ejtag { int fast_access_save; uint32_t config_regs; /* number of config registers read */ uint32_t config[4]; /* cp0 config to config3 */ + bool has_xburst_btb; + bool xburst_btb_on; uint32_t reg8; uint32_t reg9; diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index 7d1c06c..96dd146 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -1412,6 +1412,17 @@ COMMAND_HANDLER(mips_m4k_handle_scan_delay_command) return ERROR_OK; } +COMMAND_HANDLER(mips_m4k_handle_xburst_btb_command) +{ + struct target *target = get_current_target(CMD_CTX); + struct mips_m4k_common *mips_m4k = target_to_m4k(target); + struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info; + + ejtag_info->has_xburst_btb = 1; + + return ERROR_OK; +} + static const struct command_registration mips_m4k_exec_command_handlers[] = { { .name = "cp0", @@ -1448,6 +1459,13 @@ static const struct command_registration mips_m4k_exec_command_handlers[] = { .help = "display/set scan delay in nano seconds", .usage = "[value]", }, + { + .name = "xburst_btb", + .handler = mips_m4k_handle_xburst_btb_command, + .mode = COMMAND_CONFIG, + .help = "enable special handling of XBurst branch target buffer", + .usage = "", + }, COMMAND_REGISTRATION_DONE }; -- ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
