target: riscv: Sync with the RISC-V fork
Regenerate autogenerated debug_defines.{c,h} files from current
riscv-debug-spec, sync remaining RISC-V target files with the
RISC-V fork.
This is based on the work of (in alphabetic order):
Aleksey Lotosh <lotosh@gmail.com>
Alexander Rumyantsev <cetygamer@gmail.com>
Anastasiya Chernikova <anastasiya.chernikova@syntacore.com>
Anatoly Parshintsev <114445139+aap-sc@users.noreply.github.com>
Bernhard Rosenkränzer <bero@baylibre.com>
bluew <bluewww@users.noreply.github.com>
Carsten Gosvig <40368726+cgsfv@users.noreply.github.com>
cgsfv <cgsfv@users.noreply.github.com>
Craig Blackmore <craig.blackmore@embecosm.com>
Dan Robertson <danlrobertson89@gmail.com>
Darius Rad <darius@bluespec.com>
dave-estes-syzexion <53795406+dave-estes-syzexion@users.noreply.github.com>
Dmitry Ryzhov <dmitry.ryzhov@cloudbear.ru>
Dolu1990 <charles.papon.90@gmail.com>
Emmanuel Blot <emmanuel.blot@free.fr>
Ernie Edgar <43148441+ernie-sifive@users.noreply.github.com>
Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
Farid Khaydari <f.khaydari@syntacore.com>
Gleb Gagarin <gleb@sifive.com>
Greg Savin <43152568+SiFiveGregS@users.noreply.github.com>
Hang Xu <xuhang@eswincomputing.com>
Hsiangkai <Hsiangkai@gmail.com>
Jan Matyas <jan.matyas@codasip.com>
jhjung81 <48940114+jhjung81@users.noreply.github.com>
Jiuyang Liu <liu@jiuyang.me>
Kaspar Schleiser <kaspar@schleiser.de>
Khem Raj <raj.khem@gmail.com>
Kirill Radkin <kirill.radkin@syntacore.com>
liangzhen <zhen.liang@spacemit.com>
Liviu Ionescu <ilg@livius.net>
Marc Schink <openocd-dev@marcschink.de>
Megan Wachs <megan@sifive.com>
Nils Wistoff <git@wistoff.net>
Palmer Dabbelt <palmer@dabbelt.com>
panciyan <panciyan@eswincomputing.com>
Parshintsev Anatoly <anatoly.parshintsev@syntacore.com>
Paul George <command.paul@gmail.com>
Pavel S. Smirnov <Paul.Smirnov.aka.sps@gmail.com>
Philipp Wagner <mail@philipp-wagner.com>
Ryan Macdonald <rmac@sifive.com>
Samuel Obuch <samuel.obuch17@gmail.com>
Tarek BOCHKATI <tarek.bouchkati@gmail.com>
Tim Newsome <tim@casualhacker.net>
Tobias Kaiser <mail@tb-kaiser.de>
Tom Hebb <tommyhebb@gmail.com>
Tommy Murphy <tommy_murphy@hotmail.com>
wxjstz <wxjstz@126.com>
wzgpeter <wzgpeter@outlook.com>
Xiang W <wxjstz@126.com>
zhusonghe <zhusonghe@eswincomputing.com>
Checkpatch-ignore MULTISTATEMENT_MACRO_USE_DO_WHILE is added to allow a
macro in riscv-013.c that can't use do/while because it expands to a
"case ...:" statement.
Checkpatch-ignore TRAILING_SEMICOLON is added to allow a construct in
riscv-013.c where a macro expands to either code (where it needs the
semicolon) or a member of an enum (where it needs a comma).
Checkpatch-ignore LONG_LINE_COMMENT and NEW_TYPEDEFS lines are added for
the sake of the autogenerated files from riscv-debug-spec.
All non-autogenerated files have been updated for checkpatch compliance.
Checkpatch-ignore: LONG_LINE_COMMENT
Checkpatch-ignore: NEW_TYPEDEFS
Checkpatch-ignore: MULTISTATEMENT_MACRO_USE_DO_WHILE
Checkpatch-ignore: TRAILING_SEMICOLON
Change-Id: Ie594915a4d6e6f9d9dad6016b176ab76409a099a
Signed-off-by: Bernhard Rosenkränzer <bero@baylibre.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/8893
Tested-by: jenkins
Reviewed-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
This commit is contained in:
committed by
Tomas Vanek
parent
ab22b0bf8f
commit
5754aebc49
@@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef RISCV_H
|
||||
#define RISCV_H
|
||||
#ifndef OPENOCD_TARGET_RISCV_RISCV_H
|
||||
#define OPENOCD_TARGET_RISCV_RISCV_H
|
||||
|
||||
struct riscv_program;
|
||||
|
||||
@@ -9,28 +9,33 @@ struct riscv_program;
|
||||
#include "opcodes.h"
|
||||
#include "gdb_regs.h"
|
||||
#include "jtag/jtag.h"
|
||||
#include "target/register.h"
|
||||
#include "target/semihosting_common.h"
|
||||
#include "target/target.h"
|
||||
#include "target/register.h"
|
||||
#include <helper/command.h>
|
||||
#include <helper/bits.h>
|
||||
|
||||
#define RISCV_COMMON_MAGIC 0x52495356U
|
||||
|
||||
/* The register cache is statically allocated. */
|
||||
#define RISCV_MAX_HARTS 1024
|
||||
#define RISCV_MAX_REGISTERS 5000
|
||||
#define RISCV_MAX_HARTS ((int)BIT(20))
|
||||
#define RISCV_MAX_TRIGGERS 32
|
||||
#define RISCV_MAX_HWBPS 16
|
||||
#define RISCV_MAX_DMS 100
|
||||
|
||||
#define DEFAULT_COMMAND_TIMEOUT_SEC 2
|
||||
#define DEFAULT_RESET_TIMEOUT_SEC 30
|
||||
#define DEFAULT_COMMAND_TIMEOUT_SEC 5
|
||||
|
||||
#define RISCV_SATP_MODE(xlen) ((xlen) == 32 ? SATP32_MODE : SATP64_MODE)
|
||||
#define RISCV_SATP_PPN(xlen) ((xlen) == 32 ? SATP32_PPN : SATP64_PPN)
|
||||
#define RISCV_HGATP_MODE(xlen) ((xlen) == 32 ? HGATP32_MODE : HGATP64_MODE)
|
||||
#define RISCV_HGATP_PPN(xlen) ((xlen) == 32 ? HGATP32_PPN : HGATP64_PPN)
|
||||
#define RISCV_PGSHIFT 12
|
||||
#define RISCV_PGSIZE BIT(RISCV_PGSHIFT)
|
||||
#define RISCV_PGBASE(addr) ((addr) & ~(RISCV_PGSIZE - 1))
|
||||
#define RISCV_PGOFFSET(addr) ((addr) & (RISCV_PGSIZE - 1))
|
||||
|
||||
# define PG_MAX_LEVEL 4
|
||||
#define PG_MAX_LEVEL 5
|
||||
|
||||
#define RISCV_NUM_MEM_ACCESS_METHODS 3
|
||||
#define RISCV_BATCH_ALLOC_SIZE 128
|
||||
|
||||
extern struct target_type riscv011_target;
|
||||
extern struct target_type riscv013_target;
|
||||
@@ -42,16 +47,30 @@ typedef uint64_t riscv_reg_t;
|
||||
typedef uint32_t riscv_insn_t;
|
||||
typedef uint64_t riscv_addr_t;
|
||||
|
||||
enum yes_no_maybe {
|
||||
YNM_MAYBE,
|
||||
YNM_YES,
|
||||
YNM_NO
|
||||
};
|
||||
|
||||
enum riscv_mem_access_method {
|
||||
RISCV_MEM_ACCESS_UNSPECIFIED,
|
||||
RISCV_MEM_ACCESS_PROGBUF,
|
||||
RISCV_MEM_ACCESS_SYSBUS,
|
||||
RISCV_MEM_ACCESS_ABSTRACT
|
||||
RISCV_MEM_ACCESS_ABSTRACT,
|
||||
RISCV_MEM_ACCESS_MAX_METHODS_NUM
|
||||
};
|
||||
|
||||
enum riscv_virt2phys_mode {
|
||||
RISCV_VIRT2PHYS_MODE_HW,
|
||||
RISCV_VIRT2PHYS_MODE_SW,
|
||||
RISCV_VIRT2PHYS_MODE_OFF
|
||||
};
|
||||
|
||||
const char *riscv_virt2phys_mode_to_str(enum riscv_virt2phys_mode mode);
|
||||
|
||||
enum riscv_halt_reason {
|
||||
RISCV_HALT_INTERRUPT,
|
||||
RISCV_HALT_BREAKPOINT,
|
||||
RISCV_HALT_EBREAK,
|
||||
RISCV_HALT_SINGLESTEP,
|
||||
RISCV_HALT_TRIGGER,
|
||||
RISCV_HALT_UNKNOWN,
|
||||
@@ -59,8 +78,24 @@ enum riscv_halt_reason {
|
||||
RISCV_HALT_ERROR
|
||||
};
|
||||
|
||||
enum riscv_isrmasking_mode {
|
||||
/* RISCV_ISRMASK_AUTO, */ /* not supported yet */
|
||||
RISCV_ISRMASK_OFF,
|
||||
/* RISCV_ISRMASK_ON, */ /* not supported yet */
|
||||
RISCV_ISRMASK_STEPONLY,
|
||||
};
|
||||
|
||||
enum riscv_hart_state {
|
||||
RISCV_STATE_NON_EXISTENT,
|
||||
RISCV_STATE_RUNNING,
|
||||
RISCV_STATE_HALTED,
|
||||
RISCV_STATE_UNAVAILABLE
|
||||
};
|
||||
|
||||
/* RISC-V-specific data assigned to a register. */
|
||||
typedef struct {
|
||||
struct target *target;
|
||||
/* Abstract command's regno for a custom register. */
|
||||
unsigned int custom_number;
|
||||
} riscv_reg_info_t;
|
||||
|
||||
@@ -87,6 +122,49 @@ typedef struct {
|
||||
char *name;
|
||||
} range_list_t;
|
||||
|
||||
#define DTM_DTMCS_VERSION_UNKNOWN ((unsigned int)-1)
|
||||
#define RISCV_TINFO_VERSION_UNKNOWN (-1)
|
||||
|
||||
#define RISCV013_DTMCS_ABITS_MIN 7
|
||||
#define RISCV013_DTMCS_ABITS_MAX 32
|
||||
|
||||
struct reg_name_table {
|
||||
unsigned int num_entries;
|
||||
char **reg_names;
|
||||
};
|
||||
|
||||
struct riscv_mem_access_args {
|
||||
target_addr_t address;
|
||||
|
||||
const uint8_t *write_buffer;
|
||||
uint8_t *read_buffer;
|
||||
|
||||
uint32_t size;
|
||||
uint32_t count;
|
||||
uint32_t increment;
|
||||
};
|
||||
|
||||
static inline bool
|
||||
riscv_mem_access_is_valid(const struct riscv_mem_access_args args)
|
||||
{
|
||||
return !args.read_buffer != !args.write_buffer;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
riscv_mem_access_is_read(const struct riscv_mem_access_args args)
|
||||
{
|
||||
assert(riscv_mem_access_is_valid(args));
|
||||
return !args.write_buffer && args.read_buffer;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
riscv_mem_access_is_write(const struct riscv_mem_access_args args)
|
||||
{
|
||||
assert(riscv_mem_access_is_valid(args));
|
||||
return !args.read_buffer && args.write_buffer;
|
||||
}
|
||||
|
||||
|
||||
struct riscv_info {
|
||||
unsigned int common_magic;
|
||||
|
||||
@@ -95,36 +173,57 @@ struct riscv_info {
|
||||
struct command_context *cmd_ctx;
|
||||
void *version_specific;
|
||||
|
||||
/* The hart that is currently being debugged. Note that this is
|
||||
* different than the hartid that the RTOS is expected to use. This
|
||||
* one will change all the time, it's more of a global argument to
|
||||
* every function than an actual */
|
||||
int current_hartid;
|
||||
|
||||
/* Single buffer that contains all register names, instead of calling
|
||||
* malloc for each register. Needs to be freed when reg_list is freed. */
|
||||
char *reg_names;
|
||||
struct reg_name_table custom_register_names;
|
||||
char **reg_names;
|
||||
|
||||
/* It's possible that each core has a different supported ISA set. */
|
||||
int xlen;
|
||||
/* TODO: use the value from the register cache instead. */
|
||||
riscv_reg_t misa;
|
||||
/* Cached value of vlenb. 0 if vlenb is not readable for some reason. */
|
||||
/* TODO: use the value from the register cache instead.
|
||||
* Cached value of vlenb. 0 indicates there is no vector support.
|
||||
* Note that you can have vector support without misa.V set, because
|
||||
* Zve* extensions implement vector registers without setting misa.V. */
|
||||
unsigned int vlenb;
|
||||
|
||||
/* The number of triggers per hart. */
|
||||
unsigned int trigger_count;
|
||||
|
||||
/* For each physical trigger, contains -1 if the hwbp is available, or the
|
||||
* unique_id of the breakpoint/watchpoint that is using it.
|
||||
/* Data structure to record known unsupported tdata1+tdata2 trigger CSR values.
|
||||
* This is to avoid repetitive attempts to set trigger configurations that are already
|
||||
* known to be unsupported in the HW.
|
||||
* A separate data structure is created for each trigger. */
|
||||
struct list_head *wp_triggers_negative_cache;
|
||||
|
||||
/* record the tinfo of each trigger */
|
||||
unsigned int trigger_tinfo[RISCV_MAX_TRIGGERS];
|
||||
|
||||
/* Version of the implemented Sdtrig extension */
|
||||
int tinfo_version;
|
||||
|
||||
/* Record if single-step is needed prior to resuming
|
||||
* from a software breakpoint or trigger.
|
||||
* Single-step is needed if the instruction that
|
||||
* caused the halt was not retired. That is,
|
||||
* when we halted "before" that instruction.
|
||||
*/
|
||||
bool need_single_step;
|
||||
|
||||
/* For each physical trigger contains:
|
||||
* -1: the hwbp is available
|
||||
* -4: The trigger is used by the itrigger command
|
||||
* -5: The trigger is used by the etrigger command
|
||||
* >= 0: unique_id of the breakpoint/watchpoint that is using it.
|
||||
* Note that in RTOS mode the triggers are the same across all harts the
|
||||
* target controls, while otherwise only a single hart is controlled. */
|
||||
int trigger_unique_id[RISCV_MAX_HWBPS];
|
||||
int64_t trigger_unique_id[RISCV_MAX_HWBPS];
|
||||
|
||||
/* The number of entries in the debug buffer. */
|
||||
int debug_buffer_size;
|
||||
/* The unique id of the trigger that caused the most recent halt. If the
|
||||
* most recent halt was not caused by a trigger, then this is -1. */
|
||||
int64_t trigger_hit;
|
||||
|
||||
/* This hart contains an implicit ebreak at the end of the program buffer. */
|
||||
bool impebreak;
|
||||
/* The configured approach to translate virtual addresses to physical */
|
||||
enum riscv_virt2phys_mode virt2phys_mode;
|
||||
|
||||
bool triggers_enumerated;
|
||||
|
||||
@@ -137,21 +236,37 @@ struct riscv_info {
|
||||
/* This target was selected using hasel. */
|
||||
bool selected;
|
||||
|
||||
/* Used by riscv_openocd_poll(). */
|
||||
bool halted_needs_event_callback;
|
||||
enum target_event halted_callback_event;
|
||||
unsigned int halt_group_repoll_count;
|
||||
|
||||
enum riscv_isrmasking_mode isrmask_mode;
|
||||
|
||||
/* Helper functions that target the various RISC-V debug spec
|
||||
* implementations. */
|
||||
int (*get_register)(struct target *target, riscv_reg_t *value, int regid);
|
||||
int (*set_register)(struct target *target, int regid, uint64_t value);
|
||||
int (*get_register_buf)(struct target *target, uint8_t *buf, int regno);
|
||||
int (*set_register_buf)(struct target *target, int regno,
|
||||
const uint8_t *buf);
|
||||
int (*select_current_hart)(struct target *target);
|
||||
bool (*is_halted)(struct target *target);
|
||||
int (*select_target)(struct target *target);
|
||||
int (*get_hart_state)(struct target *target, enum riscv_hart_state *state);
|
||||
/* Resume this target, as well as every other prepped target that can be
|
||||
* resumed near-simultaneously. Clear the prepped flag on any target that
|
||||
* was resumed. */
|
||||
int (*resume_go)(struct target *target);
|
||||
int (*step_current_hart)(struct target *target);
|
||||
int (*on_halt)(struct target *target);
|
||||
|
||||
/* These get called from riscv_poll_hart(), which is a house of cards
|
||||
* together with openocd_poll(), so be careful not to upset things too
|
||||
* much. */
|
||||
int (*handle_became_halted)(struct target *target,
|
||||
enum riscv_hart_state previous_riscv_state);
|
||||
int (*handle_became_running)(struct target *target,
|
||||
enum riscv_hart_state previous_riscv_state);
|
||||
int (*handle_became_unavailable)(struct target *target,
|
||||
enum riscv_hart_state previous_riscv_state);
|
||||
|
||||
/* Called periodically (no guarantees about frequency), while there's
|
||||
* nothing else going on. */
|
||||
int (*tick)(struct target *target);
|
||||
|
||||
/* Get this target as ready as possible to resume, without actually
|
||||
* resuming. */
|
||||
int (*resume_prep)(struct target *target);
|
||||
@@ -159,14 +274,14 @@ struct riscv_info {
|
||||
int (*halt_go)(struct target *target);
|
||||
int (*on_step)(struct target *target);
|
||||
enum riscv_halt_reason (*halt_reason)(struct target *target);
|
||||
int (*write_debug_buffer)(struct target *target, unsigned int index,
|
||||
riscv_insn_t d);
|
||||
riscv_insn_t (*read_debug_buffer)(struct target *target, unsigned int index);
|
||||
int (*execute_debug_buffer)(struct target *target);
|
||||
int (*dmi_write_u64_bits)(struct target *target);
|
||||
void (*fill_dmi_write_u64)(struct target *target, char *buf, int a, uint64_t d);
|
||||
void (*fill_dmi_read_u64)(struct target *target, char *buf, int a);
|
||||
void (*fill_dmi_nop_u64)(struct target *target, char *buf);
|
||||
int (*write_progbuf)(struct target *target, unsigned int index, riscv_insn_t d);
|
||||
riscv_insn_t (*read_progbuf)(struct target *target, unsigned int index);
|
||||
int (*execute_progbuf)(struct target *target, uint32_t *cmderr);
|
||||
int (*invalidate_cached_progbuf)(struct target *target);
|
||||
unsigned int (*get_dmi_address_bits)(const struct target *target);
|
||||
void (*fill_dmi_write)(const struct target *target, uint8_t *buf, uint32_t a, uint32_t d);
|
||||
void (*fill_dmi_read)(const struct target *target, uint8_t *buf, uint32_t a);
|
||||
void (*fill_dm_nop)(const struct target *target, uint8_t *buf);
|
||||
|
||||
int (*authdata_read)(struct target *target, uint32_t *value, unsigned int index);
|
||||
int (*authdata_write)(struct target *target, uint32_t value, unsigned int index);
|
||||
@@ -174,20 +289,29 @@ struct riscv_info {
|
||||
int (*dmi_read)(struct target *target, uint32_t *value, uint32_t address);
|
||||
int (*dmi_write)(struct target *target, uint32_t address, uint32_t value);
|
||||
|
||||
bool (*get_impebreak)(const struct target *target);
|
||||
unsigned int (*get_progbufsize)(const struct target *target);
|
||||
|
||||
/* Get the DMI address of target's DM's register.
|
||||
* The function should return the passed address
|
||||
* if the target is not assigned a DM yet.
|
||||
*/
|
||||
uint32_t (*get_dmi_address)(const struct target *target, uint32_t dm_address);
|
||||
|
||||
int (*sample_memory)(struct target *target,
|
||||
struct riscv_sample_buf *buf,
|
||||
riscv_sample_config_t *config,
|
||||
int64_t until_ms);
|
||||
|
||||
int (*read_memory)(struct target *target, target_addr_t address,
|
||||
uint32_t size, uint32_t count, uint8_t *buffer, uint32_t increment);
|
||||
int (*access_memory)(struct target *target, const struct riscv_mem_access_args args);
|
||||
|
||||
/* How many harts are attached to the DM that this target is attached to? */
|
||||
int (*hart_count)(struct target *target);
|
||||
unsigned int (*data_bits)(struct target *target);
|
||||
|
||||
COMMAND_HELPER((*print_info), struct target *target);
|
||||
|
||||
/* Storage for arch_info of non-custom registers. */
|
||||
riscv_reg_info_t shared_reg_info;
|
||||
|
||||
/* Storage for vector register types. */
|
||||
struct reg_data_type_vector vector_uint8;
|
||||
struct reg_data_type_vector vector_uint16;
|
||||
@@ -203,18 +327,16 @@ struct riscv_info {
|
||||
struct reg_data_type_union vector_union;
|
||||
struct reg_data_type type_vector;
|
||||
|
||||
/* Set when trigger registers are changed by the user. This indicates we eed
|
||||
* to beware that we may hit a trigger that we didn't realize had been set. */
|
||||
bool manual_hwbp_set;
|
||||
bool *reserved_triggers;
|
||||
|
||||
/* Memory access methods to use, ordered by priority, highest to lowest. */
|
||||
int mem_access_methods[RISCV_NUM_MEM_ACCESS_METHODS];
|
||||
enum riscv_mem_access_method mem_access_methods[RISCV_MEM_ACCESS_MAX_METHODS_NUM];
|
||||
|
||||
unsigned int num_enabled_mem_access_methods;
|
||||
|
||||
/* Different memory regions may need different methods but single configuration is applied
|
||||
* for all. Following flags are used to warn only once about failing memory access method. */
|
||||
bool mem_access_progbuf_warn;
|
||||
bool mem_access_sysbus_warn;
|
||||
bool mem_access_abstract_warn;
|
||||
bool mem_access_warn[RISCV_MEM_ACCESS_MAX_METHODS_NUM];
|
||||
|
||||
/* In addition to the ones in the standard spec, we'll also expose additional
|
||||
* CSRs in this list. */
|
||||
@@ -224,10 +346,47 @@ struct riscv_info {
|
||||
* from range 0xc000 ... 0xffff. */
|
||||
struct list_head expose_custom;
|
||||
|
||||
/* The list of registers to mark as "hidden". Hidden registers are available
|
||||
* but do not appear in gdb targets description or reg command output. */
|
||||
struct list_head hide_csr;
|
||||
|
||||
riscv_sample_config_t sample_config;
|
||||
struct riscv_sample_buf sample_buf;
|
||||
|
||||
/* Track when we were last asked to do something substantial. */
|
||||
int64_t last_activity;
|
||||
|
||||
enum yes_no_maybe vsew64_supported;
|
||||
|
||||
bool range_trigger_fallback_encountered;
|
||||
|
||||
bool wp_allow_equality_match_trigger;
|
||||
bool wp_allow_napot_trigger;
|
||||
bool wp_allow_ge_lt_trigger;
|
||||
|
||||
bool autofence;
|
||||
};
|
||||
|
||||
enum riscv_priv_mode {
|
||||
RISCV_MODE_M,
|
||||
RISCV_MODE_S,
|
||||
RISCV_MODE_U,
|
||||
RISCV_MODE_VS,
|
||||
RISCV_MODE_VU,
|
||||
N_RISCV_MODE
|
||||
};
|
||||
|
||||
struct riscv_private_config {
|
||||
bool dcsr_ebreak_fields[N_RISCV_MODE];
|
||||
};
|
||||
|
||||
static inline struct riscv_private_config
|
||||
*riscv_private_config(const struct target *target)
|
||||
{
|
||||
assert(target->private_config);
|
||||
return target->private_config;
|
||||
}
|
||||
|
||||
COMMAND_HELPER(riscv_print_info_line, const char *section, const char *key,
|
||||
unsigned int value);
|
||||
|
||||
@@ -240,6 +399,7 @@ typedef struct {
|
||||
const char *name;
|
||||
int level;
|
||||
unsigned int va_bits;
|
||||
/* log2(PTESIZE) */
|
||||
unsigned int pte_shift;
|
||||
unsigned int vpn_shift[PG_MAX_LEVEL];
|
||||
unsigned int vpn_mask[PG_MAX_LEVEL];
|
||||
@@ -249,16 +409,11 @@ typedef struct {
|
||||
unsigned int pa_ppn_mask[PG_MAX_LEVEL];
|
||||
} virt2phys_info_t;
|
||||
|
||||
bool riscv_virt2phys_mode_is_hw(const struct target *target);
|
||||
bool riscv_virt2phys_mode_is_sw(const struct target *target);
|
||||
|
||||
/* Wall-clock timeout for a command/access. Settable via RISC-V Target commands.*/
|
||||
extern int riscv_command_timeout_sec;
|
||||
|
||||
/* Wall-clock timeout after reset. Settable via RISC-V Target commands.*/
|
||||
extern int riscv_reset_timeout_sec;
|
||||
|
||||
extern bool riscv_enable_virtual;
|
||||
extern bool riscv_ebreakm;
|
||||
extern bool riscv_ebreaks;
|
||||
extern bool riscv_ebreaku;
|
||||
int riscv_get_command_timeout_sec(void);
|
||||
|
||||
/* Everything needs the RISC-V specific info structure, so here's a nice macro
|
||||
* that provides that. */
|
||||
@@ -279,13 +434,14 @@ extern struct scan_field select_dtmcontrol;
|
||||
extern struct scan_field select_dbus;
|
||||
extern struct scan_field select_idcode;
|
||||
|
||||
int dtmcs_scan(struct jtag_tap *tap, uint32_t out, uint32_t *in_ptr);
|
||||
|
||||
extern struct scan_field *bscan_tunneled_select_dmi;
|
||||
extern uint32_t bscan_tunneled_select_dmi_num_fields;
|
||||
typedef enum { BSCAN_TUNNEL_NESTED_TAP, BSCAN_TUNNEL_DATA_REGISTER } bscan_tunnel_type_t;
|
||||
extern int bscan_tunnel_ir_width;
|
||||
extern uint8_t bscan_tunnel_ir_width;
|
||||
|
||||
uint32_t dtmcontrol_scan_via_bscan(struct target *target, uint32_t out);
|
||||
void select_dmi_via_bscan(struct target *target);
|
||||
void select_dmi_via_bscan(struct jtag_tap *tap);
|
||||
|
||||
/*** OpenOCD Interface */
|
||||
int riscv_openocd_poll(struct target *target);
|
||||
@@ -299,52 +455,37 @@ int riscv_openocd_step(
|
||||
bool handle_breakpoints
|
||||
);
|
||||
|
||||
int riscv_openocd_assert_reset(struct target *target);
|
||||
int riscv_openocd_deassert_reset(struct target *target);
|
||||
|
||||
/*** RISC-V Interface ***/
|
||||
|
||||
bool riscv_supports_extension(struct target *target, char letter);
|
||||
bool riscv_supports_extension(const struct target *target, char letter);
|
||||
|
||||
/* Returns XLEN for the given (or current) hart. */
|
||||
unsigned int riscv_xlen(const struct target *target);
|
||||
int riscv_xlen_of_hart(const struct target *target);
|
||||
|
||||
/* Sets the current hart, which is the hart that will actually be used when
|
||||
* issuing debug commands. */
|
||||
int riscv_set_current_hartid(struct target *target, int hartid);
|
||||
int riscv_select_current_hart(struct target *target);
|
||||
int riscv_current_hartid(const struct target *target);
|
||||
/* Returns VLENB for the given (or current) hart. */
|
||||
unsigned int riscv_vlenb(const struct target *target);
|
||||
|
||||
/*** Support functions for the RISC-V 'RTOS', which provides multihart support
|
||||
* without requiring multiple targets. */
|
||||
|
||||
/* Lists the number of harts in the system, which are assumed to be
|
||||
* consecutive and start with mhartid=0. */
|
||||
int riscv_count_harts(struct target *target);
|
||||
|
||||
/** Set register, updating the cache. */
|
||||
int riscv_set_register(struct target *target, enum gdb_regno i, riscv_reg_t v);
|
||||
/** Get register, from the cache if it's in there. */
|
||||
int riscv_get_register(struct target *target, riscv_reg_t *value,
|
||||
enum gdb_regno r);
|
||||
|
||||
/* Checks the state of the current hart -- "is_halted" checks the actual
|
||||
* on-device register. */
|
||||
bool riscv_is_halted(struct target *target);
|
||||
int riscv_get_hart_state(struct target *target, enum riscv_hart_state *state);
|
||||
|
||||
/* These helper functions let the generic program interface get target-specific
|
||||
* information. */
|
||||
size_t riscv_debug_buffer_size(struct target *target);
|
||||
unsigned int riscv_progbuf_size(struct target *target);
|
||||
|
||||
riscv_insn_t riscv_read_debug_buffer(struct target *target, int index);
|
||||
int riscv_write_debug_buffer(struct target *target, int index, riscv_insn_t insn);
|
||||
int riscv_execute_debug_buffer(struct target *target);
|
||||
riscv_insn_t riscv_read_progbuf(struct target *target, int index);
|
||||
int riscv_write_progbuf(struct target *target, unsigned int index, riscv_insn_t insn);
|
||||
int riscv_execute_progbuf(struct target *target, uint32_t *cmderr);
|
||||
|
||||
void riscv_fill_dmi_nop_u64(struct target *target, char *buf);
|
||||
void riscv_fill_dmi_write_u64(struct target *target, char *buf, int a, uint64_t d);
|
||||
void riscv_fill_dmi_read_u64(struct target *target, char *buf, int a);
|
||||
int riscv_dmi_write_u64_bits(struct target *target);
|
||||
void riscv_fill_dm_nop(const struct target *target, uint8_t *buf);
|
||||
void riscv_fill_dmi_write(const struct target *target, uint8_t *buf, uint32_t a, uint32_t d);
|
||||
void riscv_fill_dmi_read(const struct target *target, uint8_t *buf, uint32_t a);
|
||||
unsigned int riscv_get_dmi_address_bits(const struct target *target);
|
||||
|
||||
uint32_t riscv_get_dmi_address(const struct target *target, uint32_t dm_address);
|
||||
|
||||
int riscv_enumerate_triggers(struct target *target);
|
||||
|
||||
@@ -352,16 +493,14 @@ int riscv_add_watchpoint(struct target *target, struct watchpoint *watchpoint);
|
||||
int riscv_remove_watchpoint(struct target *target,
|
||||
struct watchpoint *watchpoint);
|
||||
|
||||
int riscv_init_registers(struct target *target);
|
||||
|
||||
void riscv_semihosting_init(struct target *target);
|
||||
|
||||
enum semihosting_result riscv_semihosting(struct target *target, int *retval);
|
||||
|
||||
void riscv_add_bscan_tunneled_scan(struct target *target, struct scan_field *field,
|
||||
void riscv_add_bscan_tunneled_scan(struct jtag_tap *tap, const struct scan_field *field,
|
||||
riscv_bscan_tunneled_scan_context_t *ctxt);
|
||||
|
||||
int riscv_read_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer);
|
||||
int riscv_write_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer);
|
||||
|
||||
#endif
|
||||
#endif /* OPENOCD_TARGET_RISCV_RISCV_H */
|
||||
|
||||
Reference in New Issue
Block a user