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

Reply via email to