aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/Makefile5
-rw-r--r--arch/arm/kernel/asm-offsets.c20
-rw-r--r--arch/arm/kernel/entry-armv.S67
-rw-r--r--arch/arm/kernel/entry-common.S65
-rw-r--r--arch/arm/kernel/entry-header.S143
-rw-r--r--arch/arm/kernel/traps.c11
6 files changed, 124 insertions, 187 deletions
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 07a56ff61494..4a2af55e134b 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -31,8 +31,3 @@ head-y := head.o
31obj-$(CONFIG_DEBUG_LL) += debug.o 31obj-$(CONFIG_DEBUG_LL) += debug.o
32 32
33extra-y := $(head-y) init_task.o vmlinux.lds 33extra-y := $(head-y) init_task.o vmlinux.lds
34
35# Spell out some dependencies that aren't automatically figured out
36$(obj)/entry-armv.o: $(obj)/entry-header.S include/asm-arm/constants.h
37$(obj)/entry-common.o: $(obj)/entry-header.S include/asm-arm/constants.h \
38 $(obj)/calls.S
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 99d43259ff89..c1ff4d1f1bfd 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -64,6 +64,26 @@ int main(void)
64 DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate)); 64 DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate));
65 DEFINE(TI_IWMMXT_STATE, (offsetof(struct thread_info, fpstate)+4)&~7); 65 DEFINE(TI_IWMMXT_STATE, (offsetof(struct thread_info, fpstate)+4)&~7);
66 BLANK(); 66 BLANK();
67 DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0));
68 DEFINE(S_R1, offsetof(struct pt_regs, ARM_r1));
69 DEFINE(S_R2, offsetof(struct pt_regs, ARM_r2));
70 DEFINE(S_R3, offsetof(struct pt_regs, ARM_r3));
71 DEFINE(S_R4, offsetof(struct pt_regs, ARM_r4));
72 DEFINE(S_R5, offsetof(struct pt_regs, ARM_r5));
73 DEFINE(S_R6, offsetof(struct pt_regs, ARM_r6));
74 DEFINE(S_R7, offsetof(struct pt_regs, ARM_r7));
75 DEFINE(S_R8, offsetof(struct pt_regs, ARM_r8));
76 DEFINE(S_R9, offsetof(struct pt_regs, ARM_r9));
77 DEFINE(S_R10, offsetof(struct pt_regs, ARM_r10));
78 DEFINE(S_FP, offsetof(struct pt_regs, ARM_fp));
79 DEFINE(S_IP, offsetof(struct pt_regs, ARM_ip));
80 DEFINE(S_SP, offsetof(struct pt_regs, ARM_sp));
81 DEFINE(S_LR, offsetof(struct pt_regs, ARM_lr));
82 DEFINE(S_PC, offsetof(struct pt_regs, ARM_pc));
83 DEFINE(S_PSR, offsetof(struct pt_regs, ARM_cpsr));
84 DEFINE(S_OLD_R0, offsetof(struct pt_regs, ARM_ORIG_r0));
85 DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
86 BLANK();
67#if __LINUX_ARM_ARCH__ >= 6 87#if __LINUX_ARM_ARCH__ >= 6
68 DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id)); 88 DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id));
69 BLANK(); 89 BLANK();
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index bb27c317d94b..2a5c3fe09a95 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -14,12 +14,12 @@
14 * it to save wrong values... Be aware! 14 * it to save wrong values... Be aware!
15 */ 15 */
16#include <linux/config.h> 16#include <linux/config.h>
17#include <linux/init.h>
18 17
19#include <asm/thread_info.h>
20#include <asm/glue.h> 18#include <asm/glue.h>
21#include <asm/ptrace.h>
22#include <asm/vfpmacros.h> 19#include <asm/vfpmacros.h>
20#include <asm/hardware.h> @ should be moved into entry-macro.S
21#include <asm/arch/irqs.h> @ should be moved into entry-macro.S
22#include <asm/arch/entry-macro.S>
23 23
24#include "entry-header.S" 24#include "entry-header.S"
25 25
@@ -118,7 +118,7 @@ __dabt_svc:
118 @ 118 @
119 @ IRQs off again before pulling preserved data off the stack 119 @ IRQs off again before pulling preserved data off the stack
120 @ 120 @
121 disable_irq r0 121 disable_irq
122 122
123 @ 123 @
124 @ restore SPSR and restart the instruction 124 @ restore SPSR and restart the instruction
@@ -198,7 +198,7 @@ __und_svc:
198 @ 198 @
199 @ IRQs off again before pulling preserved data off the stack 199 @ IRQs off again before pulling preserved data off the stack
200 @ 200 @
2011: disable_irq r0 2011: disable_irq
202 202
203 @ 203 @
204 @ restore SPSR and restart the instruction 204 @ restore SPSR and restart the instruction
@@ -232,7 +232,7 @@ __pabt_svc:
232 @ 232 @
233 @ IRQs off again before pulling preserved data off the stack 233 @ IRQs off again before pulling preserved data off the stack
234 @ 234 @
235 disable_irq r0 235 disable_irq
236 236
237 @ 237 @
238 @ restore SPSR and restart the instruction 238 @ restore SPSR and restart the instruction
@@ -316,7 +316,7 @@ __dabt_usr:
316 @ 316 @
317 @ IRQs on, then call the main handler 317 @ IRQs on, then call the main handler
318 @ 318 @
319 enable_irq r2 319 enable_irq
320 mov r2, sp 320 mov r2, sp
321 adr lr, ret_from_exception 321 adr lr, ret_from_exception
322 b do_DataAbort 322 b do_DataAbort
@@ -418,7 +418,7 @@ call_fpe:
418 movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1) 418 movcss r7, r5, lsr #(TIF_USING_IWMMXT + 1)
419 bcs iwmmxt_task_enable 419 bcs iwmmxt_task_enable
420#endif 420#endif
421 enable_irq r7 421 enable_irq
422 add pc, pc, r8, lsr #6 422 add pc, pc, r8, lsr #6
423 mov r0, r0 423 mov r0, r0
424 424
@@ -472,7 +472,7 @@ fpundefinstr:
472__pabt_usr: 472__pabt_usr:
473 usr_entry abt 473 usr_entry abt
474 474
475 enable_irq r0 @ Enable interrupts 475 enable_irq @ Enable interrupts
476 mov r0, r2 @ address (pc) 476 mov r0, r2 @ address (pc)
477 mov r1, sp @ regs 477 mov r1, sp @ regs
478 bl do_PrefetchAbort @ call abort handler 478 bl do_PrefetchAbort @ call abort handler
@@ -522,8 +522,9 @@ ENTRY(__switch_to)
522/* 522/*
523 * Vector stubs. 523 * Vector stubs.
524 * 524 *
525 * This code is copied to 0x200 or 0xffff0200 so we can use branches in the 525 * This code is copied to 0xffff0200 so we can use branches in the
526 * vectors, rather than ldr's. 526 * vectors, rather than ldr's. Note that this code must not
527 * exceed 0x300 bytes.
527 * 528 *
528 * Common stub entry macro: 529 * Common stub entry macro:
529 * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC 530 * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
@@ -544,7 +545,7 @@ vector_\name:
544 @ 545 @
545 mrs r13, cpsr 546 mrs r13, cpsr
546 bic r13, r13, #MODE_MASK 547 bic r13, r13, #MODE_MASK
547 orr r13, r13, #MODE_SVC 548 orr r13, r13, #SVC_MODE
548 msr spsr_cxsf, r13 @ switch to SVC_32 mode 549 msr spsr_cxsf, r13 @ switch to SVC_32 mode
549 550
550 and lr, lr, #15 551 and lr, lr, #15
@@ -552,6 +553,7 @@ vector_\name:
552 movs pc, lr @ Changes mode and branches 553 movs pc, lr @ Changes mode and branches
553 .endm 554 .endm
554 555
556 .globl __stubs_start
555__stubs_start: 557__stubs_start:
556/* 558/*
557 * Interrupt dispatcher 559 * Interrupt dispatcher
@@ -686,37 +688,24 @@ vector_addrexcptn:
686.LCsabt: 688.LCsabt:
687 .word __temp_abt 689 .word __temp_abt
688 690
691 .globl __stubs_end
689__stubs_end: 692__stubs_end:
690 693
691 .equ __real_stubs_start, .LCvectors + 0x200 694 .equ stubs_offset, __vectors_start + 0x200 - __stubs_start
692 695
693.LCvectors: 696 .globl __vectors_start
697__vectors_start:
694 swi SYS_ERROR0 698 swi SYS_ERROR0
695 b __real_stubs_start + (vector_und - __stubs_start) 699 b vector_und + stubs_offset
696 ldr pc, __real_stubs_start + (.LCvswi - __stubs_start) 700 ldr pc, .LCvswi + stubs_offset
697 b __real_stubs_start + (vector_pabt - __stubs_start) 701 b vector_pabt + stubs_offset
698 b __real_stubs_start + (vector_dabt - __stubs_start) 702 b vector_dabt + stubs_offset
699 b __real_stubs_start + (vector_addrexcptn - __stubs_start) 703 b vector_addrexcptn + stubs_offset
700 b __real_stubs_start + (vector_irq - __stubs_start) 704 b vector_irq + stubs_offset
701 b __real_stubs_start + (vector_fiq - __stubs_start) 705 b vector_fiq + stubs_offset
702 706
703ENTRY(__trap_init) 707 .globl __vectors_end
704 stmfd sp!, {r4 - r6, lr} 708__vectors_end:
705
706 mov r0, #0xff000000
707 orr r0, r0, #0x00ff0000 @ high vectors position
708 adr r1, .LCvectors @ set up the vectors
709 ldmia r1, {r1, r2, r3, r4, r5, r6, ip, lr}
710 stmia r0, {r1, r2, r3, r4, r5, r6, ip, lr}
711
712 add r2, r0, #0x200
713 adr r0, __stubs_start @ copy stubs to 0x200
714 adr r1, __stubs_end
7151: ldr r3, [r0], #4
716 str r3, [r2], #4
717 cmp r0, r1
718 blt 1b
719 LOADREGS(fd, sp!, {r4 - r6, pc})
720 709
721 .data 710 .data
722 711
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 53a7e0dea44d..3f8d0e3aefab 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -9,19 +9,10 @@
9 */ 9 */
10#include <linux/config.h> 10#include <linux/config.h>
11 11
12#include <asm/thread_info.h>
13#include <asm/ptrace.h>
14#include <asm/unistd.h> 12#include <asm/unistd.h>
15 13
16#include "entry-header.S" 14#include "entry-header.S"
17 15
18/*
19 * We rely on the fact that R0 is at the bottom of the stack (due to
20 * slow/fast restore user regs).
21 */
22#if S_R0 != 0
23#error "Please fix"
24#endif
25 16
26 .align 5 17 .align 5
27/* 18/*
@@ -30,11 +21,19 @@
30 * stack. 21 * stack.
31 */ 22 */
32ret_fast_syscall: 23ret_fast_syscall:
33 disable_irq r1 @ disable interrupts 24 disable_irq @ disable interrupts
34 ldr r1, [tsk, #TI_FLAGS] 25 ldr r1, [tsk, #TI_FLAGS]
35 tst r1, #_TIF_WORK_MASK 26 tst r1, #_TIF_WORK_MASK
36 bne fast_work_pending 27 bne fast_work_pending
37 fast_restore_user_regs 28
29 @ fast_restore_user_regs
30 ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr
31 ldr lr, [sp, #S_OFF + S_PC]! @ get pc
32 msr spsr_cxsf, r1 @ save in spsr_svc
33 ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
34 mov r0, r0
35 add sp, sp, #S_FRAME_SIZE - S_PC
36 movs pc, lr @ return & move spsr_svc into cpsr
38 37
39/* 38/*
40 * Ok, we need to do extra processing, enter the slow path. 39 * Ok, we need to do extra processing, enter the slow path.
@@ -49,7 +48,7 @@ work_pending:
49 mov r0, sp @ 'regs' 48 mov r0, sp @ 'regs'
50 mov r2, why @ 'syscall' 49 mov r2, why @ 'syscall'
51 bl do_notify_resume 50 bl do_notify_resume
52 disable_irq r1 @ disable interrupts 51 disable_irq @ disable interrupts
53 b no_work_pending 52 b no_work_pending
54 53
55work_resched: 54work_resched:
@@ -59,12 +58,19 @@ work_resched:
59 */ 58 */
60ENTRY(ret_to_user) 59ENTRY(ret_to_user)
61ret_slow_syscall: 60ret_slow_syscall:
62 disable_irq r1 @ disable interrupts 61 disable_irq @ disable interrupts
63 ldr r1, [tsk, #TI_FLAGS] 62 ldr r1, [tsk, #TI_FLAGS]
64 tst r1, #_TIF_WORK_MASK 63 tst r1, #_TIF_WORK_MASK
65 bne work_pending 64 bne work_pending
66no_work_pending: 65no_work_pending:
67 slow_restore_user_regs 66 @ slow_restore_user_regs
67 ldr r1, [sp, #S_PSR] @ get calling cpsr
68 ldr lr, [sp, #S_PC]! @ get pc
69 msr spsr_cxsf, r1 @ save in spsr_svc
70 ldmdb sp, {r0 - lr}^ @ get calling r1 - lr
71 mov r0, r0
72 add sp, sp, #S_FRAME_SIZE - S_PC
73 movs pc, lr @ return & move spsr_svc into cpsr
68 74
69/* 75/*
70 * This is how we return from a fork. 76 * This is how we return from a fork.
@@ -116,9 +122,26 @@ ENTRY(ret_from_fork)
116 122
117 .align 5 123 .align 5
118ENTRY(vector_swi) 124ENTRY(vector_swi)
119 save_user_regs 125 sub sp, sp, #S_FRAME_SIZE
126 stmia sp, {r0 - r12} @ Calling r0 - r12
127 add r8, sp, #S_PC
128 stmdb r8, {sp, lr}^ @ Calling sp, lr
129 mrs r8, spsr @ called from non-FIQ mode, so ok.
130 str lr, [sp, #S_PC] @ Save calling PC
131 str r8, [sp, #S_PSR] @ Save CPSR
132 str r0, [sp, #S_OLD_R0] @ Save OLD_R0
120 zero_fp 133 zero_fp
121 get_scno 134
135 /*
136 * Get the system call number.
137 */
138#ifdef CONFIG_ARM_THUMB
139 tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
140 addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
141 ldreq scno, [lr, #-4]
142#else
143 ldr scno, [lr, #-4] @ get SWI instruction
144#endif
122 arm710_bug_check scno, ip 145 arm710_bug_check scno, ip
123 146
124#ifdef CONFIG_ALIGNMENT_TRAP 147#ifdef CONFIG_ALIGNMENT_TRAP
@@ -126,14 +149,14 @@ ENTRY(vector_swi)
126 ldr ip, [ip] 149 ldr ip, [ip]
127 mcr p15, 0, ip, c1, c0 @ update control register 150 mcr p15, 0, ip, c1, c0 @ update control register
128#endif 151#endif
129 enable_irq ip 152 enable_irq
130 153
131 str r4, [sp, #-S_OFF]! @ push fifth arg 154 str r4, [sp, #-S_OFF]! @ push fifth arg
132 155
133 get_thread_info tsk 156 get_thread_info tsk
134 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing 157 ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
135 bic scno, scno, #0xff000000 @ mask off SWI op-code 158 bic scno, scno, #0xff000000 @ mask off SWI op-code
136 eor scno, scno, #OS_NUMBER << 20 @ check OS number 159 eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
137 adr tbl, sys_call_table @ load syscall table pointer 160 adr tbl, sys_call_table @ load syscall table pointer
138 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls? 161 tst ip, #_TIF_SYSCALL_TRACE @ are we tracing syscalls?
139 bne __sys_trace 162 bne __sys_trace
@@ -144,8 +167,8 @@ ENTRY(vector_swi)
144 167
145 add r1, sp, #S_OFF 168 add r1, sp, #S_OFF
1462: mov why, #0 @ no longer a real syscall 1692: mov why, #0 @ no longer a real syscall
147 cmp scno, #ARMSWI_OFFSET 170 cmp scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE)
148 eor r0, scno, #OS_NUMBER << 20 @ put OS number back 171 eor r0, scno, #__NR_SYSCALL_BASE @ put OS number back
149 bcs arm_syscall 172 bcs arm_syscall
150 b sys_ni_syscall @ not private func 173 b sys_ni_syscall @ not private func
151 174
@@ -190,7 +213,7 @@ ENTRY(sys_call_table)
190@ r5 = syscall table 213@ r5 = syscall table
191 .type sys_syscall, #function 214 .type sys_syscall, #function
192sys_syscall: 215sys_syscall:
193 eor scno, r0, #OS_NUMBER << 20 216 eor scno, r0, #__NR_SYSCALL_BASE
194 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE 217 cmp scno, #__NR_syscall - __NR_SYSCALL_BASE
195 cmpne scno, #NR_syscalls @ check range 218 cmpne scno, #NR_syscalls @ check range
196 stmloia sp, {r5, r6} @ shuffle args 219 stmloia sp, {r5, r6} @ shuffle args
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 4039d8c120b5..a3d40a0e2b04 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -1,24 +1,11 @@
1#include <linux/config.h> /* for CONFIG_ARCH_xxxx */ 1#include <linux/config.h>
2#include <linux/init.h>
2#include <linux/linkage.h> 3#include <linux/linkage.h>
3 4
4#include <asm/assembler.h> 5#include <asm/assembler.h>
5#include <asm/constants.h> 6#include <asm/constants.h>
6#include <asm/errno.h> 7#include <asm/errno.h>
7#include <asm/hardware.h> 8#include <asm/thread_info.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 9
23@ Bad Abort numbers 10@ Bad Abort numbers
24@ ----------------- 11@ -----------------
@@ -29,113 +16,44 @@
29#define BAD_IRQ 3 16#define BAD_IRQ 3
30#define BAD_UNDEFINSTR 4 17#define BAD_UNDEFINSTR 4
31 18
32#define PT_TRACESYS 0x00000002
33
34@ OS version number used in SWIs
35@ RISC OS is 0
36@ RISC iX is 8
37@ 19@
38#define OS_NUMBER 9 20@ Most of the stack format comes from struct pt_regs, but with
39#define ARMSWI_OFFSET 0x000f0000 21@ the addition of 8 bytes for storing syscall args 5 and 6.
40
41@ 22@
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 23#define S_OFF 8
65 24
66 .macro set_cpsr_c, reg, mode 25/*
67 msr cpsr_c, \mode 26 * The SWI code relies on the fact that R0 is at the bottom of the stack
27 * (due to slow/fast restore user regs).
28 */
29#if S_R0 != 0
30#error "Please fix"
31#endif
32
33 .macro zero_fp
34#ifdef CONFIG_FRAME_POINTER
35 mov fp, #0
36#endif
68 .endm 37 .endm
69 38
70#if __LINUX_ARM_ARCH__ >= 6 39#if __LINUX_ARM_ARCH__ >= 6
71 .macro disable_irq, temp 40 .macro disable_irq
72 cpsid i 41 cpsid i
73 .endm 42 .endm
74 43
75 .macro enable_irq, temp 44 .macro enable_irq
76 cpsie i 45 cpsie i
77 .endm 46 .endm
78#else 47#else
79 .macro disable_irq, temp 48 .macro disable_irq
80 set_cpsr_c \temp, #PSR_I_BIT | MODE_SVC 49 msr cpsr_c, #PSR_I_BIT | SVC_MODE
81 .endm 50 .endm
82 51
83 .macro enable_irq, temp 52 .macro enable_irq
84 set_cpsr_c \temp, #MODE_SVC 53 msr cpsr_c, #SVC_MODE
85 .endm 54 .endm
86#endif 55#endif
87 56
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 57 .macro get_thread_info, rd
140 mov \rd, sp, lsr #13 58 mov \rd, sp, lsr #13
141 mov \rd, \rd, lsl #13 59 mov \rd, \rd, lsl #13
@@ -165,18 +83,3 @@ scno .req r7 @ syscall number
165tbl .req r8 @ syscall table pointer 83tbl .req r8 @ syscall table pointer
166why .req r8 @ Linux syscall (!= 0) 84why .req r8 @ Linux syscall (!= 0)
167tsk .req r9 @ current thread_info 85tsk .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
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 6e31718f6008..0078aeb85737 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -578,9 +578,16 @@ EXPORT_SYMBOL(abort);
578 578
579void __init trap_init(void) 579void __init trap_init(void)
580{ 580{
581 extern void __trap_init(void); 581 extern char __stubs_start[], __stubs_end[];
582 extern char __vectors_start[], __vectors_end[];
582 583
583 __trap_init(); 584 /*
585 * Copy the vectors and stubs (in entry-armv.S) into the
586 * vector page, mapped at 0xffff0000, and ensure these are
587 * visible to the instruction stream.
588 */
589 memcpy((void *)0xffff0000, __vectors_start, __vectors_end - __vectors_start);
590 memcpy((void *)0xffff0200, __stubs_start, __stubs_end - __stubs_start);
584 flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE); 591 flush_icache_range(0xffff0000, 0xffff0000 + PAGE_SIZE);
585 modify_domain(DOMAIN_USER, DOMAIN_CLIENT); 592 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
586} 593}