1 #include <linux/config.h> /* for CONFIG_ARCH_xxxx */
2 #include <linux/linkage.h>
4 #include <asm/assembler.h>
5 #include <asm/constants.h>
7 #include <asm/hardware.h>
8 #include <asm/arch/irqs.h>
9 #include <asm/arch/entry-macro.S>
16 #ifdef CONFIG_FRAME_POINTER
26 #define BAD_PREFETCH 0
28 #define BAD_ADDREXCPTN 2
30 #define BAD_UNDEFINSTR 4
32 #define PT_TRACESYS 0x00000002
35 @ Most of the stack format comes from struct pt_regs, but with
36 @ the addition of 8 bytes for storing syscall args 5 and 6.
41 * The SWI code relies on the fact that R0 is at the bottom of the stack
42 * (due to slow/fast restore user regs).
48 #if __LINUX_ARM_ARCH__ >= 6
58 msr cpsr_c, #PSR_I_BIT | SVC_MODE
67 sub sp, sp, #S_FRAME_SIZE
68 stmia sp, {r0 - r12} @ Calling r0 - r12
70 stmdb r8, {sp, lr}^ @ Calling sp, lr
71 mrs r8, spsr @ called from non-FIQ mode, so ok.
72 str lr, [sp, #S_PC] @ Save calling PC
73 str r8, [sp, #S_PSR] @ Save CPSR
74 str r0, [sp, #S_OLD_R0] @ Save OLD_R0
77 .macro restore_user_regs
78 ldr r1, [sp, #S_PSR] @ Get calling cpsr
79 disable_irq ip @ disable IRQs
80 ldr lr, [sp, #S_PC]! @ Get PC
81 msr spsr_cxsf, r1 @ save in spsr_svc
82 ldmdb sp, {r0 - lr}^ @ Get calling r0 - lr
84 add sp, sp, #S_FRAME_SIZE - S_PC
85 movs pc, lr @ return & move spsr_svc into cpsr
89 * Must be called with IRQs already disabled.
91 .macro fast_restore_user_regs
92 ldr r1, [sp, #S_OFF + S_PSR] @ get calling cpsr
93 ldr lr, [sp, #S_OFF + S_PC]! @ get pc
94 msr spsr_cxsf, r1 @ save in spsr_svc
95 ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
97 add sp, sp, #S_FRAME_SIZE - S_PC
98 movs pc, lr @ return & move spsr_svc into cpsr
102 * Must be called with IRQs already disabled.
104 .macro slow_restore_user_regs
105 ldr r1, [sp, #S_PSR] @ get calling cpsr
106 ldr lr, [sp, #S_PC]! @ get pc
107 msr spsr_cxsf, r1 @ save in spsr_svc
108 ldmdb sp, {r0 - lr}^ @ get calling r1 - lr
110 add sp, sp, #S_FRAME_SIZE - S_PC
111 movs pc, lr @ return & move spsr_svc into cpsr
114 .macro mask_pc, rd, rm
117 .macro get_thread_info, rd
119 mov \rd, \rd, lsl #13
122 .macro alignment_trap, rbase, rtemp, sym
123 #ifdef CONFIG_ALIGNMENT_TRAP
124 #define OFF_CR_ALIGNMENT(x) cr_alignment - x
126 ldr \rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)]
127 mcr p15, 0, \rtemp, c1, c0
133 * These are the registers used in the syscall handler, and allow us to
134 * have in theory up to 7 arguments to a function - r0 to r6.
136 * r7 is reserved for the system call number for thumb mode.
138 * Note that tbl == why is intentional.
140 * We must set at least "tsk" and "why" when calling ret_with_reschedule.
142 scno .req r7 @ syscall number
143 tbl .req r8 @ syscall table pointer
144 why .req r8 @ Linux syscall (!= 0)
145 tsk .req r9 @ current thread_info