1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 21f6ccfffSVineet Gupta 31f6ccfffSVineet Gupta #ifndef __ASM_ARC_ENTRY_ARCV2_H 41f6ccfffSVineet Gupta #define __ASM_ARC_ENTRY_ARCV2_H 51f6ccfffSVineet Gupta 61f6ccfffSVineet Gupta #include <asm/asm-offsets.h> 74827d0cfSEugeniy Paltsev #include <asm/dsp-impl.h> 81f6ccfffSVineet Gupta #include <asm/irqflags-arcv2.h> 91f6ccfffSVineet Gupta #include <asm/thread_info.h> /* For THREAD_SIZE */ 101f6ccfffSVineet Gupta 1145869eb0SVineet Gupta /* 1245869eb0SVineet Gupta * Interrupt/Exception stack layout (pt_regs) for ARCv2 1345869eb0SVineet Gupta * (End of struct aligned to end of page [unless nested]) 1445869eb0SVineet Gupta * 1545869eb0SVineet Gupta * INTERRUPT EXCEPTION 1645869eb0SVineet Gupta * 1745869eb0SVineet Gupta * manual --------------------- manual 1845869eb0SVineet Gupta * | orig_r0 | 1945869eb0SVineet Gupta * | event/ECR | 2045869eb0SVineet Gupta * | bta | 2145869eb0SVineet Gupta * | gp | 2245869eb0SVineet Gupta * | fp | 2345869eb0SVineet Gupta * | sp | 2445869eb0SVineet Gupta * | r12 | 2545869eb0SVineet Gupta * | r30 | 2645869eb0SVineet Gupta * | r58 | 2745869eb0SVineet Gupta * | r59 | 2845869eb0SVineet Gupta * hw autosave --------------------- 2945869eb0SVineet Gupta * optional | r0 | 3045869eb0SVineet Gupta * | r1 | 3145869eb0SVineet Gupta * ~ ~ 3245869eb0SVineet Gupta * | r9 | 3345869eb0SVineet Gupta * | r10 | 3445869eb0SVineet Gupta * | r11 | 3545869eb0SVineet Gupta * | blink | 3645869eb0SVineet Gupta * | lpe | 3745869eb0SVineet Gupta * | lps | 3845869eb0SVineet Gupta * | lpc | 3945869eb0SVineet Gupta * | ei base | 4045869eb0SVineet Gupta * | ldi base | 4145869eb0SVineet Gupta * | jli base | 4245869eb0SVineet Gupta * --------------------- 4345869eb0SVineet Gupta * hw autosave | pc / eret | 4445869eb0SVineet Gupta * mandatory | stat32 / erstatus | 4545869eb0SVineet Gupta * --------------------- 4645869eb0SVineet Gupta */ 4745869eb0SVineet Gupta 481f6ccfffSVineet Gupta /*------------------------------------------------------------------------*/ 49a4880801SVineet Gupta .macro INTERRUPT_PROLOGUE 50a4880801SVineet Gupta 51c505b0daSVineet Gupta ; Before jumping to Interrupt Vector, hardware micro-ops did following: 521f6ccfffSVineet Gupta ; 1. SP auto-switched to kernel mode stack 5345869eb0SVineet Gupta ; 2. STATUS32.Z flag set if in U mode at time of interrupt (U:1,K:0) 5445869eb0SVineet Gupta ; 3. Auto save: (mandatory) Push PC and STAT32 on stack 5545869eb0SVineet Gupta ; hardware does even if CONFIG_ARC_IRQ_NO_AUTOSAVE 56c505b0daSVineet Gupta ; 4a. Auto save: (optional) r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI 571f6ccfffSVineet Gupta ; 58c505b0daSVineet Gupta ; Now 59c505b0daSVineet Gupta ; 4b. If Auto-save (optional) not enabled in hw, manually save them 60c505b0daSVineet Gupta ; 5. Manually save: r12,r30, sp,fp,gp, ACCL pair 61c505b0daSVineet Gupta ; 62c505b0daSVineet Gupta ; At the end, SP points to pt_regs 631f6ccfffSVineet Gupta 64e494239aSVineet Gupta #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE 65a4880801SVineet Gupta ; carve pt_regs on stack (case #3), PC/STAT32 already on stack 66a4880801SVineet Gupta sub sp, sp, SZ_PT_REGS - 8 67e494239aSVineet Gupta 68a4880801SVineet Gupta __SAVE_REGFILE_HARD 691f6ccfffSVineet Gupta #else 70a4880801SVineet Gupta ; carve pt_regs on stack (case #4), which grew partially already 71a4880801SVineet Gupta sub sp, sp, PT_r0 721f6ccfffSVineet Gupta #endif 731f6ccfffSVineet Gupta 74a4880801SVineet Gupta __SAVE_REGFILE_SOFT 751f6ccfffSVineet Gupta .endm 761f6ccfffSVineet Gupta 771f6ccfffSVineet Gupta /*------------------------------------------------------------------------*/ 7813347c10SVineet Gupta .macro EXCEPTION_PROLOGUE_KEEP_AE 791f6ccfffSVineet Gupta 80c505b0daSVineet Gupta ; Before jumping to Exception Vector, hardware micro-ops did following: 811f6ccfffSVineet Gupta ; 1. SP auto-switched to kernel mode stack 8245869eb0SVineet Gupta ; 2. STATUS32.Z flag set if in U mode at time of exception (U:1,K:0) 831f6ccfffSVineet Gupta ; 84c505b0daSVineet Gupta ; Now manually save rest of reg file 85c505b0daSVineet Gupta ; At the end, SP points to pt_regs 861f6ccfffSVineet Gupta 87c505b0daSVineet Gupta sub sp, sp, SZ_PT_REGS ; carve space for pt_regs 881f6ccfffSVineet Gupta 89a4880801SVineet Gupta ; _HARD saves r10 clobbered by _SOFT as scratch hence comes first 901f6ccfffSVineet Gupta 91a4880801SVineet Gupta __SAVE_REGFILE_HARD 92a4880801SVineet Gupta __SAVE_REGFILE_SOFT 931f6ccfffSVineet Gupta 94a4880801SVineet Gupta st r0, [sp] ; orig_r0 951f6ccfffSVineet Gupta 96a4880801SVineet Gupta lr r10, [eret] 97a4880801SVineet Gupta lr r11, [erstatus] 98a4880801SVineet Gupta ST2 r10, r11, PT_ret 991f6ccfffSVineet Gupta 100a4880801SVineet Gupta lr r10, [ecr] 101a4880801SVineet Gupta lr r11, [erbta] 102a4880801SVineet Gupta ST2 r10, r11, PT_event 1031f6ccfffSVineet Gupta 10468e5c6f0SVineet Gupta ; OUTPUT: r10 has ECR expected by EV_Trap 1051f6ccfffSVineet Gupta .endm 1061f6ccfffSVineet Gupta 10713347c10SVineet Gupta .macro EXCEPTION_PROLOGUE 10813347c10SVineet Gupta 10913347c10SVineet Gupta EXCEPTION_PROLOGUE_KEEP_AE ; return ECR in r10 11013347c10SVineet Gupta 11113347c10SVineet Gupta lr r0, [efa] 11213347c10SVineet Gupta mov r1, sp 11313347c10SVineet Gupta 11413347c10SVineet Gupta FAKE_RET_FROM_EXCPN ; clobbers r9 11513347c10SVineet Gupta .endm 11613347c10SVineet Gupta 117a4880801SVineet Gupta /*------------------------------------------------------------------------ 118a4880801SVineet Gupta * This macro saves the registers manually which would normally be autosaved 119a4880801SVineet Gupta * by hardware on taken interrupts. It is used by 120a4880801SVineet Gupta * - exception handlers (which don't have autosave) 121a4880801SVineet Gupta * - interrupt autosave disabled due to CONFIG_ARC_IRQ_NO_AUTOSAVE 122a4880801SVineet Gupta */ 123a4880801SVineet Gupta .macro __SAVE_REGFILE_HARD 124a4880801SVineet Gupta 125a4880801SVineet Gupta ST2 r0, r1, PT_r0 126a4880801SVineet Gupta ST2 r2, r3, PT_r2 127a4880801SVineet Gupta ST2 r4, r5, PT_r4 128a4880801SVineet Gupta ST2 r6, r7, PT_r6 129a4880801SVineet Gupta ST2 r8, r9, PT_r8 130a4880801SVineet Gupta ST2 r10, r11, PT_r10 131a4880801SVineet Gupta 132a4880801SVineet Gupta st blink, [sp, PT_blink] 133a4880801SVineet Gupta 134a4880801SVineet Gupta lr r10, [lp_end] 135a4880801SVineet Gupta lr r11, [lp_start] 136a4880801SVineet Gupta ST2 r10, r11, PT_lpe 137a4880801SVineet Gupta 138a4880801SVineet Gupta st lp_count, [sp, PT_lpc] 139a4880801SVineet Gupta 140a4880801SVineet Gupta ; skip JLI, LDI, EI for now 141a4880801SVineet Gupta .endm 142a4880801SVineet Gupta 143a4880801SVineet Gupta /*------------------------------------------------------------------------ 144a4880801SVineet Gupta * This macros saves a bunch of other registers which can't be autosaved for 145a4880801SVineet Gupta * various reasons: 146a4880801SVineet Gupta * - r12: the last caller saved scratch reg since hardware saves in pairs so r0-r11 147a4880801SVineet Gupta * - r30: free reg, used by gcc as scratch 148a4880801SVineet Gupta * - ACCL/ACCH pair when they exist 149a4880801SVineet Gupta */ 150a4880801SVineet Gupta .macro __SAVE_REGFILE_SOFT 151a4880801SVineet Gupta 152*d4624bf6SVineet Gupta st fp, [sp, PT_fp] ; r27 153c505b0daSVineet Gupta st r30, [sp, PT_r30] 154*d4624bf6SVineet Gupta st r12, [sp, PT_r12] 155*d4624bf6SVineet Gupta st r26, [sp, PT_r26] ; gp 156a4880801SVineet Gupta 157a4880801SVineet Gupta ; Saving pt_regs->sp correctly requires some extra work due to the way 158a4880801SVineet Gupta ; Auto stack switch works 159a4880801SVineet Gupta ; - U mode: retrieve it from AUX_USER_SP 160a4880801SVineet Gupta ; - K mode: add the offset from current SP where H/w starts auto push 161a4880801SVineet Gupta ; 162a4880801SVineet Gupta ; 1. Utilize the fact that Z bit is set if Intr taken in U mode 163a4880801SVineet Gupta ; 2. Upon entry SP is always saved (for any inspection, unwinding etc), 164a4880801SVineet Gupta ; but on return, restored only if U mode 165a4880801SVineet Gupta 166a4880801SVineet Gupta lr r10, [AUX_USER_SP] ; U mode SP 167a4880801SVineet Gupta 168a4880801SVineet Gupta ; ISA requires ADD.nz to have same dest and src reg operands 169a4880801SVineet Gupta mov.nz r10, sp 170656f18adSVineet Gupta add2.nz r10, r10, SZ_PT_REGS/4 ; K mode SP 171a4880801SVineet Gupta 172a4880801SVineet Gupta st r10, [sp, PT_sp] ; SP (pt_regs->sp) 173a4880801SVineet Gupta 174a4880801SVineet Gupta #ifdef CONFIG_ARC_HAS_ACCL_REGS 1757ecc6c1dSEugeniy Paltsev ST2 r58, r59, PT_r58 176a4880801SVineet Gupta #endif 177a4880801SVineet Gupta 1784827d0cfSEugeniy Paltsev /* clobbers r10, r11 registers pair */ 1794827d0cfSEugeniy Paltsev DSP_SAVE_REGFILE_IRQ 180cfca4b5aSVineet Gupta 181cfca4b5aSVineet Gupta #ifdef CONFIG_ARC_CURR_IN_REG 182cfca4b5aSVineet Gupta GET_CURR_TASK_ON_CPU gp 183cfca4b5aSVineet Gupta #endif 184cfca4b5aSVineet Gupta 185a4880801SVineet Gupta .endm 186a4880801SVineet Gupta 187a4880801SVineet Gupta /*------------------------------------------------------------------------*/ 188a4880801SVineet Gupta .macro __RESTORE_REGFILE_SOFT 189a4880801SVineet Gupta 190*d4624bf6SVineet Gupta ld fp, [sp, PT_fp] 1917ecc6c1dSEugeniy Paltsev ld r30, [sp, PT_r30] 192*d4624bf6SVineet Gupta ld r12, [sp, PT_r12] 193*d4624bf6SVineet Gupta ld r26, [sp, PT_r26] 194a4880801SVineet Gupta 195a4880801SVineet Gupta ; Restore SP (into AUX_USER_SP) only if returning to U mode 196a4880801SVineet Gupta ; - for K mode, it will be implicitly restored as stack is unwound 197a4880801SVineet Gupta ; - Z flag set on K is inverse of what hardware does on interrupt entry 198a4880801SVineet Gupta ; but that doesn't really matter 199a4880801SVineet Gupta bz 1f 200a4880801SVineet Gupta 201a4880801SVineet Gupta ld r10, [sp, PT_sp] ; SP (pt_regs->sp) 202a4880801SVineet Gupta sr r10, [AUX_USER_SP] 203a4880801SVineet Gupta 1: 204a4880801SVineet Gupta 2057321e2eaSEugeniy Paltsev /* clobbers r10, r11 registers pair */ 2067321e2eaSEugeniy Paltsev DSP_RESTORE_REGFILE_IRQ 2077321e2eaSEugeniy Paltsev 208a4880801SVineet Gupta #ifdef CONFIG_ARC_HAS_ACCL_REGS 2097ecc6c1dSEugeniy Paltsev LD2 r58, r59, PT_r58 210a4880801SVineet Gupta #endif 211a4880801SVineet Gupta .endm 212a4880801SVineet Gupta 213a4880801SVineet Gupta /*------------------------------------------------------------------------*/ 214a4880801SVineet Gupta .macro __RESTORE_REGFILE_HARD 215a4880801SVineet Gupta 216a4880801SVineet Gupta ld blink, [sp, PT_blink] 217a4880801SVineet Gupta 218a4880801SVineet Gupta LD2 r10, r11, PT_lpe 219a4880801SVineet Gupta sr r10, [lp_end] 220a4880801SVineet Gupta sr r11, [lp_start] 221a4880801SVineet Gupta 222a4880801SVineet Gupta ld r10, [sp, PT_lpc] ; lp_count can't be target of LD 223a4880801SVineet Gupta mov lp_count, r10 224a4880801SVineet Gupta 225a4880801SVineet Gupta LD2 r0, r1, PT_r0 226a4880801SVineet Gupta LD2 r2, r3, PT_r2 227a4880801SVineet Gupta LD2 r4, r5, PT_r4 228a4880801SVineet Gupta LD2 r6, r7, PT_r6 229a4880801SVineet Gupta LD2 r8, r9, PT_r8 230a4880801SVineet Gupta LD2 r10, r11, PT_r10 231a4880801SVineet Gupta .endm 232a4880801SVineet Gupta 233a4880801SVineet Gupta 234a4880801SVineet Gupta /*------------------------------------------------------------------------*/ 235a4880801SVineet Gupta .macro INTERRUPT_EPILOGUE 236a4880801SVineet Gupta 237a4880801SVineet Gupta ; INPUT: r0 has STAT32 of calling context 238a4880801SVineet Gupta ; INPUT: Z flag set if returning to K mode 239a4880801SVineet Gupta 240a4880801SVineet Gupta ; _SOFT clobbers r10 restored by _HARD hence the order 241a4880801SVineet Gupta 242a4880801SVineet Gupta __RESTORE_REGFILE_SOFT 243a4880801SVineet Gupta 244a4880801SVineet Gupta #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE 245a4880801SVineet Gupta __RESTORE_REGFILE_HARD 24649b41356SVineet Gupta 24749b41356SVineet Gupta ; SP points to PC/STAT32: hw restores them despite NO_AUTOSAVE 248a4880801SVineet Gupta add sp, sp, SZ_PT_REGS - 8 249a4880801SVineet Gupta #else 250a4880801SVineet Gupta add sp, sp, PT_r0 251a4880801SVineet Gupta #endif 252a4880801SVineet Gupta 253a4880801SVineet Gupta .endm 254a4880801SVineet Gupta 2551f6ccfffSVineet Gupta /*------------------------------------------------------------------------*/ 2561f6ccfffSVineet Gupta .macro EXCEPTION_EPILOGUE 2571f6ccfffSVineet Gupta 25845869eb0SVineet Gupta ; INPUT: r0 has STAT32 of calling context 2591f6ccfffSVineet Gupta 260a4880801SVineet Gupta btst r0, STATUS_U_BIT ; Z flag set if K, used in restoring SP 2611f6ccfffSVineet Gupta 262c505b0daSVineet Gupta ld r10, [sp, PT_bta] 263a4880801SVineet Gupta sr r10, [erbta] 2641f6ccfffSVineet Gupta 265a4880801SVineet Gupta LD2 r10, r11, PT_ret 266a4880801SVineet Gupta sr r10, [eret] 267a4880801SVineet Gupta sr r11, [erstatus] 2681f6ccfffSVineet Gupta 269a4880801SVineet Gupta __RESTORE_REGFILE_SOFT 270a4880801SVineet Gupta __RESTORE_REGFILE_HARD 2711f6ccfffSVineet Gupta 272a4880801SVineet Gupta add sp, sp, SZ_PT_REGS 2731f6ccfffSVineet Gupta .endm 2741f6ccfffSVineet Gupta 2751f6ccfffSVineet Gupta .macro FAKE_RET_FROM_EXCPN 2761f6ccfffSVineet Gupta lr r9, [status32] 277dfb12071SVineet Gupta bclr r9, r9, STATUS_AE_BIT 278dfb12071SVineet Gupta bset r9, r9, STATUS_IE_BIT 2791f6ccfffSVineet Gupta kflag r9 2801f6ccfffSVineet Gupta .endm 2811f6ccfffSVineet Gupta 2821f6ccfffSVineet Gupta /* Get thread_info of "current" tsk */ 2831f6ccfffSVineet Gupta .macro GET_CURR_THR_INFO_FROM_SP reg 2841f6ccfffSVineet Gupta bmskn \reg, sp, THREAD_SHIFT - 1 2851f6ccfffSVineet Gupta .endm 2861f6ccfffSVineet Gupta 2871f6ccfffSVineet Gupta /* Get CPU-ID of this core */ 2881f6ccfffSVineet Gupta .macro GET_CPU_ID reg 2891f6ccfffSVineet Gupta lr \reg, [identity] 2901f6ccfffSVineet Gupta xbfu \reg, \reg, 0xE8 /* 00111 01000 */ 2911f6ccfffSVineet Gupta /* M = 8-1 N = 8 */ 2921f6ccfffSVineet Gupta .endm 2931f6ccfffSVineet Gupta 2941f6ccfffSVineet Gupta #endif 295