1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited 4 */ 5 #ifndef _ASM_STACKTRACE_H 6 #define _ASM_STACKTRACE_H 7 8 #include <asm/asm.h> 9 #include <asm/ptrace.h> 10 #include <asm/loongarch.h> 11 #include <asm/unwind_hints.h> 12 #include <linux/stringify.h> 13 14 enum stack_type { 15 STACK_TYPE_UNKNOWN, 16 STACK_TYPE_IRQ, 17 STACK_TYPE_TASK, 18 }; 19 20 struct stack_info { 21 enum stack_type type; 22 unsigned long begin, end, next_sp; 23 }; 24 25 struct stack_frame { 26 unsigned long fp; 27 unsigned long ra; 28 }; 29 30 bool in_irq_stack(unsigned long stack, struct stack_info *info); 31 bool in_task_stack(unsigned long stack, struct task_struct *task, struct stack_info *info); 32 int get_stack_info(unsigned long stack, struct task_struct *task, struct stack_info *info); 33 34 #define STR_LONG_L __stringify(LONG_L) 35 #define STR_LONG_S __stringify(LONG_S) 36 #define STR_LONGSIZE __stringify(LONGSIZE) 37 38 #define STORE_ONE_REG(r) \ 39 STR_LONG_S " $r" __stringify(r)", %1, "STR_LONGSIZE"*"__stringify(r)"\n\t" 40 41 #define CSRRD_ONE_REG(reg) \ 42 __stringify(csrrd) " %0, "__stringify(reg)"\n\t" 43 44 static __always_inline void prepare_frametrace(struct pt_regs *regs) 45 { 46 __asm__ __volatile__( 47 UNWIND_HINT_SAVE 48 /* Save $ra */ 49 STORE_ONE_REG(1) 50 /* Use $ra to save PC */ 51 "pcaddi $ra, 0\n\t" 52 STR_LONG_S " $ra, %0\n\t" 53 /* Restore $ra */ 54 STR_LONG_L " $ra, %1, "STR_LONGSIZE"\n\t" 55 STORE_ONE_REG(2) 56 STORE_ONE_REG(3) 57 STORE_ONE_REG(4) 58 STORE_ONE_REG(5) 59 STORE_ONE_REG(6) 60 STORE_ONE_REG(7) 61 STORE_ONE_REG(8) 62 STORE_ONE_REG(9) 63 STORE_ONE_REG(10) 64 STORE_ONE_REG(11) 65 STORE_ONE_REG(12) 66 STORE_ONE_REG(13) 67 STORE_ONE_REG(14) 68 STORE_ONE_REG(15) 69 STORE_ONE_REG(16) 70 STORE_ONE_REG(17) 71 STORE_ONE_REG(18) 72 STORE_ONE_REG(19) 73 STORE_ONE_REG(20) 74 STORE_ONE_REG(21) 75 STORE_ONE_REG(22) 76 STORE_ONE_REG(23) 77 STORE_ONE_REG(24) 78 STORE_ONE_REG(25) 79 STORE_ONE_REG(26) 80 STORE_ONE_REG(27) 81 STORE_ONE_REG(28) 82 STORE_ONE_REG(29) 83 STORE_ONE_REG(30) 84 STORE_ONE_REG(31) 85 UNWIND_HINT_RESTORE 86 : "=m" (regs->csr_era) 87 : "r" (regs->regs) 88 : "memory"); 89 __asm__ __volatile__(CSRRD_ONE_REG(LOONGARCH_CSR_BADV) : "=r" (regs->csr_badvaddr)); 90 __asm__ __volatile__(CSRRD_ONE_REG(LOONGARCH_CSR_CRMD) : "=r" (regs->csr_crmd)); 91 __asm__ __volatile__(CSRRD_ONE_REG(LOONGARCH_CSR_PRMD) : "=r" (regs->csr_prmd)); 92 __asm__ __volatile__(CSRRD_ONE_REG(LOONGARCH_CSR_EUEN) : "=r" (regs->csr_euen)); 93 __asm__ __volatile__(CSRRD_ONE_REG(LOONGARCH_CSR_ECFG) : "=r" (regs->csr_ecfg)); 94 __asm__ __volatile__(CSRRD_ONE_REG(LOONGARCH_CSR_ESTAT) : "=r" (regs->csr_estat)); 95 } 96 97 #endif /* _ASM_STACKTRACE_H */ 98