1 2 #ifndef __ASM_ARC_ENTRY_ARCV2_H 3 #define __ASM_ARC_ENTRY_ARCV2_H 4 5 #include <asm/asm-offsets.h> 6 #include <asm/irqflags-arcv2.h> 7 #include <asm/thread_info.h> /* For THREAD_SIZE */ 8 9 /*------------------------------------------------------------------------*/ 10 .macro INTERRUPT_PROLOGUE called_from 11 12 ; Before jumping to Interrupt Vector, hardware micro-ops did following: 13 ; 1. SP auto-switched to kernel mode stack 14 ; 2. STATUS32.Z flag set to U mode at time of interrupt (U:1, K:0) 15 ; 3. Auto saved: r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI, PC, STAT32 16 ; 17 ; Now manually save: r12, sp, fp, gp, r25 18 19 PUSH r12 20 21 ; Saving pt_regs->sp correctly requires some extra work due to the way 22 ; Auto stack switch works 23 ; - U mode: retrieve it from AUX_USER_SP 24 ; - K mode: add the offset from current SP where H/w starts auto push 25 ; 26 ; Utilize the fact that Z bit is set if Intr taken in U mode 27 mov.nz r9, sp 28 add.nz r9, r9, SZ_PT_REGS - PT_sp - 4 29 bnz 1f 30 31 lr r9, [AUX_USER_SP] 32 1: 33 PUSH r9 ; SP 34 35 PUSH fp 36 PUSH gp 37 38 #ifdef CONFIG_ARC_CURR_IN_REG 39 PUSH r25 ; user_r25 40 GET_CURR_TASK_ON_CPU r25 41 #else 42 sub sp, sp, 4 43 #endif 44 45 .ifnc \called_from, exception 46 sub sp, sp, 12 ; BTA/ECR/orig_r0 placeholder per pt_regs 47 .endif 48 49 .endm 50 51 /*------------------------------------------------------------------------*/ 52 .macro INTERRUPT_EPILOGUE called_from 53 54 .ifnc \called_from, exception 55 add sp, sp, 12 ; skip BTA/ECR/orig_r0 placeholderss 56 .endif 57 58 #ifdef CONFIG_ARC_CURR_IN_REG 59 POP r25 60 #else 61 add sp, sp, 4 62 #endif 63 64 POP gp 65 POP fp 66 67 ; Don't touch AUX_USER_SP if returning to K mode (Z bit set) 68 ; (Z bit set on K mode is inverse of INTERRUPT_PROLOGUE) 69 add.z sp, sp, 4 70 bz 1f 71 72 POPAX AUX_USER_SP 73 1: 74 POP r12 75 76 .endm 77 78 /*------------------------------------------------------------------------*/ 79 .macro EXCEPTION_PROLOGUE 80 81 ; Before jumping to Exception Vector, hardware micro-ops did following: 82 ; 1. SP auto-switched to kernel mode stack 83 ; 2. STATUS32.Z flag set to U mode at time of interrupt (U:1,K:0) 84 ; 85 ; Now manually save the complete reg file 86 87 PUSH r9 ; freeup a register: slot of erstatus 88 89 PUSHAX eret 90 sub sp, sp, 12 ; skip JLI, LDI, EI 91 PUSH lp_count 92 PUSHAX lp_start 93 PUSHAX lp_end 94 PUSH blink 95 96 PUSH r11 97 PUSH r10 98 99 ld.as r9, [sp, 10] ; load stashed r9 (status32 stack slot) 100 lr r10, [erstatus] 101 st.as r10, [sp, 10] ; save status32 at it's right stack slot 102 103 PUSH r9 104 PUSH r8 105 PUSH r7 106 PUSH r6 107 PUSH r5 108 PUSH r4 109 PUSH r3 110 PUSH r2 111 PUSH r1 112 PUSH r0 113 114 ; -- for interrupts, regs above are auto-saved by h/w in that order -- 115 ; Now do what ISR prologue does (manually save r12, sp, fp, gp, r25) 116 ; 117 ; Set Z flag if this was from U mode (expected by INTERRUPT_PROLOGUE) 118 ; Although H/w exception micro-ops do set Z flag for U mode (just like 119 ; for interrupts), it could get clobbered in case we soft land here from 120 ; a TLB Miss exception handler (tlbex.S) 121 122 and r10, r10, STATUS_U_MASK 123 xor.f 0, r10, STATUS_U_MASK 124 125 INTERRUPT_PROLOGUE exception 126 127 PUSHAX erbta 128 PUSHAX ecr ; r9 contains ECR, expected by EV_Trap 129 130 PUSH r0 ; orig_r0 131 .endm 132 133 /*------------------------------------------------------------------------*/ 134 .macro EXCEPTION_EPILOGUE 135 136 ; Assumes r0 has PT_status32 137 btst r0, STATUS_U_BIT ; Z flag set if K, used in INTERRUPT_EPILOGUE 138 139 add sp, sp, 8 ; orig_r0/ECR don't need restoring 140 POPAX erbta 141 142 INTERRUPT_EPILOGUE exception 143 144 POP r0 145 POP r1 146 POP r2 147 POP r3 148 POP r4 149 POP r5 150 POP r6 151 POP r7 152 POP r8 153 POP r9 154 POP r10 155 POP r11 156 157 POP blink 158 POPAX lp_end 159 POPAX lp_start 160 161 POP r9 162 mov lp_count, r9 163 164 add sp, sp, 12 ; skip JLI, LDI, EI 165 POPAX eret 166 POPAX erstatus 167 168 ld.as r9, [sp, -12] ; reload r9 which got clobbered 169 .endm 170 171 .macro FAKE_RET_FROM_EXCPN 172 lr r9, [status32] 173 bic r9, r9, (STATUS_U_MASK|STATUS_DE_MASK|STATUS_AE_MASK) 174 or r9, r9, (STATUS_L_MASK|STATUS_IE_MASK) 175 kflag r9 176 .endm 177 178 /* Get thread_info of "current" tsk */ 179 .macro GET_CURR_THR_INFO_FROM_SP reg 180 bmskn \reg, sp, THREAD_SHIFT - 1 181 .endm 182 183 /* Get CPU-ID of this core */ 184 .macro GET_CPU_ID reg 185 lr \reg, [identity] 186 xbfu \reg, \reg, 0xE8 /* 00111 01000 */ 187 /* M = 8-1 N = 8 */ 188 .endm 189 190 #endif 191