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