mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-04 14:00:19 +00:00 
			
		
		
		
	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>
		
			
				
	
	
		
			38 lines
		
	
	
		
			633 B
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			38 lines
		
	
	
		
			633 B
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
/* SPDX-License-Identifier: GPL-2.0+ */
 | 
						|
/*
 | 
						|
 * (C) 2022 Arm Ltd.
 | 
						|
 */
 | 
						|
 | 
						|
#include <config.h>
 | 
						|
#include <asm/macro.h>
 | 
						|
#include <linux/linkage.h>
 | 
						|
 | 
						|
.pushsection .text.smh_trap, "ax"
 | 
						|
/* long smh_trap(unsigned int sysnum, void *addr); */
 | 
						|
ENTRY(smh_trap)
 | 
						|
 | 
						|
#if defined(CONFIG_ARM64)
 | 
						|
	hlt	#0xf000
 | 
						|
#elif defined(CONFIG_CPU_V7M)
 | 
						|
	bkpt	#0xab
 | 
						|
#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
 | 
						|
 | 
						|
ENDPROC(smh_trap)
 | 
						|
.popsection
 |