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