ESP32-S31 uses the same trace encoder IP as ESP32-P4. Of the E-Trace v2.0 parameters the two targets report, only privilege_width_p differs (1 on P4, 2 on S31), and it affects both the sync packet layout and the filter's privilege selector. - Add the SOC_RISCV_TRACE_* caps for ESP32-S31 along with the esp32s31 LL, and declare TRACE0/TRACE1 in the target's trace_struct.h. - Carry privilege_width_p as SOC_RISCV_TRACE_PRIV_WIDTH so the sync packet decoder can locate the address field, which starts one bit later on targets that implement supervisor mode. - Use the RISC-V architectural privilege encoding (0 user, 1 supervisor, 3 machine) in the public filter enum so the values do not change per target, and let each LL narrow them to its own register field. - Add riscv_trace_ll_priv_is_supported() per target, so a privilege level the selector cannot represent is rejected with ESP_ERR_NOT_SUPPORTED rather than being silently narrowed to a different level. It lives next to the narrowing code so the two cannot drift apart. - Fix trace buffer allocation on targets whose internal RAM is not reached through a cache. esp_cache_get_alignment() reports 0 there, which underflowed the size check and failed every allocation. Align base and size to the larger of the reported cache line and the encoder's 4-byte write granularity.
2.1 KiB
RISC-V Trace Encoder Driver
Overview
The esp_riscv_trace component provides the public driver API for the RISC-V
trace encoder peripheral. The driver is enabled by
CONFIG_ESP_RISCV_TRACE_ENABLE and creates one encoder handle per selected core
during startup auto-initialization.
Applications can override the weak esp_riscv_trace_get_user_config(int core_id)
function to customize the startup configuration per core (each encoder can be
configured independently), or use Kconfig defaults through
ESP_RISCV_TRACE_DEFAULT_CONFIG().
State Transition
stateDiagram-v2
[*] --> created: startup auto-init
created --> started: esp_riscv_trace_start
started --> stopped: esp_riscv_trace_stop
stopped --> started: esp_riscv_trace_start
esp_riscv_trace_set_filter() and esp_riscv_trace_get_buffer() are only valid
while the encoder is not started. esp_riscv_trace_get_status() can be used to
read a coherent status snapshot.
Concurrency
Public driver APIs are serialized per trace core with a task-level lock. They are task-context APIs and must not be called from ISR context.
The driver keeps the lifecycle state check and the corresponding HAL register operation under the same per-core lock. This prevents concurrent callers from double-starting an encoder, racing a stop against filter programming, or reading the buffer before a stop has completed its cache synchronization.
Buffer and Trace Stream Notes
The trace buffer must be reachable by the trace encoder AHB master. Driver allocated buffers are placed in internal RAM or PSRAM according to configuration, and are cache-line aligned when that memory is reached through a data cache. Caller-provided buffers are validated for reachable memory and cache-line alignment.
In loop memory mode, wrapped buffers need periodic resynchronization packets to remain decodable after the original start sync has been overwritten.
Dependencies
This driver depends on the RISC-V trace HAL (part of the hal component) and
currently targets SoCs that support the RISC-V trace encoder peripheral.