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