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 #ifdef CONFIG_ARC_CURR_IN_REG 90 ld r25, [sp, 12] 91 #endif 92 .endm 93 94 /*-------------------------------------------------------------- 95 * Helpers to save/restore callee-saved regs: 96 * used by several macros below 97 *-------------------------------------------------------------*/ 98 .macro SAVE_R13_TO_R24 99 PUSH r13 100 PUSH r14 101 PUSH r15 102 PUSH r16 103 PUSH r17 104 PUSH r18 105 PUSH r19 106 PUSH r20 107 PUSH r21 108 PUSH r22 109 PUSH r23 110 PUSH r24 111 .endm 112 113 .macro RESTORE_R24_TO_R13 114 POP r24 115 POP r23 116 POP r22 117 POP r21 118 POP r20 119 POP r19 120 POP r18 121 POP r17 122 POP r16 123 POP r15 124 POP r14 125 POP r13 126 .endm 127 128 /*-------------------------------------------------------------- 129 * Collect User Mode callee regs as struct callee_regs - needed by 130 * fork/do_signal/unaligned-access-emulation. 131 * (By default only scratch regs are saved on entry to kernel) 132 * 133 * Special handling for r25 if used for caching Task Pointer. 134 * It would have been saved in task->thread.user_r25 already, but to keep 135 * the interface same it is copied into regular r25 placeholder in 136 * struct callee_regs. 137 *-------------------------------------------------------------*/ 138 .macro SAVE_CALLEE_SAVED_USER 139 140 mov r12, sp ; save SP as ref to pt_regs 141 SAVE_R13_TO_R24 142 143 #ifdef CONFIG_ARC_CURR_IN_REG 144 ; Retrieve orig r25 and save it with rest of callee_regs 145 ld.as r12, [r12, PT_user_r25] 146 PUSH r12 147 #else 148 PUSH r25 149 #endif 150 151 .endm 152 153 /*-------------------------------------------------------------- 154 * Save kernel Mode callee regs at the time of Contect Switch. 155 * 156 * Special handling for r25 if used for caching Task Pointer. 157 * Kernel simply skips saving it since it will be loaded with 158 * incoming task pointer anyways 159 *-------------------------------------------------------------*/ 160 .macro SAVE_CALLEE_SAVED_KERNEL 161 162 SAVE_R13_TO_R24 163 164 #ifdef CONFIG_ARC_CURR_IN_REG 165 sub sp, sp, 4 166 #else 167 PUSH r25 168 #endif 169 .endm 170 171 /*-------------------------------------------------------------- 172 * Opposite of SAVE_CALLEE_SAVED_KERNEL 173 *-------------------------------------------------------------*/ 174 .macro RESTORE_CALLEE_SAVED_KERNEL 175 176 #ifdef CONFIG_ARC_CURR_IN_REG 177 add sp, sp, 4 /* skip usual r25 placeholder */ 178 #else 179 POP r25 180 #endif 181 RESTORE_R24_TO_R13 182 .endm 183 184 /*-------------------------------------------------------------- 185 * Opposite of SAVE_CALLEE_SAVED_USER 186 * 187 * ptrace tracer or unaligned-access fixup might have changed a user mode 188 * callee reg which is saved back to usual r25 storage location 189 *-------------------------------------------------------------*/ 190 .macro RESTORE_CALLEE_SAVED_USER 191 192 #ifdef CONFIG_ARC_CURR_IN_REG 193 POP r12 194 #else 195 POP r25 196 #endif 197 RESTORE_R24_TO_R13 198 199 ; SP is back to start of pt_regs 200 #ifdef CONFIG_ARC_CURR_IN_REG 201 st.as r12, [sp, PT_user_r25] 202 #endif 203 .endm 204 205 /*-------------------------------------------------------------- 206 * Super FAST Restore callee saved regs by simply re-adjusting SP 207 *-------------------------------------------------------------*/ 208 .macro DISCARD_CALLEE_SAVED_USER 209 add sp, sp, SZ_CALLEE_REGS 210 .endm 211 212 /*------------------------------------------------------------- 213 * given a tsk struct, get to the base of it's kernel mode stack 214 * tsk->thread_info is really a PAGE, whose bottom hoists stack 215 * which grows upwards towards thread_info 216 *------------------------------------------------------------*/ 217 218 .macro GET_TSK_STACK_BASE tsk, out 219 220 /* Get task->thread_info (this is essentially start of a PAGE) */ 221 ld \out, [\tsk, TASK_THREAD_INFO] 222 223 /* Go to end of page where stack begins (grows upwards) */ 224 add2 \out, \out, (THREAD_SIZE)/4 225 226 .endm 227 228 /* 229 * @reg [OUT] thread_info->flags of "current" 230 */ 231 .macro GET_CURR_THR_INFO_FLAGS reg 232 GET_CURR_THR_INFO_FROM_SP \reg 233 ld \reg, [\reg, THREAD_INFO_FLAGS] 234 .endm 235 236 #ifdef CONFIG_SMP 237 238 /*------------------------------------------------- 239 * Retrieve the current running task on this CPU 240 * 1. Determine curr CPU id. 241 * 2. Use it to index into _current_task[ ] 242 */ 243 .macro GET_CURR_TASK_ON_CPU reg 244 GET_CPU_ID \reg 245 ld.as \reg, [@_current_task, \reg] 246 .endm 247 248 /*------------------------------------------------- 249 * Save a new task as the "current" task on this CPU 250 * 1. Determine curr CPU id. 251 * 2. Use it to index into _current_task[ ] 252 * 253 * Coded differently than GET_CURR_TASK_ON_CPU (which uses LD.AS) 254 * because ST r0, [r1, offset] can ONLY have s9 @offset 255 * while LD can take s9 (4 byte insn) or LIMM (8 byte insn) 256 */ 257 258 .macro SET_CURR_TASK_ON_CPU tsk, tmp 259 GET_CPU_ID \tmp 260 add2 \tmp, @_current_task, \tmp 261 st \tsk, [\tmp] 262 #ifdef CONFIG_ARC_CURR_IN_REG 263 mov r25, \tsk 264 #endif 265 266 .endm 267 268 269 #else /* Uniprocessor implementation of macros */ 270 271 .macro GET_CURR_TASK_ON_CPU reg 272 ld \reg, [@_current_task] 273 .endm 274 275 .macro SET_CURR_TASK_ON_CPU tsk, tmp 276 st \tsk, [@_current_task] 277 #ifdef CONFIG_ARC_CURR_IN_REG 278 mov r25, \tsk 279 #endif 280 .endm 281 282 #endif /* SMP / UNI */ 283 284 /* ------------------------------------------------------------------ 285 * Get the ptr to some field of Current Task at @off in task struct 286 * -Uses r25 for Current task ptr if that is enabled 287 */ 288 289 #ifdef CONFIG_ARC_CURR_IN_REG 290 291 .macro GET_CURR_TASK_FIELD_PTR off, reg 292 add \reg, r25, \off 293 .endm 294 295 #else 296 297 .macro GET_CURR_TASK_FIELD_PTR off, reg 298 GET_CURR_TASK_ON_CPU \reg 299 add \reg, \reg, \off 300 .endm 301 302 #endif /* CONFIG_ARC_CURR_IN_REG */ 303 304 #endif /* __ASM_ARC_ENTRY_H */ 305