fix(riscv_trace): protect shared RCC register access with PERIPH_RCC_ATOMIC

riscv_trace_ll_enable_bus_clock and riscv_trace_ll_reset_register operate
on shared HP_SYS_CLKRST registers and were called concurrently from both
cores during SECONDARY init, creating RMW race conditions.

Move the clock/reset logic out of the HAL layer into
esp_riscv_trace_early_init, protected by PERIPH_RCC_ATOMIC() spinlock.
Wrap the LL functions with macros that enforce the caller must be inside
a PERIPH_RCC_ATOMIC() critical section at compile time.
This commit is contained in:
morris
2026-07-22 19:02:58 +08:00
parent 480d5f2559
commit 49fba58f08
4 changed files with 21 additions and 12 deletions
@@ -30,14 +30,19 @@ static inline trace_dev_t *riscv_trace_ll_get_hw(int core)
*--------------------------------------------------------------------------*/
/** @brief Enable or disable the common TRACE CPU and system clocks. */
static inline void riscv_trace_ll_enable_bus_clock(bool enable)
static inline void _riscv_trace_ll_enable_bus_clock(bool enable)
{
HP_SYS_CLKRST.soc_clk_ctrl0.reg_trace_cpu_clk_en = enable;
HP_SYS_CLKRST.soc_clk_ctrl0.reg_trace_sys_clk_en = enable;
}
#define riscv_trace_ll_enable_bus_clock(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_riscv_trace_ll_enable_bus_clock(__VA_ARGS__); \
} while (0)
/** @brief Assert and release the reset of the given encoder core. */
static inline void riscv_trace_ll_reset_register(int core)
static inline void _riscv_trace_ll_reset_register(int core)
{
if (core == 0) {
HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_coretrace0 = 1;
@@ -48,6 +53,11 @@ static inline void riscv_trace_ll_reset_register(int core)
}
}
#define riscv_trace_ll_reset_register(...) do { \
(void)__DECLARE_RCC_ATOMIC_ENV; \
_riscv_trace_ll_reset_register(__VA_ARGS__); \
} while (0)
/** @brief Enable the per-module register clock gate. */
static inline void riscv_trace_ll_enable_module_clock(trace_dev_t *hw, bool enable)
{