mips: change in restoring debug working register 46/1146/6
authorSalvador Arroyo <sarroyofdez@yahoo.es>
Sun, 24 Feb 2013 16:05:28 +0000 (17:05 +0100)
committerSpencer Oliver <spen@spen-soft.co.uk>
Tue, 2 Apr 2013 15:14:41 +0000 (15:14 +0000)
In current devel code there are 3 functions (related to m4k code) that need to restore register 8 from pracc stack:
mips32_pracc_read_u32()
mips32_cp0_read()
mips32_pracc_write_mem_generic()

And mips32_pracc_read_mem() needs to restore regs 8 and 9 from pracc stack.

Values in this registers should be the same as read by mips32_pracc_read_regs() when entering debug
mode and can be modified by mips32_pracc_write_regs() when leaving debug mode.
There is no need to read their values from the processor registers every time.

The fields reg8 and reg9 are added to struct mips_ejtag to store these register values
and the call to mips32_save_context() is shifted in mips_m4k_debug_entry() in order
to store them before any other function needs to restore these registers.
For the same reason in function mips_m4k_step() the call to mips_m4k_set_breakpoint(), if needed,
should be made after calling mips_m4k_debug_entry().
For single word write the number of pracc accesses are now 9 or 8, from 13 or 12 in current code,
single word read takes now 10 instead of 12.

This patch is really the first in a set of patches for an alternate m4k pracc code
much faster that current code. At least for me with pic32mx works fine.

Change-Id: Ibd9df5e8b9f78ce05a180949ba6a561c761b61d6
Signed-off-by: Salvador Arroyo <sarroyofdez@yahoo.es>
Reviewed-on: http://openocd.zylin.com/1146
Tested-by: jenkins
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
src/target/mips32_pracc.c
src/target/mips_ejtag.h
src/target/mips_m4k.c

index 615cc3ff59439970d3ccd2472a8d951d41796026..2ccbfc7fc4891484e41beae4892554799591b085 100644 (file)
@@ -276,13 +276,13 @@ static int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, u
                                                                                                                /* start: */
                MIPS32_MTC0(15, 31, 0),                                         /* move $15 to COP0 DeSave */
                MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR),                          /* $15 = MIPS32_PRACC_BASE_ADDR */
                                                                                                                /* start: */
                MIPS32_MTC0(15, 31, 0),                                         /* move $15 to COP0 DeSave */
                MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR),                          /* $15 = MIPS32_PRACC_BASE_ADDR */
-               MIPS32_SW(8, PRACC_STACK_OFFSET, 15),                           /* sw $8,PRACC_STACK_OFFSET($15) */
 
                MIPS32_LUI(8, UPPER16((addr + 0x8000))),                        /* load  $8 with modified upper address */
                MIPS32_LW(8, LOWER16(addr), 8),                                 /* lw $8, LOWER16(addr)($8) */
                MIPS32_SW(8, PRACC_OUT_OFFSET, 15),                             /* sw $8,PRACC_OUT_OFFSET($15) */
 
 
                MIPS32_LUI(8, UPPER16((addr + 0x8000))),                        /* load  $8 with modified upper address */
                MIPS32_LW(8, LOWER16(addr), 8),                                 /* lw $8, LOWER16(addr)($8) */
                MIPS32_SW(8, PRACC_OUT_OFFSET, 15),                             /* sw $8,PRACC_OUT_OFFSET($15) */
 
-               MIPS32_LW(8, PRACC_STACK_OFFSET, 15),                           /* lw $8,PRACC_STACK_OFFSET($15) */
+               MIPS32_LUI(8, UPPER16(ejtag_info->reg8)),                               /* restore upper 16 bits of reg 8 */
+               MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8)),                            /* restore lower 16 bits of reg 8 */
                MIPS32_B(NEG16(8)),                                                     /* b start */
                MIPS32_MFC0(15, 31, 0),                                         /* move COP0 DeSave to $15 */
        };
                MIPS32_B(NEG16(8)),                                                     /* b start */
                MIPS32_MFC0(15, 31, 0),                                         /* move COP0 DeSave to $15 */
        };
@@ -330,10 +330,8 @@ int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size
 
                *code_p++ = MIPS32_MTC0(15, 31, 0);                                     /* save $15 in DeSave */
                *code_p++ = MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR);                      /* $15 = MIPS32_PRACC_BASE_ADDR */
 
                *code_p++ = MIPS32_MTC0(15, 31, 0);                                     /* save $15 in DeSave */
                *code_p++ = MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR);                      /* $15 = MIPS32_PRACC_BASE_ADDR */
-               *code_p++ = MIPS32_SW(8, PRACC_STACK_OFFSET, 15);                       /* save $8 and $9 to pracc stack */
-               *code_p++ = MIPS32_SW(9, PRACC_STACK_OFFSET, 15);
                *code_p++ = MIPS32_LUI(9, last_upper_base_addr);                        /* load the upper memory address in $9*/
                *code_p++ = MIPS32_LUI(9, last_upper_base_addr);                        /* load the upper memory address in $9*/
-               code_len = 5;
+               code_len = 3;
 
                for (i = 0; i != this_round_count; i++) {               /* Main code loop */
                        upper_base_addr = UPPER16((addr + 0x8000));
 
                for (i = 0; i != this_round_count; i++) {               /* Main code loop */
                        upper_base_addr = UPPER16((addr + 0x8000));
@@ -356,10 +354,12 @@ int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size
                        addr += size;
                }
 
                        addr += size;
                }
 
-               *code_p++ = MIPS32_LW(9, PRACC_STACK_OFFSET, 15);                       /* restore $8 and $9 from pracc stack */
-               *code_p++ = MIPS32_LW(8, PRACC_STACK_OFFSET, 15);
+               *code_p++ = MIPS32_LUI(8, UPPER16(ejtag_info->reg8));                   /* restore upper 16 bits of reg 8 */
+               *code_p++ = MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8));                /* restore lower 16 bits of reg 8 */
+               *code_p++ = MIPS32_LUI(9, UPPER16(ejtag_info->reg8));                   /* restore upper 16 bits of reg 9 */
+               *code_p++ = MIPS32_ORI(9, 9, LOWER16(ejtag_info->reg8));                /* restore lower 16 bits of reg 9 */
 
 
-               code_len += 4;
+               code_len += 6;
                *code_p++ = MIPS32_B(NEG16(code_len - 1));                                      /* jump to start */
                *code_p = MIPS32_MFC0(15, 31, 0);                                       /* restore $15 from DeSave */
 
                *code_p++ = MIPS32_B(NEG16(code_len - 1));                                      /* jump to start */
                *code_p = MIPS32_MFC0(15, 31, 0);                                       /* restore $15 from DeSave */
 
@@ -395,18 +395,18 @@ int mips32_cp0_read(struct mips_ejtag *ejtag_info, uint32_t *val, uint32_t cp0_r
 {
        /**
         * Do not make this code static, but regenerate it every time,
 {
        /**
         * Do not make this code static, but regenerate it every time,
-        * as 3th element has to be changed to add parameters
+        * as 2th element has to be changed to add parameters
         */
        uint32_t code[] = {
                                                                                                                /* start: */
                MIPS32_MTC0(15, 31, 0),                                                 /* move $15 to COP0 DeSave */
                MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR),                                  /* $15 = MIPS32_PRACC_BASE_ADDR */
         */
        uint32_t code[] = {
                                                                                                                /* start: */
                MIPS32_MTC0(15, 31, 0),                                                 /* move $15 to COP0 DeSave */
                MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR),                                  /* $15 = MIPS32_PRACC_BASE_ADDR */
-               MIPS32_SW(8, PRACC_STACK_OFFSET, 15),                                   /* sw $8,PRACC_STACK_OFFSET($15) */
 
 
-               /* 3 */ MIPS32_MFC0(8, 0, 0),                                           /* move COP0 [cp0_reg select] to $8 */
+               /* 2 */ MIPS32_MFC0(8, 0, 0),                                           /* move COP0 [cp0_reg select] to $8 */
                MIPS32_SW(8, PRACC_OUT_OFFSET, 15),                                     /* sw $8,PRACC_OUT_OFFSET($15) */
 
                MIPS32_SW(8, PRACC_OUT_OFFSET, 15),                                     /* sw $8,PRACC_OUT_OFFSET($15) */
 
-               MIPS32_LW(8, PRACC_STACK_OFFSET, 15),                                   /* lw $8,PRACC_STACK_OFFSET($15) */
+               MIPS32_LUI(8, UPPER16(ejtag_info->reg8)),                               /* restore upper 16 bits of reg 8 */
+               MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8)),                            /* restore lower 16 bits of reg 8 */
                MIPS32_B(NEG16(7)),                                                     /* b start */
                MIPS32_MFC0(15, 31, 0),                                                 /* move COP0 DeSave to $15 */
        };
                MIPS32_B(NEG16(7)),                                                     /* b start */
                MIPS32_MFC0(15, 31, 0),                                                 /* move COP0 DeSave to $15 */
        };
@@ -425,7 +425,7 @@ int mips32_cp0_read(struct mips_ejtag *ejtag_info, uint32_t *val, uint32_t cp0_r
         * MIPS32_MTC0 is implemented via MIPS32_R_INST macro.
         * In order to insert our parameters, we must change rd and funct fields.
         */
         * MIPS32_MTC0 is implemented via MIPS32_R_INST macro.
         * In order to insert our parameters, we must change rd and funct fields.
         */
-       code[3] |= (cp0_reg << 11) | cp0_sel;  /* change rd and funct of MIPS32_R_INST macro */
+       code[2] |= (cp0_reg << 11) | cp0_sel;  /* change rd and funct of MIPS32_R_INST macro */
 
        return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, 0, NULL, 1, val, 1);
 }
 
        return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, 0, NULL, 1, val, 1);
 }
@@ -629,10 +629,8 @@ static int mips32_pracc_write_mem_generic(struct mips_ejtag *ejtag_info, uint32_
                code_p = code;
 
                *code_p++ = MIPS32_MTC0(15, 31, 0);                                     /* save $15 in DeSave */
                code_p = code;
 
                *code_p++ = MIPS32_MTC0(15, 31, 0);                                     /* save $15 in DeSave */
-               *code_p++ = MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR);                      /* $15 = MIPS32_PRACC_BASE_ADDR */
-               *code_p++ = MIPS32_SW(8, PRACC_STACK_OFFSET, 15);                       /* save $8 to pracc stack */
-               *code_p++ = MIPS32_LUI(15, last_upper_base_addr);                       /* reuse $15 as memory base address */
-               code_len = 4;
+               *code_p++ = MIPS32_LUI(15, last_upper_base_addr);                       /* load $15 with memory base address */
+               code_len = 2;
 
                for (i = 0; i != this_round_count; i++) {
                        upper_base_addr = UPPER16((addr + 0x8000));
 
                for (i = 0; i != this_round_count; i++) {
                        upper_base_addr = UPPER16((addr + 0x8000));
@@ -674,8 +672,8 @@ static int mips32_pracc_write_mem_generic(struct mips_ejtag *ejtag_info, uint32_
                        addr += size;
                }
 
                        addr += size;
                }
 
-               *code_p++ = MIPS32_LUI(15, PRACC_UPPER_BASE_ADDR);                      /* $15 = MIPS32_PRACC_BASE_ADDR */
-               *code_p++ = MIPS32_LW(8, PRACC_STACK_OFFSET, 15);                       /* restore $8 from pracc stack */
+               *code_p++ = MIPS32_LUI(8, UPPER16(ejtag_info->reg8)),                   /* restore upper 16 bits of reg 8 */
+               *code_p++ = MIPS32_ORI(8, 8, LOWER16(ejtag_info->reg8)),                /* restore lower 16 bits of reg 8 */
 
                code_len += 4;
                *code_p++ = MIPS32_B(NEG16(code_len - 1));                                      /* jump to start */
 
                code_len += 4;
                *code_p++ = MIPS32_B(NEG16(code_len - 1));                                      /* jump to start */
@@ -810,6 +808,9 @@ int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
 
        int retval = mips32_pracc_exec(ejtag_info, code_len, code, 0, NULL, 0, NULL, 1);
        free(code);
 
        int retval = mips32_pracc_exec(ejtag_info, code_len, code, 0, NULL, 0, NULL, 1);
        free(code);
+
+       ejtag_info->reg8 = regs[8];
+       ejtag_info->reg9 = regs[9];
        return retval;
 }
 
        return retval;
 }
 
@@ -852,8 +853,10 @@ int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
        *code_p = MIPS32_MFC0(1, 31, 0);                                                /* move COP0 DeSave to $1 */
 
        int retval = mips32_pracc_exec(ejtag_info, 49, code, 0, NULL, MIPS32NUMCOREREGS, regs, 1);
        *code_p = MIPS32_MFC0(1, 31, 0);                                                /* move COP0 DeSave to $1 */
 
        int retval = mips32_pracc_exec(ejtag_info, 49, code, 0, NULL, MIPS32NUMCOREREGS, regs, 1);
-
        free(code);
        free(code);
+
+       ejtag_info->reg8 = regs[8];
+       ejtag_info->reg9 = regs[9];
        return retval;
 }
 
        return retval;
 }
 
index 653103cdb6c2edbfab0691ad71d0b4dba1b381f0..1e9fd18079834fdcfd448fc034bbb830546c209d 100644 (file)
@@ -128,6 +128,8 @@ struct mips_ejtag {
        uint32_t idcode;
        uint32_t ejtag_ctrl;
        int fast_access_save;
        uint32_t idcode;
        uint32_t ejtag_ctrl;
        int fast_access_save;
+       uint32_t reg8;
+       uint32_t reg9;
 };
 
 void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info,
 };
 
 void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info,
index fb4c37624135c31a51a9bfd911e1877cb3722071..485f4e8c71c05090add1e7355449d1ac8030ae29 100644 (file)
@@ -90,14 +90,14 @@ static int mips_m4k_debug_entry(struct target *target)
        /* make sure stepping disabled, SSt bit in CP0 debug register cleared */
        mips_ejtag_config_step(ejtag_info, 0);
 
        /* make sure stepping disabled, SSt bit in CP0 debug register cleared */
        mips_ejtag_config_step(ejtag_info, 0);
 
+       mips32_save_context(target);
+
        /* make sure break unit configured */
        mips32_configure_break_unit(target);
 
        /* attempt to find halt reason */
        mips_m4k_examine_debug_reason(target);
 
        /* make sure break unit configured */
        mips32_configure_break_unit(target);
 
        /* attempt to find halt reason */
        mips_m4k_examine_debug_reason(target);
 
-       mips32_save_context(target);
-
        /* default to mips32 isa, it will be changed below if required */
        mips32->isa_mode = MIPS32_ISA_MIPS32;
 
        /* default to mips32 isa, it will be changed below if required */
        mips32->isa_mode = MIPS32_ISA_MIPS32;
 
@@ -558,12 +558,12 @@ static int mips_m4k_step(struct target *target, int current,
        /* registers are now invalid */
        register_cache_invalidate(mips32->core_cache);
 
        /* registers are now invalid */
        register_cache_invalidate(mips32->core_cache);
 
+       LOG_DEBUG("target stepped ");
+       mips_m4k_debug_entry(target);
+
        if (breakpoint)
                mips_m4k_set_breakpoint(target, breakpoint);
 
        if (breakpoint)
                mips_m4k_set_breakpoint(target, breakpoint);
 
-       LOG_DEBUG("target stepped ");
-
-       mips_m4k_debug_entry(target);
        target_call_event_callbacks(target, TARGET_EVENT_HALTED);
 
        return ERROR_OK;
        target_call_event_callbacks(target, TARGET_EVENT_HALTED);
 
        return ERROR_OK;

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)