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