18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2020 Loongson Technology Co., Ltd. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci#ifndef _ASM_STACKFRAME_H 68c2ecf20Sopenharmony_ci#define _ASM_STACKFRAME_H 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/threads.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <asm/addrspace.h> 118c2ecf20Sopenharmony_ci#include <asm/asm.h> 128c2ecf20Sopenharmony_ci#include <asm/asmmacro.h> 138c2ecf20Sopenharmony_ci#include <asm/asm-offsets.h> 148c2ecf20Sopenharmony_ci#include <asm/loongarchregs.h> 158c2ecf20Sopenharmony_ci#include <asm/thread_info.h> 168c2ecf20Sopenharmony_ci#include <asm/unwind_hints.h> 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci/* Make the addition of cfi info a little easier. */ 198c2ecf20Sopenharmony_ci .macro cfi_rel_offset reg offset=0 docfi=0 208c2ecf20Sopenharmony_ci .if \docfi 218c2ecf20Sopenharmony_ci .cfi_rel_offset \reg, \offset 228c2ecf20Sopenharmony_ci .endif 238c2ecf20Sopenharmony_ci .endm 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci .macro cfi_st reg offset=0 docfi=0 268c2ecf20Sopenharmony_ci cfi_rel_offset \reg, \offset, \docfi 278c2ecf20Sopenharmony_ci LONG_S \reg, sp, \offset 288c2ecf20Sopenharmony_ci .endm 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci .macro cfi_restore reg offset=0 docfi=0 318c2ecf20Sopenharmony_ci .if \docfi 328c2ecf20Sopenharmony_ci .cfi_restore \reg 338c2ecf20Sopenharmony_ci .endif 348c2ecf20Sopenharmony_ci .endm 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci .macro cfi_ld reg offset=0 docfi=0 378c2ecf20Sopenharmony_ci LONG_L \reg, sp, \offset 388c2ecf20Sopenharmony_ci cfi_restore \reg \offset \docfi 398c2ecf20Sopenharmony_ci .endm 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci/* Jump to the runtime virtual address. */ 428c2ecf20Sopenharmony_ci .macro JUMP_VIRT_ADDR temp1 temp2 438c2ecf20Sopenharmony_ci li.d \temp1, CACHE_BASE 448c2ecf20Sopenharmony_ci pcaddi \temp2, 0 458c2ecf20Sopenharmony_ci or \temp1, \temp1, \temp2 468c2ecf20Sopenharmony_ci jirl zero, \temp1, 0xc 478c2ecf20Sopenharmony_ci .endm 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci .macro BACKUP_T0T1 508c2ecf20Sopenharmony_ci csrwr t0, EXCEPTION_KS0 518c2ecf20Sopenharmony_ci csrwr t1, EXCEPTION_KS1 528c2ecf20Sopenharmony_ci .endm 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci .macro RELOAD_T0T1 558c2ecf20Sopenharmony_ci csrrd t0, EXCEPTION_KS0 568c2ecf20Sopenharmony_ci csrrd t1, EXCEPTION_KS1 578c2ecf20Sopenharmony_ci .endm 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci .macro SAVE_TEMP docfi=0 608c2ecf20Sopenharmony_ci RELOAD_T0T1 618c2ecf20Sopenharmony_ci cfi_st t0, PT_R12, \docfi 628c2ecf20Sopenharmony_ci cfi_st t1, PT_R13, \docfi 638c2ecf20Sopenharmony_ci cfi_st t2, PT_R14, \docfi 648c2ecf20Sopenharmony_ci cfi_st t3, PT_R15, \docfi 658c2ecf20Sopenharmony_ci cfi_st t4, PT_R16, \docfi 668c2ecf20Sopenharmony_ci cfi_st t5, PT_R17, \docfi 678c2ecf20Sopenharmony_ci cfi_st t6, PT_R18, \docfi 688c2ecf20Sopenharmony_ci cfi_st t7, PT_R19, \docfi 698c2ecf20Sopenharmony_ci cfi_st t8, PT_R20, \docfi 708c2ecf20Sopenharmony_ci .endm 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci .macro SAVE_STATIC docfi=0 738c2ecf20Sopenharmony_ci cfi_st s0, PT_R23, \docfi 748c2ecf20Sopenharmony_ci cfi_st s1, PT_R24, \docfi 758c2ecf20Sopenharmony_ci cfi_st s2, PT_R25, \docfi 768c2ecf20Sopenharmony_ci cfi_st s3, PT_R26, \docfi 778c2ecf20Sopenharmony_ci cfi_st s4, PT_R27, \docfi 788c2ecf20Sopenharmony_ci cfi_st s5, PT_R28, \docfi 798c2ecf20Sopenharmony_ci cfi_st s6, PT_R29, \docfi 808c2ecf20Sopenharmony_ci cfi_st s7, PT_R30, \docfi 818c2ecf20Sopenharmony_ci cfi_st s8, PT_R31, \docfi 828c2ecf20Sopenharmony_ci .endm 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci/* 858c2ecf20Sopenharmony_ci * get_saved_sp returns the SP for the current CPU by looking in the 868c2ecf20Sopenharmony_ci * kernelsp array for it. It stores the current sp in t0 and loads the 878c2ecf20Sopenharmony_ci * new value in sp. 888c2ecf20Sopenharmony_ci */ 898c2ecf20Sopenharmony_ci .macro get_saved_sp docfi=0 908c2ecf20Sopenharmony_ci la.abs t1, kernelsp 918c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP 928c2ecf20Sopenharmony_ci csrrd t0, PERCPU_BASE_KS 938c2ecf20Sopenharmony_ci LONG_ADD t1, t1, t0 948c2ecf20Sopenharmony_ci#endif 958c2ecf20Sopenharmony_ci move t0, sp 968c2ecf20Sopenharmony_ci .if \docfi 978c2ecf20Sopenharmony_ci .cfi_register sp, t0 988c2ecf20Sopenharmony_ci .endif 998c2ecf20Sopenharmony_ci LONG_L sp, t1, 0 1008c2ecf20Sopenharmony_ci .endm 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci .macro set_saved_sp stackp temp temp2 1038c2ecf20Sopenharmony_ci la.abs \temp, kernelsp 1048c2ecf20Sopenharmony_ci#ifdef CONFIG_SMP 1058c2ecf20Sopenharmony_ci LONG_ADD \temp, \temp, u0 1068c2ecf20Sopenharmony_ci#endif 1078c2ecf20Sopenharmony_ci LONG_S \stackp, \temp, 0 1088c2ecf20Sopenharmony_ci .endm 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci .macro SAVE_SOME docfi=0 1118c2ecf20Sopenharmony_ci csrrd t1, LOONGARCH_CSR_PRMD 1128c2ecf20Sopenharmony_ci andi t1, t1, 0x3 /* extract pplv bit */ 1138c2ecf20Sopenharmony_ci move t0, sp 1148c2ecf20Sopenharmony_ci beqz t1, 8f 1158c2ecf20Sopenharmony_ci /* Called from user mode, new stack. */ 1168c2ecf20Sopenharmony_ci get_saved_sp docfi=\docfi 1178c2ecf20Sopenharmony_ci8: 1188c2ecf20Sopenharmony_ci PTR_ADDI sp, sp, -PT_SIZE 1198c2ecf20Sopenharmony_ci .if \docfi 1208c2ecf20Sopenharmony_ci .cfi_def_cfa sp,0 1218c2ecf20Sopenharmony_ci .endif 1228c2ecf20Sopenharmony_ci cfi_st t0, PT_R3, \docfi 1238c2ecf20Sopenharmony_ci cfi_rel_offset sp, PT_R3, \docfi 1248c2ecf20Sopenharmony_ci LONG_S zero, sp, PT_R0 1258c2ecf20Sopenharmony_ci csrrd t0, LOONGARCH_CSR_PRMD 1268c2ecf20Sopenharmony_ci LONG_S t0, sp, PT_PRMD 1278c2ecf20Sopenharmony_ci csrrd t0, LOONGARCH_CSR_CRMD 1288c2ecf20Sopenharmony_ci LONG_S t0, sp, PT_CRMD 1298c2ecf20Sopenharmony_ci csrrd t0, LOONGARCH_CSR_EUEN 1308c2ecf20Sopenharmony_ci LONG_S t0, sp, PT_EUEN 1318c2ecf20Sopenharmony_ci csrrd t0, LOONGARCH_CSR_ECFG 1328c2ecf20Sopenharmony_ci LONG_S t0, sp, PT_ECFG 1338c2ecf20Sopenharmony_ci csrrd t0, LOONGARCH_CSR_ESTAT 1348c2ecf20Sopenharmony_ci PTR_S t0, sp, PT_ESTAT 1358c2ecf20Sopenharmony_ci cfi_st ra, PT_R1, \docfi 1368c2ecf20Sopenharmony_ci cfi_st a0, PT_R4, \docfi 1378c2ecf20Sopenharmony_ci cfi_st a1, PT_R5, \docfi 1388c2ecf20Sopenharmony_ci cfi_st a2, PT_R6, \docfi 1398c2ecf20Sopenharmony_ci cfi_st a3, PT_R7, \docfi 1408c2ecf20Sopenharmony_ci cfi_st a4, PT_R8, \docfi 1418c2ecf20Sopenharmony_ci cfi_st a5, PT_R9, \docfi 1428c2ecf20Sopenharmony_ci cfi_st a6, PT_R10, \docfi 1438c2ecf20Sopenharmony_ci cfi_st a7, PT_R11, \docfi 1448c2ecf20Sopenharmony_ci csrrd ra, LOONGARCH_CSR_ERA 1458c2ecf20Sopenharmony_ci LONG_S ra, sp, PT_ERA 1468c2ecf20Sopenharmony_ci .if \docfi 1478c2ecf20Sopenharmony_ci .cfi_rel_offset ra, PT_ERA 1488c2ecf20Sopenharmony_ci .endif 1498c2ecf20Sopenharmony_ci cfi_st tp, PT_R2, \docfi 1508c2ecf20Sopenharmony_ci cfi_st fp, PT_R22, \docfi 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci /* Set thread_info if we're coming from user mode */ 1538c2ecf20Sopenharmony_ci csrrd t0, LOONGARCH_CSR_PRMD 1548c2ecf20Sopenharmony_ci andi t0, t0, 0x3 /* extract pplv bit */ 1558c2ecf20Sopenharmony_ci beqz t0, 9f 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci li.d tp, ~_THREAD_MASK 1588c2ecf20Sopenharmony_ci and tp, tp, sp 1598c2ecf20Sopenharmony_ci cfi_st u0, PT_R21, \docfi 1608c2ecf20Sopenharmony_ci csrrd u0, PERCPU_BASE_KS 1618c2ecf20Sopenharmony_ci9: 1628c2ecf20Sopenharmony_ci#ifdef CONFIG_KGDB 1638c2ecf20Sopenharmony_ci li.w t0, CSR_CRMD_WE 1648c2ecf20Sopenharmony_ci csrxchg t0, t0, LOONGARCH_CSR_CRMD 1658c2ecf20Sopenharmony_ci#endif 1668c2ecf20Sopenharmony_ci UNWIND_HINT_REGS 1678c2ecf20Sopenharmony_ci .endm 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci .macro SAVE_ALL docfi=0 1708c2ecf20Sopenharmony_ci SAVE_SOME \docfi 1718c2ecf20Sopenharmony_ci SAVE_TEMP \docfi 1728c2ecf20Sopenharmony_ci SAVE_STATIC \docfi 1738c2ecf20Sopenharmony_ci .endm 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci .macro RESTORE_TEMP docfi=0 1768c2ecf20Sopenharmony_ci cfi_ld t0, PT_R12, \docfi 1778c2ecf20Sopenharmony_ci cfi_ld t1, PT_R13, \docfi 1788c2ecf20Sopenharmony_ci cfi_ld t2, PT_R14, \docfi 1798c2ecf20Sopenharmony_ci cfi_ld t3, PT_R15, \docfi 1808c2ecf20Sopenharmony_ci cfi_ld t4, PT_R16, \docfi 1818c2ecf20Sopenharmony_ci cfi_ld t5, PT_R17, \docfi 1828c2ecf20Sopenharmony_ci cfi_ld t6, PT_R18, \docfi 1838c2ecf20Sopenharmony_ci cfi_ld t7, PT_R19, \docfi 1848c2ecf20Sopenharmony_ci cfi_ld t8, PT_R20, \docfi 1858c2ecf20Sopenharmony_ci .endm 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci .macro RESTORE_STATIC docfi=0 1888c2ecf20Sopenharmony_ci cfi_ld s0, PT_R23, \docfi 1898c2ecf20Sopenharmony_ci cfi_ld s1, PT_R24, \docfi 1908c2ecf20Sopenharmony_ci cfi_ld s2, PT_R25, \docfi 1918c2ecf20Sopenharmony_ci cfi_ld s3, PT_R26, \docfi 1928c2ecf20Sopenharmony_ci cfi_ld s4, PT_R27, \docfi 1938c2ecf20Sopenharmony_ci cfi_ld s5, PT_R28, \docfi 1948c2ecf20Sopenharmony_ci cfi_ld s6, PT_R29, \docfi 1958c2ecf20Sopenharmony_ci cfi_ld s7, PT_R30, \docfi 1968c2ecf20Sopenharmony_ci cfi_ld s8, PT_R31, \docfi 1978c2ecf20Sopenharmony_ci .endm 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci .macro RESTORE_SOME docfi=0 2008c2ecf20Sopenharmony_ci LONG_L a0, sp, PT_PRMD 2018c2ecf20Sopenharmony_ci andi a0, a0, 0x3 /* extract pplv bit */ 2028c2ecf20Sopenharmony_ci beqz a0, 8f 2038c2ecf20Sopenharmony_ci cfi_ld u0, PT_R21, \docfi 2048c2ecf20Sopenharmony_ci8: 2058c2ecf20Sopenharmony_ci LONG_L a0, sp, PT_ERA 2068c2ecf20Sopenharmony_ci csrwr a0, LOONGARCH_CSR_ERA 2078c2ecf20Sopenharmony_ci LONG_L a0, sp, PT_PRMD 2088c2ecf20Sopenharmony_ci csrwr a0, LOONGARCH_CSR_PRMD 2098c2ecf20Sopenharmony_ci cfi_ld ra, PT_R1, \docfi 2108c2ecf20Sopenharmony_ci cfi_ld a0, PT_R4, \docfi 2118c2ecf20Sopenharmony_ci cfi_ld a1, PT_R5, \docfi 2128c2ecf20Sopenharmony_ci cfi_ld a2, PT_R6, \docfi 2138c2ecf20Sopenharmony_ci cfi_ld a3, PT_R7, \docfi 2148c2ecf20Sopenharmony_ci cfi_ld a4, PT_R8, \docfi 2158c2ecf20Sopenharmony_ci cfi_ld a5, PT_R9, \docfi 2168c2ecf20Sopenharmony_ci cfi_ld a6, PT_R10, \docfi 2178c2ecf20Sopenharmony_ci cfi_ld a7, PT_R11, \docfi 2188c2ecf20Sopenharmony_ci cfi_ld tp, PT_R2, \docfi 2198c2ecf20Sopenharmony_ci cfi_ld fp, PT_R22, \docfi 2208c2ecf20Sopenharmony_ci .endm 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci .macro RESTORE_SP_AND_RET docfi=0 2238c2ecf20Sopenharmony_ci cfi_ld sp, PT_R3, \docfi 2248c2ecf20Sopenharmony_ci UNWIND_HINT sp_reg=ORC_REG_SP type=ORC_TYPE_CALL 2258c2ecf20Sopenharmony_ci ertn 2268c2ecf20Sopenharmony_ci .endm 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci .macro RESTORE_ALL_AND_RET docfi=0 2298c2ecf20Sopenharmony_ci RESTORE_STATIC \docfi 2308c2ecf20Sopenharmony_ci RESTORE_TEMP \docfi 2318c2ecf20Sopenharmony_ci RESTORE_SOME \docfi 2328c2ecf20Sopenharmony_ci RESTORE_SP_AND_RET \docfi 2338c2ecf20Sopenharmony_ci .endm 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci#endif /* _ASM_STACKFRAME_H */ 236