1*9d42c84fSVineet Gupta /* 2*9d42c84fSVineet Gupta * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) 3*9d42c84fSVineet Gupta * 4*9d42c84fSVineet Gupta * This program is free software; you can redistribute it and/or modify 5*9d42c84fSVineet Gupta * it under the terms of the GNU General Public License version 2 as 6*9d42c84fSVineet Gupta * published by the Free Software Foundation. 7*9d42c84fSVineet Gupta * 8*9d42c84fSVineet Gupta * Vineetg: Aug 28th 2008: Bug #94984 9*9d42c84fSVineet Gupta * -Zero Overhead Loop Context shd be cleared when entering IRQ/EXcp/Trap 10*9d42c84fSVineet Gupta * Normally CPU does this automatically, however when doing FAKE rtie, 11*9d42c84fSVineet Gupta * we also need to explicitly do this. The problem in macros 12*9d42c84fSVineet Gupta * FAKE_RET_FROM_EXCPN and FAKE_RET_FROM_EXCPN_LOCK_IRQ was that this bit 13*9d42c84fSVineet Gupta * was being "CLEARED" rather then "SET". Actually "SET" clears ZOL context 14*9d42c84fSVineet Gupta * 15*9d42c84fSVineet Gupta * Vineetg: May 5th 2008 16*9d42c84fSVineet Gupta * - Defined Stack Switching Macro to be reused in all intr/excp hdlrs 17*9d42c84fSVineet Gupta * - Shaved off 11 instructions from RESTORE_ALL_INT1 by using the 18*9d42c84fSVineet Gupta * address Write back load ld.ab instead of seperate ld/add instn 19*9d42c84fSVineet Gupta * 20*9d42c84fSVineet Gupta * Amit Bhor, Sameer Dhavale: Codito Technologies 2004 21*9d42c84fSVineet Gupta */ 22*9d42c84fSVineet Gupta 23*9d42c84fSVineet Gupta #ifndef __ASM_ARC_ENTRY_H 24*9d42c84fSVineet Gupta #define __ASM_ARC_ENTRY_H 25*9d42c84fSVineet Gupta 26*9d42c84fSVineet Gupta #ifdef __ASSEMBLY__ 27*9d42c84fSVineet Gupta #include <asm/unistd.h> /* For NR_syscalls defination */ 28*9d42c84fSVineet Gupta #include <asm/asm-offsets.h> 29*9d42c84fSVineet Gupta #include <asm/arcregs.h> 30*9d42c84fSVineet Gupta #include <asm/ptrace.h> 31*9d42c84fSVineet Gupta #include <asm/thread_info.h> /* For THREAD_SIZE */ 32*9d42c84fSVineet Gupta 33*9d42c84fSVineet Gupta /* Note on the LD/ST addr modes with addr reg wback 34*9d42c84fSVineet Gupta * 35*9d42c84fSVineet Gupta * LD.a same as LD.aw 36*9d42c84fSVineet Gupta * 37*9d42c84fSVineet Gupta * LD.a reg1, [reg2, x] => Pre Incr 38*9d42c84fSVineet Gupta * Eff Addr for load = [reg2 + x] 39*9d42c84fSVineet Gupta * 40*9d42c84fSVineet Gupta * LD.ab reg1, [reg2, x] => Post Incr 41*9d42c84fSVineet Gupta * Eff Addr for load = [reg2] 42*9d42c84fSVineet Gupta */ 43*9d42c84fSVineet Gupta 44*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 45*9d42c84fSVineet Gupta * Save caller saved registers (scratch registers) ( r0 - r12 ) 46*9d42c84fSVineet Gupta * Registers are pushed / popped in the order defined in struct ptregs 47*9d42c84fSVineet Gupta * in asm/ptrace.h 48*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 49*9d42c84fSVineet Gupta .macro SAVE_CALLER_SAVED 50*9d42c84fSVineet Gupta st.a r0, [sp, -4] 51*9d42c84fSVineet Gupta st.a r1, [sp, -4] 52*9d42c84fSVineet Gupta st.a r2, [sp, -4] 53*9d42c84fSVineet Gupta st.a r3, [sp, -4] 54*9d42c84fSVineet Gupta st.a r4, [sp, -4] 55*9d42c84fSVineet Gupta st.a r5, [sp, -4] 56*9d42c84fSVineet Gupta st.a r6, [sp, -4] 57*9d42c84fSVineet Gupta st.a r7, [sp, -4] 58*9d42c84fSVineet Gupta st.a r8, [sp, -4] 59*9d42c84fSVineet Gupta st.a r9, [sp, -4] 60*9d42c84fSVineet Gupta st.a r10, [sp, -4] 61*9d42c84fSVineet Gupta st.a r11, [sp, -4] 62*9d42c84fSVineet Gupta st.a r12, [sp, -4] 63*9d42c84fSVineet Gupta .endm 64*9d42c84fSVineet Gupta 65*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 66*9d42c84fSVineet Gupta * Restore caller saved registers (scratch registers) 67*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 68*9d42c84fSVineet Gupta .macro RESTORE_CALLER_SAVED 69*9d42c84fSVineet Gupta ld.ab r12, [sp, 4] 70*9d42c84fSVineet Gupta ld.ab r11, [sp, 4] 71*9d42c84fSVineet Gupta ld.ab r10, [sp, 4] 72*9d42c84fSVineet Gupta ld.ab r9, [sp, 4] 73*9d42c84fSVineet Gupta ld.ab r8, [sp, 4] 74*9d42c84fSVineet Gupta ld.ab r7, [sp, 4] 75*9d42c84fSVineet Gupta ld.ab r6, [sp, 4] 76*9d42c84fSVineet Gupta ld.ab r5, [sp, 4] 77*9d42c84fSVineet Gupta ld.ab r4, [sp, 4] 78*9d42c84fSVineet Gupta ld.ab r3, [sp, 4] 79*9d42c84fSVineet Gupta ld.ab r2, [sp, 4] 80*9d42c84fSVineet Gupta ld.ab r1, [sp, 4] 81*9d42c84fSVineet Gupta ld.ab r0, [sp, 4] 82*9d42c84fSVineet Gupta .endm 83*9d42c84fSVineet Gupta 84*9d42c84fSVineet Gupta 85*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 86*9d42c84fSVineet Gupta * Save callee saved registers (non scratch registers) ( r13 - r25 ) 87*9d42c84fSVineet Gupta * on kernel stack. 88*9d42c84fSVineet Gupta * User mode callee regs need to be saved in case of 89*9d42c84fSVineet Gupta * -fork and friends for replicating from parent to child 90*9d42c84fSVineet Gupta * -before going into do_signal( ) for ptrace/core-dump 91*9d42c84fSVineet Gupta * Special case handling is required for r25 in case it is used by kernel 92*9d42c84fSVineet Gupta * for caching task ptr. Low level exception/ISR save user mode r25 93*9d42c84fSVineet Gupta * into task->thread.user_r25. So it needs to be retrieved from there and 94*9d42c84fSVineet Gupta * saved into kernel stack with rest of callee reg-file 95*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 96*9d42c84fSVineet Gupta .macro SAVE_CALLEE_SAVED_USER 97*9d42c84fSVineet Gupta st.a r13, [sp, -4] 98*9d42c84fSVineet Gupta st.a r14, [sp, -4] 99*9d42c84fSVineet Gupta st.a r15, [sp, -4] 100*9d42c84fSVineet Gupta st.a r16, [sp, -4] 101*9d42c84fSVineet Gupta st.a r17, [sp, -4] 102*9d42c84fSVineet Gupta st.a r18, [sp, -4] 103*9d42c84fSVineet Gupta st.a r19, [sp, -4] 104*9d42c84fSVineet Gupta st.a r20, [sp, -4] 105*9d42c84fSVineet Gupta st.a r21, [sp, -4] 106*9d42c84fSVineet Gupta st.a r22, [sp, -4] 107*9d42c84fSVineet Gupta st.a r23, [sp, -4] 108*9d42c84fSVineet Gupta st.a r24, [sp, -4] 109*9d42c84fSVineet Gupta st.a r25, [sp, -4] 110*9d42c84fSVineet Gupta 111*9d42c84fSVineet Gupta /* move up by 1 word to "create" callee_regs->"stack_place_holder" */ 112*9d42c84fSVineet Gupta sub sp, sp, 4 113*9d42c84fSVineet Gupta .endm 114*9d42c84fSVineet Gupta 115*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 116*9d42c84fSVineet Gupta * Save callee saved registers (non scratch registers) ( r13 - r25 ) 117*9d42c84fSVineet Gupta * kernel mode callee regs needed to be saved in case of context switch 118*9d42c84fSVineet Gupta * If r25 is used for caching task pointer then that need not be saved 119*9d42c84fSVineet Gupta * as it can be re-created from current task global 120*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 121*9d42c84fSVineet Gupta .macro SAVE_CALLEE_SAVED_KERNEL 122*9d42c84fSVineet Gupta st.a r13, [sp, -4] 123*9d42c84fSVineet Gupta st.a r14, [sp, -4] 124*9d42c84fSVineet Gupta st.a r15, [sp, -4] 125*9d42c84fSVineet Gupta st.a r16, [sp, -4] 126*9d42c84fSVineet Gupta st.a r17, [sp, -4] 127*9d42c84fSVineet Gupta st.a r18, [sp, -4] 128*9d42c84fSVineet Gupta st.a r19, [sp, -4] 129*9d42c84fSVineet Gupta st.a r20, [sp, -4] 130*9d42c84fSVineet Gupta st.a r21, [sp, -4] 131*9d42c84fSVineet Gupta st.a r22, [sp, -4] 132*9d42c84fSVineet Gupta st.a r23, [sp, -4] 133*9d42c84fSVineet Gupta st.a r24, [sp, -4] 134*9d42c84fSVineet Gupta st.a r25, [sp, -4] 135*9d42c84fSVineet Gupta sub sp, sp, 4 136*9d42c84fSVineet Gupta .endm 137*9d42c84fSVineet Gupta 138*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 139*9d42c84fSVineet Gupta * RESTORE_CALLEE_SAVED_KERNEL: 140*9d42c84fSVineet Gupta * Loads callee (non scratch) Reg File by popping from Kernel mode stack. 141*9d42c84fSVineet Gupta * This is reverse of SAVE_CALLEE_SAVED, 142*9d42c84fSVineet Gupta * 143*9d42c84fSVineet Gupta * NOTE: 144*9d42c84fSVineet Gupta * Ideally this shd only be called in switch_to for loading 145*9d42c84fSVineet Gupta * switched-IN task's CALLEE Reg File. 146*9d42c84fSVineet Gupta * For all other cases RESTORE_CALLEE_SAVED_FAST must be used 147*9d42c84fSVineet Gupta * which simply pops the stack w/o touching regs. 148*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 149*9d42c84fSVineet Gupta .macro RESTORE_CALLEE_SAVED_KERNEL 150*9d42c84fSVineet Gupta 151*9d42c84fSVineet Gupta add sp, sp, 4 /* skip "callee_regs->stack_place_holder" */ 152*9d42c84fSVineet Gupta ld.ab r25, [sp, 4] 153*9d42c84fSVineet Gupta ld.ab r24, [sp, 4] 154*9d42c84fSVineet Gupta ld.ab r23, [sp, 4] 155*9d42c84fSVineet Gupta ld.ab r22, [sp, 4] 156*9d42c84fSVineet Gupta ld.ab r21, [sp, 4] 157*9d42c84fSVineet Gupta ld.ab r20, [sp, 4] 158*9d42c84fSVineet Gupta ld.ab r19, [sp, 4] 159*9d42c84fSVineet Gupta ld.ab r18, [sp, 4] 160*9d42c84fSVineet Gupta ld.ab r17, [sp, 4] 161*9d42c84fSVineet Gupta ld.ab r16, [sp, 4] 162*9d42c84fSVineet Gupta ld.ab r15, [sp, 4] 163*9d42c84fSVineet Gupta ld.ab r14, [sp, 4] 164*9d42c84fSVineet Gupta ld.ab r13, [sp, 4] 165*9d42c84fSVineet Gupta 166*9d42c84fSVineet Gupta .endm 167*9d42c84fSVineet Gupta 168*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 169*9d42c84fSVineet Gupta * Super FAST Restore callee saved regs by simply re-adjusting SP 170*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 171*9d42c84fSVineet Gupta .macro DISCARD_CALLEE_SAVED_USER 172*9d42c84fSVineet Gupta add sp, sp, 14 * 4 173*9d42c84fSVineet Gupta .endm 174*9d42c84fSVineet Gupta 175*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 176*9d42c84fSVineet Gupta * Restore User mode r25 saved in task_struct->thread.user_r25 177*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 178*9d42c84fSVineet Gupta .macro RESTORE_USER_R25 179*9d42c84fSVineet Gupta ld r25, [r25, TASK_THREAD + THREAD_USER_R25] 180*9d42c84fSVineet Gupta .endm 181*9d42c84fSVineet Gupta 182*9d42c84fSVineet Gupta /*------------------------------------------------------------- 183*9d42c84fSVineet Gupta * given a tsk struct, get to the base of it's kernel mode stack 184*9d42c84fSVineet Gupta * tsk->thread_info is really a PAGE, whose bottom hoists stack 185*9d42c84fSVineet Gupta * which grows upwards towards thread_info 186*9d42c84fSVineet Gupta *------------------------------------------------------------*/ 187*9d42c84fSVineet Gupta 188*9d42c84fSVineet Gupta .macro GET_TSK_STACK_BASE tsk, out 189*9d42c84fSVineet Gupta 190*9d42c84fSVineet Gupta /* Get task->thread_info (this is essentially start of a PAGE) */ 191*9d42c84fSVineet Gupta ld \out, [\tsk, TASK_THREAD_INFO] 192*9d42c84fSVineet Gupta 193*9d42c84fSVineet Gupta /* Go to end of page where stack begins (grows upwards) */ 194*9d42c84fSVineet Gupta add2 \out, \out, (THREAD_SIZE - 4)/4 /* one word GUTTER */ 195*9d42c84fSVineet Gupta 196*9d42c84fSVineet Gupta .endm 197*9d42c84fSVineet Gupta 198*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 199*9d42c84fSVineet Gupta * Switch to Kernel Mode stack if SP points to User Mode stack 200*9d42c84fSVineet Gupta * 201*9d42c84fSVineet Gupta * Entry : r9 contains pre-IRQ/exception/trap status32 202*9d42c84fSVineet Gupta * Exit : SP is set to kernel mode stack pointer 203*9d42c84fSVineet Gupta * Clobbers: r9 204*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 205*9d42c84fSVineet Gupta 206*9d42c84fSVineet Gupta .macro SWITCH_TO_KERNEL_STK 207*9d42c84fSVineet Gupta 208*9d42c84fSVineet Gupta /* User Mode when this happened ? Yes: Proceed to switch stack */ 209*9d42c84fSVineet Gupta bbit1 r9, STATUS_U_BIT, 88f 210*9d42c84fSVineet Gupta 211*9d42c84fSVineet Gupta /* OK we were already in kernel mode when this event happened, thus can 212*9d42c84fSVineet Gupta * assume SP is kernel mode SP. _NO_ need to do any stack switching 213*9d42c84fSVineet Gupta */ 214*9d42c84fSVineet Gupta 215*9d42c84fSVineet Gupta /* Save Pre Intr/Exception KERNEL MODE SP on kernel stack 216*9d42c84fSVineet Gupta * safe-keeping not really needed, but it keeps the epilogue code 217*9d42c84fSVineet Gupta * (SP restore) simpler/uniform. 218*9d42c84fSVineet Gupta */ 219*9d42c84fSVineet Gupta b.d 77f 220*9d42c84fSVineet Gupta 221*9d42c84fSVineet Gupta st.a sp, [sp, -12] ; Make room for orig_r0 and orig_r8 222*9d42c84fSVineet Gupta 223*9d42c84fSVineet Gupta 88: /*------Intr/Ecxp happened in user mode, "switch" stack ------ */ 224*9d42c84fSVineet Gupta 225*9d42c84fSVineet Gupta GET_CURR_TASK_ON_CPU r9 226*9d42c84fSVineet Gupta 227*9d42c84fSVineet Gupta /* With current tsk in r9, get it's kernel mode stack base */ 228*9d42c84fSVineet Gupta GET_TSK_STACK_BASE r9, r9 229*9d42c84fSVineet Gupta 230*9d42c84fSVineet Gupta #ifdef PT_REGS_CANARY 231*9d42c84fSVineet Gupta st 0xabcdabcd, [r9, 0] 232*9d42c84fSVineet Gupta #endif 233*9d42c84fSVineet Gupta 234*9d42c84fSVineet Gupta /* Save Pre Intr/Exception User SP on kernel stack */ 235*9d42c84fSVineet Gupta st.a sp, [r9, -12] ; Make room for orig_r0 and orig_r8 236*9d42c84fSVineet Gupta 237*9d42c84fSVineet Gupta /* CAUTION: 238*9d42c84fSVineet Gupta * SP should be set at the very end when we are done with everything 239*9d42c84fSVineet Gupta * In case of 2 levels of interrupt we depend on value of SP to assume 240*9d42c84fSVineet Gupta * that everything else is done (loading r25 etc) 241*9d42c84fSVineet Gupta */ 242*9d42c84fSVineet Gupta 243*9d42c84fSVineet Gupta /* set SP to point to kernel mode stack */ 244*9d42c84fSVineet Gupta mov sp, r9 245*9d42c84fSVineet Gupta 246*9d42c84fSVineet Gupta 77: /* ----- Stack Switched to kernel Mode, Now save REG FILE ----- */ 247*9d42c84fSVineet Gupta 248*9d42c84fSVineet Gupta .endm 249*9d42c84fSVineet Gupta 250*9d42c84fSVineet Gupta /*------------------------------------------------------------ 251*9d42c84fSVineet Gupta * "FAKE" a rtie to return from CPU Exception context 252*9d42c84fSVineet Gupta * This is to re-enable Exceptions within exception 253*9d42c84fSVineet Gupta * Look at EV_ProtV to see how this is actually used 254*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 255*9d42c84fSVineet Gupta 256*9d42c84fSVineet Gupta .macro FAKE_RET_FROM_EXCPN reg 257*9d42c84fSVineet Gupta 258*9d42c84fSVineet Gupta ld \reg, [sp, PT_status32] 259*9d42c84fSVineet Gupta bic \reg, \reg, (STATUS_U_MASK|STATUS_DE_MASK) 260*9d42c84fSVineet Gupta bset \reg, \reg, STATUS_L_BIT 261*9d42c84fSVineet Gupta sr \reg, [erstatus] 262*9d42c84fSVineet Gupta mov \reg, 55f 263*9d42c84fSVineet Gupta sr \reg, [eret] 264*9d42c84fSVineet Gupta 265*9d42c84fSVineet Gupta rtie 266*9d42c84fSVineet Gupta 55: 267*9d42c84fSVineet Gupta .endm 268*9d42c84fSVineet Gupta 269*9d42c84fSVineet Gupta /* 270*9d42c84fSVineet Gupta * @reg [OUT] &thread_info of "current" 271*9d42c84fSVineet Gupta */ 272*9d42c84fSVineet Gupta .macro GET_CURR_THR_INFO_FROM_SP reg 273*9d42c84fSVineet Gupta and \reg, sp, ~(THREAD_SIZE - 1) 274*9d42c84fSVineet Gupta .endm 275*9d42c84fSVineet Gupta 276*9d42c84fSVineet Gupta /* 277*9d42c84fSVineet Gupta * @reg [OUT] thread_info->flags of "current" 278*9d42c84fSVineet Gupta */ 279*9d42c84fSVineet Gupta .macro GET_CURR_THR_INFO_FLAGS reg 280*9d42c84fSVineet Gupta GET_CURR_THR_INFO_FROM_SP \reg 281*9d42c84fSVineet Gupta ld \reg, [\reg, THREAD_INFO_FLAGS] 282*9d42c84fSVineet Gupta .endm 283*9d42c84fSVineet Gupta 284*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 285*9d42c84fSVineet Gupta * For early Exception Prologue, a core reg is temporarily needed to 286*9d42c84fSVineet Gupta * code the rest of prolog (stack switching). This is done by stashing 287*9d42c84fSVineet Gupta * it to memory (non-SMP case) or SCRATCH0 Aux Reg (SMP). 288*9d42c84fSVineet Gupta * 289*9d42c84fSVineet Gupta * Before saving the full regfile - this reg is restored back, only 290*9d42c84fSVineet Gupta * to be saved again on kernel mode stack, as part of ptregs. 291*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 292*9d42c84fSVineet Gupta .macro EXCPN_PROLOG_FREEUP_REG reg 293*9d42c84fSVineet Gupta st \reg, [@ex_saved_reg1] 294*9d42c84fSVineet Gupta .endm 295*9d42c84fSVineet Gupta 296*9d42c84fSVineet Gupta .macro EXCPN_PROLOG_RESTORE_REG reg 297*9d42c84fSVineet Gupta ld \reg, [@ex_saved_reg1] 298*9d42c84fSVineet Gupta .endm 299*9d42c84fSVineet Gupta 300*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 301*9d42c84fSVineet Gupta * Save all registers used by Exceptions (TLB Miss, Prot-V, Mem err etc) 302*9d42c84fSVineet Gupta * Requires SP to be already switched to kernel mode Stack 303*9d42c84fSVineet Gupta * sp points to the next free element on the stack at exit of this macro. 304*9d42c84fSVineet Gupta * Registers are pushed / popped in the order defined in struct ptregs 305*9d42c84fSVineet Gupta * in asm/ptrace.h 306*9d42c84fSVineet Gupta * Note that syscalls are implemented via TRAP which is also a exception 307*9d42c84fSVineet Gupta * from CPU's point of view 308*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 309*9d42c84fSVineet Gupta .macro SAVE_ALL_EXCEPTION marker 310*9d42c84fSVineet Gupta 311*9d42c84fSVineet Gupta /* Restore r9 used to code the early prologue */ 312*9d42c84fSVineet Gupta EXCPN_PROLOG_RESTORE_REG r9 313*9d42c84fSVineet Gupta 314*9d42c84fSVineet Gupta /* Save the complete regfile now */ 315*9d42c84fSVineet Gupta 316*9d42c84fSVineet Gupta /* orig_r8 marker: 317*9d42c84fSVineet Gupta * syscalls -> 1 to NR_SYSCALLS 318*9d42c84fSVineet Gupta * Exceptions -> NR_SYSCALLS + 1 319*9d42c84fSVineet Gupta * Break-point-> NR_SYSCALLS + 2 320*9d42c84fSVineet Gupta */ 321*9d42c84fSVineet Gupta st \marker, [sp, 8] 322*9d42c84fSVineet Gupta st r0, [sp, 4] /* orig_r0, needed only for sys calls */ 323*9d42c84fSVineet Gupta SAVE_CALLER_SAVED 324*9d42c84fSVineet Gupta st.a r26, [sp, -4] /* gp */ 325*9d42c84fSVineet Gupta st.a fp, [sp, -4] 326*9d42c84fSVineet Gupta st.a blink, [sp, -4] 327*9d42c84fSVineet Gupta lr r9, [eret] 328*9d42c84fSVineet Gupta st.a r9, [sp, -4] 329*9d42c84fSVineet Gupta lr r9, [erstatus] 330*9d42c84fSVineet Gupta st.a r9, [sp, -4] 331*9d42c84fSVineet Gupta st.a lp_count, [sp, -4] 332*9d42c84fSVineet Gupta lr r9, [lp_end] 333*9d42c84fSVineet Gupta st.a r9, [sp, -4] 334*9d42c84fSVineet Gupta lr r9, [lp_start] 335*9d42c84fSVineet Gupta st.a r9, [sp, -4] 336*9d42c84fSVineet Gupta lr r9, [erbta] 337*9d42c84fSVineet Gupta st.a r9, [sp, -4] 338*9d42c84fSVineet Gupta 339*9d42c84fSVineet Gupta #ifdef PT_REGS_CANARY 340*9d42c84fSVineet Gupta mov r9, 0xdeadbeef 341*9d42c84fSVineet Gupta st r9, [sp, -4] 342*9d42c84fSVineet Gupta #endif 343*9d42c84fSVineet Gupta 344*9d42c84fSVineet Gupta /* move up by 1 word to "create" pt_regs->"stack_place_holder" */ 345*9d42c84fSVineet Gupta sub sp, sp, 4 346*9d42c84fSVineet Gupta .endm 347*9d42c84fSVineet Gupta 348*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 349*9d42c84fSVineet Gupta * Save scratch regs for exceptions 350*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 351*9d42c84fSVineet Gupta .macro SAVE_ALL_SYS 352*9d42c84fSVineet Gupta SAVE_ALL_EXCEPTION (NR_syscalls + 1) 353*9d42c84fSVineet Gupta .endm 354*9d42c84fSVineet Gupta 355*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 356*9d42c84fSVineet Gupta * Save scratch regs for sys calls 357*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 358*9d42c84fSVineet Gupta .macro SAVE_ALL_TRAP 359*9d42c84fSVineet Gupta SAVE_ALL_EXCEPTION r8 360*9d42c84fSVineet Gupta .endm 361*9d42c84fSVineet Gupta 362*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 363*9d42c84fSVineet Gupta * Restore all registers used by system call or Exceptions 364*9d42c84fSVineet Gupta * SP should always be pointing to the next free stack element 365*9d42c84fSVineet Gupta * when entering this macro. 366*9d42c84fSVineet Gupta * 367*9d42c84fSVineet Gupta * NOTE: 368*9d42c84fSVineet Gupta * 369*9d42c84fSVineet Gupta * It is recommended that lp_count/ilink1/ilink2 not be used as a dest reg 370*9d42c84fSVineet Gupta * for memory load operations. If used in that way interrupts are deffered 371*9d42c84fSVineet Gupta * by hardware and that is not good. 372*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 373*9d42c84fSVineet Gupta .macro RESTORE_ALL_SYS 374*9d42c84fSVineet Gupta 375*9d42c84fSVineet Gupta add sp, sp, 4 /* hop over unused "pt_regs->stack_place_holder" */ 376*9d42c84fSVineet Gupta 377*9d42c84fSVineet Gupta ld.ab r9, [sp, 4] 378*9d42c84fSVineet Gupta sr r9, [erbta] 379*9d42c84fSVineet Gupta ld.ab r9, [sp, 4] 380*9d42c84fSVineet Gupta sr r9, [lp_start] 381*9d42c84fSVineet Gupta ld.ab r9, [sp, 4] 382*9d42c84fSVineet Gupta sr r9, [lp_end] 383*9d42c84fSVineet Gupta ld.ab r9, [sp, 4] 384*9d42c84fSVineet Gupta mov lp_count, r9 385*9d42c84fSVineet Gupta ld.ab r9, [sp, 4] 386*9d42c84fSVineet Gupta sr r9, [erstatus] 387*9d42c84fSVineet Gupta ld.ab r9, [sp, 4] 388*9d42c84fSVineet Gupta sr r9, [eret] 389*9d42c84fSVineet Gupta ld.ab blink, [sp, 4] 390*9d42c84fSVineet Gupta ld.ab fp, [sp, 4] 391*9d42c84fSVineet Gupta ld.ab r26, [sp, 4] /* gp */ 392*9d42c84fSVineet Gupta RESTORE_CALLER_SAVED 393*9d42c84fSVineet Gupta 394*9d42c84fSVineet Gupta ld sp, [sp] /* restore original sp */ 395*9d42c84fSVineet Gupta /* orig_r0 and orig_r8 skipped automatically */ 396*9d42c84fSVineet Gupta .endm 397*9d42c84fSVineet Gupta 398*9d42c84fSVineet Gupta 399*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 400*9d42c84fSVineet Gupta * Save all registers used by interrupt handlers. 401*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 402*9d42c84fSVineet Gupta .macro SAVE_ALL_INT1 403*9d42c84fSVineet Gupta 404*9d42c84fSVineet Gupta /* restore original r9 , saved in int1_saved_reg 405*9d42c84fSVineet Gupta * It will be saved on stack in macro: SAVE_CALLER_SAVED 406*9d42c84fSVineet Gupta */ 407*9d42c84fSVineet Gupta ld r9, [@int1_saved_reg] 408*9d42c84fSVineet Gupta 409*9d42c84fSVineet Gupta /* now we are ready to save the remaining context :) */ 410*9d42c84fSVineet Gupta st -1, [sp, 8] /* orig_r8, -1 for interuppt level one */ 411*9d42c84fSVineet Gupta st 0, [sp, 4] /* orig_r0 , N/A for IRQ */ 412*9d42c84fSVineet Gupta SAVE_CALLER_SAVED 413*9d42c84fSVineet Gupta st.a r26, [sp, -4] /* gp */ 414*9d42c84fSVineet Gupta st.a fp, [sp, -4] 415*9d42c84fSVineet Gupta st.a blink, [sp, -4] 416*9d42c84fSVineet Gupta st.a ilink1, [sp, -4] 417*9d42c84fSVineet Gupta lr r9, [status32_l1] 418*9d42c84fSVineet Gupta st.a r9, [sp, -4] 419*9d42c84fSVineet Gupta st.a lp_count, [sp, -4] 420*9d42c84fSVineet Gupta lr r9, [lp_end] 421*9d42c84fSVineet Gupta st.a r9, [sp, -4] 422*9d42c84fSVineet Gupta lr r9, [lp_start] 423*9d42c84fSVineet Gupta st.a r9, [sp, -4] 424*9d42c84fSVineet Gupta lr r9, [bta_l1] 425*9d42c84fSVineet Gupta st.a r9, [sp, -4] 426*9d42c84fSVineet Gupta 427*9d42c84fSVineet Gupta #ifdef PT_REGS_CANARY 428*9d42c84fSVineet Gupta mov r9, 0xdeadbee1 429*9d42c84fSVineet Gupta st r9, [sp, -4] 430*9d42c84fSVineet Gupta #endif 431*9d42c84fSVineet Gupta /* move up by 1 word to "create" pt_regs->"stack_place_holder" */ 432*9d42c84fSVineet Gupta sub sp, sp, 4 433*9d42c84fSVineet Gupta .endm 434*9d42c84fSVineet Gupta 435*9d42c84fSVineet Gupta /*-------------------------------------------------------------- 436*9d42c84fSVineet Gupta * Restore all registers used by interrupt handlers. 437*9d42c84fSVineet Gupta * 438*9d42c84fSVineet Gupta * NOTE: 439*9d42c84fSVineet Gupta * 440*9d42c84fSVineet Gupta * It is recommended that lp_count/ilink1/ilink2 not be used as a dest reg 441*9d42c84fSVineet Gupta * for memory load operations. If used in that way interrupts are deffered 442*9d42c84fSVineet Gupta * by hardware and that is not good. 443*9d42c84fSVineet Gupta *-------------------------------------------------------------*/ 444*9d42c84fSVineet Gupta 445*9d42c84fSVineet Gupta .macro RESTORE_ALL_INT1 446*9d42c84fSVineet Gupta add sp, sp, 4 /* hop over unused "pt_regs->stack_place_holder" */ 447*9d42c84fSVineet Gupta 448*9d42c84fSVineet Gupta ld.ab r9, [sp, 4] /* Actual reg file */ 449*9d42c84fSVineet Gupta sr r9, [bta_l1] 450*9d42c84fSVineet Gupta ld.ab r9, [sp, 4] 451*9d42c84fSVineet Gupta sr r9, [lp_start] 452*9d42c84fSVineet Gupta ld.ab r9, [sp, 4] 453*9d42c84fSVineet Gupta sr r9, [lp_end] 454*9d42c84fSVineet Gupta ld.ab r9, [sp, 4] 455*9d42c84fSVineet Gupta mov lp_count, r9 456*9d42c84fSVineet Gupta ld.ab r9, [sp, 4] 457*9d42c84fSVineet Gupta sr r9, [status32_l1] 458*9d42c84fSVineet Gupta ld.ab r9, [sp, 4] 459*9d42c84fSVineet Gupta mov ilink1, r9 460*9d42c84fSVineet Gupta ld.ab blink, [sp, 4] 461*9d42c84fSVineet Gupta ld.ab fp, [sp, 4] 462*9d42c84fSVineet Gupta ld.ab r26, [sp, 4] /* gp */ 463*9d42c84fSVineet Gupta RESTORE_CALLER_SAVED 464*9d42c84fSVineet Gupta 465*9d42c84fSVineet Gupta ld sp, [sp] /* restore original sp */ 466*9d42c84fSVineet Gupta /* orig_r0 and orig_r8 skipped automatically */ 467*9d42c84fSVineet Gupta .endm 468*9d42c84fSVineet Gupta 469*9d42c84fSVineet Gupta /* Get CPU-ID of this core */ 470*9d42c84fSVineet Gupta .macro GET_CPU_ID reg 471*9d42c84fSVineet Gupta lr \reg, [identity] 472*9d42c84fSVineet Gupta lsr \reg, \reg, 8 473*9d42c84fSVineet Gupta bmsk \reg, \reg, 7 474*9d42c84fSVineet Gupta .endm 475*9d42c84fSVineet Gupta 476*9d42c84fSVineet Gupta .macro GET_CURR_TASK_ON_CPU reg 477*9d42c84fSVineet Gupta ld \reg, [@_current_task] 478*9d42c84fSVineet Gupta .endm 479*9d42c84fSVineet Gupta 480*9d42c84fSVineet Gupta .macro SET_CURR_TASK_ON_CPU tsk, tmp 481*9d42c84fSVineet Gupta st \tsk, [@_current_task] 482*9d42c84fSVineet Gupta .endm 483*9d42c84fSVineet Gupta 484*9d42c84fSVineet Gupta /* ------------------------------------------------------------------ 485*9d42c84fSVineet Gupta * Get the ptr to some field of Current Task at @off in task struct 486*9d42c84fSVineet Gupta */ 487*9d42c84fSVineet Gupta 488*9d42c84fSVineet Gupta .macro GET_CURR_TASK_FIELD_PTR off, reg 489*9d42c84fSVineet Gupta GET_CURR_TASK_ON_CPU \reg 490*9d42c84fSVineet Gupta add \reg, \reg, \off 491*9d42c84fSVineet Gupta .endm 492*9d42c84fSVineet Gupta 493*9d42c84fSVineet Gupta #endif /* __ASSEMBLY__ */ 494*9d42c84fSVineet Gupta 495*9d42c84fSVineet Gupta #endif /* __ASM_ARC_ENTRY_H */ 496