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 commit 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).

Change-Id: I7918f78d0d79b97188c5703efd0296660e529f2a
Signed-off-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
  • Loading branch information
en-sc committed Jul 1, 2024
1 parent cb87885 commit 47ccad2
Show file tree
Hide file tree
Showing 17 changed files with 1,679 additions and 1,488 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
2 changes: 1 addition & 1 deletion src/target/riscv/program.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ int riscv_program_write(struct riscv_program *program);

/* Executes a program, returning 0 if the program successfully executed. Note
* that this may cause registers to be saved or restored, which could result to
* calls to things like riscv_save_register which itself could require a
* calls to things like riscv013_reg_save which itself could require a
* program to execute. That's OK, just make sure this eventually terminates.
* */
int riscv_program_exec(struct riscv_program *p, struct target *t);
Expand Down
26 changes: 13 additions & 13 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 @@ -1045,7 +1047,7 @@ static int read_remote_csr(struct target *target, uint64_t *value, uint32_t csr)
uint32_t exception = cache_get32(target, info->dramsize-1);
if (exception) {
LOG_WARNING("Got exception 0x%x when reading %s", exception,
gdb_regno_name(target, GDB_REGNO_CSR0 + csr));
riscv_reg_gdb_regno_name(target, GDB_REGNO_CSR0 + csr));
*value = ~0;
return ERROR_FAIL;
}
Expand Down Expand Up @@ -1111,7 +1113,7 @@ static int execute_resume(struct target *target, bool step)

LOG_DEBUG("step=%d", step);

if (riscv_flush_registers(target) != ERROR_OK)
if (riscv_reg_flush_all(target) != ERROR_OK)
return ERROR_FAIL;

maybe_write_tselect(target);
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 All @@ -1247,7 +1249,7 @@ static int register_read(struct target *target, riscv_reg_t *value, int regnum)

uint32_t exception = cache_get32(target, info->dramsize-1);
if (exception) {
LOG_WARNING("Got exception 0x%x when reading %s", exception, gdb_regno_name(target, regnum));
LOG_WARNING("Got exception 0x%x when reading %s", exception, riscv_reg_gdb_regno_name(target, regnum));
*value = ~0;
return ERROR_FAIL;
}
Expand Down Expand Up @@ -1322,14 +1324,14 @@ static int register_write(struct target *target, unsigned int number,
uint32_t exception = cache_get32(target, info->dramsize-1);
if (exception) {
LOG_WARNING("Got exception 0x%x when writing %s", exception,
gdb_regno_name(target, number));
riscv_reg_gdb_regno_name(target, number));
return ERROR_FAIL;
}

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_reg_init_all(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_reg_init_all(target);

return ERROR_OK;
}
Expand Down
15 changes: 15 additions & 0 deletions src/target/riscv/riscv-011.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#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*/
61 changes: 61 additions & 0 deletions src/target/riscv/riscv-011_reg.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// SPDX-License-Identifier: GPL-2.0-or-later

#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 = riscv_reg_impl_get_target(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 = riscv_reg_impl_get_target(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 riscv_reg_impl_init_one(target, regno, riscv011_gdb_regno_reg_type(regno));
}

int riscv011_reg_init_all(struct target *target)
{
if (riscv_reg_imp_init_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 (riscv_reg_impl_expose_csrs(target) != ERROR_OK)
return ERROR_FAIL;

riscv_reg_impl_hide_csrs(target);

return ERROR_OK;
}
19 changes: 19 additions & 0 deletions src/target/riscv/riscv-011_reg.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#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_reg_init_all(struct target *target);

#endif /*OPENOCD_TARGET_RISCV_RISCV_REG_011_H*/
Loading

0 comments on commit 47ccad2

Please sign in to comment.