This is an automated email from Gerrit.

Tomas Vanek ([email protected]) just uploaded a new patch set to Gerrit, which you 
can find at http://openocd.zylin.com/5321

-- gerrit

commit e24338814caffc6af7fa10467995e1af561c7b4e
Author: Tomas Vanek <[email protected]>
Date:   Tue Feb 5 09:39:11 2019 +0100

    target/cortex_m: faster reading of all CPU registers
    
    Without the change cortex_m_debug_entry() reads all registers
    calling cortexm_dap_read_coreregister_u32() for each register with
    a poor usage of JTAG/SWD queue.
    It is time consuming, especially on an USB FS based adapter.
    Moreover if target_request debugmsgs are enabled, DCB_DCRDR
    is saved and restored on each register read.
    
    This change introduces cortex_m_dap_read_all_regs()
    which queues all register reads and a single dap_run() transaction
    does all work.
    
    cortex_m_dap_read_all_regs() reads all registers unconditionally
    regardless register cache is valid or not. This is a difference
    from the original cortex_m_debug_entry() code.
    
    cortex_m_debug_entry times from -d3 log, Cortex-M4F and CMSIS-DAP
    (Kinetis K28F-FRDM kit)
    
    target_request |                time [ms]
    debugmsgs      | without the change | with the change
    ---------------+--------------------+-----------------
    disable        |        186         |       23
    enable         |        232         |       25
    
    Change-Id: I0665d94b97ede217394640871dc451ec93410254
    Signed-off-by: Tomas Vanek <[email protected]>

diff --git a/src/target/cortex_m.c b/src/target/cortex_m.c
index 7f59401..9ee9ff5 100644
--- a/src/target/cortex_m.c
+++ b/src/target/cortex_m.c
@@ -89,6 +89,124 @@ static int cortexm_dap_read_coreregister_u32(struct target 
*target,
        return retval;
 }
 
+static int cortex_m_dap_read_all_regs(struct target *target)
+{
+       struct armv7m_common *armv7m = target_to_armv7m(target);
+       int retval;
+       uint32_t dcrdr;
+
+       /* because the DCB_DCRDR is used for the emulated dcc channel
+        * we have to save/restore the DCB_DCRDR when used */
+       if (target->dbg_msg_enabled) {
+               retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &dcrdr);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
+
+       int i;
+       struct reg *r;
+       uint32_t r_vals[ARMV7M_PSP+1];
+       uint32_t ctrl_faultmsk_basepri_primask;
+       for (i = ARMV7M_R0; i <= ARMV7M_PSP; i++) {
+               retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, i);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, 
&r_vals[i]);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
+
+       /* Control / Faultmask / Basepri / Primask */
+       retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, 0x14);
+       if (retval != ERROR_OK)
+               return retval;
+
+       retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, 
&ctrl_faultmsk_basepri_primask);
+       if (retval != ERROR_OK)
+               return retval;
+
+       uint32_t fp_vals[32];
+       uint32_t fpscr;
+       if (armv7m->fp_feature != FP_NONE) {
+               for (i = 0; i < 32; i++) {
+                       retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, 
i + 0x40);
+                       if (retval != ERROR_OK)
+                               return retval;
+
+                       retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, 
&fp_vals[i]);
+                       if (retval != ERROR_OK)
+                               return retval;
+               }
+
+               /* FPSCR */
+               retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, 0x21);
+               if (retval != ERROR_OK)
+                       return retval;
+
+               retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &fpscr);
+               if (retval != ERROR_OK)
+                       return retval;
+
+       }
+
+       retval = dap_run(armv7m->debug_ap->dap);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (target->dbg_msg_enabled) {
+               /* restore DCB_DCRDR - this needs to be in a separate
+                * transaction otherwise the emulated DCC channel breaks */
+               retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRDR, 
dcrdr);
+               if (retval != ERROR_OK)
+                       return retval;
+       }
+
+       for (i = ARMV7M_R0; i <= ARMV7M_PSP; i++) {
+               r = &armv7m->arm.core_cache->reg_list[i];
+               buf_set_u32(r->value, 0, 32, r_vals[i]);
+               r->valid = true;
+               r->dirty = false;
+       }
+
+       r = &armv7m->arm.core_cache->reg_list[ARMV7M_PRIMASK];
+       buf_set_u32(r->value, 0, 8, ctrl_faultmsk_basepri_primask);
+       r->valid = true;
+       r->dirty = false;
+
+       r = &armv7m->arm.core_cache->reg_list[ARMV7M_BASEPRI];
+       buf_set_u32(r->value, 0, 8, ctrl_faultmsk_basepri_primask >> 8);
+       r->valid = true;
+       r->dirty = false;
+
+       r = &armv7m->arm.core_cache->reg_list[ARMV7M_FAULTMASK];
+       buf_set_u32(r->value, 0, 8, ctrl_faultmsk_basepri_primask >> 16);
+       r->valid = true;
+       r->dirty = false;
+
+       r = &armv7m->arm.core_cache->reg_list[ARMV7M_CONTROL];
+       buf_set_u32(r->value, 0, 8, ctrl_faultmsk_basepri_primask >> 24);
+       r->valid = true;
+       r->dirty = false;
+
+       if (armv7m->fp_feature != FP_NONE) {
+               for (i = 0; i < 16; i++) {
+                       r = 
&armv7m->arm.core_cache->reg_list[ARMV7M_NUM_CORE_REGS_NOFP + i];
+                       buf_set_u32(r->value, 0, 32, fp_vals[2*i]);
+                       buf_set_u32(r->value + 4, 0, 32, fp_vals[2*i + 1]);
+                       r->valid = true;
+                       r->dirty = false;
+               }
+
+               r = register_get_by_name(armv7m->arm.core_cache, "fpscr", 1);
+               buf_set_u32(r->value, 0, 32, fpscr);
+               r->valid = true;
+               r->dirty = false;
+       }
+
+       return retval;
+}
+
 static int cortexm_dap_write_coreregister_u32(struct target *target,
        uint32_t value, int regnum)
 {
@@ -471,7 +589,6 @@ static int cortex_m_examine_exception_reason(struct target 
*target)
 
 static int cortex_m_debug_entry(struct target *target)
 {
-       int i;
        uint32_t xPSR;
        int retval;
        struct cortex_m_common *cortex_m = target_to_cm(target);
@@ -494,15 +611,7 @@ static int cortex_m_debug_entry(struct target *target)
        if (retval != ERROR_OK)
                return retval;
 
-       /* Examine target state and mode
-        * First load register accessible through core debug port */
-       int num_regs = arm->core_cache->num_regs;
-
-       for (i = 0; i < num_regs; i++) {
-               r = &armv7m->arm.core_cache->reg_list[i];
-               if (!r->valid)
-                       arm->read_core_reg(target, r, i, ARM_MODE_ANY);
-       }
+       cortex_m_dap_read_all_regs(target);
 
        r = arm->cpsr;
        xPSR = buf_get_u32(r->value, 0, 32);

-- 


_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to