xref: /openbmc/linux/arch/arm/kernel/entry-header.S (revision 1da177e4)
1#include <linux/config.h> /* for CONFIG_ARCH_xxxx */
2#include <linux/linkage.h>
3
4#include <asm/assembler.h>
5#include <asm/constants.h>
6#include <asm/errno.h>
7#include <asm/hardware.h>
8#include <asm/arch/irqs.h>
9#include <asm/arch/entry-macro.S>
10
11#ifndef MODE_SVC
12#define MODE_SVC 0x13
13#endif
14
15	.macro	zero_fp
16#ifdef CONFIG_FRAME_POINTER
17	mov	fp, #0
18#endif
19	.endm
20
21	.text
22
23@ Bad Abort numbers
24@ -----------------
25@
26#define BAD_PREFETCH	0
27#define BAD_DATA	1
28#define BAD_ADDREXCPTN	2
29#define BAD_IRQ		3
30#define BAD_UNDEFINSTR	4
31
32#define PT_TRACESYS	0x00000002
33
34@ OS version number used in SWIs
35@  RISC OS is 0
36@  RISC iX is 8
37@
38#define OS_NUMBER	9
39#define ARMSWI_OFFSET	0x000f0000
40
41@
42@ Stack format (ensured by USER_* and SVC_*)
43@
44#define S_FRAME_SIZE	72
45#define S_OLD_R0	68
46#define S_PSR		64
47
48#define S_PC		60
49#define S_LR		56
50#define S_SP		52
51#define S_IP		48
52#define S_FP		44
53#define S_R10		40
54#define S_R9		36
55#define S_R8		32
56#define S_R7		28
57#define S_R6		24
58#define S_R5		20
59#define S_R4		16
60#define S_R3		12
61#define S_R2		8
62#define S_R1		4
63#define S_R0		0
64#define S_OFF		8
65
66	.macro	set_cpsr_c, reg, mode
67	msr	cpsr_c, \mode
68	.endm
69
70#if __LINUX_ARM_ARCH__ >= 6
71	.macro	disable_irq, temp
72	cpsid	i
73	.endm
74
75	.macro	enable_irq, temp
76	cpsie	i
77	.endm
78#else
79	.macro	disable_irq, temp
80	set_cpsr_c \temp, #PSR_I_BIT | MODE_SVC
81	.endm
82
83	.macro	enable_irq, temp
84	set_cpsr_c \temp, #MODE_SVC
85	.endm
86#endif
87
88	.macro	save_user_regs
89	sub	sp, sp, #S_FRAME_SIZE
90	stmia	sp, {r0 - r12}			@ Calling r0 - r12
91	add	r8, sp, #S_PC
92	stmdb	r8, {sp, lr}^			@ Calling sp, lr
93	mrs	r8, spsr			@ called from non-FIQ mode, so ok.
94	str	lr, [sp, #S_PC]			@ Save calling PC
95	str	r8, [sp, #S_PSR]		@ Save CPSR
96	str	r0, [sp, #S_OLD_R0]		@ Save OLD_R0
97	.endm
98
99	.macro	restore_user_regs
100	ldr	r1, [sp, #S_PSR]		@ Get calling cpsr
101	disable_irq ip				@ disable IRQs
102	ldr	lr, [sp, #S_PC]!		@ Get PC
103	msr	spsr_cxsf, r1			@ save in spsr_svc
104	ldmdb	sp, {r0 - lr}^			@ Get calling r0 - lr
105	mov	r0, r0
106	add	sp, sp, #S_FRAME_SIZE - S_PC
107	movs	pc, lr				@ return & move spsr_svc into cpsr
108	.endm
109
110/*
111 * Must be called with IRQs already disabled.
112 */
113	.macro	fast_restore_user_regs
114	ldr	r1, [sp, #S_OFF + S_PSR]	@ get calling cpsr
115	ldr	lr, [sp, #S_OFF + S_PC]!	@ get pc
116	msr	spsr_cxsf, r1			@ save in spsr_svc
117	ldmdb	sp, {r1 - lr}^			@ get calling r1 - lr
118	mov	r0, r0
119	add	sp, sp, #S_FRAME_SIZE - S_PC
120	movs	pc, lr				@ return & move spsr_svc into cpsr
121	.endm
122
123/*
124 * Must be called with IRQs already disabled.
125 */
126	.macro	slow_restore_user_regs
127	ldr	r1, [sp, #S_PSR]		@ get calling cpsr
128	ldr	lr, [sp, #S_PC]!		@ get pc
129	msr	spsr_cxsf, r1			@ save in spsr_svc
130	ldmdb	sp, {r0 - lr}^			@ get calling r1 - lr
131	mov	r0, r0
132	add	sp, sp, #S_FRAME_SIZE - S_PC
133	movs	pc, lr				@ return & move spsr_svc into cpsr
134	.endm
135
136	.macro	mask_pc, rd, rm
137	.endm
138
139	.macro	get_thread_info, rd
140	mov	\rd, sp, lsr #13
141	mov	\rd, \rd, lsl #13
142	.endm
143
144	.macro	alignment_trap, rbase, rtemp, sym
145#ifdef CONFIG_ALIGNMENT_TRAP
146#define OFF_CR_ALIGNMENT(x)	cr_alignment - x
147
148	ldr	\rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)]
149	mcr	p15, 0, \rtemp, c1, c0
150#endif
151	.endm
152
153
154/*
155 * These are the registers used in the syscall handler, and allow us to
156 * have in theory up to 7 arguments to a function - r0 to r6.
157 *
158 * r7 is reserved for the system call number for thumb mode.
159 *
160 * Note that tbl == why is intentional.
161 *
162 * We must set at least "tsk" and "why" when calling ret_with_reschedule.
163 */
164scno	.req	r7		@ syscall number
165tbl	.req	r8		@ syscall table pointer
166why	.req	r8		@ Linux syscall (!= 0)
167tsk	.req	r9		@ current thread_info
168
169/*
170 * Get the system call number.
171 */
172	.macro	get_scno
173#ifdef CONFIG_ARM_THUMB
174	tst	r8, #PSR_T_BIT		@ this is SPSR from save_user_regs
175	addne	scno, r7, #OS_NUMBER << 20 @ put OS number in
176	ldreq	scno, [lr, #-4]
177
178#else
179	mask_pc	lr, lr
180	ldr	scno, [lr, #-4]		@ get SWI instruction
181#endif
182	.endm
183