diff --git a/src/target/cortex_a.c b/src/target/cortex_a.c index 46362017a..2ebbf6577 100644 --- a/src/target/cortex_a.c +++ b/src/target/cortex_a.c @@ -1380,6 +1380,19 @@ static int cortex_a_set_breakpoint(struct target *target, buf_set_u32(code, 0, 32, ARMV5_BKPT(0x11)); } + /* + * ARMv7-A/R fetches instructions in little-endian on both LE and BE CPUs. + * But Cortex-R4 and Cortex-R5 big-endian require BE instructions. + * https://developer.arm.com/documentation/den0042/a/Coding-for-Cortex-R-Processors/Endianness + * https://developer.arm.com/documentation/den0013/d/Porting/Endianness + */ + if ((((cortex_a->cpuid & CPUDBG_CPUID_MASK) == CPUDBG_CPUID_CORTEX_R4) || + ((cortex_a->cpuid & CPUDBG_CPUID_MASK) == CPUDBG_CPUID_CORTEX_R5)) && + target->endianness == TARGET_BIG_ENDIAN) { + // In place swapping is allowed + buf_bswap32(code, code, 4); + } + retval = target_read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, diff --git a/src/target/cortex_a.h b/src/target/cortex_a.h index 37fba1a88..8e438fd95 100644 --- a/src/target/cortex_a.h +++ b/src/target/cortex_a.h @@ -30,6 +30,9 @@ #define CORTEX_A_MIDR_PARTNUM_SHIFT 4 #define CPUDBG_CPUID 0xD00 +#define CPUDBG_CPUID_MASK 0xff00fff0 +#define CPUDBG_CPUID_CORTEX_R4 0x4100c140 +#define CPUDBG_CPUID_CORTEX_R5 0x4100c150 #define CPUDBG_CTYPR 0xD04 #define CPUDBG_TTYPR 0xD0C #define CPUDBG_LOCKACCESS 0xFB0