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