Line data Source code
1 0 : /*
2 : * Copyright (c) 2024 Nordic Semiconductor ASA
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #ifndef ZEPHYR_INCLUDE_LOGGING_LOG_FRONTEND_STMESP_DEMUX_H_
8 : #define ZEPHYR_INCLUDE_LOGGING_LOG_FRONTEND_STMESP_DEMUX_H_
9 :
10 : #include <zephyr/kernel.h>
11 : #include <zephyr/sys/mpsc_packet.h>
12 :
13 : #ifdef __cplusplus
14 : extern "C" {
15 : #endif
16 :
17 : /**
18 : * @defgroup log_frontend_stmesp_apis Trace and Debug Domain APIs
19 : * @ingroup logging
20 : * @{
21 : * @}
22 : * @defgroup log_frontend_stpesp_demux_apis Logging frontend STMESP Demultiplexer API
23 : * @ingroup log_frontend_stmesp_apis
24 : * @{
25 : */
26 :
27 : /** @brief Bits used to store major index. */
28 1 : #define LOG_FRONTEND_STMESP_DEMUX_MAJOR_BITS 3
29 :
30 : /** @brief Bits used to store severity level. */
31 1 : #define LOG_FRONTEND_STMESP_DEMUX_LEVEL_BITS 3
32 :
33 : /** @brief Bits used to store total length. */
34 1 : #define LOG_FRONTEND_STMESP_DEMUX_TLENGTH_BITS 16
35 :
36 : /** @brief Bits used to store package length. */
37 1 : #define LOG_FRONTEND_STMESP_DEMUX_PLENGTH_BITS 10
38 :
39 : /** @brief Maximum number of supported majors. */
40 1 : #define LOG_FRONTEND_STMESP_DEMUX_MAJOR_MAX BIT(LOG_FRONTEND_STMESP_DEMUX_MAJOR_BITS)
41 :
42 : /** @brief Log message type. */
43 1 : #define LOG_FRONTEND_STMESP_DEMUX_TYPE_LOG 0
44 :
45 : /** @brief Trace point message type. */
46 1 : #define LOG_FRONTEND_STMESP_DEMUX_TYPE_TRACE_POINT 1
47 :
48 : /** @brief HW event message type. */
49 1 : #define LOG_FRONTEND_STMESP_DEMUX_TYPE_HW_EVENT 2
50 :
51 : /** @brief Logging message header. */
52 1 : struct log_frontend_stmesp_demux_log_header {
53 : /** Major index. */
54 1 : uint32_t major : LOG_FRONTEND_STMESP_DEMUX_MAJOR_BITS;
55 :
56 : /** Severity level. */
57 1 : uint32_t level : LOG_FRONTEND_STMESP_DEMUX_LEVEL_BITS;
58 :
59 : /** Total length excluding this header. */
60 1 : uint32_t total_len : LOG_FRONTEND_STMESP_DEMUX_TLENGTH_BITS;
61 :
62 : /** Hexdump data length. */
63 1 : uint32_t package_len : LOG_FRONTEND_STMESP_DEMUX_PLENGTH_BITS;
64 : };
65 :
66 : /** @brief Union for writing raw data to the logging message header. */
67 1 : union log_frontend_stmesp_demux_header {
68 : /** Log header structure. */
69 1 : struct log_frontend_stmesp_demux_log_header log;
70 :
71 : /** Raw word. */
72 1 : uint32_t raw;
73 : };
74 :
75 : /** @brief Generic STP demux packet. */
76 1 : struct log_frontend_stmesp_demux_packet_generic {
77 : /** Data for MPSC packet handling. */
78 1 : MPSC_PBUF_HDR;
79 :
80 : /** Type. */
81 1 : uint64_t type: 2;
82 :
83 : /** Flag indicating if packet is valid. */
84 1 : uint64_t content_invalid: 1;
85 : };
86 :
87 : /** @brief Packet with logging message. */
88 1 : struct log_frontend_stmesp_demux_log {
89 : /** Data for MPSC packet handling. */
90 1 : MPSC_PBUF_HDR;
91 :
92 : /** Type. */
93 1 : uint64_t type: 2;
94 :
95 : /** Flag indicating if packet is valid. */
96 1 : uint64_t content_invalid: 1;
97 :
98 : /** Timestamp. */
99 1 : uint64_t timestamp: 59;
100 :
101 : /** Logging header. */
102 1 : struct log_frontend_stmesp_demux_log_header hdr;
103 :
104 : /** Padding so that data is 8 bytes aligned. */
105 1 : uint32_t padding;
106 :
107 : /** Content. */
108 1 : uint8_t data[];
109 : };
110 :
111 : /** @brief Packet with trace point. */
112 1 : struct log_frontend_stmesp_demux_trace_point {
113 : /** Data for MPSC packet handling. */
114 1 : MPSC_PBUF_HDR;
115 :
116 : /** Type. */
117 1 : uint64_t type: 2;
118 :
119 : /** Flag indicating if packet is valid. */
120 1 : uint64_t content_invalid: 1;
121 :
122 : /** Flag indicating if trace point includes data. */
123 1 : uint64_t has_data: 1;
124 :
125 : /** Timestamp. 54 bits at 40MHz is >14 years. */
126 1 : uint64_t timestamp: 54;
127 :
128 : /** Major ID. */
129 1 : uint64_t major: 4;
130 :
131 : /** Source ID - used for compressed logging. */
132 1 : uint16_t source_id;
133 :
134 : /** ID */
135 1 : uint16_t id;
136 :
137 : /** Content. */
138 1 : uint32_t data;
139 : };
140 :
141 : /** @brief Packet with HW event. */
142 1 : struct log_frontend_stmesp_demux_hw_event {
143 : /** Data for MPSC packet handling. */
144 1 : MPSC_PBUF_HDR;
145 :
146 : /** Type. */
147 1 : uint64_t type: 2;
148 :
149 : /** Flag indicating if packet is valid. */
150 1 : uint64_t content_invalid: 1;
151 :
152 : /** Timestamp. */
153 1 : uint64_t timestamp: 59;
154 :
155 : /** HW event ID. */
156 1 : uint8_t evt;
157 : };
158 :
159 : /** @brief Union of all packet types. */
160 1 : union log_frontend_stmesp_demux_packet {
161 : /** Pointer to generic mpsc_pbuf const packet. */
162 1 : const union mpsc_pbuf_generic *rgeneric;
163 :
164 : /** Pointer to generic mpsc_pbuf packet. */
165 1 : union mpsc_pbuf_generic *generic;
166 :
167 : /** Pointer to the log message. */
168 1 : struct log_frontend_stmesp_demux_log *log;
169 :
170 : /** Pointer to the trace point message. */
171 1 : struct log_frontend_stmesp_demux_trace_point *trace_point;
172 :
173 : /** Pointer to the HW event message. */
174 1 : struct log_frontend_stmesp_demux_hw_event *hw_event;
175 :
176 : /** Pointer to the generic log_frontend_stmesp_demux packet. */
177 1 : struct log_frontend_stmesp_demux_packet_generic *generic_packet;
178 : };
179 :
180 : /** @brief Demultiplexer configuration. */
181 1 : struct log_frontend_stmesp_demux_config {
182 : /** Array with expected major ID's. */
183 1 : const uint16_t *m_ids;
184 :
185 : /** Array length. Must be not bigger than @ref LOG_FRONTEND_STMESP_DEMUX_MAJOR_MAX. */
186 1 : uint32_t m_ids_cnt;
187 :
188 : /** Buffer for storing source ID's. Used for turbo logging. */
189 1 : uint32_t *source_id_buf;
190 :
191 : /** It must be multiple of number of major ID's count. */
192 1 : size_t source_id_buf_len;
193 : };
194 :
195 : /** @brief Initialize the demultiplexer.
196 : *
197 : * @param config Configuration.
198 : *
199 : * @retval 0 on success.
200 : * @retval -EINVAL on invalid configuration.
201 : */
202 1 : int log_frontend_stmesp_demux_init(const struct log_frontend_stmesp_demux_config *config);
203 :
204 : /** @brief Indicate major opcode in the STPv2 stream.
205 : *
206 : * @param id Master ID.
207 : */
208 1 : void log_frontend_stmesp_demux_major(uint16_t id);
209 :
210 : /** @brief Indicate channel opcode in the STPv2 stream.
211 : *
212 : * @param id Channel ID.
213 : */
214 1 : void log_frontend_stmesp_demux_channel(uint16_t id);
215 :
216 : /** @brief Indicate detected packet start (DMTS).
217 : *
218 : * @param data Data. Can be NULL which indicates trace point without data.
219 : * @param ts Timestamp. Can be NULL.
220 : */
221 1 : int log_frontend_stmesp_demux_packet_start(uint32_t *data, uint64_t *ts);
222 :
223 : /** @brief Indicate optimized log message with no arguments.
224 : *
225 : * @param source_id Source ID.
226 : * @param ts Timestamp. Can be NULL.
227 : */
228 1 : int log_frontend_stmesp_demux_log0(uint16_t source_id, uint64_t *ts);
229 :
230 : /** @brief Indicate source ID.
231 : *
232 : * @param source_id Source ID.
233 : */
234 1 : void log_frontend_stmesp_demux_source_id(uint16_t source_id);
235 :
236 : /** @brief Indicate timestamp.
237 : *
238 : * Timestamp is separated from packet start because according to STM spec (3.2.2)
239 : * it is possible that timestamp is assigned to a later packet.
240 : *
241 : * @param ts Timestamp.
242 : */
243 1 : void log_frontend_stmesp_demux_timestamp(uint64_t ts);
244 :
245 : /** @brief Indicate data.
246 : *
247 : * @param data Data buffer.
248 : * @param len Length.
249 : */
250 1 : void log_frontend_stmesp_demux_data(uint8_t *data, size_t len);
251 :
252 : /** @brief Indicate packet end (Flag). */
253 1 : void log_frontend_stmesp_demux_packet_end(void);
254 :
255 : /** @brief Get number of dropped messages and reset the counter.
256 : *
257 : * Message can be dropped if there is no room in the packet buffer.
258 : *
259 : * @return Number of dropped messages.
260 : */
261 1 : uint32_t log_frontend_stmesp_demux_get_dropped(void);
262 :
263 : /** @brief Claim packet.
264 : *
265 : * Get pointer to the pending packet with logging message. Packet must be freed
266 : * using @ref log_frontend_stmesp_demux_free.
267 : *
268 : * @return Pointer to the packet or NULL.
269 : */
270 1 : union log_frontend_stmesp_demux_packet log_frontend_stmesp_demux_claim(void);
271 :
272 : /** @brief Free previously claimed packet.
273 : *
274 : * See @ref log_frontend_stmesp_demux_claim.
275 : *
276 : * @param packet Packet.
277 : */
278 1 : void log_frontend_stmesp_demux_free(union log_frontend_stmesp_demux_packet packet);
279 :
280 : /** @brief Get source name for a turbo log message.
281 : *
282 : * During a boot cooprocessors (FLPR and PPR) are sending location in memory where
283 : * their source data is stored. If application core is an owner of those cores
284 : * it has access to that memory and based on chip ID and source ID it can retrieve
285 : * the source name.
286 : *
287 : * @param m_id Major ID.
288 : * @param s_id Source ID.
289 : *
290 : * @return Pointer to a string which is a source name or unknown name if source name
291 : * cannot be retrieved.
292 : */
293 1 : const char *log_frontend_stmesp_demux_sname_get(uint32_t m_id, uint16_t s_id);
294 0 : const char *log_frontend_stmesp_demux_str_get(uint32_t m_id, uint16_t s_id);
295 :
296 : /** @brief Check if there are any started but not completed log messages.
297 : *
298 : * @retval True There is no pending started log message.
299 : * @retval False There is pending message.
300 : */
301 1 : bool log_frontend_stmesp_demux_is_idle(void);
302 :
303 : /** @brief Close any opened messages and mark them as invalid. */
304 1 : void log_frontend_stmesp_demux_reset(void);
305 :
306 : /** @brief Get maximum buffer utilization.
307 : *
308 : * @retval Non-negative Maximum buffer utilization.
309 : * @retval -ENOTSUP Feature not enabled.
310 : */
311 1 : int log_frontend_stmesp_demux_max_utilization(void);
312 :
313 : /**
314 : * @}
315 : */
316 :
317 : #ifdef __cplusplus
318 : }
319 : #endif
320 :
321 : #endif /* ZEPHYR_INCLUDE_LOGGING_LOG_FRONTEND_STMESP_DEMUX_H_ */
|