Line data Source code
1 0 : /*
2 : * Copyright 2023 Linaro
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #ifndef ZEPHYR_INCLUDE_INSTRUMENTATION_INSTRUMENTATION_H_
8 : #define ZEPHYR_INCLUDE_INSTRUMENTATION_INSTRUMENTATION_H_
9 :
10 : #include <zephyr/kernel.h>
11 :
12 : #ifdef __cplusplus
13 : extern "C" {
14 : #endif
15 :
16 : #if !defined(__no_instrumentation__)
17 : #error "No toolchain support for __no_instrumentation__"
18 : #endif
19 :
20 : /**
21 : * @brief Instrumentation event record types.
22 : */
23 1 : enum instr_event_types {
24 : INSTR_EVENT_ENTRY = 0, /**< Callee entry event record, followed by instr_event. */
25 : INSTR_EVENT_EXIT, /**< Callee exit event record, followed by instr_event. */
26 : INSTR_EVENT_PROFILE, /**< Profile events */
27 : INSTR_EVENT_SCHED_IN, /**< Thread switched in scheduler event */
28 : INSTR_EVENT_SCHED_OUT, /**< Thread switched out scheduler event */
29 : INSTR_EVENT_NUM, /**< Add more events above this one */
30 : INSTR_EVENT_INVALID /**< Invalid or no event generated after promotion */
31 : } __packed;
32 :
33 : /**
34 : * @brief Header for the event records.
35 : */
36 1 : struct instr_header {
37 : /** Event type */
38 1 : enum instr_event_types type;
39 : } __packed;
40 :
41 : /**
42 : * @brief Context-specific data of an event.
43 : */
44 1 : struct instr_event_context {
45 : /** Arch-specific mode indicator (thread mode, interrupt mode, etc.). */
46 1 : uint8_t mode: 3;
47 : /** CPU number. */
48 1 : uint8_t cpu: 5;
49 : /** Thread ID (correlate values with thread lookup table). */
50 1 : void *thread_id;
51 : #ifdef CONFIG_THREAD_NAME
52 : /** Thread name (that can be compacted with the correlate lookup table). */
53 : char thread_name[CONFIG_THREAD_MAX_NAME_LEN];
54 : #endif
55 : } __packed;
56 :
57 : /**
58 : * @brief Event records and associated payloads. Payloads are determined based
59 : * on the code and additional fields in the header.
60 : */
61 1 : struct instr_record {
62 0 : struct instr_header header;
63 0 : void *callee;
64 0 : void *caller;
65 0 : uint64_t timestamp;
66 : union {
67 0 : struct instr_event_context context; /* Context data */
68 : /* Add more payloads here */
69 0 : };
70 : } __packed;
71 :
72 : /**
73 : * @brief Checks if tracing feature is available.
74 : *
75 : */
76 1 : bool instr_tracing_supported(void);
77 :
78 : /**
79 : * @brief Checks if profiling feature is available.
80 : *
81 : */
82 1 : bool instr_profiling_supported(void);
83 :
84 : /**
85 : * @brief Checks if subsystem is ready to be initialized. Must called be before
86 : * instr_init().
87 : */
88 1 : bool instr_fundamentals_initialized(void);
89 :
90 : /**
91 : * @brief Performs initialisation required by the system.
92 : */
93 1 : int instr_init(void);
94 :
95 : /**
96 : * @brief Tells if instrumentation subsystem is properly initialized.
97 : */
98 1 : bool instr_initialized(void);
99 :
100 : /**
101 : * @brief Tells if instrumentation is enabled, i.e. can be turned on.
102 : */
103 1 : bool instr_enabled(void);
104 :
105 : /**
106 : * @brief Enables instrumentation.
107 : */
108 1 : int instr_enable(void);
109 :
110 : /**
111 : * @brief Disables instrumentation.
112 : */
113 1 : int instr_disable(void);
114 :
115 : /**
116 : * @brief Turns on instrumentation (start recording events).
117 : */
118 1 : int instr_turn_on(void);
119 :
120 : /**
121 : * @brief Turns off instrumentation (stop recording events).
122 : */
123 1 : int instr_turn_off(void);
124 :
125 : /**
126 : * @brief Tells if instrumentation is turned on.
127 : */
128 1 : bool instr_turned_on(void);
129 :
130 : /**
131 : * @brief Tells if instrumentation can collect traces.
132 : */
133 1 : bool instr_trace_enabled(void);
134 :
135 : /**
136 : * @brief Tells if instrumentation can collect profile info.
137 : */
138 1 : bool instr_profile_enabled(void);
139 :
140 : /**
141 : * @brief Dumps the buffered contents via UART (tracing).
142 : */
143 1 : void instr_dump_buffer_uart(void);
144 :
145 : /**
146 : * @brief Dumps the delta accumulator array via UART (profiling).
147 : */
148 1 : void instr_dump_deltas_uart(void);
149 :
150 : /**
151 : * @brief Shared callback handler to process entry/exit events.
152 : *
153 : * @param opcode The type of event to process.
154 : * @param func Address of the function being called.
155 : * @param caller Address of the function caller.
156 : */
157 1 : void instr_event_handler(enum instr_event_types opcode, void *func, void *caller);
158 :
159 : /**
160 : * @brief Given a function address, set it as the trigger function, i.e. when
161 : * the function is called it will turn on the instrumentation.
162 : *
163 : * @param callee The function address
164 : */
165 1 : void instr_set_trigger_func(void *callee);
166 :
167 : /**
168 : * @brief Given a function address, set it as the stopper function, i.e. when
169 : * the function exits it will turn off the instrumentation.
170 : *
171 : * @param callee The function address
172 : */
173 1 : void instr_set_stop_func(void *callee);
174 :
175 : /**
176 : * @brief Get the trigger function address.
177 : *
178 : */
179 1 : void *instr_get_trigger_func(void);
180 :
181 : /**
182 : * @brief Get the stopper function address.
183 : *
184 : */
185 1 : void *instr_get_stop_func(void);
186 :
187 : #ifdef __cplusplus
188 : }
189 : #endif
190 :
191 : #endif /* ZEPHYR_INCLUDE_INSTRUMENTATION_INSTRUMENTATION_H_ */
|