This is an automated email from Gerrit.

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

-- gerrit

commit 636f78d95618b6c0aa36af34d58acf339fb0786c
Author: Alamy Liu <[email protected]>
Date:   Mon Oct 19 13:05:03 2015 -0700

    aarch64: rewrite aarch64_read_apb_ab_memory()
    
    Problem:
    > mdw 0xffffffc000097dd0 4 (before: incorrect)
    0xFFFFFFC000097DD0: e00314aa 60025fd6 1f2003d5 1f2003d5
    > mdw 0xffffffc000097dd0 4 (after : correct)
    0xFFFFFFC000097DD0: aa1403e0 d65f0260 d503201f d503201f
    
    Investigation:
    memcpy() will screw up big/little endian order in the case that
    Target & Debugger have different endians.
    i.e.: Target: ARM64; Debugger MIPS
    
    Fix and Other restriction/enhancement
    *) Use buf_set_u32/_u64 instead of memcpy()
    *) 4-byte size access only
    *) Address must be aligned to 4-byte boundary
    *) Fast reading
    
    Change-Id: I84df36193928053a689a52d857beaf369b887d92
    Signed-off-by: Alamy Liu <[email protected]>

diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index b89dc44..92333af 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -28,6 +28,7 @@
 #include "target_type.h"
 #include "target_type64.h"
 #include "arm_opcodes.h"
+#include "armv8_opcodes.h"
 #include <helper/time_support.h>
 
 static int aarch64_poll(struct target *target);
@@ -1872,99 +1873,122 @@ error_free_buff_w:
        return ERROR_FAIL;
 }
 
+/* read memory through APB-AP */
 static int aarch64_read_apb_ab_memory(struct target *target,
        uint64_t address, uint32_t size,
        uint32_t count, uint8_t *buffer)
 {
-       /* read memory through APB-AP */
-
        int retval = ERROR_COMMAND_SYNTAX_ERROR;
        struct armv8_common *armv8 = target_to_armv8(target);
        struct adiv5_dap *swjdp = armv8->arm.dap;
        struct arm *arm = &armv8->arm;
+       struct arm_dpm *dpm = &armv8->dpm;      /* or arm->dpm */
        struct reg *reg;
-       uint32_t dscr, val;
-       uint8_t *tmp_buff = NULL;
-       uint32_t i = 0;
+       uint32_t itr, bytes;
+       uint64_t value;
 
-       LOG_DEBUG("WARNING(Alamy): Review this function");
-       LOG_DEBUG("Reading APB-AP memory address 0x%" PRIx64 " size %"  PRIu32 
" count%"  PRIu32,
+       LOG_DEBUG("Reading APB-AP memory address 0x%" PRIx64 " size %" PRIu32 " 
count %" PRIu32,
                          address, size, count);
        if (target->state != TARGET_HALTED) {
                LOG_WARNING("target not halted");
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       /* Mark register X0, X1 as dirty, as it will be used
+       /* Support 4-byte accessing only (for now?) */
+       if (((address & 0x3) != 0) || (size != 4)) {
+               LOG_WARNING("Unaligned access at 0x%.16" PRIx64, address);
+               return ERROR_TARGET_UNALIGNED_ACCESS;
+       }
+
+       /* Mark register X0 and X1 as dirty, as they will be used
         * for transferring the data.
         * It will be restored automatically when exiting
         * debug mode
         */
-       reg = armv8_get_reg_by_num(arm, 1);
+       reg = armv8_get_reg_by_num(arm, AARCH64_X1);
        reg->dirty = true;
 
-       reg = armv8_get_reg_by_num(arm, 0);
+       reg = armv8_get_reg_by_num(arm, AARCH64_X0);
        reg->dirty = true;
 
-       /*  clear any abort  */
+       /* Clear any sticky error */
        retval = mem_ap_sel_write_atomic_u32(swjdp, armv8->debug_ap,
-               armv8->debug_base + CPUDBG_DRCR, 1<<2);
-       if (retval != ERROR_OK)
-               goto error_free_buff_r;
+               armv8->debug_base + ARMV8_REG_EDRCR, ARMV8_EDRCR_CSE);
+       if (retval != ERROR_OK) {
+               LOG_WARNING("Fail to clear sticky error");
+               /* We could keep going, this is not a critical problem */
+       }
 
-       retval = mem_ap_sel_read_atomic_u32(swjdp, armv8->debug_ap,
-                       armv8->debug_base + CPUDBG_DSCR, &dscr);
-       if (retval != ERROR_OK)
-               goto error_unset_dtr_r;
 
-       if (size > 4) {
-               LOG_WARNING("reading size >4 bytes not yet supported");
-               goto error_unset_dtr_r;
-       }
+       /* Basic 4-byte alignment reading loop */
+       /* while() {
+        *      x1 = addr
+        *      ldr w0, [x1]
+        *      value = w0
+        * }
+        */
 
-       while (i < count * size) {
+       /* Coding consideration:
+        * *) We could load addr to X0, then "mov X1, X0" with dpm->arm->msr()
+        *   dpm->arm->msr(target, opcode <mov X1, X0>, address);
+        * Here we load 'address' into X1 directly, but we need
+        * dpm->prepare & dpm->finish to encapsulate the operations ourself.
+        * *) Use X1 as address base and take the advantage of 'LDR' instruction
+        *   to increase the address after loading, only one function call is
+        *   needed in the loop.
+        * *) Load as many bytes as possible (ldr x0)
+        *
+        * Note:
+        *   It still works without dpm->prepare/finish as they don't do much
+        * at the moment, but it's a bad coding style. Others would not know
+        * what/how to follow. (Oct-19, 2015)
+        */
 
-               retval = aarch64_instr_write_data_dcc_64(arm->dpm, 0xd5330400, 
address+4);
-               if (retval != ERROR_OK)
-                       goto error_unset_dtr_r;
-               retval = mem_ap_sel_read_atomic_u32(swjdp, armv8->debug_ap,
-                       armv8->debug_base + CPUDBG_DSCR, &dscr);
+       retval = dpm->prepare(dpm);
+       if (retval != ERROR_OK)
+               return retval;
 
-               dscr = DSCR_INSTR_COMP;
-               retval = aarch64_exec_opcode(target, 0xb85fc000, &dscr);
-               if (retval != ERROR_OK)
-                       goto error_unset_dtr_r;
-               retval = mem_ap_sel_read_atomic_u32(swjdp, armv8->debug_ap,
-                       armv8->debug_base + CPUDBG_DSCR, &dscr);
+       /* x1 = addr: addr -> DCC -> X1 */
+       retval = aarch64_instr_write_data_dcc_64(dpm,
+                       A64_OPCODE_MRS_DBGDTR_EL0(AARCH64_X1),  /* mrs x1, 
dbgdtr_el0 */
+                       address);
+       if (retval != ERROR_OK)
+               return retval;
 
-               retval = aarch64_instr_read_data_dcc(arm->dpm, 0xd5130400, 
&val);
+       while (count) {
+               /* ldr x0/w0, [x1] */
+               if (count > 1) {
+                       itr = 0xf8408420;       /* ldr  x0, [x1],#8 */
+                       bytes = 8;                      /* two words */
+               } else {
+                       itr = 0xb8404420;       /* ldr  w0, [x1],#4 */
+                       bytes = 4;                      /* one word */
+               }
+
+               /* value = X0 */
+               retval = aarch64_instr_read_data_x0(dpm, itr, &value);
                if (retval != ERROR_OK)
-                       goto error_unset_dtr_r;
-               memcpy(&buffer[i], &val, size);
-               i += 4;
-               address += 4;
-       }
+                       break;
 
-       /* Clear any sticky error */
-       mem_ap_sel_write_atomic_u32(swjdp, armv8->debug_ap,
-               armv8->debug_base + CPUDBG_DRCR, 1<<2);
+               if (count > 1)
+                       buf_set_u64(buffer, 0, 64, value);
+               else
+                       buf_set_u32(buffer, 0, 32, (uint32_t)value);
 
-       /* Done */
-       return ERROR_OK;
+               buffer += bytes;
+               count  -= bytes >> 2;
 
-error_unset_dtr_r:
-       LOG_WARNING("DSCR = 0x%" PRIx32, dscr);
-       /* Todo: Unset DTR mode */
+       }       /* End of while(count--) */
+
+       /* (void) */ dpm->finish(dpm);
 
-error_free_buff_r:
-       LOG_ERROR("error");
-       free(tmp_buff);
 
        /* Clear any sticky error */
-       mem_ap_sel_write_atomic_u32(swjdp, armv8->debug_ap,
-               armv8->debug_base + CPUDBG_DRCR, 1<<2);
+       /* (void) */ mem_ap_sel_write_atomic_u32(swjdp, armv8->debug_ap,
+               armv8->debug_base + ARMV8_REG_EDRCR, ARMV8_EDRCR_CSE);
 
-       return ERROR_FAIL;
+       /* Done */
+       return retval;
 }
 
 static int aarch64_read_phys_memory(struct target *target,

-- 

------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to