]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - arch/arm/kernel/entry-header.S
Linux-2.6.12-rc2
[mirror_ubuntu-artful-kernel.git] / arch / arm / kernel / entry-header.S
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 */
164 scno .req r7 @ syscall number
165 tbl .req r8 @ syscall table pointer
166 why .req r8 @ Linux syscall (!= 0)
167 tsk .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