55 */
66
77#include <zephyr/logging/log_frontend_stmesp_demux.h>
8+ #include <zephyr/logging/log_ctrl.h>
89#include <zephyr/sys/mpsc_pbuf.h>
910#include <zephyr/sys/__assert.h>
1011#include <zephyr/logging/log_msg.h>
@@ -14,6 +15,14 @@ LOG_MODULE_REGISTER(stmesp_demux);
1415BUILD_ASSERT (sizeof (struct log_frontend_stmesp_demux_log_header ) == sizeof (uint32_t ),
1516 "Must fit in a word" );
1617
18+ #ifndef CONFIG_LOG_FRONTEND_STPESP_TURBO_SOURCE_PORT_ID
19+ #define CONFIG_LOG_FRONTEND_STPESP_TURBO_SOURCE_PORT_ID 0
20+ #endif
21+
22+ #ifndef CONFIG_LOG_FRONTEND_STMESP_TURBO_LOG_BASE
23+ #define CONFIG_LOG_FRONTEND_STMESP_TURBO_LOG_BASE 0x8000
24+ #endif
25+
1726#define NUM_OF_ACTIVE CONFIG_LOG_FRONTEND_STMESP_DEMUX_ACTIVE_PACKETS
1827#define M_ID_OFF 16
1928#define M_ID_MASK (BIT_MASK(16) << M_ID_OFF)
@@ -22,6 +31,10 @@ BUILD_ASSERT(sizeof(struct log_frontend_stmesp_demux_log_header) == sizeof(uint3
2231#define M_CH_HW_EVENT 0x00800000
2332#define M_CH_INVALID 0xFFFFFFFF
2433
34+ #define APP_M_ID 0x22
35+ #define FLPR_M_ID 0x2D
36+ #define PPR_M_ID 0x2E
37+
2538struct log_frontend_stmesp_demux_active_entry {
2639 sys_snode_t node ;
2740 uint32_t m_ch ;
@@ -30,6 +43,11 @@ struct log_frontend_stmesp_demux_active_entry {
3043 int off ;
3144};
3245
46+ struct log_frontend_stmesp_coop_sources {
47+ uint32_t m_id ;
48+ const struct log_source_const_data * log_const ;
49+ };
50+
3351struct log_frontend_stmesp_demux {
3452 /* Pool for active entries. */
3553 struct k_mem_slab mslab ;
@@ -46,9 +64,20 @@ struct log_frontend_stmesp_demux {
4664
4765 const uint16_t * m_ids ;
4866
49- uint32_t m_ids_cnt ;
67+ uint32_t * source_ids ;
68+
69+ uint16_t m_ids_cnt ;
70+
71+ uint16_t source_id_len ;
5072
5173 uint32_t dropped ;
74+
75+ struct log_frontend_stmesp_coop_sources coop_sources [2 ];
76+ };
77+
78+ struct log_frontend_stmesp_entry_source_pair {
79+ uint16_t entry_id ;
80+ uint16_t source_id ;
5281};
5382
5483static uint32_t buffer [CONFIG_LOG_FRONTEND_STMESP_DEMUX_BUFFER_SIZE ]
@@ -64,6 +93,40 @@ static void notify_drop(const struct mpsc_pbuf_buffer *buffer,
6493 demux .dropped ++ ;
6594}
6695
96+ static void store_source_id (uint16_t m_id , uint16_t entry_id , uint16_t source_id )
97+ {
98+ uint32_t * source_ids_data = & demux .source_ids [m_id * (demux .source_id_len + 1 )];
99+ uint32_t * wr_idx = source_ids_data ;
100+ struct log_frontend_stmesp_entry_source_pair * source_ids =
101+ (struct log_frontend_stmesp_entry_source_pair * )& source_ids_data [1 ];
102+
103+ source_ids [* wr_idx ].entry_id = entry_id ;
104+ source_ids [* wr_idx ].source_id = source_id ;
105+ * wr_idx = * wr_idx + 1 ;
106+ if (* wr_idx == (demux .source_id_len )) {
107+ * wr_idx = 0 ;
108+ }
109+ }
110+
111+ static uint16_t get_source_id (uint16_t m_id , uint16_t entry_id )
112+ {
113+ uint32_t * source_ids_data = & demux .source_ids [m_id * (demux .source_id_len + 1 )];
114+ int32_t rd_idx = source_ids_data [0 ];
115+ uint32_t cnt = demux .source_id_len ;
116+ struct log_frontend_stmesp_entry_source_pair * source_ids =
117+ (struct log_frontend_stmesp_entry_source_pair * )& source_ids_data [1 ];
118+
119+ do {
120+ rd_idx = (rd_idx == 0 ) ? (demux .source_id_len - 1 ) : (rd_idx - 1 );
121+ if (source_ids [rd_idx ].entry_id == entry_id ) {
122+ return source_ids [rd_idx ].source_id ;
123+ }
124+ cnt -- ;
125+ } while (cnt );
126+
127+ return 0 ;
128+ }
129+
67130static uint32_t calc_wlen (uint32_t total_len )
68131{
69132 return DIV_ROUND_UP (ROUND_UP (total_len , Z_LOG_MSG_ALIGNMENT ), sizeof (uint32_t ));
@@ -116,6 +179,8 @@ int log_frontend_stmesp_demux_init(const struct log_frontend_stmesp_demux_config
116179 demux .dropped = 0 ;
117180 demux .curr_m_ch = M_CH_INVALID ;
118181 demux .curr = NULL ;
182+ demux .source_ids = config -> source_id_buf ;
183+ demux .source_id_len = config -> source_id_buf_len / config -> m_ids_cnt - 1 ;
119184
120185 err = k_mem_slab_init (& demux .mslab , slab_buf ,
121186 sizeof (struct log_frontend_stmesp_demux_active_entry ),
@@ -194,8 +259,41 @@ static uint8_t get_major_id(uint16_t m_id)
194259 return 0 ;
195260}
196261
197- static void log_frontend_stmesp_demux_trace_point (uint16_t m_id , uint16_t id , uint64_t * ts ,
198- uint32_t * data )
262+ static void store_turbo_log0 (uint16_t m_id , uint16_t id , uint64_t * ts , uint16_t source_id )
263+ {
264+ struct log_frontend_stmesp_demux_trace_point packet = {
265+ .valid = 1 ,
266+ .type = LOG_FRONTEND_STMESP_DEMUX_TYPE_TRACE_POINT ,
267+ .content_invalid = 0 ,
268+ .has_data = 0 ,
269+ .timestamp = ts ? * ts : 0 ,
270+ .major = m_id ,
271+ .source_id = source_id ,
272+ .id = id ,
273+ .data = 0 };
274+ static const size_t wlen = sizeof (packet ) / sizeof (uint32_t );
275+
276+ mpsc_pbuf_put_data (& demux .pbuf , (const uint32_t * )& packet , wlen );
277+ }
278+
279+ static void store_turbo_log1 (uint16_t m_id , uint16_t id , uint64_t * ts , uint32_t data )
280+ {
281+ struct log_frontend_stmesp_demux_trace_point packet = {
282+ .valid = 1 ,
283+ .type = LOG_FRONTEND_STMESP_DEMUX_TYPE_TRACE_POINT ,
284+ .content_invalid = 0 ,
285+ .has_data = 0 ,
286+ .timestamp = ts ? * ts : 0 ,
287+ .major = m_id ,
288+ .source_id = get_source_id (m_id , id ),
289+ .id = id ,
290+ .data = data };
291+ static const size_t wlen = sizeof (packet ) / sizeof (uint32_t );
292+
293+ mpsc_pbuf_put_data (& demux .pbuf , (const uint32_t * )& packet , wlen );
294+ }
295+
296+ static void store_tracepoint (uint16_t m_id , uint16_t id , uint64_t * ts , uint32_t * data )
199297{
200298 struct log_frontend_stmesp_demux_trace_point packet = {.valid = 1 ,
201299 .type = LOG_FRONTEND_STMESP_DEMUX_TYPE_TRACE_POINT ,
@@ -252,6 +350,69 @@ static void garbage_collector(uint32_t now)
252350 }
253351}
254352
353+ int log_frontend_stmesp_demux_log0 (uint16_t source_id , uint64_t * ts )
354+ {
355+ if (skip ) {
356+ return 0 ;
357+ }
358+
359+ if (demux .curr_m_ch == M_CH_INVALID ) {
360+ return - EINVAL ;
361+ }
362+
363+ if (demux .curr != NULL ) {
364+ /* Previous package was incompleted. Finish it and potentially
365+ * mark as incompleted if not all data is received.
366+ */
367+ log_frontend_stmesp_demux_packet_end ();
368+ return - EINVAL ;
369+ }
370+
371+ uint16_t ch = demux .curr_m_ch & C_ID_MASK ;
372+ uint16_t m = get_major_id (demux .curr_m_ch >> M_ID_OFF );
373+
374+ if (ch < CONFIG_LOG_FRONTEND_STMESP_TURBO_LOG_BASE ) {
375+ return - EINVAL ;
376+ }
377+
378+ store_turbo_log0 (m , ch , ts , source_id );
379+
380+ return 1 ;
381+ }
382+
383+ void log_frontend_stmesp_demux_source_id (uint16_t data )
384+ {
385+ if (skip ) {
386+ return ;
387+ }
388+
389+ if (demux .curr_m_ch == M_CH_INVALID ) {
390+ return ;
391+ }
392+
393+ uint16_t ch = demux .curr_m_ch & C_ID_MASK ;
394+ uint16_t m = get_major_id (demux .curr_m_ch >> M_ID_OFF );
395+
396+ store_source_id (m , ch , data );
397+ }
398+
399+ const char * log_frontend_stmesp_demux_sname_get (uint32_t m_id , uint16_t s_id )
400+ {
401+ if (!IS_ENABLED (CONFIG_LOG_FRONTEND_STMESP_TURBO_LOG )) {
402+ return "" ;
403+ }
404+
405+ if (demux .m_ids [m_id ] == APP_M_ID ) {
406+ return log_source_name_get (0 , s_id );
407+ } else if (m_id == demux .coop_sources [0 ].m_id ) {
408+ return demux .coop_sources [0 ].log_const [s_id ].name ;
409+ } else if (m_id == demux .coop_sources [1 ].m_id ) {
410+ return demux .coop_sources [1 ].log_const [s_id ].name ;
411+ }
412+
413+ return "unknown" ;
414+ }
415+
255416int log_frontend_stmesp_demux_packet_start (uint32_t * data , uint64_t * ts )
256417{
257418 if (skip ) {
@@ -273,6 +434,23 @@ int log_frontend_stmesp_demux_packet_start(uint32_t *data, uint64_t *ts)
273434 return 1 ;
274435 }
275436
437+ uint16_t ch = demux .curr_m_ch & C_ID_MASK ;
438+ uint16_t m = get_major_id (demux .curr_m_ch >> M_ID_OFF );
439+
440+ if (IS_ENABLED (CONFIG_LOG_FRONTEND_STMESP_TURBO_LOG ) &&
441+ (ch == CONFIG_LOG_FRONTEND_STPESP_TURBO_SOURCE_PORT_ID )) {
442+ if (demux .m_ids [m ] == FLPR_M_ID ) {
443+ demux .coop_sources [0 ].m_id = m ;
444+ demux .coop_sources [0 ].log_const =
445+ (const struct log_source_const_data * )(uintptr_t )* data ;
446+ } else if (demux .m_ids [m ] == PPR_M_ID ) {
447+ demux .coop_sources [1 ].m_id = m ;
448+ demux .coop_sources [1 ].log_const =
449+ (const struct log_source_const_data * )(uintptr_t )* data ;
450+ }
451+ return 0 ;
452+ }
453+
276454 if (demux .curr != NULL ) {
277455 /* Previous package was incompleted. Finish it and potentially
278456 * mark as incompleted if not all data is received.
@@ -281,14 +459,13 @@ int log_frontend_stmesp_demux_packet_start(uint32_t *data, uint64_t *ts)
281459 return - EINVAL ;
282460 }
283461
284- uint16_t ch = demux .curr_m_ch & C_ID_MASK ;
285- uint16_t m = get_major_id (demux .curr_m_ch >> M_ID_OFF );
286-
287462 if (ch >= CONFIG_LOG_FRONTEND_STMESP_TP_CHAN_BASE ) {
288- uint32_t id = (uint32_t )ch - CONFIG_LOG_FRONTEND_STMESP_TP_CHAN_BASE ;
289-
290463 /* Trace point */
291- log_frontend_stmesp_demux_trace_point (m , id , ts , data );
464+ if (ch >= CONFIG_LOG_FRONTEND_STMESP_TURBO_LOG_BASE ) {
465+ store_turbo_log1 (m , ch , ts , * data );
466+ } else {
467+ store_tracepoint (m , ch , ts , data );
468+ }
292469
293470 return 1 ;
294471 }
0 commit comments