xtensa: move out trax

This commit is contained in:
Renz Bagaporo 2021-02-20 20:39:55 +08:00
parent b1027005df
commit 1efdcd69d9
20 changed files with 278 additions and 178 deletions

View File

@ -159,14 +159,15 @@
#include "sdkconfig.h"
#include "soc/soc.h"
#include "soc/dport_access.h"
#if CONFIG_IDF_TARGET_ESP32
#if !CONFIG_IDF_TARGET_ESP32C3
#include "soc/dport_reg.h"
#elif CONFIG_IDF_TARGET_ESP32S2
#endif
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#include "soc/sensitive_reg.h"
#endif
#if __XTENSA__
#include "xtensa-debug-module.h"
#include "eri.h"
#include "trax.h"
#endif
#include "soc/timer_periph.h"
#include "freertos/FreeRTOS.h"
@ -210,18 +211,6 @@ const static char *TAG = "esp_apptrace";
#define ESP_APPTRACE_LOGV( format, ... ) ESP_APPTRACE_LOG_LEV(V, ESP_LOG_VERBOSE, format, ##__VA_ARGS__)
#define ESP_APPTRACE_LOGO( format, ... ) ESP_APPTRACE_LOG_LEV(E, ESP_LOG_NONE, format, ##__VA_ARGS__)
// TODO: move these (and same definitions in trax.c to dport_reg.h)
#if CONFIG_IDF_TARGET_ESP32
#define TRACEMEM_MUX_PROBLK0_APPBLK1 0
#define TRACEMEM_MUX_BLK0_ONLY 1
#define TRACEMEM_MUX_BLK1_ONLY 2
#define TRACEMEM_MUX_PROBLK1_APPBLK0 3
#elif CONFIG_IDF_TARGET_ESP32S2
#define TRACEMEM_MUX_BLK0_NUM 19
#define TRACEMEM_MUX_BLK1_NUM 20
#define TRACEMEM_BLK_NUM2ADDR(_n_) (0x3FFB8000UL + 0x4000UL*((_n_)-4))
#endif
// TRAX is disabled, so we use its registers for our own purposes
// | 31..XXXXXX..24 | 23 .(host_connect). 23 | 22 .(host_data). 22| 21..(block_id)..15 | 14..(block_len)..0 |
#define ESP_APPTRACE_TRAX_CTRL_REG ERI_TRAX_DELAYCNT

View File

@ -0,0 +1,88 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include "esp_err.h"
#include "esp_log.h"
#include "xt_trax.h"
#include "trax.h"
#include "hal/trace_ll.h"
#include "soc/dport_reg.h"
#include "sdkconfig.h"
// Utility functions for enabling TRAX in early startup (hence the use
// of ESP_EARLY_LOGX) in Xtensa targets.
#if defined(CONFIG_ESP32_TRAX) || defined(CONFIG_ESP32S2_TRAX)
#define WITH_TRAX 1
#endif
static const char* __attribute__((unused)) TAG = "trax";
int trax_enable(trax_ena_select_t which)
{
#if !WITH_TRAX
ESP_EARLY_LOGE(TAG, "trax_enable called, but trax is disabled in menuconfig!");
return ESP_ERR_NO_MEM;
#endif
#if CONFIG_IDF_TARGET_ESP32
#ifndef CONFIG_ESP32_TRAX_TWOBANKS
if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) return ESP_ERR_NO_MEM;
#endif
if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) {
trace_ll_set_mode((which == TRAX_ENA_PRO_APP_SWAP)?TRACEMEM_MUX_PROBLK1_APPBLK0:TRACEMEM_MUX_PROBLK0_APPBLK1);
} else {
trace_ll_set_mode(TRACEMEM_MUX_BLK0_ONLY);
}
trace_ll_mem_enable(0, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_PRO));
trace_ll_mem_enable(1, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_APP));
return ESP_OK;
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
if (which != TRAX_ENA_PRO) {
return ESP_ERR_INVALID_ARG;
}
trace_ll_set_mem_block(TRACEMEM_MUX_BLK1_NUM);
return ESP_OK;
#endif
}
int trax_start_trace(trax_downcount_unit_t units_until_stop)
{
#if !WITH_TRAX
ESP_EARLY_LOGE(TAG, "trax_start_trace called, but trax is disabled in menuconfig!");
return ESP_ERR_NO_MEM;
#endif
if (xt_trax_trace_is_active()) {
ESP_EARLY_LOGI(TAG, "Stopping active trace first.");
//Trace is active. Stop trace.
xt_trax_trigger_traceend_after_delay(0);
}
if (units_until_stop == TRAX_DOWNCOUNT_INSTRUCTIONS) {
xt_trax_start_trace_instructions();
} else {
xt_trax_start_trace_words();
}
return ESP_OK;
}
int trax_trigger_traceend_after_delay(int delay)
{
#if !WITH_TRAX
ESP_EARLY_LOGE(TAG, "trax_trigger_traceend_after_delay called, but trax is disabled in menuconfig!");
return ESP_ERR_NO_MEM;
#endif
xt_trax_trigger_traceend_after_delay(delay);
return ESP_OK;
}

View File

@ -1,8 +1,22 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sdkconfig.h"
#include "esp_err.h"
#include "eri.h"
#include "xtensa-debug-module.h"
#include "xt_trax.h"
typedef enum {
TRAX_DOWNCOUNT_WORDS,
@ -17,7 +31,6 @@ typedef enum {
TRAX_ENA_PRO_APP_SWAP
} trax_ena_select_t;
/**
* @brief Enable the trax memory blocks to be used as Trax memory.
*

View File

@ -7,6 +7,7 @@ set(srcs "dport_panic_highint_hdl.S"
"../../arch/xtensa/expression_with_stack_asm.S"
"../../arch/xtensa/debug_helpers.c"
"../../arch/xtensa/debug_helpers_asm.S"
"../../arch/xtensa/trax.c"
)
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs})

View File

@ -8,6 +8,7 @@ set(srcs "async_memcpy_impl_cp_dma.c"
"../../arch/xtensa/expression_with_stack_asm.S"
"../../arch/xtensa/debug_helpers.c"
"../../arch/xtensa/debug_helpers_asm.S"
"../../arch/xtensa/trax.c"
)
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs})

View File

@ -8,6 +8,7 @@ set(srcs "dport_panic_highint_hdl.S"
"../../arch/xtensa/expression_with_stack_asm.S"
"../../arch/xtensa/debug_helpers.c"
"../../arch/xtensa/debug_helpers_asm.S"
"../../arch/xtensa/trax.c"
)
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" ${srcs})

View File

@ -0,0 +1,28 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "soc/dport_reg.h"
static inline void trace_ll_mem_enable(int cpu, bool enable)
{
int reg[] = {DPORT_PRO_TRACEMEM_ENA_REG, DPORT_APP_TRACEMEM_ENA_REG};
DPORT_WRITE_PERI_REG(reg[cpu], enable);
}
static inline void trace_ll_set_mode(int mode)
{
DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, mode);
}

View File

@ -0,0 +1,23 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "esp_bit_defs.h"
#include "soc/dport_reg.h"
static inline void trace_ll_set_mem_block(int block)
{
DPORT_WRITE_PERI_REG(DPORT_PMS_OCCUPY_3_REG, BIT(block-4));
}

View File

@ -0,0 +1,24 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdlib.h>
#include "soc/dport_reg.h"
static inline void trace_ll_set_mem_block(int block)
{
// IDF-1785
abort();
}

View File

@ -4281,4 +4281,9 @@
#define DPORT_MMU_ADDRESS_MASK 0xff
#define TRACEMEM_MUX_PROBLK0_APPBLK1 0
#define TRACEMEM_MUX_BLK0_ONLY 1
#define TRACEMEM_MUX_BLK1_ONLY 2
#define TRACEMEM_MUX_PROBLK1_APPBLK0 3
#endif /*_SOC_DPORT_REG_H_ */

View File

@ -25,6 +25,10 @@ extern "C" {
#define DPORT_DATE_REG SYSTEM_DATE_REG
#define TRACEMEM_MUX_BLK0_NUM 19
#define TRACEMEM_MUX_BLK1_NUM 20
#define TRACEMEM_BLK_NUM2ADDR(_n_) (0x3FFB8000UL + 0x4000UL*((_n_)-4))
#ifndef __ASSEMBLER__
#include "dport_access.h"
#endif

View File

@ -1291,6 +1291,4 @@ extern "C" {
}
#endif
#endif /*_SOC_SENSITIVE_REG_H_ */

View File

@ -24,6 +24,10 @@ extern "C" {
#define DPORT_DATE_REG SYSTEM_DATE_REG
#define TRACEMEM_MUX_BLK0_NUM 19
#define TRACEMEM_MUX_BLK1_NUM 20
#define TRACEMEM_BLK_NUM2ADDR(_n_) (0x3FFB8000UL + 0x4000UL*((_n_)-4))
#ifndef __ASSEMBLER__
#include "dport_access.h"
#endif

View File

@ -8,12 +8,10 @@ if(BOOTLOADER_BUILD)
else()
set(priv_requires soc freertos)
set(srcs "eri.c"
"trax.c"
"xt_trax.c"
"xtensa_intr.c"
"xtensa_intr_asm.S"
"${target}/trax_init.c"
)
endif()
idf_component_register(SRCS ${srcs}

View File

@ -1,46 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include "esp_err.h"
#include "esp_log.h"
#include "trax.h"
#include "soc/dport_reg.h"
#include "sdkconfig.h"
#define TRACEMEM_MUX_PROBLK0_APPBLK1 0
#define TRACEMEM_MUX_BLK0_ONLY 1
#define TRACEMEM_MUX_BLK1_ONLY 2
#define TRACEMEM_MUX_PROBLK1_APPBLK0 3
static const char* __attribute__((unused)) TAG = "trax";
int trax_enable(trax_ena_select_t which)
{
#ifndef CONFIG_ESP32_TRAX
ESP_LOGE(TAG, "Trax_enable called, but trax is disabled in menuconfig!");
return ESP_ERR_NO_MEM;
#endif
#ifndef CONFIG_ESP32_TRAX_TWOBANKS
if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) return ESP_ERR_NO_MEM;
#endif
if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) {
DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, (which == TRAX_ENA_PRO_APP_SWAP)?TRACEMEM_MUX_PROBLK1_APPBLK0:TRACEMEM_MUX_PROBLK0_APPBLK1);
} else {
DPORT_WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, TRACEMEM_MUX_BLK0_ONLY);
}
DPORT_WRITE_PERI_REG(DPORT_PRO_TRACEMEM_ENA_REG, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_PRO));
DPORT_WRITE_PERI_REG(DPORT_APP_TRACEMEM_ENA_REG, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_APP));
return ESP_OK;
}

View File

@ -1,38 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include "esp_err.h"
#include "esp_log.h"
#include "trax.h"
#include "soc/sensitive_reg.h"
#include "sdkconfig.h"
#define TRACEMEM_MUX_BLK0_NUM 19
#define TRACEMEM_MUX_BLK1_NUM 20
static const char* __attribute__((unused)) TAG = "trax";
int trax_enable(trax_ena_select_t which)
{
#ifndef CONFIG_ESP32S2_TRAX
ESP_LOGE(TAG, "Trax_enable called, but trax is disabled in menuconfig!");
return ESP_ERR_NO_MEM;
#endif
if (which != TRAX_ENA_PRO) {
return ESP_ERR_INVALID_ARG;
}
REG_WRITE(DPORT_PMS_OCCUPY_3_REG, BIT(TRACEMEM_MUX_BLK1_NUM-4));
return ESP_OK;
}

View File

@ -1,40 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include "esp_attr.h"
#include "esp_err.h"
#include "esp_log.h"
#include "trax.h"
#include "soc/sensitive_reg.h"
#include "sdkconfig.h"
#define TRACEMEM_MUX_BLK0_NUM 19
#define TRACEMEM_MUX_BLK1_NUM 20
static const char *__attribute__((unused)) TAG = "trax";
// IDF-1785
int trax_enable(trax_ena_select_t which)
{
#ifndef CONFIG_ESP32S3_TRAX
ESP_LOGE(TAG, "Trax_enable called, but trax is disabled in menuconfig!");
return ESP_ERR_NO_MEM;
#endif
if (which != TRAX_ENA_PRO) {
return ESP_ERR_INVALID_ARG;
}
// REG_WRITE(DPORT_PMS_OCCUPY_3_REG, BIT(TRACEMEM_MUX_BLK1_NUM-4));
return ESP_OK;
}

View File

@ -0,0 +1,54 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdbool.h>
#include "eri.h"
#include "xtensa-debug-module.h"
// Low-level Xtensa TRAX utils
/**
* @brief Start a Trax trace on the current CPU with instructions as unit of delay.
* Memory blocks to be used as Trax memory must be enabled before
* calling this function, if needed.
*/
void xt_trax_start_trace_instructions(void);
/**
* @brief Start a Trax trace on the current CPU with words as unit of delay.
* Memory blocks to be used as Trax memory must be enabled before
* calling this function, if needed.
*/
void xt_trax_start_trace_words(void);
/**
* @brief Check if Trax trace is active on current CPU.
*
* @return bool. Return true if trace is active.
*/
bool xt_trax_trace_is_active(void);
/**
* @brief Trigger a Trax trace stop after the indicated delay. If this is called
* before and the previous delay hasn't ended yet, this will overwrite
* that delay with the new value. The delay will always start at the time
* the function is called.
*
* @param delay : The delay to stop the trace in, in the unit indicated to
* trax_start_trace. Note: the trace memory has 4K words available.
*/
void xt_trax_trigger_traceend_after_delay(int delay);

View File

@ -13,51 +13,44 @@
// limitations under the License.
#include <stdio.h>
#include "esp_log.h"
#include <stdbool.h>
#include "esp_err.h"
#include "xtensa-debug-module.h"
#include "eri.h"
#include "trax.h"
#include "sdkconfig.h"
#if defined(CONFIG_ESP32_TRAX) || defined(CONFIG_ESP32S2_TRAX)
#define WITH_TRAX 1
#endif
static const char* TAG = "trax";
int trax_start_trace(trax_downcount_unit_t units_until_stop)
bool xt_trax_trace_is_active(void)
{
return eri_read(ERI_TRAX_TRAXSTAT)&TRAXSTAT_TRACT;
}
static void _xt_trax_start_trace(bool instructions)
{
#if !WITH_TRAX
ESP_EARLY_LOGE(TAG, "Trax_start_trace called, but trax is disabled in menuconfig!");
return ESP_ERR_NO_MEM;
#endif
uint32_t v;
if (eri_read(ERI_TRAX_TRAXSTAT)&TRAXSTAT_TRACT) {
ESP_EARLY_LOGI(TAG, "Stopping active trace first.");
//Trace is active. Stop trace.
eri_write(ERI_TRAX_DELAYCNT, 0);
eri_write(ERI_TRAX_TRAXCTRL, eri_read(ERI_TRAX_TRAXCTRL)|TRAXCTRL_TRSTP);
//ToDo: This will probably trigger a trace done interrupt. ToDo: Fix, but how? -JD
eri_write(ERI_TRAX_TRAXCTRL, 0);
}
eri_write(ERI_TRAX_PCMATCHCTRL, 31); //do not stop at any pc match
v=TRAXCTRL_TREN | TRAXCTRL_TMEN | TRAXCTRL_PTOWS | (1<<TRAXCTRL_SMPER_SHIFT);
if (units_until_stop == TRAX_DOWNCOUNT_INSTRUCTIONS) v|=TRAXCTRL_CNTU;
if (instructions) {
v|=TRAXCTRL_CNTU;
}
//Enable trace. This trace has no stop condition and will just keep on running.
eri_write(ERI_TRAX_TRAXCTRL, v);
return ESP_OK;
}
int trax_trigger_traceend_after_delay(int delay)
void xt_trax_start_trace_instructions(void)
{
_xt_trax_start_trace(true);
}
void xt_trax_start_trace_words(void)
{
_xt_trax_start_trace(false);
}
void xt_trax_trigger_traceend_after_delay(int delay)
{
#if !WITH_TRAX
ESP_EARLY_LOGE(TAG, "Trax_trigger_traceend_after_delay called, but trax is disabled in menuconfig!");
return ESP_ERR_NO_MEM;
#endif
eri_write(ERI_TRAX_DELAYCNT, delay);
eri_write(ERI_TRAX_TRAXCTRL, eri_read(ERI_TRAX_TRAXCTRL)|TRAXCTRL_TRSTP);
return ESP_OK;
//ToDo: This will probably trigger a trace done interrupt. ToDo: Fix, but how? -JD
eri_write(ERI_TRAX_TRAXCTRL, 0);
}