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