1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright(C) 2015-2018 Linaro Limited.
5 * Author: Tor Jeremiassen <tor@ti.com>
6 * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
10 #include <linux/list.h>
12 #include <opencsd/c_api/opencsd_c_api.h>
13 #include <opencsd/etmv4/trc_pkt_types_etmv4.h>
14 #include <opencsd/ocsd_if_types.h>
17 #include "cs-etm-decoder.h"
21 #define MAX_BUFFER 1024
25 #define CS_LOG_RAW_FRAMES
27 #define CS_RAW_DEBUG_FLAGS (OCSD_DFRMTR_UNPACKED_RAW_OUT | \
28 OCSD_DFRMTR_PACKED_RAW_OUT)
30 #define CS_RAW_DEBUG_FLAGS (OCSD_DFRMTR_UNPACKED_RAW_OUT)
34 #define CS_ETM_INVAL_ADDR 0xdeadbeefdeadbeefUL
36 struct cs_etm_decoder
{
38 void (*packet_printer
)(const char *msg
);
39 dcd_tree_handle_t dcd_tree
;
40 cs_etm_mem_cb_type mem_access
;
41 ocsd_datapath_resp_t prev_return
;
45 struct cs_etm_packet packet_buffer
[MAX_BUFFER
];
49 cs_etm_decoder__mem_access(const void *context
,
50 const ocsd_vaddr_t address
,
51 const ocsd_mem_space_acc_t mem_space __maybe_unused
,
55 struct cs_etm_decoder
*decoder
= (struct cs_etm_decoder
*) context
;
57 return decoder
->mem_access(decoder
->data
,
63 int cs_etm_decoder__add_mem_access_cb(struct cs_etm_decoder
*decoder
,
65 cs_etm_mem_cb_type cb_func
)
67 decoder
->mem_access
= cb_func
;
69 if (ocsd_dt_add_callback_mem_acc(decoder
->dcd_tree
, start
, end
,
71 cs_etm_decoder__mem_access
, decoder
))
77 int cs_etm_decoder__reset(struct cs_etm_decoder
*decoder
)
79 ocsd_datapath_resp_t dp_ret
;
81 decoder
->prev_return
= OCSD_RESP_CONT
;
83 dp_ret
= ocsd_dt_process_data(decoder
->dcd_tree
, OCSD_OP_RESET
,
85 if (OCSD_DATA_RESP_IS_FATAL(dp_ret
))
91 int cs_etm_decoder__get_packet(struct cs_etm_decoder
*decoder
,
92 struct cs_etm_packet
*packet
)
94 if (!decoder
|| !packet
)
97 /* Nothing to do, might as well just return */
98 if (decoder
->packet_count
== 0)
101 * The queueing process in function cs_etm_decoder__buffer_packet()
102 * increments the tail *before* using it. This is somewhat counter
103 * intuitive but it has the advantage of centralizing tail management
104 * at a single location. Because of that we need to follow the same
105 * heuristic with the head, i.e we increment it before using its
106 * value. Otherwise the first element of the packet queue is not
109 decoder
->head
= (decoder
->head
+ 1) & (MAX_BUFFER
- 1);
111 *packet
= decoder
->packet_buffer
[decoder
->head
];
113 decoder
->packet_count
--;
118 static int cs_etm_decoder__gen_etmv3_config(struct cs_etm_trace_params
*params
,
119 ocsd_etmv3_cfg
*config
)
121 config
->reg_idr
= params
->etmv3
.reg_idr
;
122 config
->reg_ctrl
= params
->etmv3
.reg_ctrl
;
123 config
->reg_ccer
= params
->etmv3
.reg_ccer
;
124 config
->reg_trc_id
= params
->etmv3
.reg_trc_id
;
125 config
->arch_ver
= ARCH_V7
;
126 config
->core_prof
= profile_CortexA
;
131 static void cs_etm_decoder__gen_etmv4_config(struct cs_etm_trace_params
*params
,
132 ocsd_etmv4_cfg
*config
)
134 config
->reg_configr
= params
->etmv4
.reg_configr
;
135 config
->reg_traceidr
= params
->etmv4
.reg_traceidr
;
136 config
->reg_idr0
= params
->etmv4
.reg_idr0
;
137 config
->reg_idr1
= params
->etmv4
.reg_idr1
;
138 config
->reg_idr2
= params
->etmv4
.reg_idr2
;
139 config
->reg_idr8
= params
->etmv4
.reg_idr8
;
140 config
->reg_idr9
= 0;
141 config
->reg_idr10
= 0;
142 config
->reg_idr11
= 0;
143 config
->reg_idr12
= 0;
144 config
->reg_idr13
= 0;
145 config
->arch_ver
= ARCH_V8
;
146 config
->core_prof
= profile_CortexA
;
149 static void cs_etm_decoder__print_str_cb(const void *p_context
,
153 if (p_context
&& str_len
)
154 ((struct cs_etm_decoder
*)p_context
)->packet_printer(msg
);
158 cs_etm_decoder__init_def_logger_printing(struct cs_etm_decoder_params
*d_params
,
159 struct cs_etm_decoder
*decoder
)
163 if (d_params
->packet_printer
== NULL
)
166 decoder
->packet_printer
= d_params
->packet_printer
;
169 * Set up a library default logger to process any printers
170 * (packet/raw frame) we add later.
172 ret
= ocsd_def_errlog_init(OCSD_ERR_SEV_ERROR
, 1);
176 /* no stdout / err / file output */
177 ret
= ocsd_def_errlog_config_output(C_API_MSGLOGOUT_FLG_NONE
, NULL
);
182 * Set the string CB for the default logger, passes strings to
185 ret
= ocsd_def_errlog_set_strprint_cb(decoder
->dcd_tree
,
187 cs_etm_decoder__print_str_cb
);
194 #ifdef CS_LOG_RAW_FRAMES
196 cs_etm_decoder__init_raw_frame_logging(struct cs_etm_decoder_params
*d_params
,
197 struct cs_etm_decoder
*decoder
)
199 /* Only log these during a --dump operation */
200 if (d_params
->operation
== CS_ETM_OPERATION_PRINT
) {
201 /* set up a library default logger to process the
202 * raw frame printer we add later
204 ocsd_def_errlog_init(OCSD_ERR_SEV_ERROR
, 1);
206 /* no stdout / err / file output */
207 ocsd_def_errlog_config_output(C_API_MSGLOGOUT_FLG_NONE
, NULL
);
209 /* set the string CB for the default logger,
210 * passes strings to perf print logger.
212 ocsd_def_errlog_set_strprint_cb(decoder
->dcd_tree
,
214 cs_etm_decoder__print_str_cb
);
216 /* use the built in library printer for the raw frames */
217 ocsd_dt_set_raw_frame_printer(decoder
->dcd_tree
,
223 cs_etm_decoder__init_raw_frame_logging(
224 struct cs_etm_decoder_params
*d_params __maybe_unused
,
225 struct cs_etm_decoder
*decoder __maybe_unused
)
230 static int cs_etm_decoder__create_packet_printer(struct cs_etm_decoder
*decoder
,
231 const char *decoder_name
,
236 if (ocsd_dt_create_decoder(decoder
->dcd_tree
, decoder_name
,
237 OCSD_CREATE_FLG_PACKET_PROC
,
238 trace_config
, &csid
))
241 if (ocsd_dt_set_pkt_protocol_printer(decoder
->dcd_tree
, csid
, 0))
248 cs_etm_decoder__create_etm_packet_printer(struct cs_etm_trace_params
*t_params
,
249 struct cs_etm_decoder
*decoder
)
251 const char *decoder_name
;
252 ocsd_etmv3_cfg config_etmv3
;
253 ocsd_etmv4_cfg trace_config_etmv4
;
256 switch (t_params
->protocol
) {
257 case CS_ETM_PROTO_ETMV3
:
258 case CS_ETM_PROTO_PTM
:
259 cs_etm_decoder__gen_etmv3_config(t_params
, &config_etmv3
);
260 decoder_name
= (t_params
->protocol
== CS_ETM_PROTO_ETMV3
) ?
261 OCSD_BUILTIN_DCD_ETMV3
:
262 OCSD_BUILTIN_DCD_PTM
;
263 trace_config
= &config_etmv3
;
265 case CS_ETM_PROTO_ETMV4i
:
266 cs_etm_decoder__gen_etmv4_config(t_params
, &trace_config_etmv4
);
267 decoder_name
= OCSD_BUILTIN_DCD_ETMV4I
;
268 trace_config
= &trace_config_etmv4
;
274 return cs_etm_decoder__create_packet_printer(decoder
,
279 static void cs_etm_decoder__clear_buffer(struct cs_etm_decoder
*decoder
)
285 decoder
->packet_count
= 0;
286 for (i
= 0; i
< MAX_BUFFER
; i
++) {
287 decoder
->packet_buffer
[i
].isa
= CS_ETM_ISA_UNKNOWN
;
288 decoder
->packet_buffer
[i
].start_addr
= CS_ETM_INVAL_ADDR
;
289 decoder
->packet_buffer
[i
].end_addr
= CS_ETM_INVAL_ADDR
;
290 decoder
->packet_buffer
[i
].instr_count
= 0;
291 decoder
->packet_buffer
[i
].last_instr_taken_branch
= false;
292 decoder
->packet_buffer
[i
].last_instr_size
= 0;
293 decoder
->packet_buffer
[i
].last_instr_type
= 0;
294 decoder
->packet_buffer
[i
].last_instr_subtype
= 0;
295 decoder
->packet_buffer
[i
].last_instr_cond
= 0;
296 decoder
->packet_buffer
[i
].flags
= 0;
297 decoder
->packet_buffer
[i
].exception_number
= UINT32_MAX
;
298 decoder
->packet_buffer
[i
].trace_chan_id
= UINT8_MAX
;
299 decoder
->packet_buffer
[i
].cpu
= INT_MIN
;
303 static ocsd_datapath_resp_t
304 cs_etm_decoder__buffer_packet(struct cs_etm_decoder
*decoder
,
305 const u8 trace_chan_id
,
306 enum cs_etm_sample_type sample_type
)
311 if (decoder
->packet_count
>= MAX_BUFFER
- 1)
312 return OCSD_RESP_FATAL_SYS_ERR
;
314 if (cs_etm__get_cpu(trace_chan_id
, &cpu
) < 0)
315 return OCSD_RESP_FATAL_SYS_ERR
;
318 et
= (et
+ 1) & (MAX_BUFFER
- 1);
320 decoder
->packet_count
++;
322 decoder
->packet_buffer
[et
].sample_type
= sample_type
;
323 decoder
->packet_buffer
[et
].isa
= CS_ETM_ISA_UNKNOWN
;
324 decoder
->packet_buffer
[et
].cpu
= cpu
;
325 decoder
->packet_buffer
[et
].start_addr
= CS_ETM_INVAL_ADDR
;
326 decoder
->packet_buffer
[et
].end_addr
= CS_ETM_INVAL_ADDR
;
327 decoder
->packet_buffer
[et
].instr_count
= 0;
328 decoder
->packet_buffer
[et
].last_instr_taken_branch
= false;
329 decoder
->packet_buffer
[et
].last_instr_size
= 0;
330 decoder
->packet_buffer
[et
].last_instr_type
= 0;
331 decoder
->packet_buffer
[et
].last_instr_subtype
= 0;
332 decoder
->packet_buffer
[et
].last_instr_cond
= 0;
333 decoder
->packet_buffer
[et
].flags
= 0;
334 decoder
->packet_buffer
[et
].exception_number
= UINT32_MAX
;
335 decoder
->packet_buffer
[et
].trace_chan_id
= trace_chan_id
;
337 if (decoder
->packet_count
== MAX_BUFFER
- 1)
338 return OCSD_RESP_WAIT
;
340 return OCSD_RESP_CONT
;
343 static ocsd_datapath_resp_t
344 cs_etm_decoder__buffer_range(struct cs_etm_decoder
*decoder
,
345 const ocsd_generic_trace_elem
*elem
,
346 const uint8_t trace_chan_id
)
349 struct cs_etm_packet
*packet
;
351 ret
= cs_etm_decoder__buffer_packet(decoder
, trace_chan_id
,
353 if (ret
!= OCSD_RESP_CONT
&& ret
!= OCSD_RESP_WAIT
)
356 packet
= &decoder
->packet_buffer
[decoder
->tail
];
359 case ocsd_isa_aarch64
:
360 packet
->isa
= CS_ETM_ISA_A64
;
363 packet
->isa
= CS_ETM_ISA_A32
;
365 case ocsd_isa_thumb2
:
366 packet
->isa
= CS_ETM_ISA_T32
;
369 case ocsd_isa_jazelle
:
370 case ocsd_isa_custom
:
371 case ocsd_isa_unknown
:
373 packet
->isa
= CS_ETM_ISA_UNKNOWN
;
376 packet
->start_addr
= elem
->st_addr
;
377 packet
->end_addr
= elem
->en_addr
;
378 packet
->instr_count
= elem
->num_instr_range
;
379 packet
->last_instr_type
= elem
->last_i_type
;
380 packet
->last_instr_subtype
= elem
->last_i_subtype
;
381 packet
->last_instr_cond
= elem
->last_instr_cond
;
383 switch (elem
->last_i_type
) {
385 case OCSD_INSTR_BR_INDIRECT
:
386 packet
->last_instr_taken_branch
= elem
->last_instr_exec
;
389 case OCSD_INSTR_DSB_DMB
:
390 case OCSD_INSTR_WFI_WFE
:
391 case OCSD_INSTR_OTHER
:
393 packet
->last_instr_taken_branch
= false;
397 packet
->last_instr_size
= elem
->last_instr_sz
;
402 static ocsd_datapath_resp_t
403 cs_etm_decoder__buffer_discontinuity(struct cs_etm_decoder
*decoder
,
404 const uint8_t trace_chan_id
)
406 return cs_etm_decoder__buffer_packet(decoder
, trace_chan_id
,
407 CS_ETM_DISCONTINUITY
);
410 static ocsd_datapath_resp_t
411 cs_etm_decoder__buffer_exception(struct cs_etm_decoder
*decoder
,
412 const ocsd_generic_trace_elem
*elem
,
413 const uint8_t trace_chan_id
)
415 struct cs_etm_packet
*packet
;
417 ret
= cs_etm_decoder__buffer_packet(decoder
, trace_chan_id
,
419 if (ret
!= OCSD_RESP_CONT
&& ret
!= OCSD_RESP_WAIT
)
422 packet
= &decoder
->packet_buffer
[decoder
->tail
];
423 packet
->exception_number
= elem
->exception_number
;
428 static ocsd_datapath_resp_t
429 cs_etm_decoder__buffer_exception_ret(struct cs_etm_decoder
*decoder
,
430 const uint8_t trace_chan_id
)
432 return cs_etm_decoder__buffer_packet(decoder
, trace_chan_id
,
433 CS_ETM_EXCEPTION_RET
);
436 static ocsd_datapath_resp_t
cs_etm_decoder__gen_trace_elem_printer(
438 const ocsd_trc_index_t indx __maybe_unused
,
439 const u8 trace_chan_id __maybe_unused
,
440 const ocsd_generic_trace_elem
*elem
)
442 ocsd_datapath_resp_t resp
= OCSD_RESP_CONT
;
443 struct cs_etm_decoder
*decoder
= (struct cs_etm_decoder
*) context
;
445 switch (elem
->elem_type
) {
446 case OCSD_GEN_TRC_ELEM_UNKNOWN
:
448 case OCSD_GEN_TRC_ELEM_EO_TRACE
:
449 case OCSD_GEN_TRC_ELEM_NO_SYNC
:
450 case OCSD_GEN_TRC_ELEM_TRACE_ON
:
451 resp
= cs_etm_decoder__buffer_discontinuity(decoder
,
454 case OCSD_GEN_TRC_ELEM_INSTR_RANGE
:
455 resp
= cs_etm_decoder__buffer_range(decoder
, elem
,
458 case OCSD_GEN_TRC_ELEM_EXCEPTION
:
459 resp
= cs_etm_decoder__buffer_exception(decoder
, elem
,
462 case OCSD_GEN_TRC_ELEM_EXCEPTION_RET
:
463 resp
= cs_etm_decoder__buffer_exception_ret(decoder
,
466 case OCSD_GEN_TRC_ELEM_PE_CONTEXT
:
467 case OCSD_GEN_TRC_ELEM_ADDR_NACC
:
468 case OCSD_GEN_TRC_ELEM_TIMESTAMP
:
469 case OCSD_GEN_TRC_ELEM_CYCLE_COUNT
:
470 case OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN
:
471 case OCSD_GEN_TRC_ELEM_EVENT
:
472 case OCSD_GEN_TRC_ELEM_SWTRACE
:
473 case OCSD_GEN_TRC_ELEM_CUSTOM
:
481 static int cs_etm_decoder__create_etm_packet_decoder(
482 struct cs_etm_trace_params
*t_params
,
483 struct cs_etm_decoder
*decoder
)
485 const char *decoder_name
;
486 ocsd_etmv3_cfg config_etmv3
;
487 ocsd_etmv4_cfg trace_config_etmv4
;
491 switch (t_params
->protocol
) {
492 case CS_ETM_PROTO_ETMV3
:
493 case CS_ETM_PROTO_PTM
:
494 cs_etm_decoder__gen_etmv3_config(t_params
, &config_etmv3
);
495 decoder_name
= (t_params
->protocol
== CS_ETM_PROTO_ETMV3
) ?
496 OCSD_BUILTIN_DCD_ETMV3
:
497 OCSD_BUILTIN_DCD_PTM
;
498 trace_config
= &config_etmv3
;
500 case CS_ETM_PROTO_ETMV4i
:
501 cs_etm_decoder__gen_etmv4_config(t_params
, &trace_config_etmv4
);
502 decoder_name
= OCSD_BUILTIN_DCD_ETMV4I
;
503 trace_config
= &trace_config_etmv4
;
509 if (ocsd_dt_create_decoder(decoder
->dcd_tree
,
511 OCSD_CREATE_FLG_FULL_DECODER
,
512 trace_config
, &csid
))
515 if (ocsd_dt_set_gen_elem_outfn(decoder
->dcd_tree
,
516 cs_etm_decoder__gen_trace_elem_printer
,
524 cs_etm_decoder__create_etm_decoder(struct cs_etm_decoder_params
*d_params
,
525 struct cs_etm_trace_params
*t_params
,
526 struct cs_etm_decoder
*decoder
)
528 if (d_params
->operation
== CS_ETM_OPERATION_PRINT
)
529 return cs_etm_decoder__create_etm_packet_printer(t_params
,
531 else if (d_params
->operation
== CS_ETM_OPERATION_DECODE
)
532 return cs_etm_decoder__create_etm_packet_decoder(t_params
,
538 struct cs_etm_decoder
*
539 cs_etm_decoder__new(int num_cpu
, struct cs_etm_decoder_params
*d_params
,
540 struct cs_etm_trace_params t_params
[])
542 struct cs_etm_decoder
*decoder
;
543 ocsd_dcd_tree_src_t format
;
547 if ((!t_params
) || (!d_params
))
550 decoder
= zalloc(sizeof(*decoder
));
555 decoder
->data
= d_params
->data
;
556 decoder
->prev_return
= OCSD_RESP_CONT
;
557 cs_etm_decoder__clear_buffer(decoder
);
558 format
= (d_params
->formatted
? OCSD_TRC_SRC_FRAME_FORMATTED
:
559 OCSD_TRC_SRC_SINGLE
);
561 flags
|= (d_params
->fsyncs
? OCSD_DFRMTR_HAS_FSYNCS
: 0);
562 flags
|= (d_params
->hsyncs
? OCSD_DFRMTR_HAS_HSYNCS
: 0);
563 flags
|= (d_params
->frame_aligned
? OCSD_DFRMTR_FRAME_MEM_ALIGN
: 0);
566 * Drivers may add barrier frames when used with perf, set up to
567 * handle this. Barriers const of FSYNC packet repeated 4 times.
569 flags
|= OCSD_DFRMTR_RESET_ON_4X_FSYNC
;
571 /* Create decode tree for the data source */
572 decoder
->dcd_tree
= ocsd_create_dcd_tree(format
, flags
);
574 if (decoder
->dcd_tree
== 0)
575 goto err_free_decoder
;
577 /* init library print logging support */
578 ret
= cs_etm_decoder__init_def_logger_printing(d_params
, decoder
);
580 goto err_free_decoder_tree
;
582 /* init raw frame logging if required */
583 cs_etm_decoder__init_raw_frame_logging(d_params
, decoder
);
585 for (i
= 0; i
< num_cpu
; i
++) {
586 ret
= cs_etm_decoder__create_etm_decoder(d_params
,
590 goto err_free_decoder_tree
;
595 err_free_decoder_tree
:
596 ocsd_destroy_dcd_tree(decoder
->dcd_tree
);
602 int cs_etm_decoder__process_data_block(struct cs_etm_decoder
*decoder
,
603 u64 indx
, const u8
*buf
,
604 size_t len
, size_t *consumed
)
607 ocsd_datapath_resp_t cur
= OCSD_RESP_CONT
;
608 ocsd_datapath_resp_t prev_return
= decoder
->prev_return
;
609 size_t processed
= 0;
612 while (processed
< len
) {
613 if (OCSD_DATA_RESP_IS_WAIT(prev_return
)) {
614 cur
= ocsd_dt_process_data(decoder
->dcd_tree
,
620 } else if (OCSD_DATA_RESP_IS_CONT(prev_return
)) {
621 cur
= ocsd_dt_process_data(decoder
->dcd_tree
,
634 * Return to the input code if the packet buffer is full.
635 * Flushing will get done once the packet buffer has been
638 if (OCSD_DATA_RESP_IS_WAIT(cur
))
644 decoder
->prev_return
= cur
;
645 *consumed
= processed
;
650 void cs_etm_decoder__free(struct cs_etm_decoder
*decoder
)
655 ocsd_destroy_dcd_tree(decoder
->dcd_tree
);
656 decoder
->dcd_tree
= NULL
;