1 /* 2 * Copyright (c) 2020 Espressif Systems (Shanghai) Co., Ltd. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #pragma once 8 9 #ifdef __cplusplus 10 extern "C" { 11 #endif 12 13 #ifndef __ASSEMBLER__ 14 15 #include <stdbool.h> 16 #include <stdint.h> 17 18 /* 19 * @brief Structure used for backtracing 20 * 21 * This structure stores the backtrace information of a particular stack frame 22 * (i.e. the PC and SP). This structure is used iteratively with the 23 * z_xtensa_cpu_get_next_backtrace_frame() function to traverse each frame 24 * within a single stack. The next_pc represents the PC of the current 25 * frame's caller, thus a next_pc of 0 indicates that the current frame 26 * is the last frame on the stack. 27 * 28 * @note Call esp_backtrace_get_start() to obtain initialization values for 29 * this structure 30 */ 31 struct z_xtensa_backtrace_frame_t { 32 uint32_t pc; /* PC of the current frame */ 33 uint32_t sp; /* SP of the current frame */ 34 uint32_t next_pc; /* PC of the current frame's caller */ 35 }; 36 37 /** 38 * Get the first frame of the current stack's backtrace 39 * 40 * Given the following function call flow 41 * (B -> A -> X -> esp_backtrace_get_start), 42 * this function will do the following. 43 * - Flush CPU registers and window frames onto the current stack 44 * - Return PC and SP of function A (i.e. start of the stack's backtrace) 45 * - Return PC of function B (i.e. next_pc) 46 * 47 * @note This function is implemented in assembly 48 * 49 * @param[out] pc PC of the first frame in the backtrace 50 * @param[out] sp SP of the first frame in the backtrace 51 * @param[out] next_pc PC of the first frame's caller 52 * @param[in] interrupted_stack Pointer to interrupted stack 53 */ 54 void z_xtensa_backtrace_get_start(uint32_t *pc, 55 uint32_t *sp, 56 uint32_t *next_pc, 57 int *interrupted_stack); 58 59 /** 60 * Get the next frame on a stack for backtracing 61 * 62 * Given a stack frame(i), this function will obtain the next 63 * stack frame(i-1) on the same call stack (i.e. the caller of frame(i)). 64 * This function is meant to be called iteratively when doing a backtrace. 65 * 66 * Entry Conditions: Frame structure containing valid SP and next_pc 67 * Exit Conditions: 68 * - Frame structure updated with SP and PC of frame(i-1). 69 * next_pc now points to frame(i-2). 70 * - If a next_pc of 0 is returned, it indicates that frame(i-1) 71 * is last frame on the stack 72 * 73 * @param[inout] frame Pointer to frame structure 74 * 75 * @return 76 * - True if the SP and PC of the next frame(i-1) are sane 77 * - False otherwise 78 */ 79 bool z_xtensa_backtrace_get_next_frame(struct z_xtensa_backtrace_frame_t *frame); 80 81 /** 82 * @brief Print the backtrace of the current stack 83 * 84 * @param depth The maximum number of stack frames to print (should be > 0) 85 * @param interrupted_stack Pointer to interrupted stack 86 * 87 * @return 88 * - 0 Backtrace successfully printed to completion or to depth limit 89 * - -1 Backtrace is corrupted 90 */ 91 int z_xtensa_backtrace_print(int depth, int *interrupted_stack); 92 93 #endif 94 #ifdef __cplusplus 95 } 96 #endif 97