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 #include <asm/entry-compact.h> /* ISA specific bits */ 20 21 /* Note on the LD/ST addr modes with addr reg wback 22 * 23 * LD.a same as LD.aw 24 * 25 * LD.a reg1, [reg2, x] => Pre Incr 26 * Eff Addr for load = [reg2 + x] 27 * 28 * LD.ab reg1, [reg2, x] => Post Incr 29 * Eff Addr for load = [reg2] 30 */ 31 32 .macro PUSH reg 33 st.a \reg, [sp, -4] 34 .endm 35 36 .macro PUSHAX aux 37 lr r9, [\aux] 38 PUSH r9 39 .endm 40 41 .macro POP reg 42 ld.ab \reg, [sp, 4] 43 .endm 44 45 .macro POPAX aux 46 POP r9 47 sr r9, [\aux] 48 .endm 49 50 /*-------------------------------------------------------------- 51 * Helpers to save/restore Scratch Regs: 52 * used by Interrupt/Exception Prologue/Epilogue 53 *-------------------------------------------------------------*/ 54 .macro SAVE_R0_TO_R12 55 PUSH r0 56 PUSH r1 57 PUSH r2 58 PUSH r3 59 PUSH r4 60 PUSH r5 61 PUSH r6 62 PUSH r7 63 PUSH r8 64 PUSH r9 65 PUSH r10 66 PUSH r11 67 PUSH r12 68 .endm 69 70 .macro RESTORE_R12_TO_R0 71 POP r12 72 POP r11 73 POP r10 74 POP r9 75 POP r8 76 POP r7 77 POP r6 78 POP r5 79 POP r4 80 POP r3 81 POP r2 82 POP r1 83 POP r0 84 85 #ifdef CONFIG_ARC_CURR_IN_REG 86 ld r25, [sp, 12] 87 #endif 88 .endm 89 90 /*-------------------------------------------------------------- 91 * Helpers to save/restore callee-saved regs: 92 * used by several macros below 93 *-------------------------------------------------------------*/ 94 .macro SAVE_R13_TO_R24 95 PUSH r13 96 PUSH r14 97 PUSH r15 98 PUSH r16 99 PUSH r17 100 PUSH r18 101 PUSH r19 102 PUSH r20 103 PUSH r21 104 PUSH r22 105 PUSH r23 106 PUSH r24 107 .endm 108 109 .macro RESTORE_R24_TO_R13 110 POP r24 111 POP r23 112 POP r22 113 POP r21 114 POP r20 115 POP r19 116 POP r18 117 POP r17 118 POP r16 119 POP r15 120 POP r14 121 POP r13 122 .endm 123 124 #define OFF_USER_R25_FROM_R24 (SZ_CALLEE_REGS + SZ_PT_REGS - 8)/4 125 126 /*-------------------------------------------------------------- 127 * Collect User Mode callee regs as struct callee_regs - needed by 128 * fork/do_signal/unaligned-access-emulation. 129 * (By default only scratch regs are saved on entry to kernel) 130 * 131 * Special handling for r25 if used for caching Task Pointer. 132 * It would have been saved in task->thread.user_r25 already, but to keep 133 * the interface same it is copied into regular r25 placeholder in 134 * struct callee_regs. 135 *-------------------------------------------------------------*/ 136 .macro SAVE_CALLEE_SAVED_USER 137 138 SAVE_R13_TO_R24 139 140 #ifdef CONFIG_ARC_CURR_IN_REG 141 ; Retrieve orig r25 and save it on stack 142 ld.as r12, [sp, OFF_USER_R25_FROM_R24] 143 st.a r12, [sp, -4] 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 ld.ab r12, [sp, 4] 191 st.as r12, [sp, OFF_USER_R25_FROM_R24] 192 #else 193 POP r25 194 #endif 195 RESTORE_R24_TO_R13 196 .endm 197 198 /*-------------------------------------------------------------- 199 * Super FAST Restore callee saved regs by simply re-adjusting SP 200 *-------------------------------------------------------------*/ 201 .macro DISCARD_CALLEE_SAVED_USER 202 add sp, sp, SZ_CALLEE_REGS 203 .endm 204 205 /*------------------------------------------------------------- 206 * given a tsk struct, get to the base of it's kernel mode stack 207 * tsk->thread_info is really a PAGE, whose bottom hoists stack 208 * which grows upwards towards thread_info 209 *------------------------------------------------------------*/ 210 211 .macro GET_TSK_STACK_BASE tsk, out 212 213 /* Get task->thread_info (this is essentially start of a PAGE) */ 214 ld \out, [\tsk, TASK_THREAD_INFO] 215 216 /* Go to end of page where stack begins (grows upwards) */ 217 add2 \out, \out, (THREAD_SIZE)/4 218 219 .endm 220 221 /* 222 * @reg [OUT] thread_info->flags of "current" 223 */ 224 .macro GET_CURR_THR_INFO_FLAGS reg 225 GET_CURR_THR_INFO_FROM_SP \reg 226 ld \reg, [\reg, THREAD_INFO_FLAGS] 227 .endm 228 229 #ifdef CONFIG_SMP 230 231 /*------------------------------------------------- 232 * Retrieve the current running task on this CPU 233 * 1. Determine curr CPU id. 234 * 2. Use it to index into _current_task[ ] 235 */ 236 .macro GET_CURR_TASK_ON_CPU reg 237 GET_CPU_ID \reg 238 ld.as \reg, [@_current_task, \reg] 239 .endm 240 241 /*------------------------------------------------- 242 * Save a new task as the "current" task on this CPU 243 * 1. Determine curr CPU id. 244 * 2. Use it to index into _current_task[ ] 245 * 246 * Coded differently than GET_CURR_TASK_ON_CPU (which uses LD.AS) 247 * because ST r0, [r1, offset] can ONLY have s9 @offset 248 * while LD can take s9 (4 byte insn) or LIMM (8 byte insn) 249 */ 250 251 .macro SET_CURR_TASK_ON_CPU tsk, tmp 252 GET_CPU_ID \tmp 253 add2 \tmp, @_current_task, \tmp 254 st \tsk, [\tmp] 255 #ifdef CONFIG_ARC_CURR_IN_REG 256 mov r25, \tsk 257 #endif 258 259 .endm 260 261 262 #else /* Uniprocessor implementation of macros */ 263 264 .macro GET_CURR_TASK_ON_CPU reg 265 ld \reg, [@_current_task] 266 .endm 267 268 .macro SET_CURR_TASK_ON_CPU tsk, tmp 269 st \tsk, [@_current_task] 270 #ifdef CONFIG_ARC_CURR_IN_REG 271 mov r25, \tsk 272 #endif 273 .endm 274 275 #endif /* SMP / UNI */ 276 277 /* ------------------------------------------------------------------ 278 * Get the ptr to some field of Current Task at @off in task struct 279 * -Uses r25 for Current task ptr if that is enabled 280 */ 281 282 #ifdef CONFIG_ARC_CURR_IN_REG 283 284 .macro GET_CURR_TASK_FIELD_PTR off, reg 285 add \reg, r25, \off 286 .endm 287 288 #else 289 290 .macro GET_CURR_TASK_FIELD_PTR off, reg 291 GET_CURR_TASK_ON_CPU \reg 292 add \reg, \reg, \off 293 .endm 294 295 #endif /* CONFIG_ARC_CURR_IN_REG */ 296 297 #endif /* __ASM_ARC_ENTRY_H */ 298