OpenOCD
riscv_reg.c File Reference
Include dependency graph for riscv_reg.c:

Go to the source code of this file.

Macros

#define DECLARE_CSR(csr_name, number)   [(number) + GDB_REGNO_CSR0] = #csr_name,
 
#define DECLARE_CSR(csr_name, number)   [number] = true,
 

Functions

static void free_custom_register_names (struct target *target)
 
static void free_reg_names (struct target *target)
 
static bool gdb_regno_caller_save (uint32_t regno)
 
static unsigned int gdb_regno_custom_number (const struct target *target, uint32_t regno)
 
static struct reg_featuregdb_regno_feature (uint32_t regno)
 
static const char * gdb_regno_group (uint32_t regno)
 
static struct reg_data_typegdb_regno_reg_data_type (const struct target *target, uint32_t regno)
 
uint32_t gdb_regno_size (const struct target *target, uint32_t regno)
 
static void init_custom_csr_names (const struct target *target)
 
static int init_custom_register_names (struct list_head *expose_custom, struct reg_name_table *custom_register_names)
 
static char * init_reg_name (const char *name)
 
static char * init_reg_name_with_prefix (const char *name_prefix, unsigned int num)
 
static bool is_known_standard_csr (unsigned int csr_num)
 
static bool reg_exists (const struct target *target, uint32_t regno)
 
static int resize_reg (const struct target *target, uint32_t regno, bool exist, uint32_t size)
 
bool riscv_reg_cache_any_dirty (const struct target *target, int log_level)
 Check whether there are any dirty registers in the OpenOCD's register cache. More...
 
void riscv_reg_cache_invalidate_all (struct target *target)
 Invalidate all registers - forget their cached register values. More...
 
int riscv_reg_flush_all (struct target *target)
 Write all dirty registers to the target. More...
 
void riscv_reg_free_all (struct target *target)
 Free register cache and associated structures. More...
 
const char * riscv_reg_gdb_regno_name (const struct target *target, enum gdb_regno regno)
 This file describes the register cache interface available to the RISC-V target. More...
 
int riscv_reg_get (struct target *target, riscv_reg_t *value, enum gdb_regno regid)
 This function is used to get the value of a register. More...
 
struct regriscv_reg_impl_cache_entry (const struct target *target, uint32_t number)
 Return the entry in the register cache of the target. More...
 
int riscv_reg_impl_expose_csrs (const struct target *target)
 Expose additional CSRs, as specified by riscv_info_t::expose_csr list. More...
 
bool riscv_reg_impl_gdb_regno_exist (const struct target *target, uint32_t regno)
 For most registers, returns whether they exist or not. More...
 
struct targetriscv_reg_impl_get_target (const struct reg *reg)
 Return the target that owns the cache entry. More...
 
void riscv_reg_impl_hide_csrs (const struct target *target)
 Hide additional CSRs, as specified by riscv_info_t::hide_csr list. More...
 
int riscv_reg_impl_init_cache (struct target *target)
 Initialize register cache. More...
 
int riscv_reg_impl_init_cache_entry (struct target *target, uint32_t regno, bool exist, const struct reg_arch_type *reg_type)
 Initialize register. More...
 
int riscv_reg_impl_set_exist (const struct target *target, uint32_t regno, bool exist)
 Mark register as existing or not. More...
 
int riscv_reg_set (struct target *target, enum gdb_regno regid, riscv_reg_t value)
 This function is used to change the value of a register. More...
 
int riscv_reg_write (struct target *target, enum gdb_regno regid, riscv_reg_t value)
 This function is used to change the value of a register. More...
 
static int riscv_set_or_write_register (struct target *target, enum gdb_regno regid, riscv_reg_t value, bool write_through)
 This function is used internally by functions that change register values. More...
 
static bool vlenb_exists (const struct target *target)
 

Variables

static const char *const default_reg_names [GDB_REGNO_COUNT]
 TODO: Currently reg->get/set is implemented in terms of riscv_get/set_register. More...
 

Macro Definition Documentation

◆ DECLARE_CSR [1/2]

#define DECLARE_CSR (   csr_name,
  number 
)    [(number) + GDB_REGNO_CSR0] = #csr_name,

◆ DECLARE_CSR [2/2]

#define DECLARE_CSR (   csr_name,
  number 
)    [number] = true,

Function Documentation

◆ free_custom_register_names()

static void free_custom_register_names ( struct target target)
static

Definition at line 98 of file riscv_reg.c.

References info, NULL, and RISCV_INFO.

Referenced by free_reg_names().

◆ free_reg_names()

static void free_reg_names ( struct target target)
static

Definition at line 111 of file riscv_reg.c.

References free_custom_register_names(), GDB_REGNO_COUNT, info, NULL, and RISCV_INFO.

Referenced by riscv_reg_free_all().

◆ gdb_regno_caller_save()

static bool gdb_regno_caller_save ( uint32_t  regno)
static

Definition at line 255 of file riscv_reg.c.

References GDB_REGNO_FPR0, GDB_REGNO_FPR31, GDB_REGNO_PC, and GDB_REGNO_XPR31.

Referenced by riscv_reg_impl_init_cache_entry().

◆ gdb_regno_custom_number()

static unsigned int gdb_regno_custom_number ( const struct target target,
uint32_t  regno 
)
static

◆ gdb_regno_feature()

◆ gdb_regno_group()

◆ gdb_regno_reg_data_type()

◆ gdb_regno_size()

◆ init_custom_csr_names()

static void init_custom_csr_names ( const struct target target)
static

◆ init_custom_register_names()

static int init_custom_register_names ( struct list_head expose_custom,
struct reg_name_table custom_register_names 
)
static

◆ init_reg_name()

static char* init_reg_name ( const char *  name)
static

Definition at line 126 of file riscv_reg.c.

References LOG_ERROR, name, and NULL.

Referenced by init_custom_csr_names(), and init_custom_register_names().

◆ init_reg_name_with_prefix()

static char* init_reg_name_with_prefix ( const char *  name_prefix,
unsigned int  num 
)
static

Definition at line 156 of file riscv_reg.c.

References LOG_ERROR, and NULL.

Referenced by init_custom_register_names(), and riscv_reg_gdb_regno_name().

◆ is_known_standard_csr()

static bool is_known_standard_csr ( unsigned int  csr_num)
static

Definition at line 356 of file riscv_reg.c.

References ARRAY_SIZE, GDB_REGNO_CSR0, and GDB_REGNO_CSR4095.

Referenced by riscv_reg_impl_gdb_regno_exist().

◆ reg_exists()

static bool reg_exists ( const struct target target,
uint32_t  regno 
)
static

◆ resize_reg()

static int resize_reg ( const struct target target,
uint32_t  regno,
bool  exist,
uint32_t  size 
)
static

◆ riscv_reg_cache_any_dirty()

bool riscv_reg_cache_any_dirty ( const struct target target,
int  log_level 
)

Check whether there are any dirty registers in the OpenOCD's register cache.

In addition, all dirty registers will be reported to the log using the supplied "log_level".

Definition at line 880 of file riscv_reg.c.

References reg::dirty, log_printf_lf(), reg::name, reg_cache::num_regs, number, target::reg_cache, riscv_reg_impl_cache_entry(), riscv_reg_impl_is_initialized(), and target_name().

Referenced by handle_became_unavailable(), resume_finish(), riscv_assert_reset(), riscv_halt_go_all_harts(), and riscv_openocd_step_impl().

◆ riscv_reg_cache_invalidate_all()

void riscv_reg_cache_invalidate_all ( struct target target)

Invalidate all registers - forget their cached register values.

WARNING: If a register was dirty, its walue will be silently lost!

Definition at line 899 of file riscv_reg.c.

References LOG_TARGET_DEBUG, target::reg_cache, and register_cache_invalidate().

Referenced by COMMAND_HANDLER(), execute_resume(), handle_became_unavailable(), resume_finish(), riscv013_step_or_resume_current_hart(), riscv_assert_reset(), riscv_halt_go_all_harts(), and riscv_openocd_step_impl().

◆ riscv_reg_flush_all()

◆ riscv_reg_free_all()

void riscv_reg_free_all ( struct target target)

Free register cache and associated structures.

Definition at line 759 of file riscv_reg.c.

References reg::arch_info, free_reg_names(), GDB_REGNO_COUNT, NULL, reg_cache::num_regs, target::reg_cache, reg_cache::reg_list, and reg::value.

Referenced by riscv_deinit_target(), and riscv_reg_impl_init_cache().

◆ riscv_reg_gdb_regno_name()

const char* riscv_reg_gdb_regno_name ( const struct target target,
enum gdb_regno  regno 
)

This file describes the register cache interface available to the RISC-V target.

Functions declared here should be safe to use once register cache is completely initialized and may be used with caution during register cache initialization. Return the name of the register by it's number in register cache.

Definition at line 171 of file riscv_reg.c.

References default_reg_names, GDB_REGNO_COUNT, GDB_REGNO_CSR0, GDB_REGNO_CSR4095, GDB_REGNO_V0, GDB_REGNO_XPR31, GDB_REGNO_ZERO, info, init_custom_csr_names(), init_reg_name_with_prefix(), NULL, and RISCV_INFO.

Referenced by prep_for_register_access(), read_remote_csr(), register_read(), register_read_direct(), register_read_progbuf(), register_write(), register_write_direct(), register_write_progbuf(), riscv013_access_register_command(), riscv013_get_register(), riscv013_get_register_buf(), riscv013_reg_save(), riscv013_set_register(), riscv_reg_impl_init_cache_entry(), and riscv_run_algorithm().

◆ riscv_reg_get()

int riscv_reg_get ( struct target target,
riscv_reg_t value,
enum gdb_regno  regid 
)

This function is used to get the value of a register.

Get register, from the cache if it's in there.

If possible, the value in cache will be updated. TODO: Currently reg->get/set is implemented in terms of riscv_get/set_register. However, the intention behind riscv_get/set_register is to work with the cache, therefore it accesses and modifyes register cache directly. The idea is to implement riscv_get/set_register in terms of riscv_reg_impl_cache_entry and reg->get/set.

Definition at line 952 of file riscv_reg.c.

References buf_get_u64(), buf_set_u64(), reg::dirty, DTM_DTMCS_VERSION_0_11, ERROR_FAIL, ERROR_OK, reg::exist, GDB_REGNO_DPC, GDB_REGNO_PC, keep_alive(), LOG_TARGET_DEBUG, reg::name, riscv011_get_register(), riscv013_get_register(), RISCV_INFO, riscv_reg_impl_cache_entry(), riscv_reg_impl_gdb_regno_cacheable(), riscv_reg_impl_is_initialized(), reg::size, target::state, TARGET_HALTED, reg::valid, and reg::value.

Referenced by add_trigger(), check_if_trigger_exists(), examine_misa(), examine_mtopi(), examine_vlenb(), get_trigger_types(), maybe_add_trigger_t1(), modify_privilege_for_virt2phys_mode(), prep_for_register_access(), prep_for_vector_access(), remove_trigger(), riscv013_get_register(), riscv013_reg_get(), riscv013_reg_save(), riscv_effective_privilege_mode(), riscv_enumerate_triggers(), riscv_hit_watchpoint(), riscv_interrupts_disable(), riscv_interrupts_restore(), riscv_mmu(), riscv_openocd_poll(), riscv_openocd_step_impl(), riscv_run_algorithm(), riscv_set_or_write_register(), riscv_trigger_detect_hit_bits(), riscv_virt2phys(), riscv_virt2phys_v(), set_dcsr_ebreak(), set_debug_reason(), set_trigger(), and try_set_vsew().

◆ riscv_reg_impl_cache_entry()

◆ riscv_reg_impl_expose_csrs()

int riscv_reg_impl_expose_csrs ( const struct target target)

◆ riscv_reg_impl_gdb_regno_exist()

bool riscv_reg_impl_gdb_regno_exist ( const struct target target,
uint32_t  regno 
)

For most registers, returns whether they exist or not.

For some registers the "exist" bit should be set explicitly.

Definition at line 368 of file riscv_reg.c.

References CSR_CYCLEH, CSR_FCSR, CSR_FFLAGS, CSR_FRM, CSR_HIDELEGH, CSR_HPMCOUNTER10H, CSR_HPMCOUNTER11H, CSR_HPMCOUNTER12H, CSR_HPMCOUNTER13H, CSR_HPMCOUNTER14H, CSR_HPMCOUNTER15H, CSR_HPMCOUNTER16H, CSR_HPMCOUNTER17H, CSR_HPMCOUNTER18H, CSR_HPMCOUNTER19H, CSR_HPMCOUNTER20H, CSR_HPMCOUNTER21H, CSR_HPMCOUNTER22H, CSR_HPMCOUNTER23H, CSR_HPMCOUNTER24H, CSR_HPMCOUNTER25H, CSR_HPMCOUNTER26H, CSR_HPMCOUNTER27H, CSR_HPMCOUNTER28H, CSR_HPMCOUNTER29H, CSR_HPMCOUNTER30H, CSR_HPMCOUNTER31H, CSR_HPMCOUNTER3H, CSR_HPMCOUNTER4H, CSR_HPMCOUNTER5H, CSR_HPMCOUNTER6H, CSR_HPMCOUNTER7H, CSR_HPMCOUNTER8H, CSR_HPMCOUNTER9H, CSR_HVICTL, CSR_HVIEN, CSR_HVIENH, CSR_HVIPH, CSR_HVIPRIO1, CSR_HVIPRIO1H, CSR_HVIPRIO2, CSR_HVIPRIO2H, CSR_INSTRETH, CSR_MCOUNTEREN, CSR_MCYCLEH, CSR_MEDELEG, CSR_MHPMCOUNTER10H, CSR_MHPMCOUNTER11H, CSR_MHPMCOUNTER12H, CSR_MHPMCOUNTER13H, CSR_MHPMCOUNTER14H, CSR_MHPMCOUNTER15H, CSR_MHPMCOUNTER16H, CSR_MHPMCOUNTER17H, CSR_MHPMCOUNTER18H, CSR_MHPMCOUNTER19H, CSR_MHPMCOUNTER20H, CSR_MHPMCOUNTER21H, CSR_MHPMCOUNTER22H, CSR_MHPMCOUNTER23H, CSR_MHPMCOUNTER24H, CSR_MHPMCOUNTER25H, CSR_MHPMCOUNTER26H, CSR_MHPMCOUNTER27H, CSR_MHPMCOUNTER28H, CSR_MHPMCOUNTER29H, CSR_MHPMCOUNTER30H, CSR_MHPMCOUNTER31H, CSR_MHPMCOUNTER4H, CSR_MHPMCOUNTER5H, CSR_MHPMCOUNTER6H, CSR_MHPMCOUNTER7H, CSR_MHPMCOUNTER8H, CSR_MHPMCOUNTER9H, CSR_MIDELEG, CSR_MIDELEGH, CSR_MIEH, CSR_MINSTRETH, CSR_MIPH, CSR_MIREG, CSR_MISELECT, CSR_MVIEN, CSR_MVIENH, CSR_MVIP, CSR_MVIPH, CSR_PMPCFG1, CSR_PMPCFG3, CSR_SATP, CSR_SCAUSE, CSR_SCOUNTEREN, CSR_SEPC, CSR_SIE, CSR_SIEH, CSR_SIP, CSR_SIPH, CSR_SIREG, CSR_SISELECT, CSR_SSCRATCH, CSR_SSTATUS, CSR_STOPEI, CSR_STOPI, CSR_STVAL, CSR_STVEC, CSR_TIMEH, CSR_VCSR, CSR_VL, CSR_VSIEH, CSR_VSIPH, CSR_VSIREG, CSR_VSISELECT, CSR_VSTART, CSR_VSTOPEI, CSR_VSTOPI, CSR_VTYPE, CSR_VXRM, CSR_VXSAT, GDB_REGNO_COUNT, GDB_REGNO_CSR0, GDB_REGNO_CSR4095, GDB_REGNO_FPR0, GDB_REGNO_FPR31, GDB_REGNO_MTOPEI, GDB_REGNO_MTOPI, GDB_REGNO_PC, GDB_REGNO_PRIV, GDB_REGNO_V0, GDB_REGNO_V31, GDB_REGNO_VLENB, GDB_REGNO_XPR15, GDB_REGNO_XPR31, is_known_standard_csr(), reg_exists(), riscv_supports_extension(), riscv_xlen(), and vlenb_exists().

Referenced by init_cache_entry(), and riscv011_reg_init_all().

◆ riscv_reg_impl_get_target()

struct target* riscv_reg_impl_get_target ( const struct reg reg)

Return the target that owns the cache entry.

Definition at line 207 of file riscv_reg.c.

References reg::arch_info, and riscv_reg_impl_is_initialized().

Referenced by riscv011_reg_get(), riscv011_reg_set(), riscv013_reg_get(), and riscv013_reg_set().

◆ riscv_reg_impl_hide_csrs()

void riscv_reg_impl_hide_csrs ( const struct target target)

Hide additional CSRs, as specified by riscv_info_t::hide_csr list.

Definition at line 736 of file riscv_reg.c.

References reg::exist, GDB_REGNO_CSR0, GDB_REGNO_CSR4095, reg::hidden, range_list_t::high, info, list_for_each_entry, LOG_TARGET_DEBUG, range_list_t::low, reg::name, RISCV_INFO, and riscv_reg_impl_cache_entry().

Referenced by riscv011_reg_init_all(), and riscv013_reg_examine_all().

◆ riscv_reg_impl_init_cache()

int riscv_reg_impl_init_cache ( struct target target)

Initialize register cache.

Note, that each specific register cache entry is not initialized by this function.

Definition at line 678 of file riscv_reg.c.

References ERROR_FAIL, ERROR_OK, GDB_REGNO_COUNT, info, init_custom_register_names(), LOG_TARGET_DEBUG, LOG_TARGET_ERROR, reg_cache::name, reg_cache::num_regs, target::reg_cache, reg_cache::reg_list, RISCV_INFO, and riscv_reg_free_all().

Referenced by riscv011_reg_init_all(), and riscv013_reg_examine_all().

◆ riscv_reg_impl_init_cache_entry()

◆ riscv_reg_impl_set_exist()

int riscv_reg_impl_set_exist ( const struct target target,
uint32_t  regno,
bool  exist 
)

Mark register as existing or not.

Definition at line 601 of file riscv_reg.c.

References reg::exist, resize_reg(), riscv_reg_impl_cache_entry(), riscv_reg_impl_is_initialized(), and reg::size.

Referenced by examine_mtopi(), examine_vlenb(), and riscv_reg_impl_expose_csrs().

◆ riscv_reg_set()

int riscv_reg_set ( struct target target,
enum gdb_regno  regid,
riscv_reg_t  value 
)

This function is used to change the value of a register.

Set the register value.

The new value may be cached, and may not be written until the hart is resumed. TODO: Currently reg->get/set is implemented in terms of riscv_get/set_register. However, the intention behind riscv_get/set_register is to work with the cache, therefore it accesses and modifyes register cache directly. The idea is to implement riscv_get/set_register in terms of riscv_reg_impl_cache_entry and reg->get/set.

Definition at line 918 of file riscv_reg.c.

References riscv_set_or_write_register(), and reg::value.

Referenced by add_trigger(), check_if_trigger_exists(), disable_trigger_if_dmode(), modify_privilege_for_virt2phys_mode(), remove_trigger(), restore_privilege_from_virt2phys_mode(), resume_prep(), riscv013_reg_set(), riscv_enumerate_triggers(), riscv_interrupts_disable(), riscv_interrupts_restore(), riscv_openocd_step_impl(), riscv_semihosting_post_result(), riscv_trigger_detect_hit_bits(), set_dcsr_ebreak(), and set_trigger().

◆ riscv_reg_write()

int riscv_reg_write ( struct target target,
enum gdb_regno  regid,
riscv_reg_t  value 
)

This function is used to change the value of a register.

Set the register value and immediately write it to the target (write-through mode).

The new value may be cached, but it will be written to hart immediately. TODO: Currently reg->get/set is implemented in terms of riscv_get/set_register. However, the intention behind riscv_get/set_register is to work with the cache, therefore it accesses and modifyes register cache directly. The idea is to implement riscv_get/set_register in terms of riscv_reg_impl_cache_entry and reg->get/set.

Definition at line 935 of file riscv_reg.c.

References riscv_set_or_write_register(), and reg::value.

Referenced by cleanup_after_register_access(), cleanup_after_vector_access(), prep_for_register_access(), prep_for_vector_access(), riscv_reg_flush_all(), and try_set_vsew().

◆ riscv_set_or_write_register()

static int riscv_set_or_write_register ( struct target target,
enum gdb_regno  regid,
riscv_reg_t  value,
bool  write_through 
)
static

This function is used internally by functions that change register values.

If write_through is true, it is ensured that the value of the target's register is set to be equal to the value argument. The cached value is updated if the register is cacheable. TODO: Currently reg->get/set is implemented in terms of riscv_get/set_register. However, the intention behind riscv_get/set_register is to work with the cache, therefore it accesses and modifyes register cache directly. The idea is to implement riscv_get/set_register in terms of riscv_reg_impl_cache_entry and reg->get/set.

Definition at line 814 of file riscv_reg.c.

References buf_get_u64(), buf_set_u64(), CSR_DCSR_PRV, CSR_DCSR_V, reg::dirty, DTM_DTMCS_VERSION_0_11, ERROR_FAIL, ERROR_OK, reg::exist, GDB_REGNO_DCSR, GDB_REGNO_DPC, GDB_REGNO_PC, GDB_REGNO_PRIV, get_field(), keep_alive(), LOG_TARGET_DEBUG, reg::name, riscv011_set_register(), riscv013_set_register(), RISCV_INFO, riscv_reg_get(), riscv_reg_impl_cache_entry(), riscv_reg_impl_gdb_regno_cacheable(), riscv_reg_impl_is_initialized(), set_field(), reg::size, target::state, TARGET_HALTED, reg::valid, reg::value, VIRT_PRIV_PRV, and VIRT_PRIV_V.

Referenced by riscv_reg_set(), and riscv_reg_write().

◆ vlenb_exists()

static bool vlenb_exists ( const struct target target)
static

Definition at line 344 of file riscv_reg.c.

References riscv_vlenb().

Referenced by riscv_reg_impl_gdb_regno_exist().

Variable Documentation

◆ default_reg_names

const char* const default_reg_names[GDB_REGNO_COUNT]
static

TODO: Currently reg->get/set is implemented in terms of riscv_get/set_register.

However, the intention behind riscv_get/set_register is to work with the cache, therefore it accesses and modifyes register cache directly. The idea is to implement riscv_get/set_register in terms of riscv_reg_impl_cache_entry and reg->get/set. Once this is done, the following includes should be removed.

Definition at line 25 of file riscv_reg.c.

Referenced by riscv_reg_gdb_regno_name().