xref: /linux/arch/loongarch/include/asm/stackframe.h (revision 0603839b18f4fb3bffa82515efcf5b02084505ef)
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