162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci#ifndef _ASM_STACKFRAME_H 662306a36Sopenharmony_ci#define _ASM_STACKFRAME_H 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/threads.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <asm/addrspace.h> 1162306a36Sopenharmony_ci#include <asm/asm.h> 1262306a36Sopenharmony_ci#include <asm/asmmacro.h> 1362306a36Sopenharmony_ci#include <asm/asm-offsets.h> 1462306a36Sopenharmony_ci#include <asm/loongarch.h> 1562306a36Sopenharmony_ci#include <asm/thread_info.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/* Make the addition of cfi info a little easier. */ 1862306a36Sopenharmony_ci .macro cfi_rel_offset reg offset=0 docfi=0 1962306a36Sopenharmony_ci .if \docfi 2062306a36Sopenharmony_ci .cfi_rel_offset \reg, \offset 2162306a36Sopenharmony_ci .endif 2262306a36Sopenharmony_ci .endm 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci .macro cfi_st reg offset=0 docfi=0 2562306a36Sopenharmony_ci cfi_rel_offset \reg, \offset, \docfi 2662306a36Sopenharmony_ci LONG_S \reg, sp, \offset 2762306a36Sopenharmony_ci .endm 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci .macro cfi_restore reg offset=0 docfi=0 3062306a36Sopenharmony_ci .if \docfi 3162306a36Sopenharmony_ci .cfi_restore \reg 3262306a36Sopenharmony_ci .endif 3362306a36Sopenharmony_ci .endm 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci .macro cfi_ld reg offset=0 docfi=0 3662306a36Sopenharmony_ci LONG_L \reg, sp, \offset 3762306a36Sopenharmony_ci cfi_restore \reg \offset \docfi 3862306a36Sopenharmony_ci .endm 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci/* Jump to the runtime virtual address. */ 4162306a36Sopenharmony_ci .macro JUMP_VIRT_ADDR temp1 temp2 4262306a36Sopenharmony_ci li.d \temp1, CACHE_BASE 4362306a36Sopenharmony_ci pcaddi \temp2, 0 4462306a36Sopenharmony_ci or \temp1, \temp1, \temp2 4562306a36Sopenharmony_ci jirl zero, \temp1, 0xc 4662306a36Sopenharmony_ci .endm 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci .macro BACKUP_T0T1 4962306a36Sopenharmony_ci csrwr t0, EXCEPTION_KS0 5062306a36Sopenharmony_ci csrwr t1, EXCEPTION_KS1 5162306a36Sopenharmony_ci .endm 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci .macro RELOAD_T0T1 5462306a36Sopenharmony_ci csrrd t0, EXCEPTION_KS0 5562306a36Sopenharmony_ci csrrd t1, EXCEPTION_KS1 5662306a36Sopenharmony_ci .endm 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci .macro SAVE_TEMP docfi=0 5962306a36Sopenharmony_ci RELOAD_T0T1 6062306a36Sopenharmony_ci cfi_st t0, PT_R12, \docfi 6162306a36Sopenharmony_ci cfi_st t1, PT_R13, \docfi 6262306a36Sopenharmony_ci cfi_st t2, PT_R14, \docfi 6362306a36Sopenharmony_ci cfi_st t3, PT_R15, \docfi 6462306a36Sopenharmony_ci cfi_st t4, PT_R16, \docfi 6562306a36Sopenharmony_ci cfi_st t5, PT_R17, \docfi 6662306a36Sopenharmony_ci cfi_st t6, PT_R18, \docfi 6762306a36Sopenharmony_ci cfi_st t7, PT_R19, \docfi 6862306a36Sopenharmony_ci cfi_st t8, PT_R20, \docfi 6962306a36Sopenharmony_ci .endm 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci .macro SAVE_STATIC docfi=0 7262306a36Sopenharmony_ci cfi_st s0, PT_R23, \docfi 7362306a36Sopenharmony_ci cfi_st s1, PT_R24, \docfi 7462306a36Sopenharmony_ci cfi_st s2, PT_R25, \docfi 7562306a36Sopenharmony_ci cfi_st s3, PT_R26, \docfi 7662306a36Sopenharmony_ci cfi_st s4, PT_R27, \docfi 7762306a36Sopenharmony_ci cfi_st s5, PT_R28, \docfi 7862306a36Sopenharmony_ci cfi_st s6, PT_R29, \docfi 7962306a36Sopenharmony_ci cfi_st s7, PT_R30, \docfi 8062306a36Sopenharmony_ci cfi_st s8, PT_R31, \docfi 8162306a36Sopenharmony_ci .endm 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci/* 8462306a36Sopenharmony_ci * get_saved_sp returns the SP for the current CPU by looking in the 8562306a36Sopenharmony_ci * kernelsp array for it. It stores the current sp in t0 and loads the 8662306a36Sopenharmony_ci * new value in sp. 8762306a36Sopenharmony_ci */ 8862306a36Sopenharmony_ci .macro get_saved_sp docfi=0 8962306a36Sopenharmony_ci la_abs t1, kernelsp 9062306a36Sopenharmony_ci#ifdef CONFIG_SMP 9162306a36Sopenharmony_ci csrrd t0, PERCPU_BASE_KS 9262306a36Sopenharmony_ci LONG_ADD t1, t1, t0 9362306a36Sopenharmony_ci#endif 9462306a36Sopenharmony_ci move t0, sp 9562306a36Sopenharmony_ci .if \docfi 9662306a36Sopenharmony_ci .cfi_register sp, t0 9762306a36Sopenharmony_ci .endif 9862306a36Sopenharmony_ci LONG_L sp, t1, 0 9962306a36Sopenharmony_ci .endm 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci .macro set_saved_sp stackp temp temp2 10262306a36Sopenharmony_ci la.pcrel \temp, kernelsp 10362306a36Sopenharmony_ci#ifdef CONFIG_SMP 10462306a36Sopenharmony_ci LONG_ADD \temp, \temp, u0 10562306a36Sopenharmony_ci#endif 10662306a36Sopenharmony_ci LONG_S \stackp, \temp, 0 10762306a36Sopenharmony_ci .endm 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci .macro SAVE_SOME docfi=0 11062306a36Sopenharmony_ci csrrd t1, LOONGARCH_CSR_PRMD 11162306a36Sopenharmony_ci andi t1, t1, 0x3 /* extract pplv bit */ 11262306a36Sopenharmony_ci move t0, sp 11362306a36Sopenharmony_ci beqz t1, 8f 11462306a36Sopenharmony_ci /* Called from user mode, new stack. */ 11562306a36Sopenharmony_ci get_saved_sp docfi=\docfi 11662306a36Sopenharmony_ci8: 11762306a36Sopenharmony_ci PTR_ADDI sp, sp, -PT_SIZE 11862306a36Sopenharmony_ci .if \docfi 11962306a36Sopenharmony_ci .cfi_def_cfa sp, 0 12062306a36Sopenharmony_ci .endif 12162306a36Sopenharmony_ci cfi_st t0, PT_R3, \docfi 12262306a36Sopenharmony_ci cfi_rel_offset sp, PT_R3, \docfi 12362306a36Sopenharmony_ci LONG_S zero, sp, PT_R0 12462306a36Sopenharmony_ci csrrd t0, LOONGARCH_CSR_PRMD 12562306a36Sopenharmony_ci LONG_S t0, sp, PT_PRMD 12662306a36Sopenharmony_ci csrrd t0, LOONGARCH_CSR_CRMD 12762306a36Sopenharmony_ci LONG_S t0, sp, PT_CRMD 12862306a36Sopenharmony_ci csrrd t0, LOONGARCH_CSR_EUEN 12962306a36Sopenharmony_ci LONG_S t0, sp, PT_EUEN 13062306a36Sopenharmony_ci csrrd t0, LOONGARCH_CSR_ECFG 13162306a36Sopenharmony_ci LONG_S t0, sp, PT_ECFG 13262306a36Sopenharmony_ci csrrd t0, LOONGARCH_CSR_ESTAT 13362306a36Sopenharmony_ci PTR_S t0, sp, PT_ESTAT 13462306a36Sopenharmony_ci cfi_st ra, PT_R1, \docfi 13562306a36Sopenharmony_ci cfi_st a0, PT_R4, \docfi 13662306a36Sopenharmony_ci cfi_st a1, PT_R5, \docfi 13762306a36Sopenharmony_ci cfi_st a2, PT_R6, \docfi 13862306a36Sopenharmony_ci cfi_st a3, PT_R7, \docfi 13962306a36Sopenharmony_ci cfi_st a4, PT_R8, \docfi 14062306a36Sopenharmony_ci cfi_st a5, PT_R9, \docfi 14162306a36Sopenharmony_ci cfi_st a6, PT_R10, \docfi 14262306a36Sopenharmony_ci cfi_st a7, PT_R11, \docfi 14362306a36Sopenharmony_ci csrrd ra, LOONGARCH_CSR_ERA 14462306a36Sopenharmony_ci LONG_S ra, sp, PT_ERA 14562306a36Sopenharmony_ci .if \docfi 14662306a36Sopenharmony_ci .cfi_rel_offset ra, PT_ERA 14762306a36Sopenharmony_ci .endif 14862306a36Sopenharmony_ci cfi_st tp, PT_R2, \docfi 14962306a36Sopenharmony_ci cfi_st fp, PT_R22, \docfi 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci /* Set thread_info if we're coming from user mode */ 15262306a36Sopenharmony_ci csrrd t0, LOONGARCH_CSR_PRMD 15362306a36Sopenharmony_ci andi t0, t0, 0x3 /* extract pplv bit */ 15462306a36Sopenharmony_ci beqz t0, 9f 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci li.d tp, ~_THREAD_MASK 15762306a36Sopenharmony_ci and tp, tp, sp 15862306a36Sopenharmony_ci cfi_st u0, PT_R21, \docfi 15962306a36Sopenharmony_ci csrrd u0, PERCPU_BASE_KS 16062306a36Sopenharmony_ci9: 16162306a36Sopenharmony_ci#ifdef CONFIG_KGDB 16262306a36Sopenharmony_ci li.w t0, CSR_CRMD_WE 16362306a36Sopenharmony_ci csrxchg t0, t0, LOONGARCH_CSR_CRMD 16462306a36Sopenharmony_ci#endif 16562306a36Sopenharmony_ci .endm 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci .macro SAVE_ALL docfi=0 16862306a36Sopenharmony_ci SAVE_SOME \docfi 16962306a36Sopenharmony_ci SAVE_TEMP \docfi 17062306a36Sopenharmony_ci SAVE_STATIC \docfi 17162306a36Sopenharmony_ci .endm 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_ci .macro RESTORE_TEMP docfi=0 17462306a36Sopenharmony_ci cfi_ld t0, PT_R12, \docfi 17562306a36Sopenharmony_ci cfi_ld t1, PT_R13, \docfi 17662306a36Sopenharmony_ci cfi_ld t2, PT_R14, \docfi 17762306a36Sopenharmony_ci cfi_ld t3, PT_R15, \docfi 17862306a36Sopenharmony_ci cfi_ld t4, PT_R16, \docfi 17962306a36Sopenharmony_ci cfi_ld t5, PT_R17, \docfi 18062306a36Sopenharmony_ci cfi_ld t6, PT_R18, \docfi 18162306a36Sopenharmony_ci cfi_ld t7, PT_R19, \docfi 18262306a36Sopenharmony_ci cfi_ld t8, PT_R20, \docfi 18362306a36Sopenharmony_ci .endm 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci .macro RESTORE_STATIC docfi=0 18662306a36Sopenharmony_ci cfi_ld s0, PT_R23, \docfi 18762306a36Sopenharmony_ci cfi_ld s1, PT_R24, \docfi 18862306a36Sopenharmony_ci cfi_ld s2, PT_R25, \docfi 18962306a36Sopenharmony_ci cfi_ld s3, PT_R26, \docfi 19062306a36Sopenharmony_ci cfi_ld s4, PT_R27, \docfi 19162306a36Sopenharmony_ci cfi_ld s5, PT_R28, \docfi 19262306a36Sopenharmony_ci cfi_ld s6, PT_R29, \docfi 19362306a36Sopenharmony_ci cfi_ld s7, PT_R30, \docfi 19462306a36Sopenharmony_ci cfi_ld s8, PT_R31, \docfi 19562306a36Sopenharmony_ci .endm 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci .macro RESTORE_SOME docfi=0 19862306a36Sopenharmony_ci LONG_L a0, sp, PT_PRMD 19962306a36Sopenharmony_ci andi a0, a0, 0x3 /* extract pplv bit */ 20062306a36Sopenharmony_ci beqz a0, 8f 20162306a36Sopenharmony_ci cfi_ld u0, PT_R21, \docfi 20262306a36Sopenharmony_ci8: 20362306a36Sopenharmony_ci LONG_L a0, sp, PT_ERA 20462306a36Sopenharmony_ci csrwr a0, LOONGARCH_CSR_ERA 20562306a36Sopenharmony_ci LONG_L a0, sp, PT_PRMD 20662306a36Sopenharmony_ci csrwr a0, LOONGARCH_CSR_PRMD 20762306a36Sopenharmony_ci cfi_ld ra, PT_R1, \docfi 20862306a36Sopenharmony_ci cfi_ld a0, PT_R4, \docfi 20962306a36Sopenharmony_ci cfi_ld a1, PT_R5, \docfi 21062306a36Sopenharmony_ci cfi_ld a2, PT_R6, \docfi 21162306a36Sopenharmony_ci cfi_ld a3, PT_R7, \docfi 21262306a36Sopenharmony_ci cfi_ld a4, PT_R8, \docfi 21362306a36Sopenharmony_ci cfi_ld a5, PT_R9, \docfi 21462306a36Sopenharmony_ci cfi_ld a6, PT_R10, \docfi 21562306a36Sopenharmony_ci cfi_ld a7, PT_R11, \docfi 21662306a36Sopenharmony_ci cfi_ld tp, PT_R2, \docfi 21762306a36Sopenharmony_ci cfi_ld fp, PT_R22, \docfi 21862306a36Sopenharmony_ci .endm 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_ci .macro RESTORE_SP_AND_RET docfi=0 22162306a36Sopenharmony_ci cfi_ld sp, PT_R3, \docfi 22262306a36Sopenharmony_ci ertn 22362306a36Sopenharmony_ci .endm 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci .macro RESTORE_ALL_AND_RET docfi=0 22662306a36Sopenharmony_ci RESTORE_STATIC \docfi 22762306a36Sopenharmony_ci RESTORE_TEMP \docfi 22862306a36Sopenharmony_ci RESTORE_SOME \docfi 22962306a36Sopenharmony_ci RESTORE_SP_AND_RET \docfi 23062306a36Sopenharmony_ci .endm 23162306a36Sopenharmony_ci 23262306a36Sopenharmony_ci#endif /* _ASM_STACKFRAME_H */ 233