This is an automated email from Gerrit.

Rick Wertenbroek (rick.wertenbr...@heig-vd.ch) just uploaded a new patch set to 
Gerrit, which you can find at http://openocd.zylin.com/5827

-- gerrit

commit a457b928009f039e352560d98fabc41d73d37708
Author: Rick Wertenbroek <rick.wertenbr...@heig-vd.ch>
Date:   Wed Aug 26 11:54:54 2020 +0200

    topic: Added support to debug ARM AARCH32 USER mode on AARCH64
    
    The code to debug (set breakpoints, inspect memory, etc.) for
    the ARM AARCH32 USER mode was missing.
    E.g., Debugging 32-bit code that runs in user mode (EL0) on an
    AARCH64 ARM processor (e.g., on a Raspberry Pi 4) was not possible.
    
    This patch adds support to do this.
    In aarch64.c switching to SVC mode was added when in USR mode in
    order to execute the privileged instructions (e.g., mmu modify).
    In armv8_cache.c the flushing / invalidating of the caches was
    added for 32-bit mode. I.e. switch to SVC mode if in USR mode,
    execute DCCIMVAC / ICIMVAU (AARCH32) instead of DC CIVAC / IC IVAU
    (AARCH64).
    
    This now allows to set software breakpoints in AARCH32 USER mode.
    This also allows stepping over functions or syscalls in AARCH32 USER
    mode with GDB. This also allows to inspect the memory in AARCH32
    USER mode from GDB.
    
    Change-Id: I5ed80992c4384310e6cdc2a12328a8edd56c1c0a
    Signed-off-by: Rick Wertenbroek <rick.wertenbr...@heig-vd.ch>

diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index e6b1cc0..dbaf375 100644
--- a/src/target/aarch64.c
+++ b/src/target/aarch64.c
@@ -95,6 +95,9 @@ static int aarch64_restore_system_control_reg(struct target 
*target)
                        instr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL3, 0);
                        break;
 
+               case ARM_MODE_USR:
+                       target_mode = ARM_MODE_SVC;
+                       /* fall through */
                case ARM_MODE_SVC:
                case ARM_MODE_ABT:
                case ARM_MODE_FIQ:
@@ -132,6 +135,7 @@ static int aarch64_mmu_modify(struct target *target, int 
enable)
        struct aarch64_common *aarch64 = target_to_aarch64(target);
        struct armv8_common *armv8 = &aarch64->armv8_common;
        int retval = ERROR_OK;
+       enum arm_mode target_mode = ARM_MODE_ANY;
        uint32_t instr = 0;
 
        if (enable) {
@@ -170,6 +174,9 @@ static int aarch64_mmu_modify(struct target *target, int 
enable)
                instr = ARMV8_MSR_GP(SYSTEM_SCTLR_EL3, 0);
                break;
 
+       case ARM_MODE_USR:
+               target_mode = ARM_MODE_SVC;
+               /* fall through */
        case ARM_MODE_SVC:
        case ARM_MODE_ABT:
        case ARM_MODE_FIQ:
@@ -184,8 +191,24 @@ static int aarch64_mmu_modify(struct target *target, int 
enable)
                break;
        }
 
+       if (target_mode != ARM_MODE_ANY)
+               armv8_dpm_modeswitch(&armv8->dpm, target_mode);
+
        retval = armv8->dpm.instr_write_data_r0(&armv8->dpm, instr,
                                aarch64->system_control_reg_curr);
+
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (target_mode != ARM_MODE_ANY)
+               armv8_dpm_modeswitch(&armv8->dpm, ARM_MODE_ANY);
+
+       armv8->armv8_mmu.mmu_enabled =
+               (aarch64->system_control_reg & 0x1U) ? 1 : 0;
+       armv8->armv8_mmu.armv8_cache.d_u_cache_enabled =
+               (aarch64->system_control_reg & 0x4U) ? 1 : 0;
+       armv8->armv8_mmu.armv8_cache.i_cache_enabled =
+               (aarch64->system_control_reg & 0x1000U) ? 1 : 0;
        return retval;
 }
 
@@ -1032,6 +1055,9 @@ static int aarch64_post_debug_entry(struct target *target)
                instr = ARMV8_MRS(SYSTEM_SCTLR_EL3, 0);
                break;
 
+       case ARM_MODE_USR:
+               target_mode = ARM_MODE_SVC;
+               /* fall through */
        case ARM_MODE_SVC:
        case ARM_MODE_ABT:
        case ARM_MODE_FIQ:
diff --git a/src/target/armv8_cache.c b/src/target/armv8_cache.c
index 41c85c9..f3bae72 100644
--- a/src/target/armv8_cache.c
+++ b/src/target/armv8_cache.c
@@ -130,14 +130,36 @@ int armv8_cache_d_inner_flush_virt(struct armv8_common 
*armv8, target_addr_t va,
        va_line = va & (-linelen);
        va_end = va + size;
 
-       while (va_line < va_end) {
-               /* DC CIVAC */
+       if (armv8_dpm_get_core_state(dpm) != ARM_STATE_AARCH64) {
                /* Aarch32: DCCIMVAC: ARMV4_5_MCR(15, 0, 0, 7, 14, 1) */
-               retval = dpm->instr_write_data_r0_64(dpm,
+               uint32_t opcode = ARMV4_5_MCR(15, 0, 0, 7, 14, 1);
+               enum arm_mode target_mode = ARM_MODE_ANY;
+               if (armv8->arm.core_mode == ARM_MODE_USR)
+                       target_mode = ARM_MODE_SVC;
+
+               if (target_mode != ARM_MODE_ANY)
+                       armv8_dpm_modeswitch(&armv8->dpm, target_mode);
+
+               while (va_line < va_end) {
+                       retval = dpm->instr_write_data_r0(dpm, opcode, va_line);
+                       if (retval != ERROR_OK)
+                               goto done;
+                       va_line += linelen;
+               }
+
+               if (target_mode != ARM_MODE_ANY)
+                       armv8_dpm_modeswitch(&armv8->dpm, ARM_MODE_ANY);
+
+       } else {
+               while (va_line < va_end) {
+                       /* DC CIVAC */
+
+                       retval = dpm->instr_write_data_r0_64(dpm,
                                armv8_opcode(armv8, ARMV8_OPC_DCCIVAC), 
va_line);
-               if (retval != ERROR_OK)
-                       goto done;
-               va_line += linelen;
+                       if (retval != ERROR_OK)
+                               goto done;
+                       va_line += linelen;
+               }
        }
 
        dpm->finish(dpm);
@@ -169,20 +191,43 @@ int armv8_cache_i_inner_inval_virt(struct armv8_common 
*armv8, target_addr_t va,
        va_line = va & (-linelen);
        va_end = va + size;
 
-       while (va_line < va_end) {
-               /* IC IVAU - Invalidate instruction cache by VA to PoU. */
-               retval = dpm->instr_write_data_r0_64(dpm,
+       if (armv8_dpm_get_core_state(dpm) != ARM_STATE_AARCH64) {
+               /* Aarch32: ICIMVAU: ARMV4_5_MCR(15, 0, 0, 7, 5, 1) */
+               uint32_t opcode = ARMV4_5_MCR(15, 0, 0, 7, 5, 1);
+               enum arm_mode target_mode = ARM_MODE_ANY;
+               if (armv8->arm.core_mode == ARM_MODE_USR)
+                       target_mode = ARM_MODE_SVC;
+
+               if (target_mode != ARM_MODE_ANY)
+                       armv8_dpm_modeswitch(&armv8->dpm, target_mode);
+
+               while (va_line < va_end) {
+                       retval = dpm->instr_write_data_r0(dpm, opcode, va_line);
+                       if (retval != ERROR_OK)
+                               goto done;
+                       va_line += linelen;
+               }
+
+               if (target_mode != ARM_MODE_ANY)
+                       armv8_dpm_modeswitch(&armv8->dpm, ARM_MODE_ANY);
+
+       } else {
+               while (va_line < va_end) {
+                       /* IC IVAU - Invalidate instruction cache by VA to PoU. 
*/
+
+                       retval = dpm->instr_write_data_r0_64(dpm,
                                armv8_opcode(armv8, ARMV8_OPC_ICIVAU), va_line);
-               if (retval != ERROR_OK)
-                       goto done;
-               va_line += linelen;
+                       if (retval != ERROR_OK)
+                               goto done;
+                       va_line += linelen;
+               }
        }
 
        dpm->finish(dpm);
        return retval;
 
 done:
-       LOG_ERROR("d-cache invalidate failed");
+       LOG_ERROR("i-cache invalidate failed");
        dpm->finish(dpm);
 
        return retval;

-- 


_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to