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