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