1 // SPDX-License-Identifier: BSD-2-Clause 2 /*- 3 * Copyright (c) 2023 Andes Technology Corporation 4 * Copyright (c) 2015-2019 Linaro Limited 5 * Copyright (c) 2015 The FreeBSD Foundation 6 */ 7 8 #include <compiler.h> 9 #include <string.h> 10 #include <trace.h> 11 #include <types_ext.h> 12 #include <unw/unwind.h> 13 #include <util.h> 14 15 void __weak ftrace_map_lr(uint64_t *lr __unused) 16 { 17 } 18 19 bool unwind_stack_riscv(struct unwind_state_riscv *frame, 20 vaddr_t stack, size_t stack_size) 21 { 22 vaddr_t fp = frame->fp; 23 struct unwind_state_riscv *caller_state = NULL; 24 25 if (fp < stack) 26 return false; 27 if (fp > stack + stack_size) 28 return false; 29 30 /* 31 * | ..... | ^ unwind upwards 32 * | ..... | | 33 * +=============+ <--+ | +======= caller FP ==========+ 34 * | RA | | | 35 * +-------------+ | | 36 * | caller FP | ---|-+ ^ 37 * +-------------+ | caller stack frame 38 * | ..... | | v 39 * | ..... | | 40 * | ..... | | 41 * +=============+ | +== caller SP / trapped FP ==+ 42 * | RA | | 43 * +-------------+ | 44 * | caller FP | ---+ ^ 45 * +-------------+ trapped stack frame 46 * | ..... | v 47 * | ..... | 48 * | ..... | 49 * +=============+ +======== trapped SP ========+ 50 * | 51 * | grow downwards 52 * V 53 */ 54 55 /* Get caller FP and RA */ 56 caller_state = (struct unwind_state_riscv *)fp - 1; 57 frame->fp = caller_state->fp; 58 frame->pc = caller_state->pc; 59 60 ftrace_map_lr(&frame->pc); 61 62 frame->pc -= 4; 63 64 return true; 65 } 66 67 void print_stack_riscv(struct unwind_state_riscv *state, 68 vaddr_t stack, size_t stack_size) 69 { 70 int width = sizeof(unsigned long); 71 72 trace_printf_helper_raw(TRACE_ERROR, true, "Call stack:"); 73 74 ftrace_map_lr(&state->pc); 75 do { 76 trace_printf_helper_raw(TRACE_ERROR, true, " 0x%0*"PRIxVA, 77 width, state->pc); 78 } while (unwind_stack_riscv(state, stack, stack_size)); 79 } 80