1 
2 /*
3  * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <stdio.h>
9 #include "esp_err.h"
10 #include "esp_log.h"
11 #include "xt_trax.h"
12 #include "esp_private/trax.h"
13 #include "hal/trace_ll.h"
14 #include "soc/dport_reg.h"
15 #include "soc/tracemem_config.h"
16 #include "sdkconfig.h"
17 
18 // Utility functions for enabling TRAX in early startup (hence the use
19 // of ESP_EARLY_LOGX) in Xtensa targets.
20 
21 #if defined(CONFIG_ESP32_TRAX) || defined(CONFIG_ESP32S2_TRAX) || defined(CONFIG_ESP32S3_TRAX)
22 #define WITH_TRAX 1
23 #endif
24 
25 static const char* __attribute__((unused)) TAG = "trax";
26 
trax_enable(trax_ena_select_t which)27 int trax_enable(trax_ena_select_t which)
28 {
29 #if !WITH_TRAX
30     ESP_EARLY_LOGE(TAG, "trax_enable called, but trax is disabled in menuconfig!");
31     return ESP_ERR_NO_MEM;
32 #endif
33 #if CONFIG_IDF_TARGET_ESP32
34 #ifndef CONFIG_ESP32_TRAX_TWOBANKS
35     if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) return ESP_ERR_NO_MEM;
36 #endif
37     if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) {
38         trace_ll_set_mode((which == TRAX_ENA_PRO_APP_SWAP)?TRACEMEM_MUX_PROBLK1_APPBLK0:TRACEMEM_MUX_PROBLK0_APPBLK1);
39     } else {
40         trace_ll_set_mode(TRACEMEM_MUX_BLK0_ONLY);
41     }
42     trace_ll_mem_enable(0, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_PRO));
43     trace_ll_mem_enable(1, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_APP));
44     return ESP_OK;
45 #elif CONFIG_IDF_TARGET_ESP32S2
46     if (which != TRAX_ENA_PRO) {
47         return ESP_ERR_INVALID_ARG;
48     }
49     trace_ll_set_mem_block(TRACEMEM_MUX_BLK1_NUM);
50     return ESP_OK;
51 #elif CONFIG_IDF_TARGET_ESP32S3
52     if (which == TRAX_ENA_PRO) {
53         trace_ll_set_mem_block(0, TRACEMEM_MUX_BLK0_NUM);
54     }
55     else if (which == TRAX_ENA_APP) {
56         trace_ll_set_mem_block(1, TRACEMEM_MUX_BLK0_NUM);
57     }
58 #ifdef CONFIG_ESP32S3_TRAX_TWOBANKS
59     else if (which == TRAX_ENA_PRO_APP) {
60         trace_ll_set_mem_block(0, TRACEMEM_MUX_BLK0_NUM);
61         trace_ll_set_mem_block(1, TRACEMEM_MUX_BLK1_NUM);
62     }
63     else if (which == TRAX_ENA_PRO_APP_SWAP) {
64         trace_ll_set_mem_block(1, TRACEMEM_MUX_BLK0_NUM);
65         trace_ll_set_mem_block(0, TRACEMEM_MUX_BLK1_NUM);
66     }
67 #endif
68     else {
69         return ESP_ERR_INVALID_ARG;
70     }
71     return ESP_OK;
72 #endif
73 }
74 
trax_start_trace(trax_downcount_unit_t units_until_stop)75 int trax_start_trace(trax_downcount_unit_t units_until_stop)
76 {
77 #if !WITH_TRAX
78     ESP_EARLY_LOGE(TAG, "trax_start_trace called, but trax is disabled in menuconfig!");
79     return ESP_ERR_NO_MEM;
80 #endif
81     if (xt_trax_trace_is_active()) {
82         ESP_EARLY_LOGI(TAG, "Stopping active trace first.");
83         //Trace is active. Stop trace.
84         xt_trax_trigger_traceend_after_delay(0);
85     }
86     if (units_until_stop == TRAX_DOWNCOUNT_INSTRUCTIONS) {
87         xt_trax_start_trace_instructions();
88     } else {
89         xt_trax_start_trace_words();
90     }
91     return ESP_OK;
92 }
93 
trax_trigger_traceend_after_delay(int delay)94 int trax_trigger_traceend_after_delay(int delay)
95 {
96 #if !WITH_TRAX
97     ESP_EARLY_LOGE(TAG, "trax_trigger_traceend_after_delay called, but trax is disabled in menuconfig!");
98     return ESP_ERR_NO_MEM;
99 #endif
100     xt_trax_trigger_traceend_after_delay(delay);
101     return ESP_OK;
102 }
103