feat(hal): Add RISC-V trace register read-back accessors

This commit is contained in:
Erhan Kurubas
2026-09-03 08:20:11 +02:00
parent 5b4a90da6e
commit e0ffa602f7
10 changed files with 197 additions and 13 deletions
@@ -104,6 +104,11 @@ static inline void riscv_trace_ll_set_mem_loop(trace_dev_t *hw, bool loop)
hw->trigger.mem_loop = loop;
}
static inline bool riscv_trace_ll_get_mem_loop(trace_dev_t *hw)
{
return hw->trigger.mem_loop;
}
static inline void riscv_trace_ll_set_restart_ena(trace_dev_t *hw, bool enable)
{
hw->trigger.restart_ena = enable;
@@ -118,6 +123,11 @@ static inline void riscv_trace_ll_set_full_address(trace_dev_t *hw, bool full)
hw->config.full_address = full;
}
static inline bool riscv_trace_ll_get_full_address(trace_dev_t *hw)
{
return hw->config.full_address;
}
static inline void riscv_trace_ll_set_stall_ena(trace_dev_t *hw, bool enable)
{
hw->config.stall_ena = enable;
@@ -154,11 +164,21 @@ static inline void riscv_trace_ll_set_resync_mode(trace_dev_t *hw, uint32_t mode
hw->resync_prolonged.resync_mode = mode;
}
static inline uint32_t riscv_trace_ll_get_resync_mode(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_mode;
}
static inline void riscv_trace_ll_set_resync_threshold(trace_dev_t *hw, uint32_t threshold)
{
hw->resync_prolonged.resync_prolonged = threshold;
}
static inline uint32_t riscv_trace_ll_get_resync_threshold(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_prolonged;
}
/*---------------------------------------------------------------------------
* AHB configuration
*--------------------------------------------------------------------------*/
@@ -219,7 +239,7 @@ static inline bool riscv_trace_ll_priv_is_supported(uint32_t priv)
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 has no supervisor mode, so the selector is 1 bit: 0 = user, 1 = machine.
/* Target has no supervisor mode. 0 = user, 1 = machine. */
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_choice_ecause = ecause_choice;
@@ -112,6 +112,11 @@ static inline void riscv_trace_ll_set_mem_loop(trace_dev_t *hw, bool loop)
hw->trigger.mem_loop = loop;
}
static inline bool riscv_trace_ll_get_mem_loop(trace_dev_t *hw)
{
return hw->trigger.mem_loop;
}
static inline void riscv_trace_ll_set_restart_ena(trace_dev_t *hw, bool enable)
{
hw->trigger.restart_ena = enable;
@@ -134,11 +139,21 @@ static inline void riscv_trace_ll_set_resync_mode(trace_dev_t *hw, uint32_t mode
hw->resync_prolonged.resync_mode = (mode == RISCV_TRACE_RESYNC_PACKET);
}
static inline uint32_t riscv_trace_ll_get_resync_mode(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_mode ? RISCV_TRACE_RESYNC_PACKET : RISCV_TRACE_RESYNC_CYCLE;
}
static inline void riscv_trace_ll_set_resync_threshold(trace_dev_t *hw, uint32_t threshold)
{
hw->resync_prolonged.resync_prolonged = threshold;
}
static inline uint32_t riscv_trace_ll_get_resync_threshold(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_prolonged;
}
/*---------------------------------------------------------------------------
* Interrupts
*--------------------------------------------------------------------------*/
@@ -104,6 +104,11 @@ static inline void riscv_trace_ll_set_mem_loop(trace_dev_t *hw, bool loop)
hw->trigger.mem_loop = loop;
}
static inline bool riscv_trace_ll_get_mem_loop(trace_dev_t *hw)
{
return hw->trigger.mem_loop;
}
static inline void riscv_trace_ll_set_restart_ena(trace_dev_t *hw, bool enable)
{
hw->trigger.restart_ena = enable;
@@ -118,6 +123,11 @@ static inline void riscv_trace_ll_set_full_address(trace_dev_t *hw, bool full)
hw->config.full_address = full;
}
static inline bool riscv_trace_ll_get_full_address(trace_dev_t *hw)
{
return hw->config.full_address;
}
static inline void riscv_trace_ll_set_stall_ena(trace_dev_t *hw, bool enable)
{
hw->config.stall_ena = enable;
@@ -154,11 +164,21 @@ static inline void riscv_trace_ll_set_resync_mode(trace_dev_t *hw, uint32_t mode
hw->resync_prolonged.resync_mode = mode;
}
static inline uint32_t riscv_trace_ll_get_resync_mode(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_mode;
}
static inline void riscv_trace_ll_set_resync_threshold(trace_dev_t *hw, uint32_t threshold)
{
hw->resync_prolonged.resync_prolonged = threshold;
}
static inline uint32_t riscv_trace_ll_get_resync_threshold(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_prolonged;
}
/*---------------------------------------------------------------------------
* AHB configuration
*--------------------------------------------------------------------------*/
@@ -219,7 +239,7 @@ static inline bool riscv_trace_ll_priv_is_supported(uint32_t priv)
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 has no supervisor mode, so the selector is 1 bit: 0 = user, 1 = machine.
/* Target has no supervisor mode. 0 = user, 1 = machine. */
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_choice_ecause = ecause_choice;
@@ -112,6 +112,11 @@ static inline void riscv_trace_ll_set_mem_loop(trace_dev_t *hw, bool loop)
hw->trigger.mem_loop = loop;
}
static inline bool riscv_trace_ll_get_mem_loop(trace_dev_t *hw)
{
return hw->trigger.mem_loop;
}
static inline void riscv_trace_ll_set_restart_ena(trace_dev_t *hw, bool enable)
{
hw->trigger.restart_ena = enable;
@@ -134,11 +139,21 @@ static inline void riscv_trace_ll_set_resync_mode(trace_dev_t *hw, uint32_t mode
hw->resync_prolonged.resync_mode = (mode == RISCV_TRACE_RESYNC_PACKET);
}
static inline uint32_t riscv_trace_ll_get_resync_mode(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_mode ? RISCV_TRACE_RESYNC_PACKET : RISCV_TRACE_RESYNC_CYCLE;
}
static inline void riscv_trace_ll_set_resync_threshold(trace_dev_t *hw, uint32_t threshold)
{
hw->resync_prolonged.resync_prolonged = threshold;
}
static inline uint32_t riscv_trace_ll_get_resync_threshold(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_prolonged;
}
/*---------------------------------------------------------------------------
* Interrupts
*--------------------------------------------------------------------------*/
@@ -112,6 +112,11 @@ static inline void riscv_trace_ll_set_mem_loop(trace_dev_t *hw, bool loop)
hw->trigger.mem_loop = loop;
}
static inline bool riscv_trace_ll_get_mem_loop(trace_dev_t *hw)
{
return hw->trigger.mem_loop;
}
static inline void riscv_trace_ll_set_restart_ena(trace_dev_t *hw, bool enable)
{
hw->trigger.restart_ena = enable;
@@ -134,11 +139,21 @@ static inline void riscv_trace_ll_set_resync_mode(trace_dev_t *hw, uint32_t mode
hw->resync_prolonged.resync_mode = (mode == RISCV_TRACE_RESYNC_PACKET);
}
static inline uint32_t riscv_trace_ll_get_resync_mode(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_mode ? RISCV_TRACE_RESYNC_PACKET : RISCV_TRACE_RESYNC_CYCLE;
}
static inline void riscv_trace_ll_set_resync_threshold(trace_dev_t *hw, uint32_t threshold)
{
hw->resync_prolonged.resync_prolonged = threshold;
}
static inline uint32_t riscv_trace_ll_get_resync_threshold(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_prolonged;
}
/*---------------------------------------------------------------------------
* Interrupts
*--------------------------------------------------------------------------*/
@@ -114,6 +114,11 @@ static inline void riscv_trace_ll_set_mem_loop(trace_dev_t *hw, bool loop)
hw->trigger.mem_loop = loop;
}
static inline bool riscv_trace_ll_get_mem_loop(trace_dev_t *hw)
{
return hw->trigger.mem_loop;
}
static inline void riscv_trace_ll_set_restart_ena(trace_dev_t *hw, bool enable)
{
hw->trigger.restart_ena = enable;
@@ -128,6 +133,11 @@ static inline void riscv_trace_ll_set_full_address(trace_dev_t *hw, bool full)
hw->config.full_address = full;
}
static inline bool riscv_trace_ll_get_full_address(trace_dev_t *hw)
{
return hw->config.full_address;
}
static inline void riscv_trace_ll_set_stall_ena(trace_dev_t *hw, bool enable)
{
hw->config.stall_ena = enable;
@@ -164,11 +174,21 @@ static inline void riscv_trace_ll_set_resync_mode(trace_dev_t *hw, uint32_t mode
hw->resync_prolonged.resync_mode = mode;
}
static inline uint32_t riscv_trace_ll_get_resync_mode(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_mode;
}
static inline void riscv_trace_ll_set_resync_threshold(trace_dev_t *hw, uint32_t threshold)
{
hw->resync_prolonged.resync_prolonged = threshold;
}
static inline uint32_t riscv_trace_ll_get_resync_threshold(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_prolonged;
}
/*---------------------------------------------------------------------------
* AHB configuration
*--------------------------------------------------------------------------*/
@@ -229,7 +249,7 @@ static inline bool riscv_trace_ll_priv_is_supported(uint32_t priv)
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 has no supervisor mode, so the selector is 1 bit: 0 = user, 1 = machine.
/* Target has no supervisor mode. 0 = user, 1 = machine. */
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_choice_ecause = ecause_choice;
@@ -118,6 +118,11 @@ static inline void riscv_trace_ll_set_mem_loop(trace_dev_t *hw, bool loop)
hw->trigger.mem_loop = loop;
}
static inline bool riscv_trace_ll_get_mem_loop(trace_dev_t *hw)
{
return hw->trigger.mem_loop;
}
static inline void riscv_trace_ll_set_restart_ena(trace_dev_t *hw, bool enable)
{
hw->trigger.restart_ena = enable;
@@ -132,6 +137,11 @@ static inline void riscv_trace_ll_set_full_address(trace_dev_t *hw, bool full)
hw->config.full_address = full;
}
static inline bool riscv_trace_ll_get_full_address(trace_dev_t *hw)
{
return hw->config.full_address;
}
static inline void riscv_trace_ll_set_stall_ena(trace_dev_t *hw, bool enable)
{
hw->config.stall_ena = enable;
@@ -168,11 +178,21 @@ static inline void riscv_trace_ll_set_resync_mode(trace_dev_t *hw, uint32_t mode
hw->resync_prolonged.resync_mode = mode;
}
static inline uint32_t riscv_trace_ll_get_resync_mode(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_mode;
}
static inline void riscv_trace_ll_set_resync_threshold(trace_dev_t *hw, uint32_t threshold)
{
hw->resync_prolonged.resync_prolonged = threshold;
}
static inline uint32_t riscv_trace_ll_get_resync_threshold(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_prolonged;
}
/*---------------------------------------------------------------------------
* AHB configuration
*--------------------------------------------------------------------------*/
@@ -114,6 +114,11 @@ static inline void riscv_trace_ll_set_mem_loop(trace_dev_t *hw, bool loop)
hw->trigger.mem_loop = loop;
}
static inline bool riscv_trace_ll_get_mem_loop(trace_dev_t *hw)
{
return hw->trigger.mem_loop;
}
static inline void riscv_trace_ll_set_restart_ena(trace_dev_t *hw, bool enable)
{
hw->trigger.restart_ena = enable;
@@ -128,6 +133,11 @@ static inline void riscv_trace_ll_set_full_address(trace_dev_t *hw, bool full)
hw->config.full_address = full;
}
static inline bool riscv_trace_ll_get_full_address(trace_dev_t *hw)
{
return hw->config.full_address;
}
static inline void riscv_trace_ll_set_stall_ena(trace_dev_t *hw, bool enable)
{
hw->config.stall_ena = enable;
@@ -164,11 +174,21 @@ static inline void riscv_trace_ll_set_resync_mode(trace_dev_t *hw, uint32_t mode
hw->resync_prolonged.resync_mode = mode;
}
static inline uint32_t riscv_trace_ll_get_resync_mode(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_mode;
}
static inline void riscv_trace_ll_set_resync_threshold(trace_dev_t *hw, uint32_t threshold)
{
hw->resync_prolonged.resync_prolonged = threshold;
}
static inline uint32_t riscv_trace_ll_get_resync_threshold(trace_dev_t *hw)
{
return hw->resync_prolonged.resync_prolonged;
}
/*---------------------------------------------------------------------------
* AHB configuration
*--------------------------------------------------------------------------*/
@@ -8,6 +8,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "soc/soc_caps.h"
#include "hal/riscv_trace_types.h"
#ifdef __cplusplus
@@ -40,10 +41,10 @@ typedef struct {
/** @brief One comparator of the filter unit (raw register values). */
typedef struct {
uint32_t input; /*!< Compared input: 0 = iaddr, 1 = tval */
uint32_t function; /*!< Compare function: 0 ==, 1 !=, 2 <, 3 <=, 4 >, 5 >= */
uint32_t input; /*!< Compared input (0 = iaddr, 1 = tval) */
uint32_t function; /*!< Compare function (0 ==, 1 !=, 2 <, 3 <=, 4 >, 5 >=) */
uint32_t match_value; /*!< 32-bit value compared against the input */
bool notify; /*!< Emit a packet reporting the address that caused the match */
bool notify; /*!< Send a packet reporting the address that caused the match */
} riscv_trace_hal_comparator_t;
/** @brief Filter (trace qualifier) configuration. */
@@ -54,7 +55,7 @@ typedef struct {
bool match_ecause; /*!< Match from an exception cause (match_ecause) */
bool match_interrupt; /*!< Match from an interrupt trap (match_interrupt) */
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) */
riscv_trace_hal_comparator_t primary; /*!< Primary comparator */
riscv_trace_hal_comparator_t secondary; /*!< Secondary comparator */
@@ -102,6 +103,20 @@ bool riscv_trace_hal_fifo_is_overflowed(uint32_t intr_status);
/** @brief Reset the hardware write pointer and clear interrupts before a new capture. */
void riscv_trace_hal_prepare_capture(riscv_trace_hal_context_t *ctx);
/** @brief Read back the LOOP-vs-STOP bit of the trace memory configuration. */
bool riscv_trace_hal_get_mem_loop(riscv_trace_hal_context_t *ctx);
#if SOC_RISCV_TRACE_HAS_CONFIG_REG
/** @brief Read back whether the encoder is in full-address mode (vs delta). Only on targets with the config register. */
bool riscv_trace_hal_get_full_address(riscv_trace_hal_context_t *ctx);
#endif
/** @brief Read back the resynchronization mode (RISCV_TRACE_RESYNC_*). */
uint32_t riscv_trace_hal_get_resync_mode(riscv_trace_hal_context_t *ctx);
/** @brief Read back the resynchronization counter threshold from the hardware. */
uint32_t riscv_trace_hal_get_resync_threshold(riscv_trace_hal_context_t *ctx);
/** @brief Apply a filter (trace qualifier) configuration. Set before starting a capture. */
void riscv_trace_hal_set_filter(riscv_trace_hal_context_t *ctx, const riscv_trace_hal_filter_config_t *config);
@@ -5,13 +5,11 @@
*/
/*
* RISC-V trace encoder HAL: register-sequencing layer used by the
* `esp_riscv_trace` driver. It sits on top of the target-specific LL
* (hal/riscv_trace_ll.h), which performs the raw register accesses.
* RISC-V trace encoder HAL. Register sequencing layer used by the
* esp_riscv_trace driver.
*
* These interfaces are internal to ESP-IDF and subject to change. The HAL
* performs no locking: callers that use it directly are responsible for
* serializing concurrent access to the same trace encoder instance.
* Internal to ESP-IDF and subject to change. The HAL performs no locking.
* Callers must serialize concurrent access to the same encoder instance.
*/
#include <stddef.h>
@@ -156,6 +154,32 @@ void riscv_trace_hal_prepare_capture(riscv_trace_hal_context_t *ctx)
riscv_trace_ll_clear_intr(ctx->dev, TRACE_FIFO_OVERFLOW_INTR_RAW | TRACE_MEM_FULL_INTR_RAW);
}
bool riscv_trace_hal_get_mem_loop(riscv_trace_hal_context_t *ctx)
{
HAL_ASSERT(ctx != NULL);
return riscv_trace_ll_get_mem_loop(ctx->dev);
}
#if SOC_RISCV_TRACE_HAS_CONFIG_REG
bool riscv_trace_hal_get_full_address(riscv_trace_hal_context_t *ctx)
{
HAL_ASSERT(ctx != NULL);
return riscv_trace_ll_get_full_address(ctx->dev);
}
#endif
uint32_t riscv_trace_hal_get_resync_mode(riscv_trace_hal_context_t *ctx)
{
HAL_ASSERT(ctx != NULL);
return riscv_trace_ll_get_resync_mode(ctx->dev);
}
uint32_t riscv_trace_hal_get_resync_threshold(riscv_trace_hal_context_t *ctx)
{
HAL_ASSERT(ctx != NULL);
return riscv_trace_ll_get_resync_threshold(ctx->dev);
}
#if SOC_RISCV_TRACE_FILTER_SUPPORTED
void riscv_trace_hal_set_filter(riscv_trace_hal_context_t *ctx, const riscv_trace_hal_filter_config_t *config)
{