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
@@ -13,6 +13,7 @@
#include "soc/trace_struct.h" #include "soc/trace_struct.h"
#include "soc/hp_sys_clkrst_struct.h" #include "soc/hp_sys_clkrst_struct.h"
#include "hal/assert.h" #include "hal/assert.h"
#include "hal/riscv_trace_types.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -217,10 +218,15 @@ static inline void riscv_trace_ll_set_filter_control(trace_dev_t *hw, bool match
hw->filter_control.match_interrupt = match_interrupt; hw->filter_control.match_interrupt = match_interrupt;
} }
static inline void riscv_trace_ll_set_filter_match_control(trace_dev_t *hw, bool priv_choice, static inline bool riscv_trace_ll_priv_is_supported(uint32_t priv)
{
return priv == RISCV_TRACE_PRIV_USER || priv == RISCV_TRACE_PRIV_MACHINE;
}
static inline void riscv_trace_ll_set_filter_match_control(trace_dev_t *hw, uint32_t priv_choice,
bool intr_value, uint32_t ecause_choice) bool intr_value, uint32_t ecause_choice)
{ {
hw->filter_match_control.match_choice_privilege = priv_choice; hw->filter_match_control.match_choice_privilege = (priv_choice == RISCV_TRACE_PRIV_MACHINE);
hw->filter_match_control.match_value_interrupt = intr_value; hw->filter_match_control.match_value_interrupt = intr_value;
hw->filter_match_control.match_choice_ecause = ecause_choice; hw->filter_match_control.match_choice_ecause = ecause_choice;
} }
@@ -0,0 +1,265 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "soc/trace_reg.h"
#include "soc/trace_struct.h"
#include "soc/hp_sys_clkrst_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 || core == 1);
return core == 0 ? &TRACE0 : &TRACE1;
}
/*---------------------------------------------------------------------------
* Clock and reset
*--------------------------------------------------------------------------*/
static inline void _riscv_trace_ll_enable_bus_clock(bool enable)
{
HP_SYS_CLKRST.trace_ctrl0.reg_trace_cpu_clk_en = enable;
HP_SYS_CLKRST.trace_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)
static inline void _riscv_trace_ll_reset_register(int core)
{
if (core == 0) {
HP_SYS_CLKRST.trace_ctrl0.reg_trace0_rst_en = 1;
HP_SYS_CLKRST.trace_ctrl0.reg_trace0_rst_en = 0;
} else {
HP_SYS_CLKRST.trace_ctrl0.reg_trace1_rst_en = 1;
HP_SYS_CLKRST.trace_ctrl0.reg_trace1_rst_en = 0;
}
}
#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)
{
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;
}
/*---------------------------------------------------------------------------
* Encoder options (config register)
*--------------------------------------------------------------------------*/
static inline void riscv_trace_ll_set_full_address(trace_dev_t *hw, bool full)
{
hw->config.full_address = full;
}
static inline void riscv_trace_ll_set_stall_ena(trace_dev_t *hw, bool enable)
{
hw->config.stall_ena = enable;
}
static inline void riscv_trace_ll_set_halt_ena(trace_dev_t *hw, bool enable)
{
hw->config.halt_ena = enable;
}
static inline void riscv_trace_ll_set_reset_ena(trace_dev_t *hw, bool enable)
{
hw->config.reset_ena = enable;
}
static inline void riscv_trace_ll_set_dm_trigger_ena(trace_dev_t *hw, bool enable)
{
hw->config.dm_trigger_ena = enable;
}
/*---------------------------------------------------------------------------
* Resynchronization
*--------------------------------------------------------------------------*/
static inline void riscv_trace_ll_set_resync_mode(trace_dev_t *hw, uint32_t mode)
{
hw->resync_prolonged.resync_mode = mode;
}
static inline void riscv_trace_ll_set_resync_threshold(trace_dev_t *hw, uint32_t threshold)
{
hw->resync_prolonged.resync_prolonged = threshold;
}
/*---------------------------------------------------------------------------
* AHB configuration
*--------------------------------------------------------------------------*/
static inline void riscv_trace_ll_set_ahb_burst(trace_dev_t *hw, uint32_t hburst)
{
hw->ahb_config.hburst = hburst;
}
static inline void riscv_trace_ll_set_ahb_max_incr(trace_dev_t *hw, uint32_t max_incr)
{
hw->ahb_config.max_incr = max_incr;
}
/*---------------------------------------------------------------------------
* 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;
}
/*---------------------------------------------------------------------------
* Filter unit
*--------------------------------------------------------------------------*/
static inline void riscv_trace_ll_set_filter_en(trace_dev_t *hw, bool enable)
{
hw->filter_control.filter_en = enable;
}
static inline void riscv_trace_ll_set_filter_control(trace_dev_t *hw, bool match_comp,
bool match_privilege, bool match_ecause,
bool match_interrupt)
{
hw->filter_control.match_comp = match_comp;
hw->filter_control.match_privilege = match_privilege;
hw->filter_control.match_ecause = match_ecause;
hw->filter_control.match_interrupt = match_interrupt;
}
static inline bool riscv_trace_ll_priv_is_supported(uint32_t priv)
{
return priv == RISCV_TRACE_PRIV_USER || priv == RISCV_TRACE_PRIV_SUPERVISOR ||
priv == RISCV_TRACE_PRIV_MACHINE;
}
static inline void riscv_trace_ll_set_filter_match_control(trace_dev_t *hw, uint32_t priv_choice,
bool intr_value, uint32_t ecause_choice)
{
// This target implements the full architectural encoding, so no narrowing is needed.
hw->filter_match_control.match_choice_privilege = priv_choice;
hw->filter_match_control.match_value_interrupt = intr_value;
hw->filter_match_control.match_choice_ecause = ecause_choice;
}
static inline void riscv_trace_ll_set_p_comparator(trace_dev_t *hw, uint32_t input,
uint32_t function, bool notify)
{
hw->filter_comparator_control.p_input = input;
hw->filter_comparator_control.p_function = function;
hw->filter_comparator_control.p_notify = notify;
}
static inline void riscv_trace_ll_set_s_comparator(trace_dev_t *hw, uint32_t input,
uint32_t function, bool notify)
{
hw->filter_comparator_control.s_input = input;
hw->filter_comparator_control.s_function = function;
hw->filter_comparator_control.s_notify = notify;
}
static inline void riscv_trace_ll_set_match_mode(trace_dev_t *hw, uint32_t mode)
{
hw->filter_comparator_control.match_mode = mode;
}
static inline void riscv_trace_ll_set_p_match_value(trace_dev_t *hw, uint32_t value)
{
hw->filter_p_comparator_match.p_match = value;
}
static inline void riscv_trace_ll_set_s_match_value(trace_dev_t *hw, uint32_t value)
{
hw->filter_s_comparator_match.s_match = value;
}
#ifdef __cplusplus
}
#endif
@@ -53,7 +53,7 @@ typedef struct {
bool match_privilege; /*!< Gate matching on the privilege level (match_privilege) */ bool match_privilege; /*!< Gate matching on the privilege level (match_privilege) */
bool match_ecause; /*!< Match from an exception cause (match_ecause) */ bool match_ecause; /*!< Match from an exception cause (match_ecause) */
bool match_interrupt; /*!< Match from an interrupt trap (match_interrupt) */ bool match_interrupt; /*!< Match from an interrupt trap (match_interrupt) */
bool privilege_machine; /*!< match_choice_privilege: true = machine, false = user */ uint32_t privilege; /*!< match_choice_privilege (riscv_trace_priv_t) */
bool interrupt_itype2; /*!< match_value_interrupt: true = itype 2, false = itype 1 */ bool interrupt_itype2; /*!< match_value_interrupt: true = itype 2, false = itype 1 */
uint32_t ecause; /*!< match_choice_ecause (6-bit exception cause code) */ uint32_t ecause; /*!< match_choice_ecause (6-bit exception cause code) */
riscv_trace_hal_comparator_t primary; /*!< Primary comparator */ riscv_trace_hal_comparator_t primary; /*!< Primary comparator */
@@ -21,6 +21,19 @@ typedef enum {
RISCV_TRACE_INTR_MEM_FULL = BIT(1), /*!< Trace memory region became full. */ RISCV_TRACE_INTR_MEM_FULL = BIT(1), /*!< Trace memory region became full. */
} riscv_trace_intr_t; } riscv_trace_intr_t;
/**
* @brief Privilege level selected by the filter privilege qualifier.
*
* Values are the RISC-V architectural privilege encoding. Targets whose
* match_choice_privilege field is narrower implement only a subset, and their
* LL narrows the value when writing the register.
*/
typedef enum {
RISCV_TRACE_PRIV_USER = 0, /*!< User mode */
RISCV_TRACE_PRIV_SUPERVISOR = 1, /*!< Supervisor mode */
RISCV_TRACE_PRIV_MACHINE = 3, /*!< Machine mode */
} riscv_trace_priv_t;
/** /**
* @brief Trace encoder work-status field. * @brief Trace encoder work-status field.
* *
@@ -163,7 +163,7 @@ void riscv_trace_hal_set_filter(riscv_trace_hal_context_t *ctx, const riscv_trac
riscv_trace_ll_set_filter_control(ctx->dev, config->match_comparators, config->match_privilege, riscv_trace_ll_set_filter_control(ctx->dev, config->match_comparators, config->match_privilege,
config->match_ecause, config->match_interrupt); config->match_ecause, config->match_interrupt);
riscv_trace_ll_set_filter_match_control(ctx->dev, config->privilege_machine, riscv_trace_ll_set_filter_match_control(ctx->dev, config->privilege,
config->interrupt_itype2, config->ecause); config->interrupt_itype2, config->ecause);
riscv_trace_ll_set_p_comparator(ctx->dev, config->primary.input, config->primary.function, riscv_trace_ll_set_p_comparator(ctx->dev, config->primary.input, config->primary.function,
+4 -3
View File
@@ -39,9 +39,10 @@ the buffer before a stop has completed its cache synchronization.
## Buffer and Trace Stream Notes ## Buffer and Trace Stream Notes
The trace buffer must be reachable by the trace encoder AHB master. Driver The trace buffer must be reachable by the trace encoder AHB master. Driver
allocated buffers are cache-line aligned and placed in internal RAM or PSRAM allocated buffers are placed in internal RAM or PSRAM according to
according to configuration. Caller-provided buffers are validated for reachable configuration, and are cache-line aligned when that memory is reached through a
memory and cache-line alignment. 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 In loop memory mode, wrapped buffers need periodic resynchronization packets to
remain decodable after the original start sync has been overwritten. remain decodable after the original start sync has been overwritten.
@@ -83,10 +83,15 @@ typedef enum {
ESP_RISCV_TRACE_FILTER_MODE_RANGE = 3, /*!< Start when P matches, continue until S matches */ ESP_RISCV_TRACE_FILTER_MODE_RANGE = 3, /*!< Start when P matches, continue until S matches */
} esp_riscv_trace_filter_mode_t; } esp_riscv_trace_filter_mode_t;
/** @brief Privilege level selected by the privilege qualifier. */ /**
* @brief Privilege level selected by the privilege qualifier.
*
* Values are the RISC-V architectural privilege encoding, so they stay the same on every target.
*/
typedef enum { typedef enum {
ESP_RISCV_TRACE_FILTER_PRIV_USER = 0, /*!< User mode */ ESP_RISCV_TRACE_FILTER_PRIV_USER = 0, /*!< User mode */
ESP_RISCV_TRACE_FILTER_PRIV_MACHINE = 1, /*!< Machine mode */ ESP_RISCV_TRACE_FILTER_PRIV_SUPERVISOR = 1, /*!< Supervisor mode; needs SOC_RISCV_TRACE_PRIV_WIDTH >= 2 */
ESP_RISCV_TRACE_FILTER_PRIV_MACHINE = 3, /*!< Machine mode */
} esp_riscv_trace_filter_priv_t; } esp_riscv_trace_filter_priv_t;
/** @brief One filter comparator. */ /** @brief One filter comparator. */
@@ -6,8 +6,10 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/param.h>
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "esp_heap_caps.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_err.h" #include "esp_err.h"
#include "esp_cache.h" #include "esp_cache.h"
@@ -27,7 +29,7 @@
#define ESP_RISCV_TRACE_BUFFER_CAPS_INTERNAL (MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) #define ESP_RISCV_TRACE_BUFFER_CAPS_INTERNAL (MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
#define ESP_RISCV_TRACE_BUFFER_CAPS_EXTERNAL (MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT) #define ESP_RISCV_TRACE_BUFFER_CAPS_EXTERNAL (MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT)
#define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) #define ESP_RISCV_TRACE_BUFFER_ALIGNMENT 4
static const char *TAG = "esp_riscv_trace"; static const char *TAG = "esp_riscv_trace";
@@ -38,13 +40,15 @@ static uint8_t *alloc_aligned_buffer(size_t requested, uint32_t caps, size_t *ou
{ {
*out_size = 0; *out_size = 0;
size_t cache_line = 0; size_t cache_alignment = 0;
ESP_RETURN_ON_FALSE(esp_cache_get_alignment(caps, &cache_line) == ESP_OK, NULL, TAG, ESP_RETURN_ON_FALSE(esp_cache_get_alignment(caps, &cache_alignment) == ESP_OK, NULL, TAG,
"failed to get buffer alignment"); "failed to get buffer alignment");
ESP_RETURN_ON_FALSE(requested <= SIZE_MAX - (cache_line - 1), NULL, TAG, size_t alignment = MAX(cache_alignment, ESP_RISCV_TRACE_BUFFER_ALIGNMENT);
ESP_RETURN_ON_FALSE(requested <= SIZE_MAX - (alignment - 1), NULL, TAG,
"trace buffer size too large"); "trace buffer size too large");
size_t size = ALIGN_UP(requested, cache_line); size_t size = ESP_ALIGN_UP(requested, alignment);
uint8_t *buf = heap_caps_calloc(1, size, caps | MALLOC_CAP_CACHE_ALIGNED); uint8_t *buf = heap_caps_aligned_calloc(alignment, 1, size, caps);
ESP_RETURN_ON_FALSE(buf != NULL, NULL, TAG, "failed to allocate buffer"); ESP_RETURN_ON_FALSE(buf != NULL, NULL, TAG, "failed to allocate buffer");
*out_size = size; *out_size = size;
return buf; return buf;
@@ -140,8 +144,11 @@ static esp_err_t validate_filter_config(const esp_riscv_trace_filter_config_t *c
} }
if (config->match_privilege) { if (config->match_privilege) {
ESP_RETURN_ON_FALSE(config->privilege == ESP_RISCV_TRACE_FILTER_PRIV_USER || ESP_RETURN_ON_FALSE(config->privilege == ESP_RISCV_TRACE_FILTER_PRIV_USER ||
config->privilege == ESP_RISCV_TRACE_FILTER_PRIV_SUPERVISOR ||
config->privilege == ESP_RISCV_TRACE_FILTER_PRIV_MACHINE, config->privilege == ESP_RISCV_TRACE_FILTER_PRIV_MACHINE,
ESP_ERR_INVALID_ARG, TAG, "invalid filter privilege"); ESP_ERR_INVALID_ARG, TAG, "invalid filter privilege");
ESP_RETURN_ON_FALSE(riscv_trace_ll_priv_is_supported((uint32_t)config->privilege),
ESP_ERR_NOT_SUPPORTED, TAG, "filter privilege not supported on this target");
} }
if (config->match_ecause) { if (config->match_ecause) {
ESP_RETURN_ON_FALSE(config->ecause <= 0x3F, ESP_ERR_INVALID_ARG, TAG, "filter ecause out of range"); ESP_RETURN_ON_FALSE(config->ecause <= 0x3F, ESP_ERR_INVALID_ARG, TAG, "filter ecause out of range");
@@ -349,7 +356,7 @@ esp_err_t esp_riscv_trace_set_filter(esp_riscv_trace_core_t core_id, const esp_r
hal_filter.match_mode = (uint32_t)config->mode; hal_filter.match_mode = (uint32_t)config->mode;
} }
if (config->match_privilege) { if (config->match_privilege) {
hal_filter.privilege_machine = (config->privilege == ESP_RISCV_TRACE_FILTER_PRIV_MACHINE); hal_filter.privilege = (uint32_t)config->privilege;
} }
if (config->match_ecause) { if (config->match_ecause) {
hal_filter.ecause = config->ecause; hal_filter.ecause = config->ecause;
@@ -1,5 +1,5 @@
| Supported Targets | ESP32-P4 | | Supported Targets | ESP32-P4 | ESP32-S31 |
| ----------------- | -------- | | ----------------- | -------- | --------- |
# RISC-V Trace Basic Test App # 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) { if ((payload[0] & 0x3) != 3 || ((payload[0] >> 2) & 0x3) != 0) {
return false; 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; uint64_t v = 0;
for (int i = 0; i < TRACE_SYNC_PAYLOAD_BYTES; i++) { for (int i = 0; i < TRACE_SYNC_PAYLOAD_BYTES; i++) {
v |= (uint64_t)payload[i] << (8 * 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; return true;
} }
@@ -9,6 +9,7 @@
#include <stdint.h> #include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include "soc/soc_caps.h"
#include "esp_riscv_trace.h" #include "esp_riscv_trace.h"
#ifdef __cplusplus #ifdef __cplusplus
@@ -22,6 +23,9 @@ extern "C" {
#define TRACE_PACKET_MIN_LEN 4 /* prefix (3) + >=1 payload byte */ #define TRACE_PACKET_MIN_LEN 4 /* prefix (3) + >=1 payload byte */
#define TRACE_PACKET_MAX_LEN 13 /* prefix (3) + <=10 payload bytes */ #define TRACE_PACKET_MAX_LEN 13 /* prefix (3) + <=10 payload bytes */
#define TRACE_SYNC_PAYLOAD_BYTES 5 #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_ANCHOR_ZERO_RUN_BYTES 14 /* an anchor tag is >=14 zero bytes */
#define TRACE_TEST_STOP_TIMEOUT_US 1000000 #define TRACE_TEST_STOP_TIMEOUT_US 1000000
@@ -1950,3 +1950,7 @@ config SOC_RISCV_TRACE_AHB_CONFIGURABLE
config SOC_RISCV_TRACE_FILTER_SUPPORTED config SOC_RISCV_TRACE_FILTER_SUPPORTED
bool bool
default y default y
config SOC_RISCV_TRACE_PRIV_WIDTH
int
default 1
@@ -746,3 +746,4 @@
#define SOC_RISCV_TRACE_HAS_CONFIG_REG (1) /*!< Has the encoder config register */ #define SOC_RISCV_TRACE_HAS_CONFIG_REG (1) /*!< Has the encoder config register */
#define SOC_RISCV_TRACE_AHB_CONFIGURABLE (1) /*!< AHB write master is configurable */ #define SOC_RISCV_TRACE_AHB_CONFIGURABLE (1) /*!< AHB write master is configurable */
#define SOC_RISCV_TRACE_FILTER_SUPPORTED (1) /*!< Has the filter unit */ #define SOC_RISCV_TRACE_FILTER_SUPPORTED (1) /*!< Has the filter unit */
#define SOC_RISCV_TRACE_PRIV_WIDTH (1U) /*!< Bits in the privilege field (privilege_width_p) */
@@ -359,6 +359,10 @@ config SOC_SPI_EXTERNAL_NOR_FLASH_SUPPORTED
bool bool
default y default y
config SOC_RISCV_TRACE_SUPPORTED
bool
default y
config SOC_EMAC_SUPPORT_1000M config SOC_EMAC_SUPPORT_1000M
bool bool
default y default y
@@ -1854,3 +1858,19 @@ config SOC_TEMPERATURE_SENSOR_SUPPORT_SLEEP_RETENTION
config SOC_DEBUG_HAVE_OCD_STUB_BINS config SOC_DEBUG_HAVE_OCD_STUB_BINS
bool bool
default y default y
config SOC_RISCV_TRACE_HAS_CONFIG_REG
bool
default y
config SOC_RISCV_TRACE_AHB_CONFIGURABLE
bool
default y
config SOC_RISCV_TRACE_FILTER_SUPPORTED
bool
default y
config SOC_RISCV_TRACE_PRIV_WIDTH
int
default 2
@@ -113,6 +113,7 @@
#define SOC_JPEG_CODEC_SUPPORTED 1 #define SOC_JPEG_CODEC_SUPPORTED 1
#define SOC_EMAC_SUPPORTED 1 #define SOC_EMAC_SUPPORTED 1
#define SOC_SPI_EXTERNAL_NOR_FLASH_SUPPORTED 1 #define SOC_SPI_EXTERNAL_NOR_FLASH_SUPPORTED 1
#define SOC_RISCV_TRACE_SUPPORTED 1
/*-------------------------- EMAC CAPS ----------------------------------------*/ /*-------------------------- EMAC CAPS ----------------------------------------*/
#define SOC_EMAC_SUPPORT_1000M (1) /*!< EMAC Supports 1000Mbps mode */ #define SOC_EMAC_SUPPORT_1000M (1) /*!< EMAC Supports 1000Mbps mode */
@@ -690,3 +691,9 @@
/*------------------------------------- DEBUG CAPS -------------------------------------*/ /*------------------------------------- DEBUG CAPS -------------------------------------*/
#define SOC_DEBUG_HAVE_OCD_STUB_BINS (1) #define SOC_DEBUG_HAVE_OCD_STUB_BINS (1)
/*-------------------------- RISC-V TRACE CAPS ------------------------------*/
#define SOC_RISCV_TRACE_HAS_CONFIG_REG (1) /*!< Has the encoder config register */
#define SOC_RISCV_TRACE_AHB_CONFIGURABLE (1) /*!< AHB write master is configurable */
#define SOC_RISCV_TRACE_FILTER_SUPPORTED (1) /*!< Has the filter unit */
#define SOC_RISCV_TRACE_PRIV_WIDTH (2U) /*!< Bits in the privilege field (privilege_width_p) */
@@ -492,6 +492,8 @@ typedef struct {
volatile trace_date_reg_t date; volatile trace_date_reg_t date;
} trace_dev_t; } trace_dev_t;
extern trace_dev_t TRACE0;
extern trace_dev_t TRACE1;
#ifndef __cplusplus #ifndef __cplusplus
_Static_assert(sizeof(trace_dev_t) == 0x400, "Invalid size of trace_dev_t structure"); _Static_assert(sizeof(trace_dev_t) == 0x400, "Invalid size of trace_dev_t structure");