forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
....@@ -8,6 +8,7 @@
88
99 #include <linux/err.h>
1010 #include <linux/list.h>
11
+#include <linux/zalloc.h>
1112 #include <stdlib.h>
1213 #include <opencsd/c_api/opencsd_c_api.h>
1314 #include <opencsd/etmv4/trc_pkt_types_etmv4.h>
....@@ -16,9 +17,6 @@
1617 #include "cs-etm.h"
1718 #include "cs-etm-decoder.h"
1819 #include "intlist.h"
19
-#include "util.h"
20
-
21
-#define MAX_BUFFER 1024
2220
2321 /* use raw logging */
2422 #ifdef CS_DEBUG_RAW
....@@ -31,34 +29,26 @@
3129 #endif
3230 #endif
3331
34
-#define CS_ETM_INVAL_ADDR 0xdeadbeefdeadbeefUL
35
-
3632 struct cs_etm_decoder {
3733 void *data;
3834 void (*packet_printer)(const char *msg);
39
- bool trace_on;
4035 dcd_tree_handle_t dcd_tree;
4136 cs_etm_mem_cb_type mem_access;
4237 ocsd_datapath_resp_t prev_return;
43
- u32 packet_count;
44
- u32 head;
45
- u32 tail;
46
- struct cs_etm_packet packet_buffer[MAX_BUFFER];
4738 };
4839
4940 static u32
5041 cs_etm_decoder__mem_access(const void *context,
5142 const ocsd_vaddr_t address,
5243 const ocsd_mem_space_acc_t mem_space __maybe_unused,
44
+ const u8 trace_chan_id,
5345 const u32 req_size,
5446 u8 *buffer)
5547 {
5648 struct cs_etm_decoder *decoder = (struct cs_etm_decoder *) context;
5749
58
- return decoder->mem_access(decoder->data,
59
- address,
60
- req_size,
61
- buffer);
50
+ return decoder->mem_access(decoder->data, trace_chan_id,
51
+ address, req_size, buffer);
6252 }
6353
6454 int cs_etm_decoder__add_mem_access_cb(struct cs_etm_decoder *decoder,
....@@ -67,9 +57,10 @@
6757 {
6858 decoder->mem_access = cb_func;
6959
70
- if (ocsd_dt_add_callback_mem_acc(decoder->dcd_tree, start, end,
71
- OCSD_MEM_SPACE_ANY,
72
- cs_etm_decoder__mem_access, decoder))
60
+ if (ocsd_dt_add_callback_trcid_mem_acc(decoder->dcd_tree, start, end,
61
+ OCSD_MEM_SPACE_ANY,
62
+ cs_etm_decoder__mem_access,
63
+ decoder))
7364 return -1;
7465
7566 return 0;
....@@ -89,14 +80,14 @@
8980 return 0;
9081 }
9182
92
-int cs_etm_decoder__get_packet(struct cs_etm_decoder *decoder,
83
+int cs_etm_decoder__get_packet(struct cs_etm_packet_queue *packet_queue,
9384 struct cs_etm_packet *packet)
9485 {
95
- if (!decoder || !packet)
86
+ if (!packet_queue || !packet)
9687 return -EINVAL;
9788
9889 /* Nothing to do, might as well just return */
99
- if (decoder->packet_count == 0)
90
+ if (packet_queue->packet_count == 0)
10091 return 0;
10192 /*
10293 * The queueing process in function cs_etm_decoder__buffer_packet()
....@@ -107,13 +98,27 @@
10798 * value. Otherwise the first element of the packet queue is not
10899 * used.
109100 */
110
- decoder->head = (decoder->head + 1) & (MAX_BUFFER - 1);
101
+ packet_queue->head = (packet_queue->head + 1) &
102
+ (CS_ETM_PACKET_MAX_BUFFER - 1);
111103
112
- *packet = decoder->packet_buffer[decoder->head];
104
+ *packet = packet_queue->packet_buffer[packet_queue->head];
113105
114
- decoder->packet_count--;
106
+ packet_queue->packet_count--;
115107
116108 return 1;
109
+}
110
+
111
+static int cs_etm_decoder__gen_etmv3_config(struct cs_etm_trace_params *params,
112
+ ocsd_etmv3_cfg *config)
113
+{
114
+ config->reg_idr = params->etmv3.reg_idr;
115
+ config->reg_ctrl = params->etmv3.reg_ctrl;
116
+ config->reg_ccer = params->etmv3.reg_ccer;
117
+ config->reg_trc_id = params->etmv3.reg_trc_id;
118
+ config->arch_ver = ARCH_V7;
119
+ config->core_prof = profile_CortexA;
120
+
121
+ return 0;
117122 }
118123
119124 static void cs_etm_decoder__gen_etmv4_config(struct cs_etm_trace_params *params,
....@@ -237,10 +242,19 @@
237242 struct cs_etm_decoder *decoder)
238243 {
239244 const char *decoder_name;
245
+ ocsd_etmv3_cfg config_etmv3;
240246 ocsd_etmv4_cfg trace_config_etmv4;
241247 void *trace_config;
242248
243249 switch (t_params->protocol) {
250
+ case CS_ETM_PROTO_ETMV3:
251
+ case CS_ETM_PROTO_PTM:
252
+ cs_etm_decoder__gen_etmv3_config(t_params, &config_etmv3);
253
+ decoder_name = (t_params->protocol == CS_ETM_PROTO_ETMV3) ?
254
+ OCSD_BUILTIN_DCD_ETMV3 :
255
+ OCSD_BUILTIN_DCD_PTM;
256
+ trace_config = &config_etmv3;
257
+ break;
244258 case CS_ETM_PROTO_ETMV4i:
245259 cs_etm_decoder__gen_etmv4_config(t_params, &trace_config_etmv4);
246260 decoder_name = OCSD_BUILTIN_DCD_ETMV4I;
....@@ -255,72 +269,156 @@
255269 trace_config);
256270 }
257271
258
-static void cs_etm_decoder__clear_buffer(struct cs_etm_decoder *decoder)
272
+static ocsd_datapath_resp_t
273
+cs_etm_decoder__do_soft_timestamp(struct cs_etm_queue *etmq,
274
+ struct cs_etm_packet_queue *packet_queue,
275
+ const uint8_t trace_chan_id)
259276 {
260
- int i;
277
+ /* No timestamp packet has been received, nothing to do */
278
+ if (!packet_queue->timestamp)
279
+ return OCSD_RESP_CONT;
261280
262
- decoder->head = 0;
263
- decoder->tail = 0;
264
- decoder->packet_count = 0;
265
- for (i = 0; i < MAX_BUFFER; i++) {
266
- decoder->packet_buffer[i].start_addr = CS_ETM_INVAL_ADDR;
267
- decoder->packet_buffer[i].end_addr = CS_ETM_INVAL_ADDR;
268
- decoder->packet_buffer[i].last_instr_taken_branch = false;
269
- decoder->packet_buffer[i].exc = false;
270
- decoder->packet_buffer[i].exc_ret = false;
271
- decoder->packet_buffer[i].cpu = INT_MIN;
272
- }
281
+ packet_queue->timestamp = packet_queue->next_timestamp;
282
+
283
+ /* Estimate the timestamp for the next range packet */
284
+ packet_queue->next_timestamp += packet_queue->instr_count;
285
+ packet_queue->instr_count = 0;
286
+
287
+ /* Tell the front end which traceid_queue needs attention */
288
+ cs_etm__etmq_set_traceid_queue_timestamp(etmq, trace_chan_id);
289
+
290
+ return OCSD_RESP_WAIT;
273291 }
274292
275293 static ocsd_datapath_resp_t
276
-cs_etm_decoder__buffer_packet(struct cs_etm_decoder *decoder,
294
+cs_etm_decoder__do_hard_timestamp(struct cs_etm_queue *etmq,
295
+ const ocsd_generic_trace_elem *elem,
296
+ const uint8_t trace_chan_id)
297
+{
298
+ struct cs_etm_packet_queue *packet_queue;
299
+
300
+ /* First get the packet queue for this traceID */
301
+ packet_queue = cs_etm__etmq_get_packet_queue(etmq, trace_chan_id);
302
+ if (!packet_queue)
303
+ return OCSD_RESP_FATAL_SYS_ERR;
304
+
305
+ /*
306
+ * We've seen a timestamp packet before - simply record the new value.
307
+ * Function do_soft_timestamp() will report the value to the front end,
308
+ * hence asking the decoder to keep decoding rather than stopping.
309
+ */
310
+ if (packet_queue->timestamp) {
311
+ packet_queue->next_timestamp = elem->timestamp;
312
+ return OCSD_RESP_CONT;
313
+ }
314
+
315
+ /*
316
+ * This is the first timestamp we've seen since the beginning of traces
317
+ * or a discontinuity. Since timestamps packets are generated *after*
318
+ * range packets have been generated, we need to estimate the time at
319
+ * which instructions started by substracting the number of instructions
320
+ * executed to the timestamp.
321
+ */
322
+ packet_queue->timestamp = elem->timestamp - packet_queue->instr_count;
323
+ packet_queue->next_timestamp = elem->timestamp;
324
+ packet_queue->instr_count = 0;
325
+
326
+ /* Tell the front end which traceid_queue needs attention */
327
+ cs_etm__etmq_set_traceid_queue_timestamp(etmq, trace_chan_id);
328
+
329
+ /* Halt processing until we are being told to proceed */
330
+ return OCSD_RESP_WAIT;
331
+}
332
+
333
+static void
334
+cs_etm_decoder__reset_timestamp(struct cs_etm_packet_queue *packet_queue)
335
+{
336
+ packet_queue->timestamp = 0;
337
+ packet_queue->next_timestamp = 0;
338
+ packet_queue->instr_count = 0;
339
+}
340
+
341
+static ocsd_datapath_resp_t
342
+cs_etm_decoder__buffer_packet(struct cs_etm_packet_queue *packet_queue,
277343 const u8 trace_chan_id,
278344 enum cs_etm_sample_type sample_type)
279345 {
280346 u32 et = 0;
281347 int cpu;
282348
283
- if (decoder->packet_count >= MAX_BUFFER - 1)
349
+ if (packet_queue->packet_count >= CS_ETM_PACKET_MAX_BUFFER - 1)
284350 return OCSD_RESP_FATAL_SYS_ERR;
285351
286352 if (cs_etm__get_cpu(trace_chan_id, &cpu) < 0)
287353 return OCSD_RESP_FATAL_SYS_ERR;
288354
289
- et = decoder->tail;
290
- et = (et + 1) & (MAX_BUFFER - 1);
291
- decoder->tail = et;
292
- decoder->packet_count++;
355
+ et = packet_queue->tail;
356
+ et = (et + 1) & (CS_ETM_PACKET_MAX_BUFFER - 1);
357
+ packet_queue->tail = et;
358
+ packet_queue->packet_count++;
293359
294
- decoder->packet_buffer[et].sample_type = sample_type;
295
- decoder->packet_buffer[et].exc = false;
296
- decoder->packet_buffer[et].exc_ret = false;
297
- decoder->packet_buffer[et].cpu = cpu;
298
- decoder->packet_buffer[et].start_addr = CS_ETM_INVAL_ADDR;
299
- decoder->packet_buffer[et].end_addr = CS_ETM_INVAL_ADDR;
360
+ packet_queue->packet_buffer[et].sample_type = sample_type;
361
+ packet_queue->packet_buffer[et].isa = CS_ETM_ISA_UNKNOWN;
362
+ packet_queue->packet_buffer[et].cpu = cpu;
363
+ packet_queue->packet_buffer[et].start_addr = CS_ETM_INVAL_ADDR;
364
+ packet_queue->packet_buffer[et].end_addr = CS_ETM_INVAL_ADDR;
365
+ packet_queue->packet_buffer[et].instr_count = 0;
366
+ packet_queue->packet_buffer[et].last_instr_taken_branch = false;
367
+ packet_queue->packet_buffer[et].last_instr_size = 0;
368
+ packet_queue->packet_buffer[et].last_instr_type = 0;
369
+ packet_queue->packet_buffer[et].last_instr_subtype = 0;
370
+ packet_queue->packet_buffer[et].last_instr_cond = 0;
371
+ packet_queue->packet_buffer[et].flags = 0;
372
+ packet_queue->packet_buffer[et].exception_number = UINT32_MAX;
373
+ packet_queue->packet_buffer[et].trace_chan_id = trace_chan_id;
300374
301
- if (decoder->packet_count == MAX_BUFFER - 1)
375
+ if (packet_queue->packet_count == CS_ETM_PACKET_MAX_BUFFER - 1)
302376 return OCSD_RESP_WAIT;
303377
304378 return OCSD_RESP_CONT;
305379 }
306380
307381 static ocsd_datapath_resp_t
308
-cs_etm_decoder__buffer_range(struct cs_etm_decoder *decoder,
382
+cs_etm_decoder__buffer_range(struct cs_etm_queue *etmq,
383
+ struct cs_etm_packet_queue *packet_queue,
309384 const ocsd_generic_trace_elem *elem,
310385 const uint8_t trace_chan_id)
311386 {
312387 int ret = 0;
313388 struct cs_etm_packet *packet;
314389
315
- ret = cs_etm_decoder__buffer_packet(decoder, trace_chan_id,
390
+ ret = cs_etm_decoder__buffer_packet(packet_queue, trace_chan_id,
316391 CS_ETM_RANGE);
317392 if (ret != OCSD_RESP_CONT && ret != OCSD_RESP_WAIT)
318393 return ret;
319394
320
- packet = &decoder->packet_buffer[decoder->tail];
395
+ packet = &packet_queue->packet_buffer[packet_queue->tail];
396
+
397
+ switch (elem->isa) {
398
+ case ocsd_isa_aarch64:
399
+ packet->isa = CS_ETM_ISA_A64;
400
+ break;
401
+ case ocsd_isa_arm:
402
+ packet->isa = CS_ETM_ISA_A32;
403
+ break;
404
+ case ocsd_isa_thumb2:
405
+ packet->isa = CS_ETM_ISA_T32;
406
+ break;
407
+ case ocsd_isa_tee:
408
+ case ocsd_isa_jazelle:
409
+ case ocsd_isa_custom:
410
+ case ocsd_isa_unknown:
411
+ default:
412
+ packet->isa = CS_ETM_ISA_UNKNOWN;
413
+ }
321414
322415 packet->start_addr = elem->st_addr;
323416 packet->end_addr = elem->en_addr;
417
+ packet->instr_count = elem->num_instr_range;
418
+ packet->last_instr_type = elem->last_i_type;
419
+ packet->last_instr_subtype = elem->last_i_subtype;
420
+ packet->last_instr_cond = elem->last_instr_cond;
421
+
324422 switch (elem->last_i_type) {
325423 case OCSD_INSTR_BR:
326424 case OCSD_INSTR_BR_INDIRECT:
....@@ -328,21 +426,97 @@
328426 break;
329427 case OCSD_INSTR_ISB:
330428 case OCSD_INSTR_DSB_DMB:
429
+ case OCSD_INSTR_WFI_WFE:
331430 case OCSD_INSTR_OTHER:
332431 default:
333432 packet->last_instr_taken_branch = false;
334433 break;
335434 }
336435
436
+ packet->last_instr_size = elem->last_instr_sz;
437
+
438
+ /* per-thread scenario, no need to generate a timestamp */
439
+ if (cs_etm__etmq_is_timeless(etmq))
440
+ goto out;
441
+
442
+ /*
443
+ * The packet queue is full and we haven't seen a timestamp (had we
444
+ * seen one the packet queue wouldn't be full). Let the front end
445
+ * deal with it.
446
+ */
447
+ if (ret == OCSD_RESP_WAIT)
448
+ goto out;
449
+
450
+ packet_queue->instr_count += elem->num_instr_range;
451
+ /* Tell the front end we have a new timestamp to process */
452
+ ret = cs_etm_decoder__do_soft_timestamp(etmq, packet_queue,
453
+ trace_chan_id);
454
+out:
337455 return ret;
338456 }
339457
340458 static ocsd_datapath_resp_t
341
-cs_etm_decoder__buffer_trace_on(struct cs_etm_decoder *decoder,
342
- const uint8_t trace_chan_id)
459
+cs_etm_decoder__buffer_discontinuity(struct cs_etm_packet_queue *queue,
460
+ const uint8_t trace_chan_id)
343461 {
344
- return cs_etm_decoder__buffer_packet(decoder, trace_chan_id,
345
- CS_ETM_TRACE_ON);
462
+ /*
463
+ * Something happened and who knows when we'll get new traces so
464
+ * reset time statistics.
465
+ */
466
+ cs_etm_decoder__reset_timestamp(queue);
467
+ return cs_etm_decoder__buffer_packet(queue, trace_chan_id,
468
+ CS_ETM_DISCONTINUITY);
469
+}
470
+
471
+static ocsd_datapath_resp_t
472
+cs_etm_decoder__buffer_exception(struct cs_etm_packet_queue *queue,
473
+ const ocsd_generic_trace_elem *elem,
474
+ const uint8_t trace_chan_id)
475
+{ int ret = 0;
476
+ struct cs_etm_packet *packet;
477
+
478
+ ret = cs_etm_decoder__buffer_packet(queue, trace_chan_id,
479
+ CS_ETM_EXCEPTION);
480
+ if (ret != OCSD_RESP_CONT && ret != OCSD_RESP_WAIT)
481
+ return ret;
482
+
483
+ packet = &queue->packet_buffer[queue->tail];
484
+ packet->exception_number = elem->exception_number;
485
+
486
+ return ret;
487
+}
488
+
489
+static ocsd_datapath_resp_t
490
+cs_etm_decoder__buffer_exception_ret(struct cs_etm_packet_queue *queue,
491
+ const uint8_t trace_chan_id)
492
+{
493
+ return cs_etm_decoder__buffer_packet(queue, trace_chan_id,
494
+ CS_ETM_EXCEPTION_RET);
495
+}
496
+
497
+static ocsd_datapath_resp_t
498
+cs_etm_decoder__set_tid(struct cs_etm_queue *etmq,
499
+ struct cs_etm_packet_queue *packet_queue,
500
+ const ocsd_generic_trace_elem *elem,
501
+ const uint8_t trace_chan_id)
502
+{
503
+ pid_t tid;
504
+
505
+ /* Ignore PE_CONTEXT packets that don't have a valid contextID */
506
+ if (!elem->context.ctxt_id_valid)
507
+ return OCSD_RESP_CONT;
508
+
509
+ tid = elem->context.context_id;
510
+ if (cs_etm__etmq_set_tid(etmq, tid, trace_chan_id))
511
+ return OCSD_RESP_FATAL_SYS_ERR;
512
+
513
+ /*
514
+ * A timestamp is generated after a PE_CONTEXT element so make sure
515
+ * to rely on that coming one.
516
+ */
517
+ cs_etm_decoder__reset_timestamp(packet_queue);
518
+
519
+ return OCSD_RESP_CONT;
346520 }
347521
348522 static ocsd_datapath_resp_t cs_etm_decoder__gen_trace_elem_printer(
....@@ -353,32 +527,46 @@
353527 {
354528 ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
355529 struct cs_etm_decoder *decoder = (struct cs_etm_decoder *) context;
530
+ struct cs_etm_queue *etmq = decoder->data;
531
+ struct cs_etm_packet_queue *packet_queue;
532
+
533
+ /* First get the packet queue for this traceID */
534
+ packet_queue = cs_etm__etmq_get_packet_queue(etmq, trace_chan_id);
535
+ if (!packet_queue)
536
+ return OCSD_RESP_FATAL_SYS_ERR;
356537
357538 switch (elem->elem_type) {
358539 case OCSD_GEN_TRC_ELEM_UNKNOWN:
359540 break;
541
+ case OCSD_GEN_TRC_ELEM_EO_TRACE:
360542 case OCSD_GEN_TRC_ELEM_NO_SYNC:
361
- decoder->trace_on = false;
362
- break;
363543 case OCSD_GEN_TRC_ELEM_TRACE_ON:
364
- resp = cs_etm_decoder__buffer_trace_on(decoder,
365
- trace_chan_id);
366
- decoder->trace_on = true;
544
+ resp = cs_etm_decoder__buffer_discontinuity(packet_queue,
545
+ trace_chan_id);
367546 break;
368547 case OCSD_GEN_TRC_ELEM_INSTR_RANGE:
369
- resp = cs_etm_decoder__buffer_range(decoder, elem,
548
+ resp = cs_etm_decoder__buffer_range(etmq, packet_queue, elem,
370549 trace_chan_id);
371550 break;
372551 case OCSD_GEN_TRC_ELEM_EXCEPTION:
373
- decoder->packet_buffer[decoder->tail].exc = true;
552
+ resp = cs_etm_decoder__buffer_exception(packet_queue, elem,
553
+ trace_chan_id);
374554 break;
375555 case OCSD_GEN_TRC_ELEM_EXCEPTION_RET:
376
- decoder->packet_buffer[decoder->tail].exc_ret = true;
556
+ resp = cs_etm_decoder__buffer_exception_ret(packet_queue,
557
+ trace_chan_id);
558
+ break;
559
+ case OCSD_GEN_TRC_ELEM_TIMESTAMP:
560
+ resp = cs_etm_decoder__do_hard_timestamp(etmq, elem,
561
+ trace_chan_id);
377562 break;
378563 case OCSD_GEN_TRC_ELEM_PE_CONTEXT:
379
- case OCSD_GEN_TRC_ELEM_EO_TRACE:
564
+ resp = cs_etm_decoder__set_tid(etmq, packet_queue,
565
+ elem, trace_chan_id);
566
+ break;
567
+ /* Unused packet types */
568
+ case OCSD_GEN_TRC_ELEM_I_RANGE_NOPATH:
380569 case OCSD_GEN_TRC_ELEM_ADDR_NACC:
381
- case OCSD_GEN_TRC_ELEM_TIMESTAMP:
382570 case OCSD_GEN_TRC_ELEM_CYCLE_COUNT:
383571 case OCSD_GEN_TRC_ELEM_ADDR_UNKNOWN:
384572 case OCSD_GEN_TRC_ELEM_EVENT:
....@@ -396,11 +584,20 @@
396584 struct cs_etm_decoder *decoder)
397585 {
398586 const char *decoder_name;
587
+ ocsd_etmv3_cfg config_etmv3;
399588 ocsd_etmv4_cfg trace_config_etmv4;
400589 void *trace_config;
401590 u8 csid;
402591
403592 switch (t_params->protocol) {
593
+ case CS_ETM_PROTO_ETMV3:
594
+ case CS_ETM_PROTO_PTM:
595
+ cs_etm_decoder__gen_etmv3_config(t_params, &config_etmv3);
596
+ decoder_name = (t_params->protocol == CS_ETM_PROTO_ETMV3) ?
597
+ OCSD_BUILTIN_DCD_ETMV3 :
598
+ OCSD_BUILTIN_DCD_PTM;
599
+ trace_config = &config_etmv3;
600
+ break;
404601 case CS_ETM_PROTO_ETMV4i:
405602 cs_etm_decoder__gen_etmv4_config(t_params, &trace_config_etmv4);
406603 decoder_name = OCSD_BUILTIN_DCD_ETMV4I;
....@@ -458,7 +655,6 @@
458655
459656 decoder->data = d_params->data;
460657 decoder->prev_return = OCSD_RESP_CONT;
461
- cs_etm_decoder__clear_buffer(decoder);
462658 format = (d_params->formatted ? OCSD_TRC_SRC_FRAME_FORMATTED :
463659 OCSD_TRC_SRC_SINGLE);
464660 flags = 0;
....@@ -481,7 +677,7 @@
481677 /* init library print logging support */
482678 ret = cs_etm_decoder__init_def_logger_printing(d_params, decoder);
483679 if (ret != 0)
484
- goto err_free_decoder_tree;
680
+ goto err_free_decoder;
485681
486682 /* init raw frame logging if required */
487683 cs_etm_decoder__init_raw_frame_logging(d_params, decoder);
....@@ -491,15 +687,13 @@
491687 &t_params[i],
492688 decoder);
493689 if (ret != 0)
494
- goto err_free_decoder_tree;
690
+ goto err_free_decoder;
495691 }
496692
497693 return decoder;
498694
499
-err_free_decoder_tree:
500
- ocsd_destroy_dcd_tree(decoder->dcd_tree);
501695 err_free_decoder:
502
- free(decoder);
696
+ cs_etm_decoder__free(decoder);
503697 return NULL;
504698 }
505699