linux/arch/arc/include/asm/entry-arcv2.h
<<
>>
Prefs
   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]
  321:
  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
  731:
  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