1 /* 2 * Copyright (C) 2014-15 Synopsys, Inc. (www.synopsys.com) 3 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ 9 10 #ifndef __ASM_ARC_ENTRY_H 11 #define __ASM_ARC_ENTRY_H 12 13 #include <asm/unistd.h> /* For NR_syscalls defination */ 14 #include <asm/arcregs.h> 15 #include <asm/ptrace.h> 16 #include <asm/processor.h> /* For VMALLOC_START */ 17 #include <asm/mmu.h> 18 19 #ifdef CONFIG_ISA_ARCOMPACT 20 #include <asm/entry-compact.h> /* ISA specific bits */ 21 #else 22 #include <asm/entry-arcv2.h> 23 #endif 24 25 /* Note on the LD/ST addr modes with addr reg wback 26 * 27 * LD.a same as LD.aw 28 * 29 * LD.a reg1, [reg2, x] => Pre Incr 30 * Eff Addr for load = [reg2 + x] 31 * 32 * LD.ab reg1, [reg2, x] => Post Incr 33 * Eff Addr for load = [reg2] 34 */ 35 36 .macro PUSH reg 37 st.a \reg, [sp, -4] 38 .endm 39 40 .macro PUSHAX aux 41 lr r9, [\aux] 42 PUSH r9 43 .endm 44 45 .macro POP reg 46 ld.ab \reg, [sp, 4] 47 .endm 48 49 .macro POPAX aux 50 POP r9 51 sr r9, [\aux] 52 .endm 53 54 /*-------------------------------------------------------------- 55 * Helpers to save/restore Scratch Regs: 56 * used by Interrupt/Exception Prologue/Epilogue 57 *-------------------------------------------------------------*/ 58 .macro SAVE_R0_TO_R12 59 PUSH r0 60 PUSH r1 61 PUSH r2 62 PUSH r3 63 PUSH r4 64 PUSH r5 65 PUSH r6 66 PUSH r7 67 PUSH r8 68 PUSH r9 69 PUSH r10 70 PUSH r11 71 PUSH r12 72 .endm 73 74 .macro RESTORE_R12_TO_R0 75 POP r12 76 POP r11 77 POP r10 78 POP r9 79 POP r8 80 POP r7 81 POP r6 82 POP r5 83 POP r4 84 POP r3 85 POP r2 86 POP r1 87 POP r0 88 89 .endm 90 91 /*-------------------------------------------------------------- 92 * Helpers to save/restore callee-saved regs: 93 * used by several macros below 94 *-------------------------------------------------------------*/ 95 .macro SAVE_R13_TO_R24 96 PUSH r13 97 PUSH r14 98 PUSH r15 99 PUSH r16 100 PUSH r17 101 PUSH r18 102 PUSH r19 103 PUSH r20 104 PUSH r21 105 PUSH r22 106 PUSH r23 107 PUSH r24 108 .endm 109 110 .macro RESTORE_R24_TO_R13 111 POP r24 112 POP r23 113 POP r22 114 POP r21 115 POP r20 116 POP r19 117 POP r18 118 POP r17 119 POP r16 120 POP r15 121 POP r14 122 POP r13 123 .endm 124 125 /*-------------------------------------------------------------- 126 * Collect User Mode callee regs as struct callee_regs - needed by 127 * fork/do_signal/unaligned-access-emulation. 128 * (By default only scratch regs are saved on entry to kernel) 129 * 130 * Special handling for r25 if used for caching Task Pointer. 131 * It would have been saved in task->thread.user_r25 already, but to keep 132 * the interface same it is copied into regular r25 placeholder in 133 * struct callee_regs. 134 *-------------------------------------------------------------*/ 135 .macro SAVE_CALLEE_SAVED_USER 136 137 mov r12, sp ; save SP as ref to pt_regs 138 SAVE_R13_TO_R24 139 140 #ifdef CONFIG_ARC_CURR_IN_REG 141 ; Retrieve orig r25 and save it with rest of callee_regs 142 ld r12, [r12, PT_user_r25] 143 PUSH r12 144 #else 145 PUSH r25 146 #endif 147 148 .endm 149 150 /*-------------------------------------------------------------- 151 * Save kernel Mode callee regs at the time of Contect Switch. 152 * 153 * Special handling for r25 if used for caching Task Pointer. 154 * Kernel simply skips saving it since it will be loaded with 155 * incoming task pointer anyways 156 *-------------------------------------------------------------*/ 157 .macro SAVE_CALLEE_SAVED_KERNEL 158 159 SAVE_R13_TO_R24 160 161 #ifdef CONFIG_ARC_CURR_IN_REG 162 sub sp, sp, 4 163 #else 164 PUSH r25 165 #endif 166 .endm 167 168 /*-------------------------------------------------------------- 169 * Opposite of SAVE_CALLEE_SAVED_KERNEL 170 *-------------------------------------------------------------*/ 171 .macro RESTORE_CALLEE_SAVED_KERNEL 172 173 #ifdef CONFIG_ARC_CURR_IN_REG 174 add sp, sp, 4 /* skip usual r25 placeholder */ 175 #else 176 POP r25 177 #endif 178 RESTORE_R24_TO_R13 179 .endm 180 181 /*-------------------------------------------------------------- 182 * Opposite of SAVE_CALLEE_SAVED_USER 183 * 184 * ptrace tracer or unaligned-access fixup might have changed a user mode 185 * callee reg which is saved back to usual r25 storage location 186 *-------------------------------------------------------------*/ 187 .macro RESTORE_CALLEE_SAVED_USER 188 189 #ifdef CONFIG_ARC_CURR_IN_REG 190 POP r12 191 #else 192 POP r25 193 #endif 194 RESTORE_R24_TO_R13 195 196 ; SP is back to start of pt_regs 197 #ifdef CONFIG_ARC_CURR_IN_REG 198 st r12, [sp, PT_user_r25] 199 #endif 200 .endm 201 202 /*-------------------------------------------------------------- 203 * Super FAST Restore callee saved regs by simply re-adjusting SP 204 *-------------------------------------------------------------*/ 205 .macro DISCARD_CALLEE_SAVED_USER 206 add sp, sp, SZ_CALLEE_REGS 207 .endm 208 209 /*------------------------------------------------------------- 210 * given a tsk struct, get to the base of it's kernel mode stack 211 * tsk->thread_info is really a PAGE, whose bottom hoists stack 212 * which grows upwards towards thread_info 213 *------------------------------------------------------------*/ 214 215 .macro GET_TSK_STACK_BASE tsk, out 216 217 /* Get task->thread_info (this is essentially start of a PAGE) */ 218 ld \out, [\tsk, TASK_THREAD_INFO] 219 220 /* Go to end of page where stack begins (grows upwards) */ 221 add2 \out, \out, (THREAD_SIZE)/4 222 223 .endm 224 225 /* 226 * @reg [OUT] thread_info->flags of "current" 227 */ 228 .macro GET_CURR_THR_INFO_FLAGS reg 229 GET_CURR_THR_INFO_FROM_SP \reg 230 ld \reg, [\reg, THREAD_INFO_FLAGS] 231 .endm 232 233 #ifdef CONFIG_SMP 234 235 /*------------------------------------------------- 236 * Retrieve the current running task on this CPU 237 * 1. Determine curr CPU id. 238 * 2. Use it to index into _current_task[ ] 239 */ 240 .macro GET_CURR_TASK_ON_CPU reg 241 GET_CPU_ID \reg 242 ld.as \reg, [@_current_task, \reg] 243 .endm 244 245 /*------------------------------------------------- 246 * Save a new task as the "current" task on this CPU 247 * 1. Determine curr CPU id. 248 * 2. Use it to index into _current_task[ ] 249 * 250 * Coded differently than GET_CURR_TASK_ON_CPU (which uses LD.AS) 251 * because ST r0, [r1, offset] can ONLY have s9 @offset 252 * while LD can take s9 (4 byte insn) or LIMM (8 byte insn) 253 */ 254 255 .macro SET_CURR_TASK_ON_CPU tsk, tmp 256 GET_CPU_ID \tmp 257 add2 \tmp, @_current_task, \tmp 258 st \tsk, [\tmp] 259 #ifdef CONFIG_ARC_CURR_IN_REG 260 mov r25, \tsk 261 #endif 262 263 .endm 264 265 266 #else /* Uniprocessor implementation of macros */ 267 268 .macro GET_CURR_TASK_ON_CPU reg 269 ld \reg, [@_current_task] 270 .endm 271 272 .macro SET_CURR_TASK_ON_CPU tsk, tmp 273 st \tsk, [@_current_task] 274 #ifdef CONFIG_ARC_CURR_IN_REG 275 mov r25, \tsk 276 #endif 277 .endm 278 279 #endif /* SMP / UNI */ 280 281 /* ------------------------------------------------------------------ 282 * Get the ptr to some field of Current Task at @off in task struct 283 * -Uses r25 for Current task ptr if that is enabled 284 */ 285 286 #ifdef CONFIG_ARC_CURR_IN_REG 287 288 .macro GET_CURR_TASK_FIELD_PTR off, reg 289 add \reg, r25, \off 290 .endm 291 292 #else 293 294 .macro GET_CURR_TASK_FIELD_PTR off, reg 295 GET_CURR_TASK_ON_CPU \reg 296 add \reg, \reg, \off 297 .endm 298 299 #endif /* CONFIG_ARC_CURR_IN_REG */ 300 301 #endif /* __ASM_ARC_ENTRY_H */ 302