xref: /haiku/src/system/kernel/arch/arm/arch_exceptions.S (revision da8162be21b36442f34a731873d2358a0d63c25a)
102081e09SIthamar R. Adema/*
21b895c83SDavid Karoly * Copyright 2012-2022, Haiku Inc. All rights reserved.
302081e09SIthamar R. Adema * Distributed under the terms of the MIT License.
402081e09SIthamar R. Adema *
502081e09SIthamar R. Adema * Authors:
602081e09SIthamar R. Adema *		Ithamar R. Adema <ithamar@upgrade-android.com>
702081e09SIthamar R. Adema *
802081e09SIthamar R. Adema */
902081e09SIthamar R. Adema
1017569c02SDavid Karoly#include <arch/arm/arch_cpu_defs.h>
1102081e09SIthamar R. Adema
1217569c02SDavid Karoly#include <asm_defs.h>
13f86b5828SIthamar R. Adema
14*61299599SDavid Karoly
15*61299599SDavid Karoly.macro DISABLE_INTERRUPTS
16*61299599SDavid Karoly	mrs		r0, cpsr
17*61299599SDavid Karoly	orr		r0, r0, #(CPSR_I | CPSR_F)
18*61299599SDavid Karoly	msr		cpsr_c, r0
19*61299599SDavid Karoly.endm
20*61299599SDavid Karoly
21f86b5828SIthamar R. Adema/* The following two macros are taken from FreeBSD... */
22f86b5828SIthamar R. Adema
23d244e9efSDavid Karoly.macro PUSH_FRAME_IN_SVC
24f86b5828SIthamar R. Adema	stmdb	sp, {r0-r3}					/* Save 4 registers */
25f86b5828SIthamar R. Adema	mov		r0, lr						/* Save xxx32 r14 */
26f86b5828SIthamar R. Adema	mov		r1, sp						/* Save xxx32 sp */
27f86b5828SIthamar R. Adema	mrs		r3, spsr					/* Save xxx32 spsr */
28f86b5828SIthamar R. Adema	mrs		r2, cpsr					/* Get the CPSR */
29f86b5828SIthamar R. Adema	bic		r2, r2, #(CPSR_MODE_MASK)	/* Fix for SVC mode */
30f86b5828SIthamar R. Adema	orr		r2, r2, #(CPSR_MODE_SVC)
31f86b5828SIthamar R. Adema	msr		cpsr_c, r2					/* Punch into SVC mode */
32f86b5828SIthamar R. Adema	mov		r2, sp						/* Save SVC sp */
33f86b5828SIthamar R. Adema	str		r0, [sp, #-4]!				/* Push return address */
34f86b5828SIthamar R. Adema	str		lr, [sp, #-4]!				/* Push SVC lr */
35f86b5828SIthamar R. Adema	str		r2, [sp, #-4]!				/* Push SVC sp */
3693bcaf36SJonathan Schleifer	msr		spsr, r3					/* Restore correct spsr */
37f86b5828SIthamar R. Adema	ldmdb	r1, {r0-r3}					/* Restore 4 regs from xxx mode */
38f86b5828SIthamar R. Adema	sub		sp, sp, #(4*15)				/* Adjust the stack pointer */
39f86b5828SIthamar R. Adema	stmia	sp, {r0-r12}				/* Push the user mode registers */
40f86b5828SIthamar R. Adema	add		r0, sp, #(4*13)				/* Adjust the stack pointer */
41f86b5828SIthamar R. Adema	stmia	r0, {r13-r14}^				/* Push the user mode registers */
42f86b5828SIthamar R. Adema	mov		r0, r0						/* NOP for previous instruction */
4393bcaf36SJonathan Schleifer	mrs		r0, spsr
44f86b5828SIthamar R. Adema	str		r0, [sp, #-4]!				/* Save spsr */
45f86b5828SIthamar R. Adema.endm
46f86b5828SIthamar R. Adema
47d244e9efSDavid Karoly.macro PULL_FRAME_FROM_SVC_AND_EXIT
48f86b5828SIthamar R. Adema	ldr		r0, [sp], #0x0004			/* Get the SPSR from stack */
4993bcaf36SJonathan Schleifer	msr		spsr, r0					/* restore SPSR */
50f86b5828SIthamar R. Adema	ldmia	sp, {r0-r14}^				/* Restore registers (usr mode) */
51f86b5828SIthamar R. Adema	mov		r0, r0						/* NOP for previous instruction */
52f86b5828SIthamar R. Adema	add		sp, sp, #(4*15)				/* Adjust the stack pointer */
53f86b5828SIthamar R. Adema	ldmia	sp, {sp, lr, pc}^			/* Restore lr and exit */
54f86b5828SIthamar R. Adema.endm
55f86b5828SIthamar R. Adema
561b895c83SDavid Karoly/* The following two macros are adapted from the two macros above, taken from FreeBSD. */
571b895c83SDavid Karoly
58d244e9efSDavid Karoly.macro	PUSH_FRAME
591b895c83SDavid Karoly	str		lr, [sp, #-4]!				/* Push the return address */
601b895c83SDavid Karoly	sub		sp, sp, #(4*17)				/* Adjust the stack pointer */
611b895c83SDavid Karoly	stmia	sp, {r0-r12}				/* Store the general purpose registers */
621b895c83SDavid Karoly	add		r0, sp, #(4*13)				/* Adjust the stack pointer */
631b895c83SDavid Karoly	stmia	r0, {r13-r14}^				/* Store the user mode sp and lr registers */
641b895c83SDavid Karoly	mrs		r0, spsr					/* Store the SPSR */
651b895c83SDavid Karoly	str		r0, [sp, #-4]!
661b895c83SDavid Karoly	mov		r0, #0						/* Fill in svc mode sp and lr with zeroes */
671b895c83SDavid Karoly	str		r0, [sp, #(4*16)]
681b895c83SDavid Karoly	str		r0, [sp, #(4*17)]
691b895c83SDavid Karoly.endm
701b895c83SDavid Karoly
71d244e9efSDavid Karoly.macro	PULL_FRAME_AND_EXIT
721b895c83SDavid Karoly	ldr		r0, [sp], #4				/* Get SPSR from stack */
731b895c83SDavid Karoly	msr		spsr, r0
741b895c83SDavid Karoly	ldmia	sp, {r0-r14}^				/* Restore user mode registers */
751b895c83SDavid Karoly	add		sp, sp, #(4*17)				/* Adjust the stack pointer */
761b895c83SDavid Karoly	ldr		lr, [sp], #4				/* Pull the return address */
771b895c83SDavid Karoly	movs	pc, lr						/* Return to user mode */
781b895c83SDavid Karoly.endm
791b895c83SDavid Karoly
8002081e09SIthamar R. Adema.text
8102081e09SIthamar R. Adema
8202081e09SIthamar R. Adema.globl _vectors_start
8302081e09SIthamar R. Adema_vectors_start:
8402081e09SIthamar R. Adema	ldr		pc, _arm_reset
8502081e09SIthamar R. Adema	ldr		pc, _arm_undefined
8602081e09SIthamar R. Adema	ldr		pc, _arm_syscall
8702081e09SIthamar R. Adema	ldr		pc, _arm_prefetch_abort
8802081e09SIthamar R. Adema	ldr		pc, _arm_data_abort
8902081e09SIthamar R. Adema	ldr		pc, _arm_reserved
9002081e09SIthamar R. Adema	ldr		pc, _arm_irq
9102081e09SIthamar R. Adema	ldr		pc, _arm_fiq
9202081e09SIthamar R. Adema
932b5d52a1SMichael Lotz
9402081e09SIthamar R. Adema_arm_reset:
9502081e09SIthamar R. Adema	.word	arm_reserved // actually reset, but not used when mapped
962b5d52a1SMichael Lotz
9702081e09SIthamar R. Adema_arm_undefined:
9802081e09SIthamar R. Adema	.word	arm_undefined
992b5d52a1SMichael Lotz
10002081e09SIthamar R. Adema_arm_syscall:
10102081e09SIthamar R. Adema	.word	arm_syscall
1022b5d52a1SMichael Lotz
10302081e09SIthamar R. Adema_arm_prefetch_abort:
10402081e09SIthamar R. Adema	.word	arm_prefetch_abort
1052b5d52a1SMichael Lotz
10602081e09SIthamar R. Adema_arm_data_abort:
10702081e09SIthamar R. Adema	.word	arm_data_abort
1082b5d52a1SMichael Lotz
10902081e09SIthamar R. Adema_arm_reserved:
11002081e09SIthamar R. Adema	.word	arm_reserved
1112b5d52a1SMichael Lotz
11202081e09SIthamar R. Adema_arm_irq:
11302081e09SIthamar R. Adema	.word	arm_irq
1142b5d52a1SMichael Lotz
11502081e09SIthamar R. Adema_arm_fiq:
11602081e09SIthamar R. Adema	.word	arm_fiq
1172b5d52a1SMichael Lotz
1182b5d52a1SMichael Lotz
11902081e09SIthamar R. Adema.globl _vectors_end
12002081e09SIthamar R. Adema_vectors_end:
121f8a9b57cSDavid Karoly
122f8a9b57cSDavid Karoly.data
123f8a9b57cSDavid Karoly
12402081e09SIthamar R. Adema	.rept	64
125f86b5828SIthamar R. Adema	.word	0xdeadbeef
12602081e09SIthamar R. Adema	.endr
1272b5d52a1SMichael Lotz
12802081e09SIthamar R. Ademaabort_stack:
129f86b5828SIthamar R. Adema	.word	. - 4
130f86b5828SIthamar R. Adema	.word	0xdeadbeef
131f86b5828SIthamar R. Adema
132f86b5828SIthamar R. Adema	.rept	64
133f86b5828SIthamar R. Adema	.word	0xcafebabe
134f86b5828SIthamar R. Adema	.endr
1352b5d52a1SMichael Lotz
136f86b5828SIthamar R. Ademairq_stack:
137f86b5828SIthamar R. Adema	.word	. - 4
138f86b5828SIthamar R. Adema	.word	0xcafebabe
139f86b5828SIthamar R. Adema
140f86b5828SIthamar R. Adema	.rept	64
141f86b5828SIthamar R. Adema	.word	0xaaaabbbb
142f86b5828SIthamar R. Adema	.endr
1432b5d52a1SMichael Lotz
144f86b5828SIthamar R. Ademafiq_stack:
145f86b5828SIthamar R. Adema	.word	. - 4
146f86b5828SIthamar R. Adema	.word	0xaaaabbbb
147f86b5828SIthamar R. Adema
148f86b5828SIthamar R. Adema	.rept	64
149f86b5828SIthamar R. Adema	.word	0xccccdddd
150f86b5828SIthamar R. Adema	.endr
1512b5d52a1SMichael Lotz
152f86b5828SIthamar R. Ademaund_stack:
153f86b5828SIthamar R. Adema	.word	. - 4
154f86b5828SIthamar R. Adema	.word	0xccccdddd
155f86b5828SIthamar R. Adema
156f8a9b57cSDavid Karoly.text
15702081e09SIthamar R. Adema
15802081e09SIthamar R. AdemaFUNCTION(arm_undefined):
159d244e9efSDavid Karoly	PUSH_FRAME_IN_SVC
160f86b5828SIthamar R. Adema
161c791590aSDavid Karoly	mov		r0, sp		/* iframe */
162c791590aSDavid Karoly	mov		fp, r0
163f86b5828SIthamar R. Adema	bl		arch_arm_undefined
164f86b5828SIthamar R. Adema
165*61299599SDavid Karoly	DISABLE_INTERRUPTS
166d244e9efSDavid Karoly	PULL_FRAME_FROM_SVC_AND_EXIT
167f86b5828SIthamar R. AdemaFUNCTION_END(arm_undefined)
168f86b5828SIthamar R. Adema
16902081e09SIthamar R. Adema
17002081e09SIthamar R. AdemaFUNCTION(arm_syscall):
171d244e9efSDavid Karoly	PUSH_FRAME
172f86b5828SIthamar R. Adema
173c791590aSDavid Karoly	mov		r0, sp		/* iframe */
174c791590aSDavid Karoly	mov		fp, r0
175f86b5828SIthamar R. Adema	bl		arch_arm_syscall
176f86b5828SIthamar R. Adema
177*61299599SDavid Karoly	DISABLE_INTERRUPTS
178d244e9efSDavid Karoly	PULL_FRAME_AND_EXIT
179f86b5828SIthamar R. AdemaFUNCTION_END(arm_syscall)
180f86b5828SIthamar R. Adema
18102081e09SIthamar R. Adema
18202081e09SIthamar R. AdemaFUNCTION(arm_prefetch_abort):
183f86b5828SIthamar R. Adema#ifdef __XSCALE__
184f86b5828SIthamar R. Adema	nop					/* Make absolutely sure any pending */
185f86b5828SIthamar R. Adema	nop					/* imprecise aborts have occurred. */
186f86b5828SIthamar R. Adema#endif
187c791590aSDavid Karoly	sub		lr, lr, #4	/* Adjust LR */
188d244e9efSDavid Karoly	PUSH_FRAME_IN_SVC
189f86b5828SIthamar R. Adema
190c791590aSDavid Karoly	mov		r0, sp		/* iframe */
191c791590aSDavid Karoly	mov		fp, r0
192f86b5828SIthamar R. Adema	bl		arch_arm_prefetch_abort
193f86b5828SIthamar R. Adema
194*61299599SDavid Karoly	DISABLE_INTERRUPTS
195d244e9efSDavid Karoly	PULL_FRAME_FROM_SVC_AND_EXIT
196f86b5828SIthamar R. AdemaFUNCTION_END(arm_prefetch_abort)
197f86b5828SIthamar R. Adema
19802081e09SIthamar R. Adema
19902081e09SIthamar R. AdemaFUNCTION(arm_data_abort):
200f86b5828SIthamar R. Adema#ifdef __XSCALE__
201f86b5828SIthamar R. Adema	nop					/* Make absolutely sure any pending */
202f86b5828SIthamar R. Adema	nop					/* imprecise aborts have occurred. */
203f86b5828SIthamar R. Adema#endif
204c791590aSDavid Karoly	sub		lr, lr, #8	/* Adjust LR */
205d244e9efSDavid Karoly	PUSH_FRAME_IN_SVC
20602081e09SIthamar R. Adema
207c791590aSDavid Karoly	mov		r0, sp		/* iframe */
208c791590aSDavid Karoly	mov		fp, r0
20902081e09SIthamar R. Adema	bl		arch_arm_data_abort
21002081e09SIthamar R. Adema
211*61299599SDavid Karoly	DISABLE_INTERRUPTS
212d244e9efSDavid Karoly	PULL_FRAME_FROM_SVC_AND_EXIT
2131ed5f66cSMichael LotzFUNCTION_END(arm_data_abort)
21402081e09SIthamar R. Adema
21502081e09SIthamar R. Adema
21602081e09SIthamar R. AdemaFUNCTION(arm_reserved):
21702081e09SIthamar R. Adema	b	.
218f86b5828SIthamar R. AdemaFUNCTION_END(arm_reserved)
21902081e09SIthamar R. Adema
2202b5d52a1SMichael Lotz
22102081e09SIthamar R. AdemaFUNCTION(arm_irq):
222c791590aSDavid Karoly	sub		lr, lr, #4	/* Adjust LR */
223d244e9efSDavid Karoly	PUSH_FRAME_IN_SVC
22402081e09SIthamar R. Adema
22502081e09SIthamar R. Adema	mov		r0, sp		/* iframe */
226c791590aSDavid Karoly	mov		fp, r0
22702081e09SIthamar R. Adema	bl		arch_arm_irq
22802081e09SIthamar R. Adema
229*61299599SDavid Karoly	DISABLE_INTERRUPTS
230d244e9efSDavid Karoly	PULL_FRAME_FROM_SVC_AND_EXIT
231f86b5828SIthamar R. AdemaFUNCTION_END(arm_irq)
23202081e09SIthamar R. Adema
23302081e09SIthamar R. Adema
23402081e09SIthamar R. AdemaFUNCTION(arm_fiq):
235c791590aSDavid Karoly	sub		lr, lr, #4	/* Adjust LR */
236d244e9efSDavid Karoly	PUSH_FRAME_IN_SVC
23702081e09SIthamar R. Adema
238f86b5828SIthamar R. Adema	mov		r0, sp		/* iframe */
239c791590aSDavid Karoly	mov		fp, r0
24002081e09SIthamar R. Adema	bl		arch_arm_fiq
24102081e09SIthamar R. Adema
242*61299599SDavid Karoly	DISABLE_INTERRUPTS
243d244e9efSDavid Karoly	PULL_FRAME_FROM_SVC_AND_EXIT
244f86b5828SIthamar R. AdemaFUNCTION_END(arm_fiq)
24502081e09SIthamar R. Adema
246f86b5828SIthamar R. Adema
247f86b5828SIthamar R. Adema
248f86b5828SIthamar R. AdemaFUNCTION(arm_vector_init):
249f86b5828SIthamar R. Adema	mrs	r1, cpsr
250f86b5828SIthamar R. Adema	bic	r1, r1, #CPSR_MODE_MASK
251f86b5828SIthamar R. Adema
252f86b5828SIthamar R. Adema	/* move into modes and set initial sp */
253f86b5828SIthamar R. Adema	mov	r0, r1
254f86b5828SIthamar R. Adema	orr	r0, r0, #CPSR_MODE_FIQ
255f86b5828SIthamar R. Adema	msr	cpsr_c, r0
256f8a9b57cSDavid Karoly	ldr r2, =fiq_stack
257f8a9b57cSDavid Karoly	ldr sp, [r2]
258f86b5828SIthamar R. Adema
259f86b5828SIthamar R. Adema	mov	r0, r1
260f86b5828SIthamar R. Adema	orr	r0, r0, #CPSR_MODE_IRQ
261f86b5828SIthamar R. Adema	msr	cpsr_c, r0
262f8a9b57cSDavid Karoly	ldr r2, =irq_stack
263f8a9b57cSDavid Karoly	ldr sp, [r2]
264f86b5828SIthamar R. Adema
265f86b5828SIthamar R. Adema	mov	r0, r1
266f86b5828SIthamar R. Adema	orr	r0, r0, #CPSR_MODE_ABT
267f86b5828SIthamar R. Adema	msr	cpsr_c, r0
268f8a9b57cSDavid Karoly	ldr r2, =abort_stack
269f8a9b57cSDavid Karoly	ldr sp, [r2]
270f86b5828SIthamar R. Adema
271f86b5828SIthamar R. Adema	mov	r0, r1
272f86b5828SIthamar R. Adema	orr	r0, r0, #CPSR_MODE_UND
273f86b5828SIthamar R. Adema	msr	cpsr_c, r0
274f8a9b57cSDavid Karoly	ldr r2, =und_stack
275f8a9b57cSDavid Karoly	ldr sp, [r2]
276f86b5828SIthamar R. Adema
277f86b5828SIthamar R. Adema	/* ... and return back to supervisor mode */
278f86b5828SIthamar R. Adema	mov	r0, r1
279f86b5828SIthamar R. Adema	orr	r0, r0, #CPSR_MODE_SVC
280f86b5828SIthamar R. Adema	msr	cpsr_c, r0
281f86b5828SIthamar R. Adema
282f86b5828SIthamar R. Adema	bx	lr
283f86b5828SIthamar R. AdemaFUNCTION_END(arm_vector_init)
284