feat(esp_riscv_trace): add ESP32-S31 support

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.
This commit is contained in:
Erhan Kurubas
2026-08-06 13:08:26 +08:00
committed by BOT
parent a063a8440f
commit 3dfd8f0154
16 changed files with 356 additions and 21 deletions
@@ -1,5 +1,5 @@
| Supported Targets | ESP32-P4 |
| ----------------- | -------- |
| Supported Targets | ESP32-P4 | ESP32-S31 |
| ----------------- | -------- | --------- |
# RISC-V Trace Basic Test App
@@ -16,12 +16,12 @@ bool decode_sync_pc(const uint8_t *payload, size_t payload_len, uint32_t *pc)
if ((payload[0] & 0x3) != 3 || ((payload[0] >> 2) & 0x3) != 0) {
return false;
}
/* Address is 31 bits starting at payload bit 6; byte address is addr << 1. */
/* Address is 31 bits starting at TRACE_SYNC_ADDR_BIT_OFFSET; byte address is addr << 1. */
uint64_t v = 0;
for (int i = 0; i < TRACE_SYNC_PAYLOAD_BYTES; i++) {
v |= (uint64_t)payload[i] << (8 * i);
}
*pc = (uint32_t)((v >> 6) & 0x7FFFFFFFu) << 1;
*pc = (uint32_t)((v >> TRACE_SYNC_ADDR_BIT_OFFSET) & 0x7FFFFFFFu) << 1;
return true;
}
@@ -9,6 +9,7 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "soc/soc_caps.h"
#include "esp_riscv_trace.h"
#ifdef __cplusplus
@@ -22,6 +23,9 @@ extern "C" {
#define TRACE_PACKET_MIN_LEN 4 /* prefix (3) + >=1 payload byte */
#define TRACE_PACKET_MAX_LEN 13 /* prefix (3) + <=10 payload bytes */
#define TRACE_SYNC_PAYLOAD_BYTES 5
/* Sync payload layout: format(2) + subformat(2) + branch(1) + privilege(N) + address(31), where N
* is the encoder's privilege_width_p. Targets with supervisor mode push the address up one bit. */
#define TRACE_SYNC_ADDR_BIT_OFFSET (2 + 2 + 1 + SOC_RISCV_TRACE_PRIV_WIDTH)
#define TRACE_ANCHOR_ZERO_RUN_BYTES 14 /* an anchor tag is >=14 zero bytes */
#define TRACE_TEST_STOP_TIMEOUT_US 1000000