/* * Copyright (c) 2024 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_LOGGING_LOG_FRONTEND_STMESP_DEMUX_H_ #define ZEPHYR_INCLUDE_LOGGING_LOG_FRONTEND_STMESP_DEMUX_H_ #include #include #ifdef __cplusplus extern "C" { #endif /** * @defgroup log_frontend_stmesp_apis Trace and Debug Domain APIs * @{ * @} * @defgroup log_frontend_stpesp_demux_apis Logging frontend STMESP Demultiplexer API * @ingroup log_frontend_stmesp_apis * @{ */ /** @brief Bits used to store major index. */ #define LOG_FRONTEND_STMESP_DEMUX_MAJOR_BITS 3 /** @brief Bits used to store severity level. */ #define LOG_FRONTEND_STMESP_DEMUX_LEVEL_BITS 3 /** @brief Bits used to store total length. */ #define LOG_FRONTEND_STMESP_DEMUX_TLENGTH_BITS 16 /** @brief Bits used to store package length. */ #define LOG_FRONTEND_STMESP_DEMUX_PLENGTH_BITS 10 /** @brief Maximum number of supported majors. */ #define LOG_FRONTEND_STMESP_DEMUX_MAJOR_MAX BIT(LOG_FRONTEND_STMESP_DEMUX_MAJOR_BITS) /** @brief Log message type. */ #define LOG_FRONTEND_STMESP_DEMUX_TYPE_LOG 0 /** @brief Trace point message type. */ #define LOG_FRONTEND_STMESP_DEMUX_TYPE_TRACE_POINT 1 /** @brief HW event message type. */ #define LOG_FRONTEND_STMESP_DEMUX_TYPE_HW_EVENT 2 /** @brief Logging message header. */ struct log_frontend_stmesp_demux_log_header { /** Major index. */ uint32_t major : LOG_FRONTEND_STMESP_DEMUX_MAJOR_BITS; /** Severity level. */ uint32_t level : LOG_FRONTEND_STMESP_DEMUX_LEVEL_BITS; /** Total length excluding this header. */ uint32_t total_len : LOG_FRONTEND_STMESP_DEMUX_TLENGTH_BITS; /** Hexdump data length. */ uint32_t package_len : LOG_FRONTEND_STMESP_DEMUX_PLENGTH_BITS; }; /** @brief Union for writing raw data to the logging message header. */ union log_frontend_stmesp_demux_header { /** Log header structure. */ struct log_frontend_stmesp_demux_log_header log; /** Raw word. */ uint32_t raw; }; /** @brief Generic STP demux packet. */ struct log_frontend_stmesp_demux_packet_generic { /** Data for MPSC packet handling. */ MPSC_PBUF_HDR; /** Type. */ uint64_t type: 2; /** Flag indicating if packet is valid. */ uint64_t content_invalid: 1; }; /** @brief Packet with logging message. */ struct log_frontend_stmesp_demux_log { /** Data for MPSC packet handling. */ MPSC_PBUF_HDR; /** Type. */ uint64_t type: 2; /** Flag indicating if packet is valid. */ uint64_t content_invalid: 1; /** Timestamp. */ uint64_t timestamp: 59; /** Logging header. */ struct log_frontend_stmesp_demux_log_header hdr; /** Padding so that data is 8 bytes aligned. */ uint32_t padding; /** Content. */ uint8_t data[]; }; /** @brief Packet with trace point. */ struct log_frontend_stmesp_demux_trace_point { /** Data for MPSC packet handling. */ MPSC_PBUF_HDR; /** Type. */ uint64_t type: 2; /** Flag indicating if packet is valid. */ uint64_t content_invalid: 1; /** Flag indicating if trace point includes data. */ uint64_t has_data: 1; /** Timestamp. 54 bits at 40MHz is >14 years. */ uint64_t timestamp: 54; /** Major ID. */ uint64_t major: 4; /** Source ID - used for compressed logging. */ uint16_t source_id; /** ID */ uint16_t id; /** Content. */ uint32_t data; }; /** @brief Packet with HW event. */ struct log_frontend_stmesp_demux_hw_event { /** Data for MPSC packet handling. */ MPSC_PBUF_HDR; /** Type. */ uint64_t type: 2; /** Flag indicating if packet is valid. */ uint64_t content_invalid: 1; /** Timestamp. */ uint64_t timestamp: 59; /** HW event ID. */ uint8_t evt; }; /** @brief Union of all packet types. */ union log_frontend_stmesp_demux_packet { /** Pointer to generic mpsc_pbuf const packet. */ const union mpsc_pbuf_generic *rgeneric; /** Pointer to generic mpsc_pbuf packet. */ union mpsc_pbuf_generic *generic; /** Pointer to the log message. */ struct log_frontend_stmesp_demux_log *log; /** Pointer to the trace point message. */ struct log_frontend_stmesp_demux_trace_point *trace_point; /** Pointer to the HW event message. */ struct log_frontend_stmesp_demux_hw_event *hw_event; /** Pointer to the generic log_frontend_stmesp_demux packet. */ struct log_frontend_stmesp_demux_packet_generic *generic_packet; }; /** @brief Demultiplexer configuration. */ struct log_frontend_stmesp_demux_config { /** Array with expected major ID's. */ const uint16_t *m_ids; /** Array length. Must be not bigger than @ref LOG_FRONTEND_STMESP_DEMUX_MAJOR_MAX. */ uint32_t m_ids_cnt; /** Buffer for storing source ID's. Used for turbo logging. */ uint32_t *source_id_buf; /** It must be multiple of number of major ID's count. */ size_t source_id_buf_len; }; /** @brief Initialize the demultiplexer. * * @param config Configuration. * * @retval 0 on success. * @retval -EINVAL on invalid configuration. */ int log_frontend_stmesp_demux_init(const struct log_frontend_stmesp_demux_config *config); /** @brief Indicate major opcode in the STPv2 stream. * * @param id Master ID. */ void log_frontend_stmesp_demux_major(uint16_t id); /** @brief Indicate channel opcode in the STPv2 stream. * * @param id Channel ID. */ void log_frontend_stmesp_demux_channel(uint16_t id); /** @brief Indicate detected packet start (DMTS). * * @param data Data. Can be NULL which indicates trace point without data. * @param ts Timestamp. Can be NULL. */ int log_frontend_stmesp_demux_packet_start(uint32_t *data, uint64_t *ts); /** @brief Indicate optimized log message with no arguments. * * @param source_id Source ID. * @param ts Timestamp. Can be NULL. */ int log_frontend_stmesp_demux_log0(uint16_t source_id, uint64_t *ts); /** @brief Indicate source ID. * * @param source_id Source ID. */ void log_frontend_stmesp_demux_source_id(uint16_t source_id); /** @brief Indicate timestamp. * * Timestamp is separated from packet start because according to STM spec (3.2.2) * it is possible that timestamp is assigned to a later packet. * * @param ts Timestamp. */ void log_frontend_stmesp_demux_timestamp(uint64_t ts); /** @brief Indicate data. * * @param data Data buffer. * @param len Length. */ void log_frontend_stmesp_demux_data(uint8_t *data, size_t len); /** @brief Indicate packet end (Flag). */ void log_frontend_stmesp_demux_packet_end(void); /** @brief Get number of dropped messages and reset the counter. * * Message can be dropped if there is no room in the packet buffer. * * @return Number of dropped messages. */ uint32_t log_frontend_stmesp_demux_get_dropped(void); /** @brief Claim packet. * * Get pointer to the pending packet with logging message. Packet must be freed * using @ref log_frontend_stmesp_demux_free. * * @return Pointer to the packet or NULL. */ union log_frontend_stmesp_demux_packet log_frontend_stmesp_demux_claim(void); /** @brief Free previously claimed packet. * * See @ref log_frontend_stmesp_demux_claim. * * @param packet Packet. */ void log_frontend_stmesp_demux_free(union log_frontend_stmesp_demux_packet packet); /** @brief Get source name for a turbo log message. * * During a boot cooprocessors (FLPR and PPR) are sending location in memory where * their source data is stored. If application core is an owner of those cores * it has access to that memory and based on chip ID and source ID it can retrieve * the source name. * * @param m_id Major ID. * @param s_id Source ID. * * @return Pointer to a string which is a source name or unknown name if source name * cannot be retrieved. */ const char *log_frontend_stmesp_demux_sname_get(uint32_t m_id, uint16_t s_id); /** @brief Check if there are any started but not completed log messages. * * @retval True There is no pending started log message. * @retval False There is pending message. */ bool log_frontend_stmesp_demux_is_idle(void); /** @brief Close any opened messages and mark them as invalid. */ void log_frontend_stmesp_demux_reset(void); /** @brief Get maximum buffer utilization. * * @retval Non-negative Maximum buffer utilization. * @retval -ENOTSUP Feature not enabled. */ int log_frontend_stmesp_demux_max_utilization(void); /** * @} */ #ifdef __cplusplus } #endif #endif /* ZEPHYR_INCLUDE_LOGGING_LOG_FRONTEND_STMESP_DEMUX_H_ */