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/5826

-- gerrit

commit fa2248e602b09093922c5bb043bcfe69cc66e086
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: I9c20e674837ce10ee605ef7a5f1563bd84e95189
    Signed-off-by: Rick Wertenbroek <rick.wertenbr...@heig-vd.ch>

diff --git a/src/target/aarch64.c b/src/target/aarch64.c
index e6b1cc0..ce9012d 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..54a6400 100644
--- a/src/target/armv8_cache.c
+++ b/src/target/armv8_cache.c
@@ -133,8 +133,25 @@ int armv8_cache_d_inner_flush_virt(struct armv8_common 
*armv8, target_addr_t va,
        while (va_line < va_end) {
                /* DC CIVAC */
                /* Aarch32: DCCIMVAC: ARMV4_5_MCR(15, 0, 0, 7, 14, 1) */
-               retval = dpm->instr_write_data_r0_64(dpm,
-                               armv8_opcode(armv8, ARMV8_OPC_DCCIVAC), 
va_line);
+               if (armv8_dpm_get_core_state(dpm) != ARM_STATE_AARCH64) {
+                       enum arm_mode target_mode = ARM_MODE_ANY;
+                       uint32_t opcode = ARMV4_5_MCR(15, 0, 0, 7, 14, 1);
+                       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);
+
+                       retval = dpm->instr_write_data_r0(dpm, opcode, va_line);
+                       if (retval != ERROR_OK)
+                               goto done;
+
+                       if (target_mode != ARM_MODE_ANY)
+                               armv8_dpm_modeswitch(&armv8->dpm, ARM_MODE_ANY);
+               } else {
+                       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;
@@ -171,8 +188,26 @@ int armv8_cache_i_inner_inval_virt(struct armv8_common 
*armv8, target_addr_t va,
 
        while (va_line < va_end) {
                /* IC IVAU - Invalidate instruction cache by VA to PoU. */
-               retval = dpm->instr_write_data_r0_64(dpm,
+               /* Aarch32: ICIMVAU: ARMV4_5_MCR(15, 0, 0, 7, 5, 1) */
+               if (armv8_dpm_get_core_state(dpm) != ARM_STATE_AARCH64) {
+                       enum arm_mode target_mode = ARM_MODE_ANY;
+                       uint32_t opcode = ARMV4_5_MCR(15, 0, 0, 7, 5, 1);
+                       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);
+
+                       retval = dpm->instr_write_data_r0(dpm, opcode, va_line);
+                       if (retval != ERROR_OK)
+                               goto done;
+
+                       if (target_mode != ARM_MODE_ANY)
+                               armv8_dpm_modeswitch(&armv8->dpm, ARM_MODE_ANY);
+               } else {
+                       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;

-- 


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

Reply via email to