mips32, add option to avoid check in last instruction 21/4021/2
authorSalvador Arroyo <sarroyofdez@yahoo.es>
Mon, 27 Feb 2017 11:25:49 +0000 (12:25 +0100)
committerFreddie Chopin <freddie.chopin@gmail.com>
Mon, 8 May 2017 17:00:09 +0000 (18:00 +0100)
This option is needed, for example, when exiting
debug mode in bmips targets. The last instruction
is a NOP, not a DERET. When working in async mode
this check is not done, mips32_pracc_queue_exec() pass
the parameter to mips32_pracc_exec() and never use it.

Change-Id: I4c7ed4feb1588b62e2645b955b501b6671113b36
Signed-off-by: Salvador Arroyo <sarroyofdez@yahoo.es>
Reviewed-on: http://openocd.zylin.com/4021
Tested-by: jenkins
Reviewed-by: Freddie Chopin <freddie.chopin@gmail.com>
src/target/mips32_pracc.c
src/target/mips32_pracc.h
src/target/mips_ejtag.c

index da1cee13c98ebc95ec3f7a527efed1b5d5b05339..73242463888a3db8d145b0026ff32b2e3d94e38d 100644 (file)
@@ -159,7 +159,8 @@ int mips32_pracc_clean_text_jump(struct mips_ejtag *ejtag_info)
        return ERROR_OK;
 }
 
-int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx, uint32_t *param_out)
+int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx,
+                                       uint32_t *param_out, bool check_last)
 {
        int code_count = 0;
        int store_pending = 0;          /* increases with every store instruction at dmseg, decreases with every store pa */
@@ -289,7 +290,7 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ct
                /* finish processor access, let the processor eat! */
                mips32_pracc_finish(ejtag_info);
 
-               if (instr == MIPS32_DRET)       /* after leaving debug mode nothing to do */
+               if (final_check && !check_last)                 /* last instr, don't check, execute and exit */
                        return jtag_execute_queue();
 
                if (store_pending == 0 && pass) {       /* store access done, but after passing pracc text */
@@ -346,7 +347,8 @@ inline void pracc_queue_free(struct pracc_queue_info *ctx)
                free(ctx->pracc_list);
 }
 
-int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx, uint32_t *buf)
+int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx,
+                                       uint32_t *buf, bool check_last)
 {
        if (ctx->retval != ERROR_OK) {
                LOG_ERROR("Out of memory");
@@ -354,7 +356,7 @@ int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_in
        }
 
        if (ejtag_info->mode == 0)
-               return mips32_pracc_exec(ejtag_info, ctx, buf);
+               return mips32_pracc_exec(ejtag_info, ctx, buf, check_last);
 
        union scan_in {
                uint8_t scan_96[12];
@@ -459,7 +461,7 @@ int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t
        pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1)));                                        /* jump to start */
        pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0));                                     /* move COP0 DeSave to $15 */
 
-       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf);
+       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf, 1);
        pracc_queue_free(&ctx);
        return ctx.retval;
 }
@@ -491,40 +493,40 @@ int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size
                int this_round_count = (count > 256) ? 256 : count;
                uint32_t last_upper_base_addr = UPPER16((addr + 0x8000));
 
-               pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR));                      /* $15 = MIPS32_PRACC_BASE_ADDR */
-               pracc_add(&ctx, 0, MIPS32_LUI(9, last_upper_base_addr));                /* load the upper memory address in $9 */
+               pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR));      /* $15 = MIPS32_PRACC_BASE_ADDR */
+               pracc_add(&ctx, 0, MIPS32_LUI(9, last_upper_base_addr));        /* load the upper memory address in $9 */
 
                for (int i = 0; i != this_round_count; i++) {                   /* Main code loop */
                        uint32_t upper_base_addr = UPPER16((addr + 0x8000));
-                       if (last_upper_base_addr != upper_base_addr) {                  /* if needed, change upper address in $9 */
+                       if (last_upper_base_addr != upper_base_addr) {          /* if needed, change upper address in $9 */
                                pracc_add(&ctx, 0, MIPS32_LUI(9, upper_base_addr));
                                last_upper_base_addr = upper_base_addr;
                        }
 
                        if (size == 4)
-                               pracc_add(&ctx, 0, MIPS32_LW(8, LOWER16(addr), 9));             /* load from memory to $8 */
+                               pracc_add(&ctx, 0, MIPS32_LW(8, LOWER16(addr), 9));     /* load from memory to $8 */
                        else if (size == 2)
                                pracc_add(&ctx, 0, MIPS32_LHU(8, LOWER16(addr), 9));
                        else
                                pracc_add(&ctx, 0, MIPS32_LBU(8, LOWER16(addr), 9));
 
                        pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT + i * 4,
-                                         MIPS32_SW(8, PRACC_OUT_OFFSET + i * 4, 15));          /* store $8 at param out */
+                                         MIPS32_SW(8, PRACC_OUT_OFFSET + i * 4, 15));  /* store $8 at param out */
                        addr += size;
                }
                pracc_add_li32(&ctx, 8, ejtag_info->reg8, 0);                           /* restore $8 */
                pracc_add_li32(&ctx, 9, ejtag_info->reg9, 0);                           /* restore $9 */
 
-               pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1)));                                /* jump to start */
-               pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0));                                     /* restore $15 from DeSave */
+               pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1)));                /* jump to start */
+               pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0));                             /* restore $15 from DeSave */
 
                if (size == 4) {
-                       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf32);
+                       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, buf32, 1);
                        if (ctx.retval != ERROR_OK)
                                goto exit;
                        buf32 += this_round_count;
                } else {
-                       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, data);
+                       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, data, 1);
                        if (ctx.retval != ERROR_OK)
                                goto exit;
 
@@ -550,16 +552,16 @@ int mips32_cp0_read(struct mips_ejtag *ejtag_info, uint32_t *val, uint32_t cp0_r
        struct pracc_queue_info ctx;
        pracc_queue_init(&ctx);
 
-       pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR));                      /* $15 = MIPS32_PRACC_BASE_ADDR */
+       pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR));              /* $15 = MIPS32_PRACC_BASE_ADDR */
        pracc_add(&ctx, 0, MIPS32_MFC0(8, cp0_reg, cp0_sel));                   /* move cp0 reg / sel to $8 */
        pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT,
                                MIPS32_SW(8, PRACC_OUT_OFFSET, 15));                    /* store $8 to pracc_out */
        pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0));                                     /* restore $15 from DeSave */
        pracc_add(&ctx, 0, MIPS32_LUI(8, UPPER16(ejtag_info->reg8)));           /* restore upper 16 bits  of $8 */
-       pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1)));                                        /* jump to start */
-       pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8)));                /* restore lower 16 bits of $8 */
+       pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1)));                                /* jump to start */
+       pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8)));        /* restore lower 16 bits of $8 */
 
-       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, val);
+       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, val, 1);
        pracc_queue_free(&ctx);
        return ctx.retval;
 }
@@ -575,7 +577,7 @@ int mips32_cp0_write(struct mips_ejtag *ejtag_info, uint32_t val, uint32_t cp0_r
        pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1)));                /* jump to start */
        pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0));                             /* restore $15 from DeSave */
 
-       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
+       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
        pracc_queue_free(&ctx);
        return ctx.retval;
 }
@@ -616,19 +618,19 @@ static int mips32_pracc_synchronize_cache(struct mips_ejtag *ejtag_info,
        /** Find cache line size in bytes */
        uint32_t clsiz;
        if (rel) {      /* Release 2 (rel = 1) */
-               pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR));                      /* $15 = MIPS32_PRACC_BASE_ADDR */
+               pracc_add(&ctx, 0, MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR));      /* $15 = MIPS32_PRACC_BASE_ADDR */
 
-               pracc_add(&ctx, 0, MIPS32_RDHWR(8, MIPS32_SYNCI_STEP));                 /* load synci_step value to $8 */
+               pracc_add(&ctx, 0, MIPS32_RDHWR(8, MIPS32_SYNCI_STEP));         /* load synci_step value to $8 */
 
                pracc_add(&ctx, MIPS32_PRACC_PARAM_OUT,
                                MIPS32_SW(8, PRACC_OUT_OFFSET, 15));                    /* store $8 to pracc_out */
 
                pracc_add_li32(&ctx, 8, ejtag_info->reg8, 0);                           /* restore $8 */
 
-               pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1)));                                        /* jump to start */
-               pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0));                                     /* move COP0 DeSave to $15 */
+               pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1)));        /* jump to start */
+               pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0));                             /* restore $15 from DeSave */
 
-               ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, &clsiz);
+               ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, &clsiz, 1);
                if (ctx.retval != ERROR_OK)
                        goto exit;
 
@@ -689,7 +691,7 @@ static int mips32_pracc_synchronize_cache(struct mips_ejtag *ejtag_info,
                        pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1)));                /* jump to start */
                        pracc_add(&ctx, 0, MIPS32_NOP);                                         /* nop in delay slot */
 
-                       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
+                       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
                        if (ctx.retval != ERROR_OK)
                                goto exit;
 
@@ -701,7 +703,7 @@ static int mips32_pracc_synchronize_cache(struct mips_ejtag *ejtag_info,
        pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1)));                                        /* jump to start */
        pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0));                                     /* restore $15 from DeSave*/
 
-       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
+       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
 exit:
        pracc_queue_free(&ctx);
        return ctx.retval;
@@ -755,7 +757,7 @@ static int mips32_pracc_write_mem_generic(struct mips_ejtag *ejtag_info,
                pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1)));                                /* jump to start */
                pracc_add(&ctx, 0, MIPS32_MFC0(15, 31, 0));                             /* restore $15 from DeSave */
 
-               ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
+               ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
                if (ctx.retval != ERROR_OK)
                        goto exit;
                count -= this_round_count;
@@ -847,7 +849,7 @@ int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
        pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1)));                                /* jump to start */
        pracc_add(&ctx, 0, MIPS32_ORI(1, 1, LOWER16((regs[1]))));               /* load lower half word in $1 */
 
-       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
+       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
 
        ejtag_info->reg8 = regs[8];
        ejtag_info->reg9 = regs[9];
@@ -889,7 +891,7 @@ int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
        pracc_add(&ctx, 0, MIPS32_B(NEG16(ctx.code_count + 1)));                                        /* jump to start */
        pracc_add(&ctx, 0, MIPS32_MTC0(15, 31, 0));                                     /* load $15 in DeSave */
 
-       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, regs);
+       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, regs, 1);
 
        ejtag_info->reg8 = regs[8];     /* reg8 is saved but not restored, next called function should restore it */
        ejtag_info->reg9 = regs[9];
index 525d6e618ec5646770e392cf8c7bfc306b04ad78..e990f8d0c7cabe258d2c84ad2031d337e16042f9 100644 (file)
@@ -61,7 +61,7 @@ void pracc_add(struct pracc_queue_info *ctx, uint32_t addr, uint32_t instr);
 void pracc_add_li32(struct pracc_queue_info *ctx, uint32_t reg_num, uint32_t data, bool optimize);
 void pracc_queue_free(struct pracc_queue_info *ctx);
 int mips32_pracc_queue_exec(struct mips_ejtag *ejtag_info,
-                           struct pracc_queue_info *ctx, uint32_t *buf);
+                           struct pracc_queue_info *ctx, uint32_t *buf, bool check_last);
 
 int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info,
                uint32_t addr, int size, int count, void *buf);
@@ -73,7 +73,8 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
 int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs);
 int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs);
 
-int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx, uint32_t *param_out);
+int mips32_pracc_exec(struct mips_ejtag *ejtag_info, struct pracc_queue_info *ctx,
+                               uint32_t *param_out, bool check_last);
 
 /**
  * \b mips32_cp0_read
index 1a8a843a89797d77fe0837f65f4fa63cdf200731..e35758d1f803bbe7c2d2c1e43c36fbd0fe548afb 100644 (file)
@@ -210,7 +210,7 @@ int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step)
        pracc_add(&ctx, 0, MIPS32_B(NEG16((ctx.code_count + 1))));                      /* jump to start */
        pracc_add(&ctx, 0, MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8)));        /* restore lower 16 bits of $8 */
 
-       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
+       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
        pracc_queue_free(&ctx);
        return ctx.retval;
 }
@@ -273,7 +273,7 @@ int mips_ejtag_exit_debug(struct mips_ejtag *ejtag_info)
        struct pracc_queue_info ctx = {.max_code = 1, .pracc_list = &pracc_list, .code_count = 1, .store_count = 0};
 
        /* execute our dret instruction */
-       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL);
+       ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 0);
 
        /* pic32mx workaround, false pending at low core clock */
        jtag_add_sleep(1000);

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)