xref: /haiku/src/system/kernel/arch/arm/arch_exceptions.S (revision 17569c02ff5fdcb1feea243be687fc83568e206a)
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
10*17569c02SDavid Karoly#include <arch/arm/arch_cpu_defs.h>
1102081e09SIthamar R. Adema
12*17569c02SDavid Karoly#include <asm_defs.h>
13f86b5828SIthamar R. Adema
14f86b5828SIthamar R. Adema/* The following two macros are taken from FreeBSD... */
15f86b5828SIthamar R. Adema
16d244e9efSDavid Karoly.macro PUSH_FRAME_IN_SVC
17f86b5828SIthamar R. Adema	stmdb	sp, {r0-r3}					/* Save 4 registers */
18f86b5828SIthamar R. Adema	mov		r0, lr						/* Save xxx32 r14 */
19f86b5828SIthamar R. Adema	mov		r1, sp						/* Save xxx32 sp */
20f86b5828SIthamar R. Adema	mrs		r3, spsr					/* Save xxx32 spsr */
21f86b5828SIthamar R. Adema	mrs		r2, cpsr					/* Get the CPSR */
22f86b5828SIthamar R. Adema	bic		r2, r2, #(CPSR_MODE_MASK)	/* Fix for SVC mode */
23f86b5828SIthamar R. Adema	orr		r2, r2, #(CPSR_MODE_SVC)
24f86b5828SIthamar R. Adema	msr		cpsr_c, r2					/* Punch into SVC mode */
25f86b5828SIthamar R. Adema	mov		r2, sp						/* Save SVC sp */
26f86b5828SIthamar R. Adema	str		r0, [sp, #-4]!				/* Push return address */
27f86b5828SIthamar R. Adema	str		lr, [sp, #-4]!				/* Push SVC lr */
28f86b5828SIthamar R. Adema	str		r2, [sp, #-4]!				/* Push SVC sp */
2993bcaf36SJonathan Schleifer	msr		spsr, r3					/* Restore correct spsr */
30f86b5828SIthamar R. Adema	ldmdb	r1, {r0-r3}					/* Restore 4 regs from xxx mode */
31f86b5828SIthamar R. Adema	sub		sp, sp, #(4*15)				/* Adjust the stack pointer */
32f86b5828SIthamar R. Adema	stmia	sp, {r0-r12}				/* Push the user mode registers */
33f86b5828SIthamar R. Adema	add		r0, sp, #(4*13)				/* Adjust the stack pointer */
34f86b5828SIthamar R. Adema	stmia	r0, {r13-r14}^				/* Push the user mode registers */
35f86b5828SIthamar R. Adema	mov		r0, r0						/* NOP for previous instruction */
3693bcaf36SJonathan Schleifer	mrs		r0, spsr
37f86b5828SIthamar R. Adema	str		r0, [sp, #-4]!				/* Save spsr */
38f86b5828SIthamar R. Adema.endm
39f86b5828SIthamar R. Adema
40d244e9efSDavid Karoly.macro PULL_FRAME_FROM_SVC_AND_EXIT
41f86b5828SIthamar R. Adema	ldr		r0, [sp], #0x0004			/* Get the SPSR from stack */
4293bcaf36SJonathan Schleifer	msr		spsr, r0					/* restore SPSR */
43f86b5828SIthamar R. Adema	ldmia	sp, {r0-r14}^				/* Restore registers (usr mode) */
44f86b5828SIthamar R. Adema	mov		r0, r0						/* NOP for previous instruction */
45f86b5828SIthamar R. Adema	add		sp, sp, #(4*15)				/* Adjust the stack pointer */
46f86b5828SIthamar R. Adema	ldmia	sp, {sp, lr, pc}^			/* Restore lr and exit */
47f86b5828SIthamar R. Adema.endm
48f86b5828SIthamar R. Adema
491b895c83SDavid Karoly/* The following two macros are adapted from the two macros above, taken from FreeBSD. */
501b895c83SDavid Karoly
51d244e9efSDavid Karoly.macro	PUSH_FRAME
521b895c83SDavid Karoly	str		lr, [sp, #-4]!				/* Push the return address */
531b895c83SDavid Karoly	sub		sp, sp, #(4*17)				/* Adjust the stack pointer */
541b895c83SDavid Karoly	stmia	sp, {r0-r12}				/* Store the general purpose registers */
551b895c83SDavid Karoly	add		r0, sp, #(4*13)				/* Adjust the stack pointer */
561b895c83SDavid Karoly	stmia	r0, {r13-r14}^				/* Store the user mode sp and lr registers */
571b895c83SDavid Karoly	mrs		r0, spsr					/* Store the SPSR */
581b895c83SDavid Karoly	str		r0, [sp, #-4]!
591b895c83SDavid Karoly	mov		r0, #0						/* Fill in svc mode sp and lr with zeroes */
601b895c83SDavid Karoly	str		r0, [sp, #(4*16)]
611b895c83SDavid Karoly	str		r0, [sp, #(4*17)]
621b895c83SDavid Karoly.endm
631b895c83SDavid Karoly
64d244e9efSDavid Karoly.macro	PULL_FRAME_AND_EXIT
651b895c83SDavid Karoly	ldr		r0, [sp], #4				/* Get SPSR from stack */
661b895c83SDavid Karoly	msr		spsr, r0
671b895c83SDavid Karoly	ldmia	sp, {r0-r14}^				/* Restore user mode registers */
681b895c83SDavid Karoly	add		sp, sp, #(4*17)				/* Adjust the stack pointer */
691b895c83SDavid Karoly	ldr		lr, [sp], #4				/* Pull the return address */
701b895c83SDavid Karoly	movs	pc, lr						/* Return to user mode */
711b895c83SDavid Karoly.endm
721b895c83SDavid Karoly
7302081e09SIthamar R. Adema.text
7402081e09SIthamar R. Adema
7502081e09SIthamar R. Adema.globl _vectors_start
7602081e09SIthamar R. Adema_vectors_start:
7702081e09SIthamar R. Adema	ldr		pc, _arm_reset
7802081e09SIthamar R. Adema	ldr		pc, _arm_undefined
7902081e09SIthamar R. Adema	ldr		pc, _arm_syscall
8002081e09SIthamar R. Adema	ldr		pc, _arm_prefetch_abort
8102081e09SIthamar R. Adema	ldr		pc, _arm_data_abort
8202081e09SIthamar R. Adema	ldr		pc, _arm_reserved
8302081e09SIthamar R. Adema	ldr		pc, _arm_irq
8402081e09SIthamar R. Adema	ldr		pc, _arm_fiq
8502081e09SIthamar R. Adema
862b5d52a1SMichael Lotz
8702081e09SIthamar R. Adema_arm_reset:
8802081e09SIthamar R. Adema	.word	arm_reserved // actually reset, but not used when mapped
892b5d52a1SMichael Lotz
9002081e09SIthamar R. Adema_arm_undefined:
9102081e09SIthamar R. Adema	.word	arm_undefined
922b5d52a1SMichael Lotz
9302081e09SIthamar R. Adema_arm_syscall:
9402081e09SIthamar R. Adema	.word	arm_syscall
952b5d52a1SMichael Lotz
9602081e09SIthamar R. Adema_arm_prefetch_abort:
9702081e09SIthamar R. Adema	.word	arm_prefetch_abort
982b5d52a1SMichael Lotz
9902081e09SIthamar R. Adema_arm_data_abort:
10002081e09SIthamar R. Adema	.word	arm_data_abort
1012b5d52a1SMichael Lotz
10202081e09SIthamar R. Adema_arm_reserved:
10302081e09SIthamar R. Adema	.word	arm_reserved
1042b5d52a1SMichael Lotz
10502081e09SIthamar R. Adema_arm_irq:
10602081e09SIthamar R. Adema	.word	arm_irq
1072b5d52a1SMichael Lotz
10802081e09SIthamar R. Adema_arm_fiq:
10902081e09SIthamar R. Adema	.word	arm_fiq
1102b5d52a1SMichael Lotz
1112b5d52a1SMichael Lotz
11202081e09SIthamar R. Adema.globl _vectors_end
11302081e09SIthamar R. Adema_vectors_end:
114f8a9b57cSDavid Karoly
115f8a9b57cSDavid Karoly.data
116f8a9b57cSDavid Karoly
11702081e09SIthamar R. Adema	.rept	64
118f86b5828SIthamar R. Adema	.word	0xdeadbeef
11902081e09SIthamar R. Adema	.endr
1202b5d52a1SMichael Lotz
12102081e09SIthamar R. Ademaabort_stack:
122f86b5828SIthamar R. Adema	.word	. - 4
123f86b5828SIthamar R. Adema	.word	0xdeadbeef
124f86b5828SIthamar R. Adema
125f86b5828SIthamar R. Adema	.rept	64
126f86b5828SIthamar R. Adema	.word	0xcafebabe
127f86b5828SIthamar R. Adema	.endr
1282b5d52a1SMichael Lotz
129f86b5828SIthamar R. Ademairq_stack:
130f86b5828SIthamar R. Adema	.word	. - 4
131f86b5828SIthamar R. Adema	.word	0xcafebabe
132f86b5828SIthamar R. Adema
133f86b5828SIthamar R. Adema	.rept	64
134f86b5828SIthamar R. Adema	.word	0xaaaabbbb
135f86b5828SIthamar R. Adema	.endr
1362b5d52a1SMichael Lotz
137f86b5828SIthamar R. Ademafiq_stack:
138f86b5828SIthamar R. Adema	.word	. - 4
139f86b5828SIthamar R. Adema	.word	0xaaaabbbb
140f86b5828SIthamar R. Adema
141f86b5828SIthamar R. Adema	.rept	64
142f86b5828SIthamar R. Adema	.word	0xccccdddd
143f86b5828SIthamar R. Adema	.endr
1442b5d52a1SMichael Lotz
145f86b5828SIthamar R. Ademaund_stack:
146f86b5828SIthamar R. Adema	.word	. - 4
147f86b5828SIthamar R. Adema	.word	0xccccdddd
148f86b5828SIthamar R. Adema
149f8a9b57cSDavid Karoly.text
15002081e09SIthamar R. Adema
15102081e09SIthamar R. AdemaFUNCTION(arm_undefined):
152d244e9efSDavid Karoly	PUSH_FRAME_IN_SVC
153f86b5828SIthamar R. Adema
154c791590aSDavid Karoly	mov		r0, sp		/* iframe */
155c791590aSDavid Karoly	mov		fp, r0
156f86b5828SIthamar R. Adema	bl		arch_arm_undefined
157f86b5828SIthamar R. Adema
158d244e9efSDavid Karoly	PULL_FRAME_FROM_SVC_AND_EXIT
159f86b5828SIthamar R. AdemaFUNCTION_END(arm_undefined)
160f86b5828SIthamar R. Adema
16102081e09SIthamar R. Adema
16202081e09SIthamar R. AdemaFUNCTION(arm_syscall):
163d244e9efSDavid Karoly	PUSH_FRAME
164f86b5828SIthamar R. Adema
165c791590aSDavid Karoly	mov		r0, sp		/* iframe */
166c791590aSDavid Karoly	mov		fp, r0
167f86b5828SIthamar R. Adema	bl		arch_arm_syscall
168f86b5828SIthamar R. Adema
169d244e9efSDavid Karoly	PULL_FRAME_AND_EXIT
170f86b5828SIthamar R. AdemaFUNCTION_END(arm_syscall)
171f86b5828SIthamar R. Adema
17202081e09SIthamar R. Adema
17302081e09SIthamar R. AdemaFUNCTION(arm_prefetch_abort):
174f86b5828SIthamar R. Adema#ifdef __XSCALE__
175f86b5828SIthamar R. Adema	nop					/* Make absolutely sure any pending */
176f86b5828SIthamar R. Adema	nop					/* imprecise aborts have occurred. */
177f86b5828SIthamar R. Adema#endif
178c791590aSDavid Karoly	sub		lr, lr, #4	/* Adjust LR */
179d244e9efSDavid Karoly	PUSH_FRAME_IN_SVC
180f86b5828SIthamar R. Adema
181c791590aSDavid Karoly	mov		r0, sp		/* iframe */
182c791590aSDavid Karoly	mov		fp, r0
183f86b5828SIthamar R. Adema	bl		arch_arm_prefetch_abort
184f86b5828SIthamar R. Adema
185d244e9efSDavid Karoly	PULL_FRAME_FROM_SVC_AND_EXIT
186f86b5828SIthamar R. AdemaFUNCTION_END(arm_prefetch_abort)
187f86b5828SIthamar R. Adema
18802081e09SIthamar R. Adema
18902081e09SIthamar R. AdemaFUNCTION(arm_data_abort):
190f86b5828SIthamar R. Adema#ifdef __XSCALE__
191f86b5828SIthamar R. Adema	nop					/* Make absolutely sure any pending */
192f86b5828SIthamar R. Adema	nop					/* imprecise aborts have occurred. */
193f86b5828SIthamar R. Adema#endif
194c791590aSDavid Karoly	sub		lr, lr, #8	/* Adjust LR */
195d244e9efSDavid Karoly	PUSH_FRAME_IN_SVC
19602081e09SIthamar R. Adema
197c791590aSDavid Karoly	mov		r0, sp		/* iframe */
198c791590aSDavid Karoly	mov		fp, r0
19902081e09SIthamar R. Adema	bl		arch_arm_data_abort
20002081e09SIthamar R. Adema
201d244e9efSDavid Karoly	PULL_FRAME_FROM_SVC_AND_EXIT
2021ed5f66cSMichael LotzFUNCTION_END(arm_data_abort)
20302081e09SIthamar R. Adema
20402081e09SIthamar R. Adema
20502081e09SIthamar R. AdemaFUNCTION(arm_reserved):
20602081e09SIthamar R. Adema	b	.
207f86b5828SIthamar R. AdemaFUNCTION_END(arm_reserved)
20802081e09SIthamar R. Adema
2092b5d52a1SMichael Lotz
21002081e09SIthamar R. AdemaFUNCTION(arm_irq):
211c791590aSDavid Karoly	sub		lr, lr, #4	/* Adjust LR */
212d244e9efSDavid Karoly	PUSH_FRAME_IN_SVC
21302081e09SIthamar R. Adema
21402081e09SIthamar R. Adema	mov		r0, sp		/* iframe */
215c791590aSDavid Karoly	mov		fp, r0
21602081e09SIthamar R. Adema	bl		arch_arm_irq
21702081e09SIthamar R. Adema
218d244e9efSDavid Karoly	PULL_FRAME_FROM_SVC_AND_EXIT
219f86b5828SIthamar R. AdemaFUNCTION_END(arm_irq)
22002081e09SIthamar R. Adema
22102081e09SIthamar R. Adema
22202081e09SIthamar R. AdemaFUNCTION(arm_fiq):
223c791590aSDavid Karoly	sub		lr, lr, #4	/* Adjust LR */
224d244e9efSDavid Karoly	PUSH_FRAME_IN_SVC
22502081e09SIthamar R. Adema
226f86b5828SIthamar R. Adema	mov		r0, sp		/* iframe */
227c791590aSDavid Karoly	mov		fp, r0
22802081e09SIthamar R. Adema	bl		arch_arm_fiq
22902081e09SIthamar R. Adema
230d244e9efSDavid Karoly	PULL_FRAME_FROM_SVC_AND_EXIT
231f86b5828SIthamar R. AdemaFUNCTION_END(arm_fiq)
23202081e09SIthamar R. Adema
233f86b5828SIthamar R. Adema
234f86b5828SIthamar R. Adema
235f86b5828SIthamar R. AdemaFUNCTION(arm_vector_init):
236f86b5828SIthamar R. Adema	mrs	r1, cpsr
237f86b5828SIthamar R. Adema	bic	r1, r1, #CPSR_MODE_MASK
238f86b5828SIthamar R. Adema
239f86b5828SIthamar R. Adema	/* move into modes and set initial sp */
240f86b5828SIthamar R. Adema	mov	r0, r1
241f86b5828SIthamar R. Adema	orr	r0, r0, #CPSR_MODE_FIQ
242f86b5828SIthamar R. Adema	msr	cpsr_c, r0
243f8a9b57cSDavid Karoly	ldr r2, =fiq_stack
244f8a9b57cSDavid Karoly	ldr sp, [r2]
245f86b5828SIthamar R. Adema
246f86b5828SIthamar R. Adema	mov	r0, r1
247f86b5828SIthamar R. Adema	orr	r0, r0, #CPSR_MODE_IRQ
248f86b5828SIthamar R. Adema	msr	cpsr_c, r0
249f8a9b57cSDavid Karoly	ldr r2, =irq_stack
250f8a9b57cSDavid Karoly	ldr sp, [r2]
251f86b5828SIthamar R. Adema
252f86b5828SIthamar R. Adema	mov	r0, r1
253f86b5828SIthamar R. Adema	orr	r0, r0, #CPSR_MODE_ABT
254f86b5828SIthamar R. Adema	msr	cpsr_c, r0
255f8a9b57cSDavid Karoly	ldr r2, =abort_stack
256f8a9b57cSDavid Karoly	ldr sp, [r2]
257f86b5828SIthamar R. Adema
258f86b5828SIthamar R. Adema	mov	r0, r1
259f86b5828SIthamar R. Adema	orr	r0, r0, #CPSR_MODE_UND
260f86b5828SIthamar R. Adema	msr	cpsr_c, r0
261f8a9b57cSDavid Karoly	ldr r2, =und_stack
262f8a9b57cSDavid Karoly	ldr sp, [r2]
263f86b5828SIthamar R. Adema
264f86b5828SIthamar R. Adema	/* ... and return back to supervisor mode */
265f86b5828SIthamar R. Adema	mov	r0, r1
266f86b5828SIthamar R. Adema	orr	r0, r0, #CPSR_MODE_SVC
267f86b5828SIthamar R. Adema	msr	cpsr_c, r0
268f86b5828SIthamar R. Adema
269f86b5828SIthamar R. Adema	bx	lr
270f86b5828SIthamar R. AdemaFUNCTION_END(arm_vector_init)
271