1*0603839bSHuacai Chen /* SPDX-License-Identifier: GPL-2.0 */ 2*0603839bSHuacai Chen /* 3*0603839bSHuacai Chen * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4*0603839bSHuacai Chen */ 5*0603839bSHuacai Chen #ifndef _ASM_STACKFRAME_H 6*0603839bSHuacai Chen #define _ASM_STACKFRAME_H 7*0603839bSHuacai Chen 8*0603839bSHuacai Chen #include <linux/threads.h> 9*0603839bSHuacai Chen 10*0603839bSHuacai Chen #include <asm/asm.h> 11*0603839bSHuacai Chen #include <asm/asmmacro.h> 12*0603839bSHuacai Chen #include <asm/asm-offsets.h> 13*0603839bSHuacai Chen #include <asm/loongarch.h> 14*0603839bSHuacai Chen #include <asm/thread_info.h> 15*0603839bSHuacai Chen 16*0603839bSHuacai Chen /* Make the addition of cfi info a little easier. */ 17*0603839bSHuacai Chen .macro cfi_rel_offset reg offset=0 docfi=0 18*0603839bSHuacai Chen .if \docfi 19*0603839bSHuacai Chen .cfi_rel_offset \reg, \offset 20*0603839bSHuacai Chen .endif 21*0603839bSHuacai Chen .endm 22*0603839bSHuacai Chen 23*0603839bSHuacai Chen .macro cfi_st reg offset=0 docfi=0 24*0603839bSHuacai Chen cfi_rel_offset \reg, \offset, \docfi 25*0603839bSHuacai Chen LONG_S \reg, sp, \offset 26*0603839bSHuacai Chen .endm 27*0603839bSHuacai Chen 28*0603839bSHuacai Chen .macro cfi_restore reg offset=0 docfi=0 29*0603839bSHuacai Chen .if \docfi 30*0603839bSHuacai Chen .cfi_restore \reg 31*0603839bSHuacai Chen .endif 32*0603839bSHuacai Chen .endm 33*0603839bSHuacai Chen 34*0603839bSHuacai Chen .macro cfi_ld reg offset=0 docfi=0 35*0603839bSHuacai Chen LONG_L \reg, sp, \offset 36*0603839bSHuacai Chen cfi_restore \reg \offset \docfi 37*0603839bSHuacai Chen .endm 38*0603839bSHuacai Chen 39*0603839bSHuacai Chen .macro BACKUP_T0T1 40*0603839bSHuacai Chen csrwr t0, EXCEPTION_KS0 41*0603839bSHuacai Chen csrwr t1, EXCEPTION_KS1 42*0603839bSHuacai Chen .endm 43*0603839bSHuacai Chen 44*0603839bSHuacai Chen .macro RELOAD_T0T1 45*0603839bSHuacai Chen csrrd t0, EXCEPTION_KS0 46*0603839bSHuacai Chen csrrd t1, EXCEPTION_KS1 47*0603839bSHuacai Chen .endm 48*0603839bSHuacai Chen 49*0603839bSHuacai Chen .macro SAVE_TEMP docfi=0 50*0603839bSHuacai Chen RELOAD_T0T1 51*0603839bSHuacai Chen cfi_st t0, PT_R12, \docfi 52*0603839bSHuacai Chen cfi_st t1, PT_R13, \docfi 53*0603839bSHuacai Chen cfi_st t2, PT_R14, \docfi 54*0603839bSHuacai Chen cfi_st t3, PT_R15, \docfi 55*0603839bSHuacai Chen cfi_st t4, PT_R16, \docfi 56*0603839bSHuacai Chen cfi_st t5, PT_R17, \docfi 57*0603839bSHuacai Chen cfi_st t6, PT_R18, \docfi 58*0603839bSHuacai Chen cfi_st t7, PT_R19, \docfi 59*0603839bSHuacai Chen cfi_st t8, PT_R20, \docfi 60*0603839bSHuacai Chen .endm 61*0603839bSHuacai Chen 62*0603839bSHuacai Chen .macro SAVE_STATIC docfi=0 63*0603839bSHuacai Chen cfi_st s0, PT_R23, \docfi 64*0603839bSHuacai Chen cfi_st s1, PT_R24, \docfi 65*0603839bSHuacai Chen cfi_st s2, PT_R25, \docfi 66*0603839bSHuacai Chen cfi_st s3, PT_R26, \docfi 67*0603839bSHuacai Chen cfi_st s4, PT_R27, \docfi 68*0603839bSHuacai Chen cfi_st s5, PT_R28, \docfi 69*0603839bSHuacai Chen cfi_st s6, PT_R29, \docfi 70*0603839bSHuacai Chen cfi_st s7, PT_R30, \docfi 71*0603839bSHuacai Chen cfi_st s8, PT_R31, \docfi 72*0603839bSHuacai Chen .endm 73*0603839bSHuacai Chen 74*0603839bSHuacai Chen /* 75*0603839bSHuacai Chen * get_saved_sp returns the SP for the current CPU by looking in the 76*0603839bSHuacai Chen * kernelsp array for it. It stores the current sp in t0 and loads the 77*0603839bSHuacai Chen * new value in sp. 78*0603839bSHuacai Chen */ 79*0603839bSHuacai Chen .macro get_saved_sp docfi=0 80*0603839bSHuacai Chen la.abs t1, kernelsp 81*0603839bSHuacai Chen move t0, sp 82*0603839bSHuacai Chen .if \docfi 83*0603839bSHuacai Chen .cfi_register sp, t0 84*0603839bSHuacai Chen .endif 85*0603839bSHuacai Chen LONG_L sp, t1, 0 86*0603839bSHuacai Chen .endm 87*0603839bSHuacai Chen 88*0603839bSHuacai Chen .macro set_saved_sp stackp temp temp2 89*0603839bSHuacai Chen la.abs \temp, kernelsp 90*0603839bSHuacai Chen LONG_S \stackp, \temp, 0 91*0603839bSHuacai Chen .endm 92*0603839bSHuacai Chen 93*0603839bSHuacai Chen .macro SAVE_SOME docfi=0 94*0603839bSHuacai Chen csrrd t1, LOONGARCH_CSR_PRMD 95*0603839bSHuacai Chen andi t1, t1, 0x3 /* extract pplv bit */ 96*0603839bSHuacai Chen move t0, sp 97*0603839bSHuacai Chen beqz t1, 8f 98*0603839bSHuacai Chen /* Called from user mode, new stack. */ 99*0603839bSHuacai Chen get_saved_sp docfi=\docfi 100*0603839bSHuacai Chen 8: 101*0603839bSHuacai Chen PTR_ADDI sp, sp, -PT_SIZE 102*0603839bSHuacai Chen .if \docfi 103*0603839bSHuacai Chen .cfi_def_cfa sp, 0 104*0603839bSHuacai Chen .endif 105*0603839bSHuacai Chen cfi_st t0, PT_R3, \docfi 106*0603839bSHuacai Chen cfi_rel_offset sp, PT_R3, \docfi 107*0603839bSHuacai Chen LONG_S zero, sp, PT_R0 108*0603839bSHuacai Chen csrrd t0, LOONGARCH_CSR_PRMD 109*0603839bSHuacai Chen LONG_S t0, sp, PT_PRMD 110*0603839bSHuacai Chen csrrd t0, LOONGARCH_CSR_CRMD 111*0603839bSHuacai Chen LONG_S t0, sp, PT_CRMD 112*0603839bSHuacai Chen csrrd t0, LOONGARCH_CSR_EUEN 113*0603839bSHuacai Chen LONG_S t0, sp, PT_EUEN 114*0603839bSHuacai Chen csrrd t0, LOONGARCH_CSR_ECFG 115*0603839bSHuacai Chen LONG_S t0, sp, PT_ECFG 116*0603839bSHuacai Chen csrrd t0, LOONGARCH_CSR_ESTAT 117*0603839bSHuacai Chen PTR_S t0, sp, PT_ESTAT 118*0603839bSHuacai Chen cfi_st ra, PT_R1, \docfi 119*0603839bSHuacai Chen cfi_st a0, PT_R4, \docfi 120*0603839bSHuacai Chen cfi_st a1, PT_R5, \docfi 121*0603839bSHuacai Chen cfi_st a2, PT_R6, \docfi 122*0603839bSHuacai Chen cfi_st a3, PT_R7, \docfi 123*0603839bSHuacai Chen cfi_st a4, PT_R8, \docfi 124*0603839bSHuacai Chen cfi_st a5, PT_R9, \docfi 125*0603839bSHuacai Chen cfi_st a6, PT_R10, \docfi 126*0603839bSHuacai Chen cfi_st a7, PT_R11, \docfi 127*0603839bSHuacai Chen csrrd ra, LOONGARCH_CSR_ERA 128*0603839bSHuacai Chen LONG_S ra, sp, PT_ERA 129*0603839bSHuacai Chen .if \docfi 130*0603839bSHuacai Chen .cfi_rel_offset ra, PT_ERA 131*0603839bSHuacai Chen .endif 132*0603839bSHuacai Chen cfi_st tp, PT_R2, \docfi 133*0603839bSHuacai Chen cfi_st fp, PT_R22, \docfi 134*0603839bSHuacai Chen 135*0603839bSHuacai Chen /* Set thread_info if we're coming from user mode */ 136*0603839bSHuacai Chen csrrd t0, LOONGARCH_CSR_PRMD 137*0603839bSHuacai Chen andi t0, t0, 0x3 /* extract pplv bit */ 138*0603839bSHuacai Chen beqz t0, 9f 139*0603839bSHuacai Chen 140*0603839bSHuacai Chen li.d tp, ~_THREAD_MASK 141*0603839bSHuacai Chen and tp, tp, sp 142*0603839bSHuacai Chen cfi_st u0, PT_R21, \docfi 143*0603839bSHuacai Chen csrrd u0, PERCPU_BASE_KS 144*0603839bSHuacai Chen 9: 145*0603839bSHuacai Chen .endm 146*0603839bSHuacai Chen 147*0603839bSHuacai Chen .macro SAVE_ALL docfi=0 148*0603839bSHuacai Chen SAVE_SOME \docfi 149*0603839bSHuacai Chen SAVE_TEMP \docfi 150*0603839bSHuacai Chen SAVE_STATIC \docfi 151*0603839bSHuacai Chen .endm 152*0603839bSHuacai Chen 153*0603839bSHuacai Chen .macro RESTORE_TEMP docfi=0 154*0603839bSHuacai Chen cfi_ld t0, PT_R12, \docfi 155*0603839bSHuacai Chen cfi_ld t1, PT_R13, \docfi 156*0603839bSHuacai Chen cfi_ld t2, PT_R14, \docfi 157*0603839bSHuacai Chen cfi_ld t3, PT_R15, \docfi 158*0603839bSHuacai Chen cfi_ld t4, PT_R16, \docfi 159*0603839bSHuacai Chen cfi_ld t5, PT_R17, \docfi 160*0603839bSHuacai Chen cfi_ld t6, PT_R18, \docfi 161*0603839bSHuacai Chen cfi_ld t7, PT_R19, \docfi 162*0603839bSHuacai Chen cfi_ld t8, PT_R20, \docfi 163*0603839bSHuacai Chen .endm 164*0603839bSHuacai Chen 165*0603839bSHuacai Chen .macro RESTORE_STATIC docfi=0 166*0603839bSHuacai Chen cfi_ld s0, PT_R23, \docfi 167*0603839bSHuacai Chen cfi_ld s1, PT_R24, \docfi 168*0603839bSHuacai Chen cfi_ld s2, PT_R25, \docfi 169*0603839bSHuacai Chen cfi_ld s3, PT_R26, \docfi 170*0603839bSHuacai Chen cfi_ld s4, PT_R27, \docfi 171*0603839bSHuacai Chen cfi_ld s5, PT_R28, \docfi 172*0603839bSHuacai Chen cfi_ld s6, PT_R29, \docfi 173*0603839bSHuacai Chen cfi_ld s7, PT_R30, \docfi 174*0603839bSHuacai Chen cfi_ld s8, PT_R31, \docfi 175*0603839bSHuacai Chen .endm 176*0603839bSHuacai Chen 177*0603839bSHuacai Chen .macro RESTORE_SOME docfi=0 178*0603839bSHuacai Chen LONG_L a0, sp, PT_PRMD 179*0603839bSHuacai Chen andi a0, a0, 0x3 /* extract pplv bit */ 180*0603839bSHuacai Chen beqz a0, 8f 181*0603839bSHuacai Chen cfi_ld u0, PT_R21, \docfi 182*0603839bSHuacai Chen 8: 183*0603839bSHuacai Chen LONG_L a0, sp, PT_ERA 184*0603839bSHuacai Chen csrwr a0, LOONGARCH_CSR_ERA 185*0603839bSHuacai Chen LONG_L a0, sp, PT_PRMD 186*0603839bSHuacai Chen csrwr a0, LOONGARCH_CSR_PRMD 187*0603839bSHuacai Chen cfi_ld ra, PT_R1, \docfi 188*0603839bSHuacai Chen cfi_ld a0, PT_R4, \docfi 189*0603839bSHuacai Chen cfi_ld a1, PT_R5, \docfi 190*0603839bSHuacai Chen cfi_ld a2, PT_R6, \docfi 191*0603839bSHuacai Chen cfi_ld a3, PT_R7, \docfi 192*0603839bSHuacai Chen cfi_ld a4, PT_R8, \docfi 193*0603839bSHuacai Chen cfi_ld a5, PT_R9, \docfi 194*0603839bSHuacai Chen cfi_ld a6, PT_R10, \docfi 195*0603839bSHuacai Chen cfi_ld a7, PT_R11, \docfi 196*0603839bSHuacai Chen cfi_ld tp, PT_R2, \docfi 197*0603839bSHuacai Chen cfi_ld fp, PT_R22, \docfi 198*0603839bSHuacai Chen .endm 199*0603839bSHuacai Chen 200*0603839bSHuacai Chen .macro RESTORE_SP_AND_RET docfi=0 201*0603839bSHuacai Chen cfi_ld sp, PT_R3, \docfi 202*0603839bSHuacai Chen ertn 203*0603839bSHuacai Chen .endm 204*0603839bSHuacai Chen 205*0603839bSHuacai Chen .macro RESTORE_ALL_AND_RET docfi=0 206*0603839bSHuacai Chen RESTORE_STATIC \docfi 207*0603839bSHuacai Chen RESTORE_TEMP \docfi 208*0603839bSHuacai Chen RESTORE_SOME \docfi 209*0603839bSHuacai Chen RESTORE_SP_AND_RET \docfi 210*0603839bSHuacai Chen .endm 211*0603839bSHuacai Chen 212*0603839bSHuacai Chen #endif /* _ASM_STACKFRAME_H */ 213