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 __ASSEMBLY__ 17 18 #ifdef CONFIG_ISA_ARCOMPACT 19 #include <asm/entry-compact.h> /* ISA specific bits */ 20 #else 21 #include <asm/entry-arcv2.h> 22 #endif 23 24 /* Note on the LD/ST addr modes with addr reg wback 25 * 26 * LD.a same as LD.aw 27 * 28 * LD.a reg1, [reg2, x] => Pre Incr 29 * Eff Addr for load = [reg2 + x] 30 * 31 * LD.ab reg1, [reg2, x] => Post Incr 32 * Eff Addr for load = [reg2] 33 */ 34 35 .macro PUSH reg 36 st.a \reg, [sp, -4] 37 .endm 38 39 .macro PUSHAX aux 40 lr r9, [\aux] 41 PUSH r9 42 .endm 43 44 .macro POP reg 45 ld.ab \reg, [sp, 4] 46 .endm 47 48 .macro POPAX aux 49 POP r9 50 sr r9, [\aux] 51 .endm 52 53 /*-------------------------------------------------------------- 54 * Helpers to save/restore Scratch Regs: 55 * used by Interrupt/Exception Prologue/Epilogue 56 *-------------------------------------------------------------*/ 57 .macro SAVE_R0_TO_R12 58 PUSH r0 59 PUSH r1 60 PUSH r2 61 PUSH r3 62 PUSH r4 63 PUSH r5 64 PUSH r6 65 PUSH r7 66 PUSH r8 67 PUSH r9 68 PUSH r10 69 PUSH r11 70 PUSH r12 71 .endm 72 73 .macro RESTORE_R12_TO_R0 74 POP r12 75 POP r11 76 POP r10 77 POP r9 78 POP r8 79 POP r7 80 POP r6 81 POP r5 82 POP r4 83 POP r3 84 POP r2 85 POP r1 86 POP r0 87 88 .endm 89 90 /*-------------------------------------------------------------- 91 * Helpers to save/restore callee-saved regs: 92 * used by several macros below 93 *-------------------------------------------------------------*/ 94 .macro SAVE_R13_TO_R25 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 PUSH r25 108 .endm 109 110 .macro RESTORE_R25_TO_R13 111 POP r25 112 POP r24 113 POP r23 114 POP r22 115 POP r21 116 POP r20 117 POP r19 118 POP r18 119 POP r17 120 POP r16 121 POP r15 122 POP r14 123 POP r13 124 .endm 125 126 /* 127 * save user mode callee regs as struct callee_regs 128 * - needed by fork/do_signal/unaligned-access-emulation. 129 */ 130 .macro SAVE_CALLEE_SAVED_USER 131 SAVE_R13_TO_R25 132 .endm 133 134 /* 135 * restore user mode callee regs as struct callee_regs 136 * - could have been changed by ptrace tracer or unaligned-access fixup 137 */ 138 .macro RESTORE_CALLEE_SAVED_USER 139 RESTORE_R25_TO_R13 140 .endm 141 142 /* 143 * save/restore kernel mode callee regs at the time of context switch 144 */ 145 .macro SAVE_CALLEE_SAVED_KERNEL 146 SAVE_R13_TO_R25 147 .endm 148 149 .macro RESTORE_CALLEE_SAVED_KERNEL 150 RESTORE_R25_TO_R13 151 .endm 152 153 /*-------------------------------------------------------------- 154 * Super FAST Restore callee saved regs by simply re-adjusting SP 155 *-------------------------------------------------------------*/ 156 .macro DISCARD_CALLEE_SAVED_USER 157 add sp, sp, SZ_CALLEE_REGS 158 .endm 159 160 /*------------------------------------------------------------- 161 * given a tsk struct, get to the base of it's kernel mode stack 162 * tsk->thread_info is really a PAGE, whose bottom hoists stack 163 * which grows upwards towards thread_info 164 *------------------------------------------------------------*/ 165 166 .macro GET_TSK_STACK_BASE tsk, out 167 168 /* Get task->thread_info (this is essentially start of a PAGE) */ 169 ld \out, [\tsk, TASK_THREAD_INFO] 170 171 /* Go to end of page where stack begins (grows upwards) */ 172 add2 \out, \out, (THREAD_SIZE)/4 173 174 .endm 175 176 /* 177 * @reg [OUT] thread_info->flags of "current" 178 */ 179 .macro GET_CURR_THR_INFO_FLAGS reg 180 GET_CURR_THR_INFO_FROM_SP \reg 181 ld \reg, [\reg, THREAD_INFO_FLAGS] 182 .endm 183 184 #ifdef CONFIG_SMP 185 186 /* 187 * Retrieve the current running task on this CPU 188 * - loads it from backing _current_task[] (and can't use the 189 * caching reg for current task 190 */ 191 .macro GET_CURR_TASK_ON_CPU reg 192 GET_CPU_ID \reg 193 ld.as \reg, [@_current_task, \reg] 194 .endm 195 196 /*------------------------------------------------- 197 * Save a new task as the "current" task on this CPU 198 * 1. Determine curr CPU id. 199 * 2. Use it to index into _current_task[ ] 200 * 201 * Coded differently than GET_CURR_TASK_ON_CPU (which uses LD.AS) 202 * because ST r0, [r1, offset] can ONLY have s9 @offset 203 * while LD can take s9 (4 byte insn) or LIMM (8 byte insn) 204 */ 205 206 .macro SET_CURR_TASK_ON_CPU tsk, tmp 207 GET_CPU_ID \tmp 208 add2 \tmp, @_current_task, \tmp 209 st \tsk, [\tmp] 210 #ifdef CONFIG_ARC_CURR_IN_REG 211 mov gp, \tsk 212 #endif 213 214 .endm 215 216 217 #else /* Uniprocessor implementation of macros */ 218 219 .macro GET_CURR_TASK_ON_CPU reg 220 ld \reg, [@_current_task] 221 .endm 222 223 .macro SET_CURR_TASK_ON_CPU tsk, tmp 224 st \tsk, [@_current_task] 225 #ifdef CONFIG_ARC_CURR_IN_REG 226 mov gp, \tsk 227 #endif 228 .endm 229 230 #endif /* SMP / UNI */ 231 232 /* 233 * Get the ptr to some field of Current Task at @off in task struct 234 * - Uses current task cached in reg if enabled 235 */ 236 #ifdef CONFIG_ARC_CURR_IN_REG 237 238 .macro GET_CURR_TASK_FIELD_PTR off, reg 239 add \reg, gp, \off 240 .endm 241 242 #else 243 244 .macro GET_CURR_TASK_FIELD_PTR off, reg 245 GET_CURR_TASK_ON_CPU \reg 246 add \reg, \reg, \off 247 .endm 248 249 #endif /* CONFIG_ARC_CURR_IN_REG */ 250 251 #else /* !__ASSEMBLY__ */ 252 253 extern void do_signal(struct pt_regs *); 254 extern void do_notify_resume(struct pt_regs *); 255 extern int do_privilege_fault(unsigned long, struct pt_regs *); 256 extern int do_extension_fault(unsigned long, struct pt_regs *); 257 extern int insterror_is_error(unsigned long, struct pt_regs *); 258 extern int do_memory_error(unsigned long, struct pt_regs *); 259 extern int trap_is_brkpt(unsigned long, struct pt_regs *); 260 extern int do_misaligned_error(unsigned long, struct pt_regs *); 261 extern int do_trap5_error(unsigned long, struct pt_regs *); 262 extern int do_misaligned_access(unsigned long, struct pt_regs *, struct callee_regs *); 263 extern void do_machine_check_fault(unsigned long, struct pt_regs *); 264 extern void do_non_swi_trap(unsigned long, struct pt_regs *); 265 extern void do_insterror_or_kprobe(unsigned long, struct pt_regs *); 266 extern void do_page_fault(unsigned long, struct pt_regs *); 267 268 #endif 269 270 #endif /* __ASM_ARC_ENTRY_H */ 271