Blame view
arch/arm/kernel/entry-header.S
4.38 KB
bce495d86 [PATCH] ARM: make... |
1 |
#include <linux/init.h> |
1da177e4c Linux-2.6.12-rc2 |
2 3 4 |
#include <linux/linkage.h> #include <asm/assembler.h> |
e6ae744dd kbuild: arm - use... |
5 |
#include <asm/asm-offsets.h> |
1da177e4c Linux-2.6.12-rc2 |
6 |
#include <asm/errno.h> |
bce495d86 [PATCH] ARM: make... |
7 |
#include <asm/thread_info.h> |
1da177e4c Linux-2.6.12-rc2 |
8 9 10 11 12 13 14 15 16 |
@ Bad Abort numbers @ ----------------- @ #define BAD_PREFETCH 0 #define BAD_DATA 1 #define BAD_ADDREXCPTN 2 #define BAD_IRQ 3 #define BAD_UNDEFINSTR 4 |
1da177e4c Linux-2.6.12-rc2 |
17 |
@ |
925c8a1a8 [PATCH] ARM: pt_r... |
18 19 |
@ Most of the stack format comes from struct pt_regs, but with @ the addition of 8 bytes for storing syscall args 5 and 6. |
2dede2d8e [ARM] 3102/1: ARM... |
20 |
@ This _must_ remain a multiple of 8 for EABI. |
1da177e4c Linux-2.6.12-rc2 |
21 |
@ |
1da177e4c Linux-2.6.12-rc2 |
22 |
#define S_OFF 8 |
925c8a1a8 [PATCH] ARM: pt_r... |
23 24 25 26 27 28 29 |
/* * The SWI code relies on the fact that R0 is at the bottom of the stack * (due to slow/fast restore user regs). */ #if S_R0 != 0 #error "Please fix" #endif |
bce495d86 [PATCH] ARM: make... |
30 31 32 33 34 |
.macro zero_fp #ifdef CONFIG_FRAME_POINTER mov fp, #0 #endif .endm |
49f680ea7 [PATCH] ARM SMP: ... |
35 |
.macro alignment_trap, rtemp |
1da177e4c Linux-2.6.12-rc2 |
36 |
#ifdef CONFIG_ALIGNMENT_TRAP |
49f680ea7 [PATCH] ARM SMP: ... |
37 38 |
ldr \rtemp, .LCcralign ldr \rtemp, [\rtemp] |
1da177e4c Linux-2.6.12-rc2 |
39 40 41 |
mcr p15, 0, \rtemp, c1, c0 #endif .endm |
b86040a59 Thumb-2: Implemen... |
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
@ @ Store/load the USER SP and LR registers by switching to the SYS @ mode. Useful in Thumb-2 mode where "stm/ldm rd, {sp, lr}^" is not @ available. Should only be called from SVC mode @ .macro store_user_sp_lr, rd, rtemp, offset = 0 mrs \rtemp, cpsr eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE) msr cpsr_c, \rtemp @ switch to the SYS mode str sp, [\rd, #\offset] @ save sp_usr str lr, [\rd, #\offset + 4] @ save lr_usr eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE) msr cpsr_c, \rtemp @ switch back to the SVC mode .endm .macro load_user_sp_lr, rd, rtemp, offset = 0 mrs \rtemp, cpsr eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE) msr cpsr_c, \rtemp @ switch to the SYS mode ldr sp, [\rd, #\offset] @ load sp_usr ldr lr, [\rd, #\offset + 4] @ load lr_usr eor \rtemp, \rtemp, #(SVC_MODE ^ SYSTEM_MODE) msr cpsr_c, \rtemp @ switch back to the SVC mode .endm #ifndef CONFIG_THUMB2_KERNEL .macro svc_exit, rpsr msr spsr_cxsf, \rpsr |
7db44c75a ARM: v6k: select ... |
74 |
#if defined(CONFIG_CPU_V6) |
200b812d0 Clear the exclusi... |
75 76 77 |
ldr r0, [sp] strex r1, r2, [sp] @ clear the exclusive monitor ldmib sp, {r1 - pc}^ @ load r1 - pc, cpsr |
7db44c75a ARM: v6k: select ... |
78 79 80 |
#elif defined(CONFIG_CPU_32v6K) clrex @ clear the exclusive monitor ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr |
9e6ec39be make Linux bootab... |
81 82 |
#else ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr |
200b812d0 Clear the exclusi... |
83 |
#endif |
b86040a59 Thumb-2: Implemen... |
84 85 86 87 88 89 |
.endm .macro restore_user_regs, fast = 0, offset = 0 ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr ldr lr, [sp, #\offset + S_PC]! @ get pc msr spsr_cxsf, r1 @ save in spsr_svc |
7db44c75a ARM: v6k: select ... |
90 |
#if defined(CONFIG_CPU_V6) |
200b812d0 Clear the exclusi... |
91 |
strex r1, r2, [sp] @ clear the exclusive monitor |
7db44c75a ARM: v6k: select ... |
92 93 |
#elif defined(CONFIG_CPU_32v6K) clrex @ clear the exclusive monitor |
200b812d0 Clear the exclusi... |
94 |
#endif |
b86040a59 Thumb-2: Implemen... |
95 96 97 98 99 |
.if \fast ldmdb sp, {r1 - lr}^ @ get calling r1 - lr .else ldmdb sp, {r0 - lr}^ @ get calling r0 - lr .endif |
8e4971f2f ARM: 5991/1: Fix ... |
100 101 |
mov r0, r0 @ ARMv5T and earlier require a nop @ after ldm {}^ |
b86040a59 Thumb-2: Implemen... |
102 103 104 105 106 107 108 109 |
add sp, sp, #S_FRAME_SIZE - S_PC movs pc, lr @ return & move spsr_svc into cpsr .endm .macro get_thread_info, rd mov \rd, sp, lsr #13 mov \rd, \rd, lsl #13 .endm |
a771fe6e4 ARM: 5757/1: Thum... |
110 111 112 113 114 115 116 |
@ @ 32-bit wide "mov pc, reg" @ .macro movw_pc, reg mov pc, \reg .endm |
b86040a59 Thumb-2: Implemen... |
117 118 |
#else /* CONFIG_THUMB2_KERNEL */ .macro svc_exit, rpsr |
594810621 ARM: Thumb-2: Fix... |
119 120 |
ldr lr, [sp, #S_SP] @ top of the stack ldrd r0, r1, [sp, #S_LR] @ calling lr and pc |
200b812d0 Clear the exclusi... |
121 |
clrex @ clear the exclusive monitor |
594810621 ARM: Thumb-2: Fix... |
122 |
stmdb lr!, {r0, r1, \rpsr} @ calling lr and rfe context |
b86040a59 Thumb-2: Implemen... |
123 |
ldmia sp, {r0 - r12} |
594810621 ARM: Thumb-2: Fix... |
124 125 |
mov sp, lr ldr lr, [sp], #4 |
b86040a59 Thumb-2: Implemen... |
126 127 128 129 |
rfeia sp! .endm .macro restore_user_regs, fast = 0, offset = 0 |
200b812d0 Clear the exclusi... |
130 |
clrex @ clear the exclusive monitor |
b86040a59 Thumb-2: Implemen... |
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
mov r2, sp load_user_sp_lr r2, r3, \offset + S_SP @ calling sp, lr ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr ldr lr, [sp, #\offset + S_PC] @ get pc add sp, sp, #\offset + S_SP msr spsr_cxsf, r1 @ save in spsr_svc .if \fast ldmdb sp, {r1 - r12} @ get calling r1 - r12 .else ldmdb sp, {r0 - r12} @ get calling r0 - r12 .endif add sp, sp, #S_FRAME_SIZE - S_SP movs pc, lr @ return & move spsr_svc into cpsr .endm .macro get_thread_info, rd mov \rd, sp lsr \rd, \rd, #13 mov \rd, \rd, lsl #13 .endm |
a771fe6e4 ARM: 5757/1: Thum... |
151 152 153 154 155 156 157 158 |
@ @ 32-bit wide "mov pc, reg" @ .macro movw_pc, reg mov pc, \reg nop .endm |
b86040a59 Thumb-2: Implemen... |
159 |
#endif /* !CONFIG_THUMB2_KERNEL */ |
1da177e4c Linux-2.6.12-rc2 |
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
/* * These are the registers used in the syscall handler, and allow us to * have in theory up to 7 arguments to a function - r0 to r6. * * r7 is reserved for the system call number for thumb mode. * * Note that tbl == why is intentional. * * We must set at least "tsk" and "why" when calling ret_with_reschedule. */ scno .req r7 @ syscall number tbl .req r8 @ syscall table pointer why .req r8 @ Linux syscall (!= 0) tsk .req r9 @ current thread_info |