Skip to content

Commit

Permalink
target/riscv: separate register cache stuff into files
Browse files Browse the repository at this point in the history
This commits creates file structure for register cache related
functions.
Specifically:

* `riscv_reg.h` -- general interface to registers. Safe to use after
  register cache initialization is successful.
* `riscv_reg_impl.h` -- helper functions to use while implementing
  register cache initialization.
* `riscv_reg.c` -- definitions of functions from `riscv_reg.h` and
  `riscv_reg_impl.h`.
* `riscv-011_reg.h` -- register cache interface specific to 0.11
  targets.
* `riscv-013_reg.h` -- register cache interface specific to 0.13+
  targets.
* `riscv-011/0.13.h` -- version-specific methods used to access
  registers. Will be extended as needed once other functionality (not
  related to register access) is separated (e.g. DM/DTM specific stuff).

Checkpatch-ignore: SPDX_LICENSE_TAG
Change-Id: I7918f78d0d79b97188c5703efd0296660e529f2a
Signed-off-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
  • Loading branch information
en-sc committed Jun 5, 2024
1 parent cb87885 commit 84b1597
Show file tree
Hide file tree
Showing 16 changed files with 1,548 additions and 1,374 deletions.
7 changes: 7 additions & 0 deletions src/target/riscv/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,18 @@ noinst_LTLIBRARIES += %D%/libriscv.la
%D%/opcodes.h \
%D%/program.h \
%D%/riscv.h \
%D%/riscv-011.h \
%D%/riscv-011_reg.h \
%D%/riscv-013.h \
%D%/riscv-013_reg.h \
%D%/batch.c \
%D%/program.c \
%D%/riscv-011.c \
%D%/riscv-011_reg.c \
%D%/riscv-013.c \
%D%/riscv-013_reg.c \
%D%/riscv.c \
%D%/riscv_reg.c \
%D%/riscv_semihosting.c \
%D%/debug_defines.c \
%D%/debug_reg_printer.c
4 changes: 2 additions & 2 deletions src/target/riscv/gdb_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#ifndef TARGET__RISCV__GDB_REGS_H
#define TARGET__RISCV__GDB_REGS_H

#include "encoding.h"

/* gdb's register list is defined in riscv_gdb_reg_names gdb/riscv-tdep.c in
* its source tree. We must interpret the numbers the same here. */
enum gdb_regno {
Expand Down Expand Up @@ -123,6 +125,4 @@ enum gdb_regno {
GDB_REGNO_COUNT
};

const char *gdb_regno_name(const struct target *target, enum gdb_regno regno);

#endif
18 changes: 9 additions & 9 deletions src/target/riscv/riscv-011.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "config.h"
#endif

#include "riscv-011.h"

#include "target/target.h"
#include "target/algorithm.h"
#include "target/target_type.h"
Expand All @@ -22,6 +24,8 @@
#include "target/breakpoints.h"
#include "helper/time_support.h"
#include "riscv.h"
#include "riscv_reg.h"
#include "riscv-011_reg.h"
#include "asm.h"
#include "gdb_regs.h"
#include "field_helpers.h"
Expand Down Expand Up @@ -210,8 +214,6 @@ typedef struct {

static int poll_target(struct target *target, bool announce);
static int riscv011_poll(struct target *target);
static int get_register(struct target *target, riscv_reg_t *value,
enum gdb_regno regid);

/*** Utility functions. ***/

Expand Down Expand Up @@ -1225,7 +1227,7 @@ static int update_mstatus_actual(struct target *target)
/* Force reading the register. In that process mstatus_actual will be
* updated. */
riscv_reg_t mstatus;
return get_register(target, &mstatus, GDB_REGNO_MSTATUS);
return riscv011_get_register(target, &mstatus, GDB_REGNO_MSTATUS);
}

/*** OpenOCD target functions. ***/
Expand Down Expand Up @@ -1329,7 +1331,7 @@ static int register_write(struct target *target, unsigned int number,
return ERROR_OK;
}

static int get_register(struct target *target, riscv_reg_t *value,
int riscv011_get_register(struct target *target, riscv_reg_t *value,
enum gdb_regno regid)
{
riscv011_info_t *info = get_info(target);
Expand Down Expand Up @@ -1377,7 +1379,7 @@ static int get_register(struct target *target, riscv_reg_t *value,

/* This function is intended to handle accesses to registers through register
* cache. */
static int set_register(struct target *target, enum gdb_regno regid,
int riscv011_set_register(struct target *target, enum gdb_regno regid,
riscv_reg_t value)
{
assert(target->reg_cache);
Expand Down Expand Up @@ -1595,7 +1597,7 @@ static int examine(struct target *target)
}

/* Update register list to match discovered XLEN/supported extensions. */
riscv_init_registers(target);
riscv011_init_registers(target);

info->never_halted = true;

Expand Down Expand Up @@ -2391,8 +2393,6 @@ static int init_target(struct command_context *cmd_ctx,
{
LOG_DEBUG("init");
RISCV_INFO(generic_info);
generic_info->get_register = get_register;
generic_info->set_register = set_register;
generic_info->read_memory = read_memory;
generic_info->authdata_read = &riscv011_authdata_read;
generic_info->authdata_write = &riscv011_authdata_write;
Expand All @@ -2404,7 +2404,7 @@ static int init_target(struct command_context *cmd_ctx,

/* Assume 32-bit until we discover the real value in examine(). */
generic_info->xlen = 32;
riscv_init_registers(target);
riscv011_init_registers(target);

return ERROR_OK;
}
Expand Down
13 changes: 13 additions & 0 deletions src/target/riscv/riscv-011.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef OPENOCD_TARGET_RISCV_RISCV_011_H
#define OPENOCD_TARGET_RISCV_RISCV_011_H

#include "riscv.h"
#include "gdb_regs.h"
#include "target/target.h"

int riscv011_get_register(struct target *target, riscv_reg_t *value,
enum gdb_regno regid);
int riscv011_set_register(struct target *target, enum gdb_regno regid,
riscv_reg_t value);

#endif /*OPENOCD_TARGET_RISCV_RISCV_011_H*/
60 changes: 60 additions & 0 deletions src/target/riscv/riscv-011_reg.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "riscv-011_reg.h"

#include "riscv_reg_impl.h"
#include "riscv-011.h"

static int riscv011_reg_get(struct reg *reg)
{
struct target * const target = get_target_from_reg(reg);
riscv_reg_t value;
const int result = riscv011_get_register(target, &value, reg->number);
if (result != ERROR_OK)
return result;
buf_set_u64(reg->value, 0, reg->size, value);
return ERROR_OK;
}

static int riscv011_reg_set(struct reg *reg, uint8_t *buf)
{
const riscv_reg_t value = buf_get_u64(buf, 0, reg->size);
struct target * const target = get_target_from_reg(reg);
return riscv011_set_register(target, reg->number, value);
}

static const struct reg_arch_type *riscv011_gdb_regno_reg_type(uint32_t regno)
{
static const struct reg_arch_type riscv011_reg_type = {
.get = riscv011_reg_get,
.set = riscv011_reg_set
};
return &riscv011_reg_type;
}

static int riscv011_init_reg(struct target *target, uint32_t regno)
{
return init_reg(target, regno, riscv011_gdb_regno_reg_type(regno));
}

int riscv011_init_registers(struct target *target)
{
//TODO move to init
if (riscv_init_reg_cache(target) != ERROR_OK)
return ERROR_FAIL;

init_shared_reg_info(target);

for (uint32_t regno = 0; regno < target->reg_cache->num_regs; ++regno)
if (riscv011_init_reg(target, regno) != ERROR_OK)
return ERROR_FAIL;

if (expose_csrs(target) != ERROR_OK)
return ERROR_FAIL;

hide_csrs(target);

return ERROR_OK;
}
17 changes: 17 additions & 0 deletions src/target/riscv/riscv-011_reg.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef OPENOCD_TARGET_RISCV_RISCV_REG_011_H
#define OPENOCD_TARGET_RISCV_RISCV_REG_011_H

#include "target/target.h"

/**
* This file describes additional register cache interface available to the
* RISC-V Debug Specification v0.11 targets.
*/

/**
* Initialize register cache. After this function all registers can be
* safely accessed via functions described here and in `riscv_reg.h`.
*/
int riscv011_init_registers(struct target *target);

#endif /*OPENOCD_TARGET_RISCV_RISCV_REG_011_H*/
25 changes: 10 additions & 15 deletions src/target/riscv/riscv-013.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
#include "helper/time_support.h"
#include "helper/list.h"
#include "riscv.h"
#include "riscv-013.h"
#include "riscv_reg.h"
#include "riscv-013_reg.h"
#include "debug_defines.h"
#include "rtos/rtos.h"
#include "program.h"
Expand All @@ -37,10 +40,6 @@ static int riscv013_step_or_resume_current_hart(struct target *target,
static int riscv013_clear_abstract_error(struct target *target);

/* Implementations of the functions in struct riscv_info. */
static int riscv013_get_register(struct target *target,
riscv_reg_t *value, enum gdb_regno rid);
static int riscv013_set_register(struct target *target, enum gdb_regno regid,
riscv_reg_t value);
static int dm013_select_hart(struct target *target, int hart_index);
static int riscv013_halt_prep(struct target *target);
static int riscv013_halt_go(struct target *target);
Expand Down Expand Up @@ -2332,7 +2331,7 @@ static int examine(struct target *target)
}

/* Now init registers based on what we discovered. */
if (riscv_init_registers(target) != ERROR_OK)
if (riscv013_init_registers(target) != ERROR_OK)
return ERROR_FAIL;

if (set_dcsr_ebreak(target, false) != ERROR_OK)
Expand Down Expand Up @@ -2557,8 +2556,8 @@ static int cleanup_after_vector_access(struct target *target,
return cleanup_after_register_access(target, mstatus, GDB_REGNO_VL);
}

static int riscv013_get_register_buf(struct target *target,
uint8_t *value, enum gdb_regno regno)
int riscv013_get_register_buf(struct target *target, uint8_t *value,
enum gdb_regno regno)
{
assert(regno >= GDB_REGNO_V0 && regno <= GDB_REGNO_V31);

Expand Down Expand Up @@ -2612,8 +2611,8 @@ static int riscv013_get_register_buf(struct target *target,
return result;
}

static int riscv013_set_register_buf(struct target *target,
enum gdb_regno regno, const uint8_t *value)
int riscv013_set_register_buf(struct target *target, enum gdb_regno regno,
const uint8_t *value)
{
assert(regno >= GDB_REGNO_V0 && regno <= GDB_REGNO_V31);

Expand Down Expand Up @@ -3002,10 +3001,6 @@ static int init_target(struct command_context *cmd_ctx,
LOG_TARGET_DEBUG(target, "Init.");
RISCV_INFO(generic_info);

generic_info->get_register = &riscv013_get_register;
generic_info->set_register = &riscv013_set_register;
generic_info->get_register_buf = &riscv013_get_register_buf;
generic_info->set_register_buf = &riscv013_set_register_buf;
generic_info->select_target = &dm013_select_target;
generic_info->get_hart_state = &riscv013_get_hart_state;
generic_info->resume_go = &riscv013_resume_go;
Expand Down Expand Up @@ -5148,7 +5143,7 @@ struct target_type riscv013_target = {
};

/*** 0.13-specific implementations of various RISC-V helper functions. ***/
static int riscv013_get_register(struct target *target,
int riscv013_get_register(struct target *target,
riscv_reg_t *value, enum gdb_regno rid)
{
/* It would be beneficial to move this redirection to the
Expand Down Expand Up @@ -5177,7 +5172,7 @@ static int riscv013_get_register(struct target *target,
return ERROR_OK;
}

static int riscv013_set_register(struct target *target, enum gdb_regno rid,
int riscv013_set_register(struct target *target, enum gdb_regno rid,
riscv_reg_t value)
{
LOG_TARGET_DEBUG(target, "writing 0x%" PRIx64 " to register %s",
Expand Down
20 changes: 20 additions & 0 deletions src/target/riscv/riscv-013.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef OPENOCD_TARGET_RISCV_RISCV_013_H
#define OPENOCD_TARGET_RISCV_RISCV_013_H

#include "riscv.h"

/**
* TODO: This functions will be and replaced here by specific access methods
* (e.g. abstract commands, program buffer writes and so on.), while specifics
* on how to use them to get a register's value will be in `riscv-013_reg.c`.
*/
int riscv013_get_register(struct target *target,
riscv_reg_t *value, enum gdb_regno rid);
int riscv013_get_register_buf(struct target *target, uint8_t *value,
enum gdb_regno regno);
int riscv013_set_register(struct target *target, enum gdb_regno rid,
riscv_reg_t value);
int riscv013_set_register_buf(struct target *target, enum gdb_regno regno,
const uint8_t *value);

#endif /*OPENOCD_TARGET_RISCV_RISCV_013_H*/
Loading

0 comments on commit 84b1597

Please sign in to comment.