diff --git a/components/esp_hal_debug_assist/esp32h21/include/hal/riscv_trace_ll.h b/components/esp_hal_debug_assist/esp32h21/include/hal/riscv_trace_ll.h new file mode 100644 index 00000000000..cd301883be0 --- /dev/null +++ b/components/esp_hal_debug_assist/esp32h21/include/hal/riscv_trace_ll.h @@ -0,0 +1,163 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * ESP32-H21 has a v1.0-spec trace encoder: no filter unit, no encoder config + * register (delta/full address, stall, halt, reset, debug trigger) and no AHB + * config register, so the LL only exposes the base register set. Its resync + * mode field is 1 bit with a different encoding than the v2.0 targets, handled + * in riscv_trace_ll_set_resync_mode() below. + */ + +#pragma once + +#include +#include + +#include "soc/trace_reg.h" +#include "soc/trace_struct.h" +#include "soc/pcr_struct.h" +#include "hal/assert.h" +#include "hal/riscv_trace_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Return the register block for the given core. */ +static inline trace_dev_t *riscv_trace_ll_get_hw(int core) +{ + HAL_ASSERT(core == 0); + (void)core; + return &TRACE; +} + +/*--------------------------------------------------------------------------- + * Clock and reset + *--------------------------------------------------------------------------*/ + +/** @brief Enable or disable the TRACE clock. */ +static inline void riscv_trace_ll_enable_bus_clock(bool enable) +{ + PCR.trace_conf.trace_clk_en = enable; +} + +/** @brief Assert and release the reset of the encoder. */ +static inline void riscv_trace_ll_reset_register(int core) +{ + (void)core; + PCR.trace_conf.trace_rst_en = 1; + PCR.trace_conf.trace_rst_en = 0; +} + +/** @brief Enable the per-module register clock gate. */ +static inline void riscv_trace_ll_enable_module_clock(trace_dev_t *hw, bool enable) +{ + hw->clock_gate.clk_en = enable; +} + +/*--------------------------------------------------------------------------- + * Memory configuration + *--------------------------------------------------------------------------*/ + +static inline void riscv_trace_ll_set_mem_start_addr(trace_dev_t *hw, uint32_t addr) +{ + hw->mem_start_addr.mem_start_addr = addr; +} + +static inline void riscv_trace_ll_set_mem_end_addr(trace_dev_t *hw, uint32_t addr) +{ + hw->mem_end_addr.mem_end_addr = addr; +} + +static inline uint32_t riscv_trace_ll_get_mem_current_addr(trace_dev_t *hw) +{ + return hw->mem_current_addr.mem_current_addr; +} + +/** @brief Reload the current address from the start address. */ +static inline void riscv_trace_ll_update_mem_current_addr(trace_dev_t *hw) +{ + hw->mem_addr_update.mem_current_addr_update = 1; +} + +/*--------------------------------------------------------------------------- + * Status + *--------------------------------------------------------------------------*/ + +static inline uint32_t riscv_trace_ll_get_fifo_status(trace_dev_t *hw) +{ + return hw->fifo_status.val; +} + +/*--------------------------------------------------------------------------- + * Trigger, loop mode and restart + *--------------------------------------------------------------------------*/ + +static inline void riscv_trace_ll_trigger_on(trace_dev_t *hw) +{ + hw->trigger.trigger_on = 1; +} + +static inline void riscv_trace_ll_trigger_off(trace_dev_t *hw) +{ + hw->trigger.trigger_off = 1; +} + +static inline void riscv_trace_ll_set_mem_loop(trace_dev_t *hw, bool loop) +{ + hw->trigger.mem_loop = loop; +} + +static inline void riscv_trace_ll_set_restart_ena(trace_dev_t *hw, bool enable) +{ + hw->trigger.restart_ena = enable; +} + +/*--------------------------------------------------------------------------- + * Resynchronization + *--------------------------------------------------------------------------*/ + +/** @brief Whether the resync counter can represent the given mode. */ +static inline bool riscv_trace_ll_resync_mode_is_supported(uint32_t mode) +{ + // 1-bit field: this encoder always counts and has no "disabled" mode. + return mode == RISCV_TRACE_RESYNC_PACKET || mode == RISCV_TRACE_RESYNC_CYCLE; +} + +static inline void riscv_trace_ll_set_resync_mode(trace_dev_t *hw, uint32_t mode) +{ + // 1-bit field: 0 = count by cycle, 1 = count by packet. + hw->resync_prolonged.resync_mode = (mode == RISCV_TRACE_RESYNC_PACKET); +} + +static inline void riscv_trace_ll_set_resync_threshold(trace_dev_t *hw, uint32_t threshold) +{ + hw->resync_prolonged.resync_prolonged = threshold; +} + +/*--------------------------------------------------------------------------- + * Interrupts + *--------------------------------------------------------------------------*/ + +static inline void riscv_trace_ll_set_intr_ena(trace_dev_t *hw, uint32_t mask) +{ + hw->intr_ena.val = mask; +} + +static inline uint32_t riscv_trace_ll_get_intr_raw(trace_dev_t *hw) +{ + return hw->intr_raw.val; +} + +static inline void riscv_trace_ll_clear_intr(trace_dev_t *hw, uint32_t mask) +{ + hw->intr_clr.val = mask; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_riscv_trace/test_apps/basic/README.md b/components/esp_riscv_trace/test_apps/basic/README.md index 6d2d5a419b8..52f194e67f6 100644 --- a/components/esp_riscv_trace/test_apps/basic/README.md +++ b/components/esp_riscv_trace/test_apps/basic/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-P4 | ESP32-S31 | -| ----------------- | -------- | -------- | --------- | -------- | -------- | -------- | --------- | +| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S31 | +| ----------------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | --------- | # RISC-V Trace Basic Test App diff --git a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in index da21f9c0f22..b798b9856d5 100644 --- a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in @@ -143,6 +143,10 @@ config SOC_BOD_SUPPORTED bool default y +config SOC_RISCV_TRACE_SUPPORTED + bool + default y + config SOC_PMU_SUPPORTED bool default y @@ -1150,3 +1154,7 @@ config SOC_BLE_PERIODIC_ADV_WITH_RESPONSE config SOC_DEBUG_HAVE_OCD_STUB_BINS bool default y + +config SOC_RISCV_TRACE_PRIV_WIDTH + int + default 1 diff --git a/components/soc/esp32h21/include/soc/soc_caps.h b/components/soc/esp32h21/include/soc/soc_caps.h index 5789cdc4d45..42ebbd065b5 100644 --- a/components/soc/esp32h21/include/soc/soc_caps.h +++ b/components/soc/esp32h21/include/soc/soc_caps.h @@ -61,6 +61,7 @@ #define SOC_SECURE_BOOT_SUPPORTED 1 #define SOC_BOD_SUPPORTED 1 // #define SOC_APM_SUPPORTED 1 //TODO: [ESP32H21] IDF-11494 +#define SOC_RISCV_TRACE_SUPPORTED 1 #define SOC_PMU_SUPPORTED 1 #define SOC_RTC_TIMER_SUPPORTED 1 #define SOC_LP_AON_SUPPORTED 1 @@ -498,3 +499,6 @@ /*------------------------------------- DEBUG CAPS -------------------------------------*/ #define SOC_DEBUG_HAVE_OCD_STUB_BINS (1) + +/*-------------------------- RISC-V TRACE CAPS ------------------------------*/ +#define SOC_RISCV_TRACE_PRIV_WIDTH (1U) /*!< Bits in the privilege field (privilege_width_p) */