root/arch/arc/include/asm/entry-arcv2.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 
   3 #ifndef __ASM_ARC_ENTRY_ARCV2_H
   4 #define __ASM_ARC_ENTRY_ARCV2_H
   5 
   6 #include <asm/asm-offsets.h>
   7 #include <asm/irqflags-arcv2.h>
   8 #include <asm/thread_info.h>    /* For THREAD_SIZE */
   9 
  10 /*
  11  * Interrupt/Exception stack layout (pt_regs) for ARCv2
  12  *   (End of struct aligned to end of page [unless nested])
  13  *
  14  *  INTERRUPT                          EXCEPTION
  15  *
  16  *    manual    ---------------------  manual
  17  *              |      orig_r0      |
  18  *              |      event/ECR    |
  19  *              |      bta          |
  20  *              |      user_r25     |
  21  *              |      gp           |
  22  *              |      fp           |
  23  *              |      sp           |
  24  *              |      r12          |
  25  *              |      r30          |
  26  *              |      r58          |
  27  *              |      r59          |
  28  *  hw autosave ---------------------
  29  *    optional  |      r0           |
  30  *              |      r1           |
  31  *              ~                   ~
  32  *              |      r9           |
  33  *              |      r10          |
  34  *              |      r11          |
  35  *              |      blink        |
  36  *              |      lpe          |
  37  *              |      lps          |
  38  *              |      lpc          |
  39  *              |      ei base      |
  40  *              |      ldi base     |
  41  *              |      jli base     |
  42  *              ---------------------
  43  *  hw autosave |       pc / eret   |
  44  *   mandatory  | stat32 / erstatus |
  45  *              ---------------------
  46  */
  47 
  48 /*------------------------------------------------------------------------*/
  49 .macro INTERRUPT_PROLOGUE
  50 
  51         ; (A) Before jumping to Interrupt Vector, hardware micro-ops did following:
  52         ;   1. SP auto-switched to kernel mode stack
  53         ;   2. STATUS32.Z flag set if in U mode at time of interrupt (U:1,K:0)
  54         ;   3. Auto save: (mandatory) Push PC and STAT32 on stack
  55         ;                 hardware does even if CONFIG_ARC_IRQ_NO_AUTOSAVE
  56         ;   4. Auto save: (optional) r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI
  57         ;
  58         ; (B) Manually saved some regs: r12,r25,r30, sp,fp,gp, ACCL pair
  59 
  60 #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
  61         ; carve pt_regs on stack (case #3), PC/STAT32 already on stack
  62         sub     sp, sp, SZ_PT_REGS - 8
  63 
  64         __SAVE_REGFILE_HARD
  65 #else
  66         ; carve pt_regs on stack (case #4), which grew partially already
  67         sub     sp, sp, PT_r0
  68 #endif
  69 
  70         __SAVE_REGFILE_SOFT
  71 .endm
  72 
  73 /*------------------------------------------------------------------------*/
  74 .macro EXCEPTION_PROLOGUE
  75 
  76         ; (A) Before jumping to Exception Vector, hardware micro-ops did following:
  77         ;   1. SP auto-switched to kernel mode stack
  78         ;   2. STATUS32.Z flag set if in U mode at time of exception (U:1,K:0)
  79         ;
  80         ; (B) Manually save the complete reg file below
  81 
  82         sub     sp, sp, SZ_PT_REGS      ; carve pt_regs
  83 
  84         ; _HARD saves r10 clobbered by _SOFT as scratch hence comes first
  85 
  86         __SAVE_REGFILE_HARD
  87         __SAVE_REGFILE_SOFT
  88 
  89         st      r0, [sp]        ; orig_r0
  90 
  91         lr      r10, [eret]
  92         lr      r11, [erstatus]
  93         ST2     r10, r11, PT_ret
  94 
  95         lr      r10, [ecr]
  96         lr      r11, [erbta]
  97         ST2     r10, r11, PT_event
  98 
  99         ; OUTPUT: r10 has ECR expected by EV_Trap
 100 .endm
 101 
 102 /*------------------------------------------------------------------------
 103  * This macro saves the registers manually which would normally be autosaved
 104  * by hardware on taken interrupts. It is used by
 105  *   - exception handlers (which don't have autosave)
 106  *   - interrupt autosave disabled due to CONFIG_ARC_IRQ_NO_AUTOSAVE
 107  */
 108 .macro __SAVE_REGFILE_HARD
 109 
 110         ST2     r0,  r1,  PT_r0
 111         ST2     r2,  r3,  PT_r2
 112         ST2     r4,  r5,  PT_r4
 113         ST2     r6,  r7,  PT_r6
 114         ST2     r8,  r9,  PT_r8
 115         ST2     r10, r11, PT_r10
 116 
 117         st      blink, [sp, PT_blink]
 118 
 119         lr      r10, [lp_end]
 120         lr      r11, [lp_start]
 121         ST2     r10, r11, PT_lpe
 122 
 123         st      lp_count, [sp, PT_lpc]
 124 
 125         ; skip JLI, LDI, EI for now
 126 .endm
 127 
 128 /*------------------------------------------------------------------------
 129  * This macros saves a bunch of other registers which can't be autosaved for
 130  * various reasons:
 131  *   - r12: the last caller saved scratch reg since hardware saves in pairs so r0-r11
 132  *   - r30: free reg, used by gcc as scratch
 133  *   - ACCL/ACCH pair when they exist
 134  */
 135 .macro __SAVE_REGFILE_SOFT
 136 
 137         ST2     gp, fp, PT_r26          ; gp (r26), fp (r27)
 138 
 139         st      r12, [sp, PT_sp + 4]
 140         st      r30, [sp, PT_sp + 8]
 141 
 142         ; Saving pt_regs->sp correctly requires some extra work due to the way
 143         ; Auto stack switch works
 144         ;  - U mode: retrieve it from AUX_USER_SP
 145         ;  - K mode: add the offset from current SP where H/w starts auto push
 146         ;
 147         ; 1. Utilize the fact that Z bit is set if Intr taken in U mode
 148         ; 2. Upon entry SP is always saved (for any inspection, unwinding etc),
 149         ;    but on return, restored only if U mode
 150 
 151         lr      r10, [AUX_USER_SP]      ; U mode SP
 152 
 153         ; ISA requires ADD.nz to have same dest and src reg operands
 154         mov.nz  r10, sp
 155         add.nz  r10, r10, SZ_PT_REGS    ; K mode SP
 156 
 157         st      r10, [sp, PT_sp]        ; SP (pt_regs->sp)
 158 
 159 #ifdef CONFIG_ARC_CURR_IN_REG
 160         st      r25, [sp, PT_user_r25]
 161         GET_CURR_TASK_ON_CPU    r25
 162 #endif
 163 
 164 #ifdef CONFIG_ARC_HAS_ACCL_REGS
 165         ST2     r58, r59, PT_sp + 12
 166 #endif
 167 
 168 .endm
 169 
 170 /*------------------------------------------------------------------------*/
 171 .macro __RESTORE_REGFILE_SOFT
 172 
 173         LD2     gp, fp, PT_r26          ; gp (r26), fp (r27)
 174 
 175         ld      r12, [sp, PT_sp + 4]
 176         ld      r30, [sp, PT_sp + 8]
 177 
 178         ; Restore SP (into AUX_USER_SP) only if returning to U mode
 179         ;  - for K mode, it will be implicitly restored as stack is unwound
 180         ;  - Z flag set on K is inverse of what hardware does on interrupt entry
 181         ;    but that doesn't really matter
 182         bz      1f
 183 
 184         ld      r10, [sp, PT_sp]        ; SP (pt_regs->sp)
 185         sr      r10, [AUX_USER_SP]
 186 1:
 187 
 188 #ifdef CONFIG_ARC_CURR_IN_REG
 189         ld      r25, [sp, PT_user_r25]
 190 #endif
 191 
 192 #ifdef CONFIG_ARC_HAS_ACCL_REGS
 193         LD2     r58, r59, PT_sp + 12
 194 #endif
 195 .endm
 196 
 197 /*------------------------------------------------------------------------*/
 198 .macro __RESTORE_REGFILE_HARD
 199 
 200         ld      blink, [sp, PT_blink]
 201 
 202         LD2     r10, r11, PT_lpe
 203         sr      r10, [lp_end]
 204         sr      r11, [lp_start]
 205 
 206         ld      r10, [sp, PT_lpc]       ; lp_count can't be target of LD
 207         mov     lp_count, r10
 208 
 209         LD2     r0,  r1,  PT_r0
 210         LD2     r2,  r3,  PT_r2
 211         LD2     r4,  r5,  PT_r4
 212         LD2     r6,  r7,  PT_r6
 213         LD2     r8,  r9,  PT_r8
 214         LD2     r10, r11, PT_r10
 215 .endm
 216 
 217 
 218 /*------------------------------------------------------------------------*/
 219 .macro INTERRUPT_EPILOGUE
 220 
 221         ; INPUT: r0 has STAT32 of calling context
 222         ; INPUT: Z flag set if returning to K mode
 223 
 224         ; _SOFT clobbers r10 restored by _HARD hence the order
 225 
 226         __RESTORE_REGFILE_SOFT
 227 
 228 #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
 229         __RESTORE_REGFILE_HARD
 230         add     sp, sp, SZ_PT_REGS - 8
 231 #else
 232         add     sp, sp, PT_r0
 233 #endif
 234 
 235 .endm
 236 
 237 /*------------------------------------------------------------------------*/
 238 .macro EXCEPTION_EPILOGUE
 239 
 240         ; INPUT: r0 has STAT32 of calling context
 241 
 242         btst    r0, STATUS_U_BIT        ; Z flag set if K, used in restoring SP
 243 
 244         ld      r10, [sp, PT_event + 4]
 245         sr      r10, [erbta]
 246 
 247         LD2     r10, r11, PT_ret
 248         sr      r10, [eret]
 249         sr      r11, [erstatus]
 250 
 251         __RESTORE_REGFILE_SOFT
 252         __RESTORE_REGFILE_HARD
 253 
 254         add     sp, sp, SZ_PT_REGS
 255 .endm
 256 
 257 .macro FAKE_RET_FROM_EXCPN
 258         lr      r9, [status32]
 259         bic     r9, r9, STATUS_AE_MASK
 260         or      r9, r9, STATUS_IE_MASK
 261         kflag   r9
 262 .endm
 263 
 264 /* Get thread_info of "current" tsk */
 265 .macro GET_CURR_THR_INFO_FROM_SP  reg
 266         bmskn \reg, sp, THREAD_SHIFT - 1
 267 .endm
 268 
 269 /* Get CPU-ID of this core */
 270 .macro  GET_CPU_ID  reg
 271         lr  \reg, [identity]
 272         xbfu \reg, \reg, 0xE8   /* 00111    01000 */
 273                                 /* M = 8-1  N = 8 */
 274 .endm
 275 
 276 #endif

/* [<][>][^][v][top][bottom][index][help] */