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