xref: /linux/arch/loongarch/include/asm/stackframe.h (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
10603839bSHuacai Chen /* SPDX-License-Identifier: GPL-2.0 */
20603839bSHuacai Chen /*
30603839bSHuacai Chen  * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
40603839bSHuacai Chen  */
50603839bSHuacai Chen #ifndef _ASM_STACKFRAME_H
60603839bSHuacai Chen #define _ASM_STACKFRAME_H
70603839bSHuacai Chen 
80603839bSHuacai Chen #include <linux/threads.h>
90603839bSHuacai Chen 
108cbd5ebfSYouling Tang #include <asm/addrspace.h>
110603839bSHuacai Chen #include <asm/asm.h>
120603839bSHuacai Chen #include <asm/asmmacro.h>
130603839bSHuacai Chen #include <asm/asm-offsets.h>
140603839bSHuacai Chen #include <asm/loongarch.h>
150603839bSHuacai Chen #include <asm/thread_info.h>
16cb8a2ef0STiezhu Yang #include <asm/unwind_hints.h>
170603839bSHuacai Chen 
180603839bSHuacai Chen /* Make the addition of cfi info a little easier. */
190603839bSHuacai Chen 	.macro cfi_rel_offset reg offset=0 docfi=0
200603839bSHuacai Chen 	.if \docfi
210603839bSHuacai Chen 	.cfi_rel_offset \reg, \offset
220603839bSHuacai Chen 	.endif
230603839bSHuacai Chen 	.endm
240603839bSHuacai Chen 
250603839bSHuacai Chen 	.macro cfi_st reg offset=0 docfi=0
260603839bSHuacai Chen 	cfi_rel_offset \reg, \offset, \docfi
270603839bSHuacai Chen 	LONG_S	\reg, sp, \offset
280603839bSHuacai Chen 	.endm
290603839bSHuacai Chen 
300603839bSHuacai Chen 	.macro cfi_restore reg offset=0 docfi=0
310603839bSHuacai Chen 	.if \docfi
320603839bSHuacai Chen 	.cfi_restore \reg
330603839bSHuacai Chen 	.endif
340603839bSHuacai Chen 	.endm
350603839bSHuacai Chen 
360603839bSHuacai Chen 	.macro cfi_ld reg offset=0 docfi=0
370603839bSHuacai Chen 	LONG_L	\reg, sp, \offset
380603839bSHuacai Chen 	cfi_restore \reg \offset \docfi
390603839bSHuacai Chen 	.endm
400603839bSHuacai Chen 
41*8e02c3b7SHuacai Chen 	.macro SETUP_DMWINS temp
42*8e02c3b7SHuacai Chen 	li.d	\temp, CSR_DMW0_INIT	# WUC, PLV0, 0x8000 xxxx xxxx xxxx
43*8e02c3b7SHuacai Chen 	csrwr	\temp, LOONGARCH_CSR_DMWIN0
44*8e02c3b7SHuacai Chen 	li.d	\temp, CSR_DMW1_INIT	# CAC, PLV0, 0x9000 xxxx xxxx xxxx
45*8e02c3b7SHuacai Chen 	csrwr	\temp, LOONGARCH_CSR_DMWIN1
46*8e02c3b7SHuacai Chen 	li.d	\temp, CSR_DMW2_INIT	# WUC, PLV0, 0xa000 xxxx xxxx xxxx
47*8e02c3b7SHuacai Chen 	csrwr	\temp, LOONGARCH_CSR_DMWIN2
48*8e02c3b7SHuacai Chen 	li.d	\temp, CSR_DMW3_INIT	# 0x0, unused
49*8e02c3b7SHuacai Chen 	csrwr	\temp, LOONGARCH_CSR_DMWIN3
50*8e02c3b7SHuacai Chen 	.endm
51*8e02c3b7SHuacai Chen 
528cbd5ebfSYouling Tang /* Jump to the runtime virtual address. */
538cbd5ebfSYouling Tang 	.macro JUMP_VIRT_ADDR temp1 temp2
548cbd5ebfSYouling Tang 	li.d	\temp1, CACHE_BASE
558cbd5ebfSYouling Tang 	pcaddi	\temp2, 0
561098efd2SJiaxun Yang 	bstrins.d  \temp1, \temp2, (DMW_PABITS - 1), 0
578cbd5ebfSYouling Tang 	jirl	zero, \temp1, 0xc
588cbd5ebfSYouling Tang 	.endm
598cbd5ebfSYouling Tang 
600603839bSHuacai Chen 	.macro BACKUP_T0T1
610603839bSHuacai Chen 	csrwr	t0, EXCEPTION_KS0
620603839bSHuacai Chen 	csrwr	t1, EXCEPTION_KS1
630603839bSHuacai Chen 	.endm
640603839bSHuacai Chen 
650603839bSHuacai Chen 	.macro RELOAD_T0T1
660603839bSHuacai Chen 	csrrd   t0, EXCEPTION_KS0
670603839bSHuacai Chen 	csrrd   t1, EXCEPTION_KS1
680603839bSHuacai Chen 	.endm
690603839bSHuacai Chen 
700603839bSHuacai Chen 	.macro	SAVE_TEMP docfi=0
710603839bSHuacai Chen 	RELOAD_T0T1
720603839bSHuacai Chen 	cfi_st	t0, PT_R12, \docfi
730603839bSHuacai Chen 	cfi_st	t1, PT_R13, \docfi
740603839bSHuacai Chen 	cfi_st	t2, PT_R14, \docfi
750603839bSHuacai Chen 	cfi_st	t3, PT_R15, \docfi
760603839bSHuacai Chen 	cfi_st	t4, PT_R16, \docfi
770603839bSHuacai Chen 	cfi_st	t5, PT_R17, \docfi
780603839bSHuacai Chen 	cfi_st	t6, PT_R18, \docfi
790603839bSHuacai Chen 	cfi_st	t7, PT_R19, \docfi
800603839bSHuacai Chen 	cfi_st	t8, PT_R20, \docfi
810603839bSHuacai Chen 	.endm
820603839bSHuacai Chen 
830603839bSHuacai Chen 	.macro	SAVE_STATIC docfi=0
840603839bSHuacai Chen 	cfi_st	s0, PT_R23, \docfi
850603839bSHuacai Chen 	cfi_st	s1, PT_R24, \docfi
860603839bSHuacai Chen 	cfi_st	s2, PT_R25, \docfi
870603839bSHuacai Chen 	cfi_st	s3, PT_R26, \docfi
880603839bSHuacai Chen 	cfi_st	s4, PT_R27, \docfi
890603839bSHuacai Chen 	cfi_st	s5, PT_R28, \docfi
900603839bSHuacai Chen 	cfi_st	s6, PT_R29, \docfi
910603839bSHuacai Chen 	cfi_st	s7, PT_R30, \docfi
920603839bSHuacai Chen 	cfi_st	s8, PT_R31, \docfi
930603839bSHuacai Chen 	.endm
940603839bSHuacai Chen 
950603839bSHuacai Chen /*
960603839bSHuacai Chen  * get_saved_sp returns the SP for the current CPU by looking in the
970603839bSHuacai Chen  * kernelsp array for it. It stores the current sp in t0 and loads the
980603839bSHuacai Chen  * new value in sp.
990603839bSHuacai Chen  */
1000603839bSHuacai Chen 	.macro	get_saved_sp docfi=0
101396233c6SYouling Tang 	la_abs	  t1, kernelsp
10246859ac8SHuacai Chen #ifdef CONFIG_SMP
10346859ac8SHuacai Chen 	csrrd	  t0, PERCPU_BASE_KS
10446859ac8SHuacai Chen 	LONG_ADD  t1, t1, t0
10546859ac8SHuacai Chen #endif
1060603839bSHuacai Chen 	move	  t0, sp
1070603839bSHuacai Chen 	.if \docfi
1080603839bSHuacai Chen 	.cfi_register sp, t0
1090603839bSHuacai Chen 	.endif
1100603839bSHuacai Chen 	LONG_L	  sp, t1, 0
1110603839bSHuacai Chen 	.endm
1120603839bSHuacai Chen 
1130603839bSHuacai Chen 	.macro	set_saved_sp stackp temp temp2
114f733f119SXi Ruoyao 	la.pcrel  \temp, kernelsp
11546859ac8SHuacai Chen #ifdef CONFIG_SMP
11646859ac8SHuacai Chen 	LONG_ADD  \temp, \temp, u0
11746859ac8SHuacai Chen #endif
1180603839bSHuacai Chen 	LONG_S	  \stackp, \temp, 0
1190603839bSHuacai Chen 	.endm
1200603839bSHuacai Chen 
1210603839bSHuacai Chen 	.macro	SAVE_SOME docfi=0
1220603839bSHuacai Chen 	csrrd	t1, LOONGARCH_CSR_PRMD
1230603839bSHuacai Chen 	andi	t1, t1, 0x3	/* extract pplv bit */
1240603839bSHuacai Chen 	move	t0, sp
1250603839bSHuacai Chen 	beqz	t1, 8f
1260603839bSHuacai Chen 	/* Called from user mode, new stack. */
1270603839bSHuacai Chen 	get_saved_sp docfi=\docfi
1280603839bSHuacai Chen 8:
1290603839bSHuacai Chen 	PTR_ADDI sp, sp, -PT_SIZE
1300603839bSHuacai Chen 	.if \docfi
1310603839bSHuacai Chen 	.cfi_def_cfa sp, 0
1320603839bSHuacai Chen 	.endif
1330603839bSHuacai Chen 	cfi_st	t0, PT_R3, \docfi
1340603839bSHuacai Chen 	cfi_rel_offset  sp, PT_R3, \docfi
1350603839bSHuacai Chen 	LONG_S	zero, sp, PT_R0
1360603839bSHuacai Chen 	csrrd	t0, LOONGARCH_CSR_PRMD
1370603839bSHuacai Chen 	LONG_S	t0, sp, PT_PRMD
1380603839bSHuacai Chen 	csrrd	t0, LOONGARCH_CSR_CRMD
1390603839bSHuacai Chen 	LONG_S	t0, sp, PT_CRMD
1400603839bSHuacai Chen 	csrrd	t0, LOONGARCH_CSR_EUEN
1410603839bSHuacai Chen 	LONG_S  t0, sp, PT_EUEN
1420603839bSHuacai Chen 	csrrd	t0, LOONGARCH_CSR_ECFG
1430603839bSHuacai Chen 	LONG_S	t0, sp, PT_ECFG
1440603839bSHuacai Chen 	csrrd	t0, LOONGARCH_CSR_ESTAT
1450603839bSHuacai Chen 	PTR_S	t0, sp, PT_ESTAT
1460603839bSHuacai Chen 	cfi_st	ra, PT_R1, \docfi
1470603839bSHuacai Chen 	cfi_st	a0, PT_R4, \docfi
1480603839bSHuacai Chen 	cfi_st	a1, PT_R5, \docfi
1490603839bSHuacai Chen 	cfi_st	a2, PT_R6, \docfi
1500603839bSHuacai Chen 	cfi_st	a3, PT_R7, \docfi
1510603839bSHuacai Chen 	cfi_st	a4, PT_R8, \docfi
1520603839bSHuacai Chen 	cfi_st	a5, PT_R9, \docfi
1530603839bSHuacai Chen 	cfi_st	a6, PT_R10, \docfi
1540603839bSHuacai Chen 	cfi_st	a7, PT_R11, \docfi
1550603839bSHuacai Chen 	csrrd	ra, LOONGARCH_CSR_ERA
1560603839bSHuacai Chen 	LONG_S	ra, sp, PT_ERA
1570603839bSHuacai Chen 	.if \docfi
1580603839bSHuacai Chen 	.cfi_rel_offset ra, PT_ERA
1590603839bSHuacai Chen 	.endif
1600603839bSHuacai Chen 	cfi_st	tp, PT_R2, \docfi
1610603839bSHuacai Chen 	cfi_st	fp, PT_R22, \docfi
1620603839bSHuacai Chen 
1630603839bSHuacai Chen 	/* Set thread_info if we're coming from user mode */
1640603839bSHuacai Chen 	csrrd	t0, LOONGARCH_CSR_PRMD
1650603839bSHuacai Chen 	andi	t0, t0, 0x3	/* extract pplv bit */
1660603839bSHuacai Chen 	beqz	t0, 9f
1670603839bSHuacai Chen 
1680603839bSHuacai Chen 	li.d	tp, ~_THREAD_MASK
1690603839bSHuacai Chen 	and	tp, tp, sp
1700603839bSHuacai Chen 	cfi_st  u0, PT_R21, \docfi
1710603839bSHuacai Chen 	csrrd	u0, PERCPU_BASE_KS
1720603839bSHuacai Chen 9:
173e14dd076SQing Zhang #ifdef CONFIG_KGDB
174e14dd076SQing Zhang 	li.w	t0, CSR_CRMD_WE
175e14dd076SQing Zhang 	csrxchg	t0, t0, LOONGARCH_CSR_CRMD
176e14dd076SQing Zhang #endif
177cb8a2ef0STiezhu Yang 	UNWIND_HINT_REGS
1780603839bSHuacai Chen 	.endm
1790603839bSHuacai Chen 
1800603839bSHuacai Chen 	.macro	SAVE_ALL docfi=0
1810603839bSHuacai Chen 	SAVE_SOME \docfi
1820603839bSHuacai Chen 	SAVE_TEMP \docfi
1830603839bSHuacai Chen 	SAVE_STATIC \docfi
1840603839bSHuacai Chen 	.endm
1850603839bSHuacai Chen 
1860603839bSHuacai Chen 	.macro	RESTORE_TEMP docfi=0
1870603839bSHuacai Chen 	cfi_ld	t0, PT_R12, \docfi
1880603839bSHuacai Chen 	cfi_ld	t1, PT_R13, \docfi
1890603839bSHuacai Chen 	cfi_ld	t2, PT_R14, \docfi
1900603839bSHuacai Chen 	cfi_ld	t3, PT_R15, \docfi
1910603839bSHuacai Chen 	cfi_ld	t4, PT_R16, \docfi
1920603839bSHuacai Chen 	cfi_ld	t5, PT_R17, \docfi
1930603839bSHuacai Chen 	cfi_ld	t6, PT_R18, \docfi
1940603839bSHuacai Chen 	cfi_ld	t7, PT_R19, \docfi
1950603839bSHuacai Chen 	cfi_ld	t8, PT_R20, \docfi
1960603839bSHuacai Chen 	.endm
1970603839bSHuacai Chen 
1980603839bSHuacai Chen 	.macro	RESTORE_STATIC docfi=0
1990603839bSHuacai Chen 	cfi_ld	s0, PT_R23, \docfi
2000603839bSHuacai Chen 	cfi_ld	s1, PT_R24, \docfi
2010603839bSHuacai Chen 	cfi_ld	s2, PT_R25, \docfi
2020603839bSHuacai Chen 	cfi_ld	s3, PT_R26, \docfi
2030603839bSHuacai Chen 	cfi_ld	s4, PT_R27, \docfi
2040603839bSHuacai Chen 	cfi_ld	s5, PT_R28, \docfi
2050603839bSHuacai Chen 	cfi_ld	s6, PT_R29, \docfi
2060603839bSHuacai Chen 	cfi_ld	s7, PT_R30, \docfi
2070603839bSHuacai Chen 	cfi_ld	s8, PT_R31, \docfi
2080603839bSHuacai Chen 	.endm
2090603839bSHuacai Chen 
2100603839bSHuacai Chen 	.macro	RESTORE_SOME docfi=0
2110603839bSHuacai Chen 	LONG_L	a0, sp, PT_PRMD
2120603839bSHuacai Chen 	andi    a0, a0, 0x3	/* extract pplv bit */
2130603839bSHuacai Chen 	beqz    a0, 8f
2140603839bSHuacai Chen 	cfi_ld  u0, PT_R21, \docfi
2150603839bSHuacai Chen 8:
2160603839bSHuacai Chen 	LONG_L	a0, sp, PT_ERA
2170603839bSHuacai Chen 	csrwr	a0, LOONGARCH_CSR_ERA
2180603839bSHuacai Chen 	LONG_L	a0, sp, PT_PRMD
2190603839bSHuacai Chen 	csrwr	a0, LOONGARCH_CSR_PRMD
2200603839bSHuacai Chen 	cfi_ld	ra, PT_R1, \docfi
2210603839bSHuacai Chen 	cfi_ld	a0, PT_R4, \docfi
2220603839bSHuacai Chen 	cfi_ld	a1, PT_R5, \docfi
2230603839bSHuacai Chen 	cfi_ld	a2, PT_R6, \docfi
2240603839bSHuacai Chen 	cfi_ld	a3, PT_R7, \docfi
2250603839bSHuacai Chen 	cfi_ld	a4, PT_R8, \docfi
2260603839bSHuacai Chen 	cfi_ld	a5, PT_R9, \docfi
2270603839bSHuacai Chen 	cfi_ld	a6, PT_R10, \docfi
2280603839bSHuacai Chen 	cfi_ld	a7, PT_R11, \docfi
2290603839bSHuacai Chen 	cfi_ld	tp, PT_R2, \docfi
2300603839bSHuacai Chen 	cfi_ld	fp, PT_R22, \docfi
2310603839bSHuacai Chen 	.endm
2320603839bSHuacai Chen 
2330603839bSHuacai Chen 	.macro	RESTORE_SP_AND_RET docfi=0
2340603839bSHuacai Chen 	cfi_ld	sp, PT_R3, \docfi
235cb8a2ef0STiezhu Yang 	UNWIND_HINT_FUNC
2360603839bSHuacai Chen 	ertn
2370603839bSHuacai Chen 	.endm
2380603839bSHuacai Chen 
2390603839bSHuacai Chen 	.macro	RESTORE_ALL_AND_RET docfi=0
2400603839bSHuacai Chen 	RESTORE_STATIC \docfi
2410603839bSHuacai Chen 	RESTORE_TEMP \docfi
2420603839bSHuacai Chen 	RESTORE_SOME \docfi
2430603839bSHuacai Chen 	RESTORE_SP_AND_RET \docfi
2440603839bSHuacai Chen 	.endm
2450603839bSHuacai Chen 
2460603839bSHuacai Chen #endif /* _ASM_STACKFRAME_H */
247