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
@@ -14,9 +14,11 @@
#include "esp_check.h"
#include "esp_private/esp_cache_private.h"
#include "esp_private/startup_internal.h"
#include "esp_private/periph_ctrl.h"
#include "esp_cpu.h"
#include "soc/soc_caps.h"
#include "hal/riscv_trace_hal.h"
#include "hal/riscv_trace_ll.h"
#include "esp_riscv_trace.h"
#include "esp_riscv_trace_priv.h"
@@ -387,6 +389,12 @@ ESP_SYSTEM_INIT_FN(esp_riscv_trace_early_init, SECONDARY, ESP_SYSTEM_INIT_ALL_CO
int core_id = esp_cpu_get_core_id();
esp_riscv_trace_config_t config = esp_riscv_trace_get_user_config(core_id);
// Enable the clocks and reset the encoder core before accessing its registers.
PERIPH_RCC_ATOMIC() {
riscv_trace_ll_enable_bus_clock(true);
riscv_trace_ll_reset_register(core_id);
}
if (!is_valid_core_mask(config.core_mask)) {
ESP_EARLY_LOGE(TAG, "invalid core mask");
return ESP_ERR_INVALID_ARG;
@@ -1,3 +1,4 @@
# CONFIG_ESP_TASK_WDT_INIT is not set
CONFIG_ESP_RISCV_TRACE_ENABLE=y
CONFIG_ESP_RISCV_TRACE_RESYNC_MODE_PACKET=y
CONFIG_ESP_RISCV_TRACE_RESYNC_THRESHOLD=32