summaryrefslogtreecommitdiff
path: root/arch/arm/lib
diff options
context:
space:
mode:
authorSean Anderson <sean.anderson@seco.com>2023-10-27 16:40:14 -0400
committerTom Rini <trini@konsulko.com>2023-11-10 12:52:28 -0500
commit6ef83ab6be8978ab85a7d8967e9585ddf5f2bbbd (patch)
tree0df8a7d4c98ecb921119080aacb5726601c4a5f5 /arch/arm/lib
parent298c26c5c7f4105f4e421d227009baeba5c59678 (diff)
downloadu-boot-6ef83ab6be8978ab85a7d8967e9585ddf5f2bbbd.tar.gz
u-boot-6ef83ab6be8978ab85a7d8967e9585ddf5f2bbbd.tar.bz2
u-boot-6ef83ab6be8978ab85a7d8967e9585ddf5f2bbbd.zip
arm: semihosting: Fix returning from traps on ARMv6 and lower
U-Boot runs in supervisor mode. On ARMv6 and lower, software interrupts are taken in supervisor mode. When entering an interrupt, the link register is set to the address of the next instruction. However, if we are already in supervisor mode, this clobbers the link register. The debugger can't help us, since by the time it notices we've taken a software interrupt, the link register is already gone. Work around this by moving the return address to another register. Signed-off-by: Sean Anderson <sean.anderson@seco.com>
Diffstat (limited to 'arch/arm/lib')
-rw-r--r--arch/arm/lib/semihosting.S6
1 files changed, 6 insertions, 0 deletions
diff --git a/arch/arm/lib/semihosting.S b/arch/arm/lib/semihosting.S
index 393aade94a..6e1691a832 100644
--- a/arch/arm/lib/semihosting.S
+++ b/arch/arm/lib/semihosting.S
@@ -18,11 +18,17 @@ ENTRY(smh_trap)
#elif defined(CONFIG_SYS_THUMB_BUILD)
svc #0xab
#else
+#if CONFIG_SYS_ARM_ARCH < 7
+ /* Before the ARMv7 exception model, svc (swi) clobbers lr */
+ mov r2, lr
+#endif
svc #0x123456
#endif
#if defined(CONFIG_ARM64)
ret
+#elif CONFIG_SYS_ARM_ARCH < 7
+ bx r2
#else
bx lr
#endif