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