Merge remote-tracking branch 'origin/riscv' into HEAD
This commit is contained in:
@@ -19,6 +19,7 @@ noinst_LTLIBRARIES += %D%/libtarget.la
|
||||
$(AVR32_SRC) \
|
||||
$(MIPS32_SRC) \
|
||||
$(NDS32_SRC) \
|
||||
$(STM8_SRC) \
|
||||
$(INTEL_IA32_SRC) \
|
||||
$(RISCV_SRC) \
|
||||
%D%/avrt.c \
|
||||
@@ -125,6 +126,9 @@ NDS32_SRC = \
|
||||
%D%/nds32_v3m.c \
|
||||
%D%/nds32_aice.c
|
||||
|
||||
STM8_SRC = \
|
||||
%D%/stm8.c
|
||||
|
||||
INTEL_IA32_SRC = \
|
||||
%D%/quark_x10xx.c \
|
||||
%D%/quark_d20xx.c \
|
||||
@@ -213,6 +217,7 @@ RISCV_SRC = \
|
||||
%D%/nds32_v3.h \
|
||||
%D%/nds32_v3m.h \
|
||||
%D%/nds32_aice.h \
|
||||
%D%/stm8.h \
|
||||
%D%/lakemont.h \
|
||||
%D%/x86_32_common.h \
|
||||
%D%/arm_cti.h
|
||||
|
||||
@@ -427,7 +427,10 @@ static int swd_init(struct command_context *ctx)
|
||||
/* First connect after init is not reconnecting. */
|
||||
dap->do_reconnect = false;
|
||||
|
||||
return swd_connect(dap);
|
||||
int retval = swd_connect(dap);
|
||||
if (retval != ERROR_OK)
|
||||
LOG_ERROR("SWD connect failed");
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct transport swd_transport = {
|
||||
|
||||
@@ -157,6 +157,9 @@ struct arm {
|
||||
|
||||
int (*setup_semihosting)(struct target *target, int enable);
|
||||
|
||||
/** Semihosting command line. */
|
||||
char *semihosting_cmdline;
|
||||
|
||||
/** Backpointer to the target. */
|
||||
struct target *target;
|
||||
|
||||
|
||||
@@ -346,8 +346,10 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz
|
||||
case 4:
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
|
||||
/* fallthrough */
|
||||
case 1:
|
||||
outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
|
||||
}
|
||||
@@ -509,8 +511,10 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint
|
||||
case 4:
|
||||
*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
|
||||
*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
|
||||
/* fallthrough */
|
||||
case 1:
|
||||
*buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
|
||||
}
|
||||
@@ -519,8 +523,10 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint
|
||||
case 4:
|
||||
*buffer++ = *read_ptr >> 8 * (address++ & 3);
|
||||
*buffer++ = *read_ptr >> 8 * (address++ & 3);
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
*buffer++ = *read_ptr >> 8 * (address++ & 3);
|
||||
/* fallthrough */
|
||||
case 1:
|
||||
*buffer++ = *read_ptr >> 8 * (address++ & 3);
|
||||
}
|
||||
@@ -1053,7 +1059,7 @@ static int dap_rom_display(struct command_context *cmd_ctx,
|
||||
int retval;
|
||||
uint64_t pid;
|
||||
uint32_t cid;
|
||||
char tabs[7] = "";
|
||||
char tabs[16] = "";
|
||||
|
||||
if (depth > 16) {
|
||||
command_print(cmd_ctx, "\tTables too deep");
|
||||
|
||||
@@ -3299,6 +3299,7 @@ static int t2ev_data_immed(uint32_t opcode, uint32_t address,
|
||||
case 0x10:
|
||||
case 0x12:
|
||||
is_signed = true;
|
||||
/* fallthrough */
|
||||
case 0x18:
|
||||
case 0x1a:
|
||||
/* signed/unsigned saturated add */
|
||||
|
||||
@@ -465,7 +465,7 @@ static int do_semihosting(struct target *target)
|
||||
else {
|
||||
uint32_t a = target_buffer_get_u32(target, params+0);
|
||||
uint32_t l = target_buffer_get_u32(target, params+4);
|
||||
char *arg = "foobar";
|
||||
char *arg = arm->semihosting_cmdline != NULL ? arm->semihosting_cmdline : "";
|
||||
uint32_t s = strlen(arg) + 1;
|
||||
if (l < s)
|
||||
arm->semihosting_result = -1;
|
||||
|
||||
@@ -1091,6 +1091,42 @@ COMMAND_HANDLER(handle_arm_semihosting_fileio_command)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
COMMAND_HANDLER(handle_arm_semihosting_cmdline)
|
||||
{
|
||||
struct target *target = get_current_target(CMD_CTX);
|
||||
unsigned int i;
|
||||
|
||||
if (target == NULL) {
|
||||
LOG_ERROR("No target selected");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
struct arm *arm = target_to_arm(target);
|
||||
|
||||
if (!is_arm(arm)) {
|
||||
command_print(CMD_CTX, "current target isn't an ARM");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (!arm->setup_semihosting) {
|
||||
command_print(CMD_CTX, "semihosting not supported for current target");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
free(arm->semihosting_cmdline);
|
||||
arm->semihosting_cmdline = CMD_ARGC > 0 ? strdup(CMD_ARGV[0]) : NULL;
|
||||
|
||||
for (i = 1; i < CMD_ARGC; i++) {
|
||||
char *cmdline = alloc_printf("%s %s", arm->semihosting_cmdline, CMD_ARGV[i]);
|
||||
if (cmdline == NULL)
|
||||
break;
|
||||
free(arm->semihosting_cmdline);
|
||||
arm->semihosting_cmdline = cmdline;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static const struct command_registration arm_exec_command_handlers[] = {
|
||||
{
|
||||
.name = "reg",
|
||||
@@ -1133,6 +1169,13 @@ static const struct command_registration arm_exec_command_handlers[] = {
|
||||
.usage = "['enable'|'disable']",
|
||||
.help = "activate support for semihosting operations",
|
||||
},
|
||||
{
|
||||
"semihosting_cmdline",
|
||||
.handler = handle_arm_semihosting_cmdline,
|
||||
.mode = COMMAND_EXEC,
|
||||
.usage = "arguments",
|
||||
.help = "command line arguments to be passed to program",
|
||||
},
|
||||
{
|
||||
"semihosting_fileio",
|
||||
.handler = handle_arm_semihosting_fileio_command,
|
||||
|
||||
+1
-1
@@ -355,7 +355,7 @@ int armv7a_mmu_translate_va_pa(struct target *target, uint32_t va,
|
||||
break;
|
||||
case 7:
|
||||
LOG_INFO("inner: Write-Back, no Write-Allocate");
|
||||
|
||||
break;
|
||||
default:
|
||||
LOG_INFO("inner: %" PRIx32 " ???", INNER);
|
||||
}
|
||||
|
||||
+1
-1
@@ -174,7 +174,7 @@ target_to_armv7m(struct target *target)
|
||||
return container_of(target->arch_info, struct armv7m_common, arm);
|
||||
}
|
||||
|
||||
static inline bool is_armv7m(struct armv7m_common *armv7m)
|
||||
static inline bool is_armv7m(const struct armv7m_common *armv7m)
|
||||
{
|
||||
return armv7m->common_magic == ARMV7M_COMMON_MAGIC;
|
||||
}
|
||||
|
||||
+4
-10
@@ -168,12 +168,8 @@ static int cortex_m_single_step_core(struct target *target)
|
||||
{
|
||||
struct cortex_m_common *cortex_m = target_to_cm(target);
|
||||
struct armv7m_common *armv7m = &cortex_m->armv7m;
|
||||
uint32_t dhcsr_save;
|
||||
int retval;
|
||||
|
||||
/* backup dhcsr reg */
|
||||
dhcsr_save = cortex_m->dcb_dhcsr;
|
||||
|
||||
/* Mask interrupts before clearing halt, if done already. This avoids
|
||||
* Erratum 377497 (fixed in r1p0) where setting MASKINTS while clearing
|
||||
* HALT can put the core into an unknown state.
|
||||
@@ -191,7 +187,6 @@ static int cortex_m_single_step_core(struct target *target)
|
||||
LOG_DEBUG(" ");
|
||||
|
||||
/* restore dhcsr reg */
|
||||
cortex_m->dcb_dhcsr = dhcsr_save;
|
||||
cortex_m_clear_halt(target);
|
||||
|
||||
return ERROR_OK;
|
||||
@@ -242,7 +237,7 @@ static int cortex_m_endreset_event(struct target *target)
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) {
|
||||
retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_DEBUGEN);
|
||||
retval = cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP | C_MASKINTS);
|
||||
if (retval != ERROR_OK)
|
||||
return retval;
|
||||
}
|
||||
@@ -1005,12 +1000,12 @@ static int cortex_m_assert_reset(struct target *target)
|
||||
/* Store important errors instead of failing and proceed to reset assert */
|
||||
|
||||
if (retval != ERROR_OK || !(cortex_m->dcb_dhcsr & C_DEBUGEN))
|
||||
retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_DEBUGEN);
|
||||
retval = cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP | C_MASKINTS);
|
||||
|
||||
/* If the processor is sleeping in a WFI or WFE instruction, the
|
||||
* C_HALT bit must be asserted to regain control */
|
||||
if (retval == ERROR_OK && (cortex_m->dcb_dhcsr & S_SLEEP))
|
||||
retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN);
|
||||
retval = cortex_m_write_debug_halt_mask(target, C_HALT, 0);
|
||||
|
||||
mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0);
|
||||
/* Ignore less important errors */
|
||||
@@ -1018,8 +1013,7 @@ static int cortex_m_assert_reset(struct target *target)
|
||||
if (!target->reset_halt) {
|
||||
/* Set/Clear C_MASKINTS in a separate operation */
|
||||
if (cortex_m->dcb_dhcsr & C_MASKINTS)
|
||||
mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR,
|
||||
DBGKEY | C_DEBUGEN | C_HALT);
|
||||
cortex_m_write_debug_halt_mask(target, 0, C_MASKINTS);
|
||||
|
||||
/* clear any debug flags before resuming */
|
||||
cortex_m_clear_halt(target);
|
||||
|
||||
@@ -816,7 +816,7 @@ static int jim_nds32_bulk_read(Jim_Interp *interp, int argc, Jim_Obj * const *ar
|
||||
uint32_t *data = malloc(count * sizeof(uint32_t));
|
||||
int result;
|
||||
result = target_read_buffer(target, address, count * 4, (uint8_t *)data);
|
||||
char data_str[11];
|
||||
char data_str[12];
|
||||
|
||||
jim_wide i;
|
||||
Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
|
||||
|
||||
@@ -88,7 +88,6 @@ static int jsp_new_connection(struct connection *connection)
|
||||
telnet_connection->closed = 0;
|
||||
telnet_connection->line_size = 0;
|
||||
telnet_connection->line_cursor = 0;
|
||||
telnet_connection->option_size = 0;
|
||||
telnet_connection->state = TELNET_STATE_DATA;
|
||||
|
||||
/* negotiate telnet options */
|
||||
|
||||
@@ -114,9 +114,9 @@ struct reg_data_type {
|
||||
};
|
||||
|
||||
struct reg {
|
||||
/** Canonical name of the register. */
|
||||
/* Canonical name of the register. */
|
||||
const char *name;
|
||||
/** Number that gdb uses to access this register. */
|
||||
/* Number that gdb uses to access this register. */
|
||||
uint32_t number;
|
||||
/* TODO. This should probably be const. */
|
||||
struct reg_feature *feature;
|
||||
|
||||
@@ -17,7 +17,7 @@ static uint32_t load(const struct target *target, unsigned int rd,
|
||||
return ld(rd, base, offset);
|
||||
}
|
||||
assert(0);
|
||||
return 0; // Silence -Werror=return-type
|
||||
return 0; /* Silence -Werror=return-type */
|
||||
}
|
||||
|
||||
static uint32_t store(const struct target *target, unsigned int src,
|
||||
@@ -32,7 +32,7 @@ static uint32_t store(const struct target *target, unsigned int src,
|
||||
return sd(src, base, offset);
|
||||
}
|
||||
assert(0);
|
||||
return 0; // Silence -Werror=return-type
|
||||
return 0; /* Silence -Werror=return-type */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -42,20 +42,19 @@ bool riscv_batch_full(struct riscv_batch *batch)
|
||||
return batch->used_scans > (batch->allocated_scans - 4);
|
||||
}
|
||||
|
||||
void riscv_batch_run(struct riscv_batch *batch)
|
||||
int riscv_batch_run(struct riscv_batch *batch)
|
||||
{
|
||||
if (batch->used_scans == 0) {
|
||||
LOG_DEBUG("Ignoring empty batch.");
|
||||
return;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
keep_alive();
|
||||
keep_alive();
|
||||
|
||||
LOG_DEBUG("running a batch of %ld scans", (long)batch->used_scans);
|
||||
riscv_batch_add_nop(batch);
|
||||
|
||||
for (size_t i = 0; i < batch->used_scans; ++i) {
|
||||
dump_field(batch->fields + i);
|
||||
jtag_add_dr_scan(batch->target->tap, 1, batch->fields + i, TAP_IDLE);
|
||||
if (batch->idle_count > 0)
|
||||
jtag_add_runtest(batch->idle_count, TAP_IDLE);
|
||||
@@ -64,11 +63,13 @@ void riscv_batch_run(struct riscv_batch *batch)
|
||||
LOG_DEBUG("executing queue");
|
||||
if (jtag_execute_queue() != ERROR_OK) {
|
||||
LOG_ERROR("Unable to execute JTAG queue");
|
||||
abort();
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < batch->used_scans; ++i)
|
||||
dump_field(batch->fields + i);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
void riscv_batch_add_dmi_write(struct riscv_batch *batch, unsigned address, uint64_t data)
|
||||
@@ -139,8 +140,8 @@ void riscv_batch_add_nop(struct riscv_batch *batch)
|
||||
|
||||
void dump_field(const struct scan_field *field)
|
||||
{
|
||||
static const char *op_string[] = {"-", "r", "w", "?"};
|
||||
static const char *status_string[] = {"+", "?", "F", "b"};
|
||||
static const char * const op_string[] = {"-", "r", "w", "?"};
|
||||
static const char * const status_string[] = {"+", "?", "F", "b"};
|
||||
|
||||
if (debug_level < LOG_LVL_DEBUG)
|
||||
return;
|
||||
|
||||
@@ -48,7 +48,7 @@ void riscv_batch_free(struct riscv_batch *batch);
|
||||
bool riscv_batch_full(struct riscv_batch *batch);
|
||||
|
||||
/* Executes this scan batch. */
|
||||
void riscv_batch_run(struct riscv_batch *batch);
|
||||
int riscv_batch_run(struct riscv_batch *batch);
|
||||
|
||||
/* Adds a DMI write to this batch. */
|
||||
void riscv_batch_add_dmi_write(struct riscv_batch *batch, unsigned address, uint64_t data);
|
||||
|
||||
+173
-107
@@ -173,12 +173,6 @@
|
||||
#define CSR_DCSR_EBREAKM_LENGTH 1
|
||||
#define CSR_DCSR_EBREAKM (0x1U << CSR_DCSR_EBREAKM_OFFSET)
|
||||
/*
|
||||
* When 1, {\tt ebreak} instructions in Hypervisor Mode enter Debug Mode.
|
||||
*/
|
||||
#define CSR_DCSR_EBREAKH_OFFSET 14
|
||||
#define CSR_DCSR_EBREAKH_LENGTH 1
|
||||
#define CSR_DCSR_EBREAKH (0x1U << CSR_DCSR_EBREAKH_OFFSET)
|
||||
/*
|
||||
* When 1, {\tt ebreak} instructions in Supervisor Mode enter Debug Mode.
|
||||
*/
|
||||
#define CSR_DCSR_EBREAKS_OFFSET 13
|
||||
@@ -207,9 +201,10 @@
|
||||
/*
|
||||
* 0: Increment counters as usual.
|
||||
*
|
||||
* 1: Don't increment any counters while in Debug Mode. This includes
|
||||
* the {\tt cycle} and {\tt instret} CSRs. This is preferred for most
|
||||
* debugging scenarios.
|
||||
* 1: Don't increment any counters while in Debug Mode or on {\tt
|
||||
* ebreak} instructions that cause entry into Debug Mode. These
|
||||
* counters include the {\tt cycle} and {\tt instret} CSRs. This is
|
||||
* preferred for most debugging scenarios.
|
||||
*
|
||||
* An implementation may choose not to support writing to this bit.
|
||||
* The debugger must read back the value it writes to check whether
|
||||
@@ -300,7 +295,7 @@
|
||||
*
|
||||
* Other values are reserved for future use.
|
||||
*/
|
||||
#define CSR_TDATA1_TYPE_OFFSET XLEN-4
|
||||
#define CSR_TDATA1_TYPE_OFFSET (XLEN-4)
|
||||
#define CSR_TDATA1_TYPE_LENGTH 4
|
||||
#define CSR_TDATA1_TYPE (0xfULL << CSR_TDATA1_TYPE_OFFSET)
|
||||
/*
|
||||
@@ -312,14 +307,14 @@
|
||||
*
|
||||
* This bit is only writable from Debug Mode.
|
||||
*/
|
||||
#define CSR_TDATA1_HMODE_OFFSET XLEN-5
|
||||
#define CSR_TDATA1_HMODE_LENGTH 1
|
||||
#define CSR_TDATA1_HMODE (0x1ULL << CSR_TDATA1_HMODE_OFFSET)
|
||||
#define CSR_TDATA1_DMODE_OFFSET (XLEN-5)
|
||||
#define CSR_TDATA1_DMODE_LENGTH 1
|
||||
#define CSR_TDATA1_DMODE (0x1ULL << CSR_TDATA1_DMODE_OFFSET)
|
||||
/*
|
||||
* Trigger-specific data.
|
||||
*/
|
||||
#define CSR_TDATA1_DATA_OFFSET 0
|
||||
#define CSR_TDATA1_DATA_LENGTH XLEN - 5
|
||||
#define CSR_TDATA1_DATA_LENGTH (XLEN - 5)
|
||||
#define CSR_TDATA1_DATA (((1L<<XLEN - 5)-1) << CSR_TDATA1_DATA_OFFSET)
|
||||
#define CSR_TDATA2 0x7a2
|
||||
#define CSR_TDATA2_DATA_OFFSET 0
|
||||
@@ -330,10 +325,10 @@
|
||||
#define CSR_TDATA3_DATA_LENGTH XLEN
|
||||
#define CSR_TDATA3_DATA (((1L<<XLEN)-1) << CSR_TDATA3_DATA_OFFSET)
|
||||
#define CSR_MCONTROL 0x7a1
|
||||
#define CSR_MCONTROL_TYPE_OFFSET XLEN-4
|
||||
#define CSR_MCONTROL_TYPE_OFFSET (XLEN-4)
|
||||
#define CSR_MCONTROL_TYPE_LENGTH 4
|
||||
#define CSR_MCONTROL_TYPE (0xfULL << CSR_MCONTROL_TYPE_OFFSET)
|
||||
#define CSR_MCONTROL_DMODE_OFFSET XLEN-5
|
||||
#define CSR_MCONTROL_DMODE_OFFSET (XLEN-5)
|
||||
#define CSR_MCONTROL_DMODE_LENGTH 1
|
||||
#define CSR_MCONTROL_DMODE (0x1ULL << CSR_MCONTROL_DMODE_OFFSET)
|
||||
/*
|
||||
@@ -344,7 +339,7 @@
|
||||
* corresponds to the maximum NAPOT range, which is $2^{63}$ bytes in
|
||||
* size.
|
||||
*/
|
||||
#define CSR_MCONTROL_MASKMAX_OFFSET XLEN-11
|
||||
#define CSR_MCONTROL_MASKMAX_OFFSET (XLEN-11)
|
||||
#define CSR_MCONTROL_MASKMAX_LENGTH 6
|
||||
#define CSR_MCONTROL_MASKMAX (0x3fULL << CSR_MCONTROL_MASKMAX_OFFSET)
|
||||
/*
|
||||
@@ -390,7 +385,7 @@
|
||||
* 0: Raise a breakpoint exception. (Used when software wants to use
|
||||
* the trigger module without an external debugger attached.)
|
||||
*
|
||||
* 1: Enter Debug Mode. (Only supported when \Fhmode is 1.)
|
||||
* 1: Enter Debug Mode. (Only supported when \Fdmode is 1.)
|
||||
*
|
||||
* 2: Start tracing.
|
||||
*
|
||||
@@ -446,12 +441,6 @@
|
||||
#define CSR_MCONTROL_M_LENGTH 1
|
||||
#define CSR_MCONTROL_M (0x1ULL << CSR_MCONTROL_M_OFFSET)
|
||||
/*
|
||||
* When set, enable this trigger in H mode.
|
||||
*/
|
||||
#define CSR_MCONTROL_H_OFFSET 5
|
||||
#define CSR_MCONTROL_H_LENGTH 1
|
||||
#define CSR_MCONTROL_H (0x1ULL << CSR_MCONTROL_H_OFFSET)
|
||||
/*
|
||||
* When set, enable this trigger in S mode.
|
||||
*/
|
||||
#define CSR_MCONTROL_S_OFFSET 4
|
||||
@@ -483,16 +472,16 @@
|
||||
#define CSR_MCONTROL_LOAD_LENGTH 1
|
||||
#define CSR_MCONTROL_LOAD (0x1ULL << CSR_MCONTROL_LOAD_OFFSET)
|
||||
#define CSR_ICOUNT 0x7a1
|
||||
#define CSR_ICOUNT_TYPE_OFFSET XLEN-4
|
||||
#define CSR_ICOUNT_TYPE_OFFSET (XLEN-4)
|
||||
#define CSR_ICOUNT_TYPE_LENGTH 4
|
||||
#define CSR_ICOUNT_TYPE (0xfULL << CSR_ICOUNT_TYPE_OFFSET)
|
||||
#define CSR_ICOUNT_DMODE_OFFSET XLEN-5
|
||||
#define CSR_ICOUNT_DMODE_OFFSET (XLEN-5)
|
||||
#define CSR_ICOUNT_DMODE_LENGTH 1
|
||||
#define CSR_ICOUNT_DMODE (0x1ULL << CSR_ICOUNT_DMODE_OFFSET)
|
||||
/*
|
||||
* When count is decremented to 0, the trigger fires. Instead of
|
||||
* changing \Fcount from 1 to 0, it is also acceptable for hardware to
|
||||
* clear \Fm, \Fh, \Fs, and \Fu. This allows \Fcount to be hard-wired
|
||||
* clear \Fm, \Fs, and \Fu. This allows \Fcount to be hard-wired
|
||||
* to 1 if this register just exists for single step.
|
||||
*/
|
||||
#define CSR_ICOUNT_COUNT_OFFSET 10
|
||||
@@ -506,13 +495,6 @@
|
||||
#define CSR_ICOUNT_M_LENGTH 1
|
||||
#define CSR_ICOUNT_M (0x1ULL << CSR_ICOUNT_M_OFFSET)
|
||||
/*
|
||||
* When set, every instruction completed or exception taken in in H mode decrements \Fcount
|
||||
* by 1.
|
||||
*/
|
||||
#define CSR_ICOUNT_H_OFFSET 8
|
||||
#define CSR_ICOUNT_H_LENGTH 1
|
||||
#define CSR_ICOUNT_H (0x1ULL << CSR_ICOUNT_H_OFFSET)
|
||||
/*
|
||||
* When set, every instruction completed or exception taken in S mode decrements \Fcount
|
||||
* by 1.
|
||||
*/
|
||||
@@ -532,7 +514,7 @@
|
||||
* 0: Raise a breakpoint exception. (Used when software wants to use the
|
||||
* trigger module without an external debugger attached.)
|
||||
*
|
||||
* 1: Enter Debug Mode. (Only supported when \Fhmode is 1.)
|
||||
* 1: Enter Debug Mode. (Only supported when \Fdmode is 1.)
|
||||
*
|
||||
* 2: Start tracing.
|
||||
*
|
||||
@@ -549,13 +531,38 @@
|
||||
#define CSR_ICOUNT_ACTION (0x3fULL << CSR_ICOUNT_ACTION_OFFSET)
|
||||
#define DMI_DMSTATUS 0x11
|
||||
/*
|
||||
* This field is 1 when all currently selected harts have acknowledged the previous \Fresumereq.
|
||||
* If 1, then there is an implicit {\tt ebreak} instruction at the
|
||||
* non-existent word immediately after the Program Buffer. This saves
|
||||
* the debugger from having to write the {\tt ebreak} itself, and
|
||||
* allows the Program Buffer to be one word smaller.
|
||||
*
|
||||
* This must be 1 when \Fprogbufsize is 1.
|
||||
*/
|
||||
#define DMI_DMSTATUS_IMPEBREAK_OFFSET 22
|
||||
#define DMI_DMSTATUS_IMPEBREAK_LENGTH 1
|
||||
#define DMI_DMSTATUS_IMPEBREAK (0x1U << DMI_DMSTATUS_IMPEBREAK_OFFSET)
|
||||
/*
|
||||
* This field is 1 when all currently selected harts have been reset but the reset has not been acknowledged.
|
||||
*/
|
||||
#define DMI_DMSTATUS_ALLHAVERESET_OFFSET 19
|
||||
#define DMI_DMSTATUS_ALLHAVERESET_LENGTH 1
|
||||
#define DMI_DMSTATUS_ALLHAVERESET (0x1U << DMI_DMSTATUS_ALLHAVERESET_OFFSET)
|
||||
/*
|
||||
* This field is 1 when any currently selected hart has been reset but the reset has not been acknowledged.
|
||||
*/
|
||||
#define DMI_DMSTATUS_ANYHAVERESET_OFFSET 18
|
||||
#define DMI_DMSTATUS_ANYHAVERESET_LENGTH 1
|
||||
#define DMI_DMSTATUS_ANYHAVERESET (0x1U << DMI_DMSTATUS_ANYHAVERESET_OFFSET)
|
||||
/*
|
||||
* This field is 1 when all currently selected harts have acknowledged
|
||||
* the previous resume request.
|
||||
*/
|
||||
#define DMI_DMSTATUS_ALLRESUMEACK_OFFSET 17
|
||||
#define DMI_DMSTATUS_ALLRESUMEACK_LENGTH 1
|
||||
#define DMI_DMSTATUS_ALLRESUMEACK (0x1U << DMI_DMSTATUS_ALLRESUMEACK_OFFSET)
|
||||
/*
|
||||
* This field is 1 when any currently selected hart has acknowledged the previous \Fresumereq.
|
||||
* This field is 1 when any currently selected hart has acknowledged
|
||||
* the previous resume request.
|
||||
*/
|
||||
#define DMI_DMSTATUS_ANYRESUMEACK_OFFSET 16
|
||||
#define DMI_DMSTATUS_ANYRESUMEACK_LENGTH 1
|
||||
@@ -629,6 +636,13 @@
|
||||
#define DMI_DMSTATUS_AUTHBUSY_OFFSET 6
|
||||
#define DMI_DMSTATUS_AUTHBUSY_LENGTH 1
|
||||
#define DMI_DMSTATUS_AUTHBUSY (0x1U << DMI_DMSTATUS_AUTHBUSY_OFFSET)
|
||||
/*
|
||||
* 0: \Rdevtreeaddrzero--\Rdevtreeaddrthree hold information which
|
||||
* is not relevant to the Device Tree.
|
||||
*
|
||||
* 1: \Rdevtreeaddrzero--\Rdevtreeaddrthree registers hold the address of the
|
||||
* Device Tree.
|
||||
*/
|
||||
#define DMI_DMSTATUS_DEVTREEVALID_OFFSET 4
|
||||
#define DMI_DMSTATUS_DEVTREEVALID_LENGTH 1
|
||||
#define DMI_DMSTATUS_DEVTREEVALID (0x1U << DMI_DMSTATUS_DEVTREEVALID_OFFSET)
|
||||
@@ -649,32 +663,35 @@
|
||||
#define DMI_DMSTATUS_VERSION (0xfU << DMI_DMSTATUS_VERSION_OFFSET)
|
||||
#define DMI_DMCONTROL 0x10
|
||||
/*
|
||||
* Halt request signal for all currently selected harts. When set to
|
||||
* 1, each selected hart will halt if it is not currently halted.
|
||||
* Writes the halt request bit for all currently selected harts.
|
||||
* When set to 1, each selected hart will halt if it is not currently
|
||||
* halted.
|
||||
*
|
||||
* Writing 1 or 0 has no effect on a hart which is already halted, but
|
||||
* the bit should be cleared to 0 before the hart is resumed.
|
||||
* Setting both \Fhaltreq and \Fresumereq leads to undefined behavior.
|
||||
* the bit must be cleared to 0 before the hart is resumed.
|
||||
*
|
||||
* Writes apply to the new value of \Fhartsel and \Fhasel.
|
||||
*/
|
||||
#define DMI_DMCONTROL_HALTREQ_OFFSET 31
|
||||
#define DMI_DMCONTROL_HALTREQ_LENGTH 1
|
||||
#define DMI_DMCONTROL_HALTREQ (0x1U << DMI_DMCONTROL_HALTREQ_OFFSET)
|
||||
#define DMI_DMCONTROL_HALTREQ (0x1ULL << DMI_DMCONTROL_HALTREQ_OFFSET)
|
||||
/*
|
||||
* Resume request signal for all currently selected harts. When set to 1,
|
||||
* each selected hart will resume if it is currently halted.
|
||||
* Setting both \Fhaltreq and \Fresumereq leads to undefined behavior.
|
||||
* Writes the resume request bit for all currently selected harts.
|
||||
* When set to 1, each selected hart will resume if it is currently
|
||||
* halted.
|
||||
*
|
||||
* The resume request bit is ignored while the halt request bit is
|
||||
* set.
|
||||
*
|
||||
* Writes apply to the new value of \Fhartsel and \Fhasel.
|
||||
*/
|
||||
#define DMI_DMCONTROL_RESUMEREQ_OFFSET 30
|
||||
#define DMI_DMCONTROL_RESUMEREQ_LENGTH 1
|
||||
#define DMI_DMCONTROL_RESUMEREQ (0x1U << DMI_DMCONTROL_RESUMEREQ_OFFSET)
|
||||
#define DMI_DMCONTROL_RESUMEREQ (0x1ULL << DMI_DMCONTROL_RESUMEREQ_OFFSET)
|
||||
/*
|
||||
* This optional bit controls reset to all the currently selected harts.
|
||||
* To perform a reset the debugger writes 1, and then writes 0 to
|
||||
* deassert the reset signal.
|
||||
* This optional field writes the reset bit for all the currently
|
||||
* selected harts. To perform a reset the debugger writes 1, and then
|
||||
* writes 0 to deassert the reset signal.
|
||||
*
|
||||
* If this feature is not implemented, the bit always stays 0, so
|
||||
* after writing 1 the debugger can read the register back to see if
|
||||
@@ -684,7 +701,16 @@
|
||||
*/
|
||||
#define DMI_DMCONTROL_HARTRESET_OFFSET 29
|
||||
#define DMI_DMCONTROL_HARTRESET_LENGTH 1
|
||||
#define DMI_DMCONTROL_HARTRESET (0x1U << DMI_DMCONTROL_HARTRESET_OFFSET)
|
||||
#define DMI_DMCONTROL_HARTRESET (0x1ULL << DMI_DMCONTROL_HARTRESET_OFFSET)
|
||||
/*
|
||||
* Writing 1 to this bit clears the {\tt havereset} bits for
|
||||
* any selected harts.
|
||||
*
|
||||
* Writes apply to the new value of \Fhartsel and \Fhasel.
|
||||
*/
|
||||
#define DMI_DMCONTROL_ACKHAVERESET_OFFSET 28
|
||||
#define DMI_DMCONTROL_ACKHAVERESET_LENGTH 1
|
||||
#define DMI_DMCONTROL_ACKHAVERESET (0x1ULL << DMI_DMCONTROL_ACKHAVERESET_OFFSET)
|
||||
/*
|
||||
* Selects the definition of currently selected harts.
|
||||
*
|
||||
@@ -700,25 +726,26 @@
|
||||
*/
|
||||
#define DMI_DMCONTROL_HASEL_OFFSET 26
|
||||
#define DMI_DMCONTROL_HASEL_LENGTH 1
|
||||
#define DMI_DMCONTROL_HASEL (0x1U << DMI_DMCONTROL_HASEL_OFFSET)
|
||||
#define DMI_DMCONTROL_HASEL (0x1ULL << DMI_DMCONTROL_HASEL_OFFSET)
|
||||
/*
|
||||
* The DM-specific index of the hart to select. This hart is always part of the
|
||||
* currently selected harts.
|
||||
*/
|
||||
#define DMI_DMCONTROL_HARTSEL_OFFSET 16
|
||||
#define DMI_DMCONTROL_HARTSEL_LENGTH 10
|
||||
#define DMI_DMCONTROL_HARTSEL (0x3ffU << DMI_DMCONTROL_HARTSEL_OFFSET)
|
||||
#define DMI_DMCONTROL_HARTSEL_LENGTH HARTSELLEN
|
||||
#define DMI_DMCONTROL_HARTSEL (((1L<<HARTSELLEN)-1) << DMI_DMCONTROL_HARTSEL_OFFSET)
|
||||
/*
|
||||
* This bit controls the reset signal from the DM to the rest of the
|
||||
* system. To perform a system reset the debugger writes 1,
|
||||
* system. The signal should reset every part of the system, including
|
||||
* every hart, except for the DM and any logic required to access the
|
||||
* DM.
|
||||
* To perform a system reset the debugger writes 1,
|
||||
* and then writes 0
|
||||
* to deassert the reset. This bit must not reset the Debug Module
|
||||
* registers. What it does reset is platform-specific (it may
|
||||
* reset nothing).
|
||||
* to deassert the reset.
|
||||
*/
|
||||
#define DMI_DMCONTROL_NDMRESET_OFFSET 1
|
||||
#define DMI_DMCONTROL_NDMRESET_LENGTH 1
|
||||
#define DMI_DMCONTROL_NDMRESET (0x1U << DMI_DMCONTROL_NDMRESET_OFFSET)
|
||||
#define DMI_DMCONTROL_NDMRESET (0x1ULL << DMI_DMCONTROL_NDMRESET_OFFSET)
|
||||
/*
|
||||
* This bit serves as a reset signal for the Debug Module itself.
|
||||
*
|
||||
@@ -741,7 +768,7 @@
|
||||
*/
|
||||
#define DMI_DMCONTROL_DMACTIVE_OFFSET 0
|
||||
#define DMI_DMCONTROL_DMACTIVE_LENGTH 1
|
||||
#define DMI_DMCONTROL_DMACTIVE (0x1U << DMI_DMCONTROL_DMACTIVE_OFFSET)
|
||||
#define DMI_DMCONTROL_DMACTIVE (0x1ULL << DMI_DMCONTROL_DMACTIVE_OFFSET)
|
||||
#define DMI_HARTINFO 0x12
|
||||
/*
|
||||
* Number of {\tt dscratch} registers available for the debugger
|
||||
@@ -769,6 +796,9 @@
|
||||
*
|
||||
* If \Fdataaccess is 1: Number of 32-bit words in the memory map
|
||||
* dedicated to shadowing the {\tt data} registers.
|
||||
*
|
||||
* Since there are at most 12 {\tt data} registers, the value in this
|
||||
* register must be 12 or smaller.
|
||||
*/
|
||||
#define DMI_HARTINFO_DATASIZE_OFFSET 12
|
||||
#define DMI_HARTINFO_DATASIZE_LENGTH 4
|
||||
@@ -778,7 +808,7 @@
|
||||
* shadowing the {\tt data} registers.
|
||||
*
|
||||
* If \Fdataaccess is 1: Signed address of RAM where the {\tt data}
|
||||
* registers are shadowed.
|
||||
* registers are shadowed, to be used to access relative to \Rzero.
|
||||
*/
|
||||
#define DMI_HARTINFO_DATAADDR_OFFSET 0
|
||||
#define DMI_HARTINFO_DATAADDR_LENGTH 12
|
||||
@@ -891,13 +921,10 @@
|
||||
#define DMI_ABSTRACTCS 0x16
|
||||
/*
|
||||
* Size of the Program Buffer, in 32-bit words. Valid sizes are 0 - 16.
|
||||
*
|
||||
* TODO: Explain what can be done with each size of the buffer, to suggest
|
||||
* why you would want more or less words.
|
||||
*/
|
||||
#define DMI_ABSTRACTCS_PROGSIZE_OFFSET 24
|
||||
#define DMI_ABSTRACTCS_PROGSIZE_LENGTH 5
|
||||
#define DMI_ABSTRACTCS_PROGSIZE (0x1fU << DMI_ABSTRACTCS_PROGSIZE_OFFSET)
|
||||
#define DMI_ABSTRACTCS_PROGBUFSIZE_OFFSET 24
|
||||
#define DMI_ABSTRACTCS_PROGBUFSIZE_LENGTH 5
|
||||
#define DMI_ABSTRACTCS_PROGBUFSIZE (0x1fU << DMI_ABSTRACTCS_PROGBUFSIZE_OFFSET)
|
||||
/*
|
||||
* 1: An abstract command is currently being executed.
|
||||
*
|
||||
@@ -938,8 +965,8 @@
|
||||
* abstract command interface. Valid sizes are 0 - 12.
|
||||
*/
|
||||
#define DMI_ABSTRACTCS_DATACOUNT_OFFSET 0
|
||||
#define DMI_ABSTRACTCS_DATACOUNT_LENGTH 5
|
||||
#define DMI_ABSTRACTCS_DATACOUNT (0x1fU << DMI_ABSTRACTCS_DATACOUNT_OFFSET)
|
||||
#define DMI_ABSTRACTCS_DATACOUNT_LENGTH 4
|
||||
#define DMI_ABSTRACTCS_DATACOUNT (0xfU << DMI_ABSTRACTCS_DATACOUNT_OFFSET)
|
||||
#define DMI_COMMAND 0x17
|
||||
/*
|
||||
* The type determines the overall functionality of this
|
||||
@@ -957,14 +984,14 @@
|
||||
#define DMI_COMMAND_CONTROL (0xffffffU << DMI_COMMAND_CONTROL_OFFSET)
|
||||
#define DMI_ABSTRACTAUTO 0x18
|
||||
/*
|
||||
* When a bit in this field is 1, read or write accesses the corresponding {\tt progbuf} word
|
||||
* When a bit in this field is 1, read or write accesses to the corresponding {\tt progbuf} word
|
||||
* cause the command in \Rcommand to be executed again.
|
||||
*/
|
||||
#define DMI_ABSTRACTAUTO_AUTOEXECPROGBUF_OFFSET 16
|
||||
#define DMI_ABSTRACTAUTO_AUTOEXECPROGBUF_LENGTH 16
|
||||
#define DMI_ABSTRACTAUTO_AUTOEXECPROGBUF (0xffffU << DMI_ABSTRACTAUTO_AUTOEXECPROGBUF_OFFSET)
|
||||
/*
|
||||
* When a bit in this field is 1, read or write accesses the corresponding {\tt data} word
|
||||
* When a bit in this field is 1, read or write accesses to the corresponding {\tt data} word
|
||||
* cause the command in \Rcommand to be executed again.
|
||||
*/
|
||||
#define DMI_ABSTRACTAUTO_AUTOEXECDATA_OFFSET 0
|
||||
@@ -991,17 +1018,59 @@
|
||||
#define DMI_AUTHDATA_DATA_OFFSET 0
|
||||
#define DMI_AUTHDATA_DATA_LENGTH 32
|
||||
#define DMI_AUTHDATA_DATA (0xffffffffU << DMI_AUTHDATA_DATA_OFFSET)
|
||||
#define DMI_SBADDRESS3 0x37
|
||||
/*
|
||||
* Accesses bits 127:96 of the physical address in {\tt sbaddress} (if
|
||||
* the system address bus is that wide).
|
||||
*/
|
||||
#define DMI_SBADDRESS3_ADDRESS_OFFSET 0
|
||||
#define DMI_SBADDRESS3_ADDRESS_LENGTH 32
|
||||
#define DMI_SBADDRESS3_ADDRESS (0xffffffffU << DMI_SBADDRESS3_ADDRESS_OFFSET)
|
||||
#define DMI_SBCS 0x38
|
||||
/*
|
||||
* When a 1 is written here, triggers a read at the address in {\tt
|
||||
* sbaddress} using the access size set by \Fsbaccess.
|
||||
* 0: The System Bus interface conforms to mainline drafts of this
|
||||
* spec older than 1 January, 2018.
|
||||
*
|
||||
* 1: The System Bus interface conforms to this version of the spec.
|
||||
*
|
||||
* Other values are reserved for future versions.
|
||||
*/
|
||||
#define DMI_SBCS_SBSINGLEREAD_OFFSET 20
|
||||
#define DMI_SBCS_SBSINGLEREAD_LENGTH 1
|
||||
#define DMI_SBCS_SBSINGLEREAD (0x1U << DMI_SBCS_SBSINGLEREAD_OFFSET)
|
||||
#define DMI_SBCS_SBVERSION_OFFSET 29
|
||||
#define DMI_SBCS_SBVERSION_LENGTH 3
|
||||
#define DMI_SBCS_SBVERSION (0x7U << DMI_SBCS_SBVERSION_OFFSET)
|
||||
/*
|
||||
* Select the access size to use for system bus accesses triggered by
|
||||
* writes to the {\tt sbaddress} registers or \Rsbdatazero.
|
||||
* Set when the debugger attempts to read data while a read is in
|
||||
* progress, or when the debugger initiates a new access while one is
|
||||
* already in progress (while \Fsbbusy is set). It remains set until
|
||||
* it's explicitly cleared by the debugger.
|
||||
*
|
||||
* While this field is non-zero, no more system bus accesses can be
|
||||
* initiated by the debug module.
|
||||
*/
|
||||
#define DMI_SBCS_SBBUSYERROR_OFFSET 22
|
||||
#define DMI_SBCS_SBBUSYERROR_LENGTH 1
|
||||
#define DMI_SBCS_SBBUSYERROR (0x1U << DMI_SBCS_SBBUSYERROR_OFFSET)
|
||||
/*
|
||||
* When 1, indicates the system bus master is busy. (Whether the
|
||||
* system bus itself is busy is related, but not the same thing.) This
|
||||
* bit goes high immediately when a read or write is requested for any
|
||||
* reason, and does not go low until the access is fully completed.
|
||||
*
|
||||
* To avoid race conditions, debuggers must not try to clear \Fsberror
|
||||
* until they read \Fsbbusy as 0.
|
||||
*/
|
||||
#define DMI_SBCS_SBBUSY_OFFSET 21
|
||||
#define DMI_SBCS_SBBUSY_LENGTH 1
|
||||
#define DMI_SBCS_SBBUSY (0x1U << DMI_SBCS_SBBUSY_OFFSET)
|
||||
/*
|
||||
* When 1, every write to \Rsbaddresszero automatically triggers a
|
||||
* system bus read at the new address.
|
||||
*/
|
||||
#define DMI_SBCS_SBREADONADDR_OFFSET 20
|
||||
#define DMI_SBCS_SBREADONADDR_LENGTH 1
|
||||
#define DMI_SBCS_SBREADONADDR (0x1U << DMI_SBCS_SBREADONADDR_OFFSET)
|
||||
/*
|
||||
* Select the access size to use for system bus accesses.
|
||||
*
|
||||
* 0: 8-bit
|
||||
*
|
||||
@@ -1013,28 +1082,26 @@
|
||||
*
|
||||
* 4: 128-bit
|
||||
*
|
||||
* If an unsupported system bus access size is written here,
|
||||
* the DM may not perform the access, or may perform the access
|
||||
* with any access size.
|
||||
* If \Fsbaccess has an unsupported value when the DM starts a bus
|
||||
* access, the access is not performed and \Fsberror is set to 3.
|
||||
*/
|
||||
#define DMI_SBCS_SBACCESS_OFFSET 17
|
||||
#define DMI_SBCS_SBACCESS_LENGTH 3
|
||||
#define DMI_SBCS_SBACCESS (0x7U << DMI_SBCS_SBACCESS_OFFSET)
|
||||
/*
|
||||
* When 1, the internal address value (used by the system bus master)
|
||||
* is incremented by the access size (in bytes) selected in \Fsbaccess
|
||||
* after every system bus access.
|
||||
* When 1, {\tt sbaddress} is incremented by the access size (in
|
||||
* bytes) selected in \Fsbaccess after every system bus access.
|
||||
*/
|
||||
#define DMI_SBCS_SBAUTOINCREMENT_OFFSET 16
|
||||
#define DMI_SBCS_SBAUTOINCREMENT_LENGTH 1
|
||||
#define DMI_SBCS_SBAUTOINCREMENT (0x1U << DMI_SBCS_SBAUTOINCREMENT_OFFSET)
|
||||
/*
|
||||
* When 1, every read from \Rsbdatazero automatically triggers a system
|
||||
* bus read at the new address.
|
||||
* When 1, every read from \Rsbdatazero automatically triggers a
|
||||
* system bus read at the (possibly auto-incremented) address.
|
||||
*/
|
||||
#define DMI_SBCS_SBAUTOREAD_OFFSET 15
|
||||
#define DMI_SBCS_SBAUTOREAD_LENGTH 1
|
||||
#define DMI_SBCS_SBAUTOREAD (0x1U << DMI_SBCS_SBAUTOREAD_OFFSET)
|
||||
#define DMI_SBCS_SBREADONDATA_OFFSET 15
|
||||
#define DMI_SBCS_SBREADONDATA_LENGTH 1
|
||||
#define DMI_SBCS_SBREADONDATA (0x1U << DMI_SBCS_SBREADONDATA_OFFSET)
|
||||
/*
|
||||
* When the debug module's system bus
|
||||
* master causes a bus error, this field gets set. The bits in this
|
||||
@@ -1049,11 +1116,6 @@
|
||||
* 2: A bad address was accessed.
|
||||
*
|
||||
* 3: There was some other error (eg. alignment).
|
||||
*
|
||||
* 4: The system bus master was busy when one of the
|
||||
* {\tt sbaddress} or {\tt sbdata} registers was written,
|
||||
* or the {\tt sbdata} register was read when it had
|
||||
* stale data.
|
||||
*/
|
||||
#define DMI_SBCS_SBERROR_OFFSET 12
|
||||
#define DMI_SBCS_SBERROR_LENGTH 3
|
||||
@@ -1097,54 +1159,54 @@
|
||||
#define DMI_SBCS_SBACCESS8 (0x1U << DMI_SBCS_SBACCESS8_OFFSET)
|
||||
#define DMI_SBADDRESS0 0x39
|
||||
/*
|
||||
* Accesses bits 31:0 of the internal address.
|
||||
* Accesses bits 31:0 of the physical address in {\tt sbaddress}.
|
||||
*/
|
||||
#define DMI_SBADDRESS0_ADDRESS_OFFSET 0
|
||||
#define DMI_SBADDRESS0_ADDRESS_LENGTH 32
|
||||
#define DMI_SBADDRESS0_ADDRESS (0xffffffffU << DMI_SBADDRESS0_ADDRESS_OFFSET)
|
||||
#define DMI_SBADDRESS1 0x3a
|
||||
/*
|
||||
* Accesses bits 63:32 of the internal address (if the system address
|
||||
* bus is that wide).
|
||||
* Accesses bits 63:32 of the physical address in {\tt sbaddress} (if
|
||||
* the system address bus is that wide).
|
||||
*/
|
||||
#define DMI_SBADDRESS1_ADDRESS_OFFSET 0
|
||||
#define DMI_SBADDRESS1_ADDRESS_LENGTH 32
|
||||
#define DMI_SBADDRESS1_ADDRESS (0xffffffffU << DMI_SBADDRESS1_ADDRESS_OFFSET)
|
||||
#define DMI_SBADDRESS2 0x3b
|
||||
/*
|
||||
* Accesses bits 95:64 of the internal address (if the system address
|
||||
* bus is that wide).
|
||||
* Accesses bits 95:64 of the physical address in {\tt sbaddress} (if
|
||||
* the system address bus is that wide).
|
||||
*/
|
||||
#define DMI_SBADDRESS2_ADDRESS_OFFSET 0
|
||||
#define DMI_SBADDRESS2_ADDRESS_LENGTH 32
|
||||
#define DMI_SBADDRESS2_ADDRESS (0xffffffffU << DMI_SBADDRESS2_ADDRESS_OFFSET)
|
||||
#define DMI_SBDATA0 0x3c
|
||||
/*
|
||||
* Accesses bits 31:0 of the internal data.
|
||||
* Accesses bits 31:0 of {\tt sbdata}.
|
||||
*/
|
||||
#define DMI_SBDATA0_DATA_OFFSET 0
|
||||
#define DMI_SBDATA0_DATA_LENGTH 32
|
||||
#define DMI_SBDATA0_DATA (0xffffffffU << DMI_SBDATA0_DATA_OFFSET)
|
||||
#define DMI_SBDATA1 0x3d
|
||||
/*
|
||||
* Accesses bits 63:32 of the internal data (if the system bus is
|
||||
* that wide).
|
||||
* Accesses bits 63:32 of {\tt sbdata} (if the system bus is that
|
||||
* wide).
|
||||
*/
|
||||
#define DMI_SBDATA1_DATA_OFFSET 0
|
||||
#define DMI_SBDATA1_DATA_LENGTH 32
|
||||
#define DMI_SBDATA1_DATA (0xffffffffU << DMI_SBDATA1_DATA_OFFSET)
|
||||
#define DMI_SBDATA2 0x3e
|
||||
/*
|
||||
* Accesses bits 95:64 of the internal data (if the system bus is
|
||||
* that wide).
|
||||
* Accesses bits 95:64 of {\tt sbdata} (if the system bus is that
|
||||
* wide).
|
||||
*/
|
||||
#define DMI_SBDATA2_DATA_OFFSET 0
|
||||
#define DMI_SBDATA2_DATA_LENGTH 32
|
||||
#define DMI_SBDATA2_DATA (0xffffffffU << DMI_SBDATA2_DATA_OFFSET)
|
||||
#define DMI_SBDATA3 0x3f
|
||||
/*
|
||||
* Accesses bits 127:96 of the internal data (if the system bus is
|
||||
* that wide).
|
||||
* Accesses bits 127:96 of {\tt sbdata} (if the system bus is that
|
||||
* wide).
|
||||
*/
|
||||
#define DMI_SBDATA3_DATA_OFFSET 0
|
||||
#define DMI_SBDATA3_DATA_LENGTH 32
|
||||
@@ -1188,6 +1250,9 @@
|
||||
* 0: Don't do the operation specified by \Fwrite.
|
||||
*
|
||||
* 1: Do the operation specified by \Fwrite.
|
||||
*
|
||||
* This bit can be used to just execute the Program Buffer without
|
||||
* having to worry about placing valid values into \Fsize or \Fregno.
|
||||
*/
|
||||
#define AC_ACCESS_REGISTER_TRANSFER_OFFSET 17
|
||||
#define AC_ACCESS_REGISTER_TRANSFER_LENGTH 1
|
||||
@@ -1223,8 +1288,9 @@
|
||||
/*
|
||||
* Contains the privilege level the hart was operating in when Debug
|
||||
* Mode was entered. The encoding is described in Table
|
||||
* \ref{tab:privlevel}. A user can write this value to change the
|
||||
* hart's privilege level when exiting Debug Mode.
|
||||
* \ref{tab:privlevel}, and matches the privilege level encoding from
|
||||
* the RISC-V Privileged ISA Specification. A user can write this
|
||||
* value to change the hart's privilege level when exiting Debug Mode.
|
||||
*/
|
||||
#define VIRT_PRIV_PRV_OFFSET 0
|
||||
#define VIRT_PRIV_PRV_LENGTH 2
|
||||
|
||||
+216
-58
@@ -17,10 +17,14 @@
|
||||
#define MSTATUS_FS 0x00006000
|
||||
#define MSTATUS_XS 0x00018000
|
||||
#define MSTATUS_MPRV 0x00020000
|
||||
#define MSTATUS_PUM 0x00040000
|
||||
#define MSTATUS_SUM 0x00040000
|
||||
#define MSTATUS_MXR 0x00080000
|
||||
#define MSTATUS_VM 0x1F000000
|
||||
#define MSTATUS_TVM 0x00100000
|
||||
#define MSTATUS_TW 0x00200000
|
||||
#define MSTATUS_TSR 0x00400000
|
||||
#define MSTATUS32_SD 0x80000000
|
||||
#define MSTATUS_UXL 0x0000000300000000
|
||||
#define MSTATUS_SXL 0x0000000C00000000
|
||||
#define MSTATUS64_SD 0x8000000000000000
|
||||
|
||||
#define SSTATUS_UIE 0x00000001
|
||||
@@ -30,8 +34,10 @@
|
||||
#define SSTATUS_SPP 0x00000100
|
||||
#define SSTATUS_FS 0x00006000
|
||||
#define SSTATUS_XS 0x00018000
|
||||
#define SSTATUS_PUM 0x00040000
|
||||
#define SSTATUS_SUM 0x00040000
|
||||
#define SSTATUS_MXR 0x00080000
|
||||
#define SSTATUS32_SD 0x80000000
|
||||
#define SSTATUS_UXL 0x0000000300000000
|
||||
#define SSTATUS64_SD 0x8000000000000000
|
||||
|
||||
#define DCSR_XDEBUGVER (3U<<30)
|
||||
@@ -107,12 +113,30 @@
|
||||
#define PRV_H 2
|
||||
#define PRV_M 3
|
||||
|
||||
#define VM_MBARE 0
|
||||
#define VM_MBB 1
|
||||
#define VM_MBBID 2
|
||||
#define VM_SV32 8
|
||||
#define VM_SV39 9
|
||||
#define VM_SV48 10
|
||||
#define SATP32_MODE 0x80000000
|
||||
#define SATP32_ASID 0x7FC00000
|
||||
#define SATP32_PPN 0x003FFFFF
|
||||
#define SATP64_MODE 0xF000000000000000
|
||||
#define SATP64_ASID 0x0FFFF00000000000
|
||||
#define SATP64_PPN 0x00000FFFFFFFFFFF
|
||||
|
||||
#define SATP_MODE_OFF 0
|
||||
#define SATP_MODE_SV32 1
|
||||
#define SATP_MODE_SV39 8
|
||||
#define SATP_MODE_SV48 9
|
||||
#define SATP_MODE_SV57 10
|
||||
#define SATP_MODE_SV64 11
|
||||
|
||||
#define PMP_R 0x01
|
||||
#define PMP_W 0x02
|
||||
#define PMP_X 0x04
|
||||
#define PMP_A 0x18
|
||||
#define PMP_L 0x80
|
||||
#define PMP_SHIFT 2
|
||||
|
||||
#define PMP_TOR 0x08
|
||||
#define PMP_NA4 0x10
|
||||
#define PMP_NAPOT 0x18
|
||||
|
||||
#define IRQ_S_SOFT 1
|
||||
#define IRQ_H_SOFT 2
|
||||
@@ -127,9 +151,8 @@
|
||||
#define IRQ_HOST 13
|
||||
|
||||
#define DEFAULT_RSTVEC 0x00001000
|
||||
#define DEFAULT_NMIVEC 0x00001004
|
||||
#define DEFAULT_MTVEC 0x00001010
|
||||
#define CONFIG_STRING_ADDR 0x0000100C
|
||||
#define CLINT_BASE 0x02000000
|
||||
#define CLINT_SIZE 0x000c0000
|
||||
#define EXT_IO_BASE 0x40000000
|
||||
#define DRAM_BASE 0x80000000
|
||||
|
||||
@@ -150,14 +173,16 @@
|
||||
|
||||
#ifdef __riscv
|
||||
|
||||
#ifdef __riscv64
|
||||
#if __riscv_xlen == 64
|
||||
# define MSTATUS_SD MSTATUS64_SD
|
||||
# define SSTATUS_SD SSTATUS64_SD
|
||||
# define RISCV_PGLEVEL_BITS 9
|
||||
# define SATP_MODE SATP64_MODE
|
||||
#else
|
||||
# define MSTATUS_SD MSTATUS32_SD
|
||||
# define SSTATUS_SD SSTATUS32_SD
|
||||
# define RISCV_PGLEVEL_BITS 10
|
||||
# define SATP_MODE SATP32_MODE
|
||||
#endif
|
||||
#define RISCV_PGSHIFT 12
|
||||
#define RISCV_PGSIZE (1 << RISCV_PGSHIFT)
|
||||
@@ -171,30 +196,18 @@
|
||||
__tmp; })
|
||||
|
||||
#define write_csr(reg, val) ({ \
|
||||
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
|
||||
asm volatile ("csrw " #reg ", %0" :: "i"(val)); \
|
||||
else \
|
||||
asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
|
||||
asm volatile ("csrw " #reg ", %0" :: "rK"(val)); })
|
||||
|
||||
#define swap_csr(reg, val) ({ unsigned long __tmp; \
|
||||
if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
|
||||
asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \
|
||||
else \
|
||||
asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \
|
||||
asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "rK"(val)); \
|
||||
__tmp; })
|
||||
|
||||
#define set_csr(reg, bit) ({ unsigned long __tmp; \
|
||||
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
|
||||
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
|
||||
else \
|
||||
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
|
||||
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
|
||||
__tmp; })
|
||||
|
||||
#define clear_csr(reg, bit) ({ unsigned long __tmp; \
|
||||
if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \
|
||||
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \
|
||||
else \
|
||||
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \
|
||||
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
|
||||
__tmp; })
|
||||
|
||||
#define rdtime() read_csr(time)
|
||||
@@ -208,7 +221,7 @@
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* Automatically generated by parse-opcodes */
|
||||
/* Automatically generated by parse-opcodes. */
|
||||
#ifndef RISCV_ENCODING_H
|
||||
#define RISCV_ENCODING_H
|
||||
#define MATCH_BEQ 0x63
|
||||
@@ -391,14 +404,12 @@
|
||||
#define MASK_URET 0xffffffff
|
||||
#define MATCH_SRET 0x10200073
|
||||
#define MASK_SRET 0xffffffff
|
||||
#define MATCH_HRET 0x20200073
|
||||
#define MASK_HRET 0xffffffff
|
||||
#define MATCH_MRET 0x30200073
|
||||
#define MASK_MRET 0xffffffff
|
||||
#define MATCH_DRET 0x7b200073
|
||||
#define MASK_DRET 0xffffffff
|
||||
#define MATCH_SFENCE_VM 0x10400073
|
||||
#define MASK_SFENCE_VM 0xfff07fff
|
||||
#define MATCH_SFENCE_VMA 0x12000073
|
||||
#define MASK_SFENCE_VMA 0xfe007fff
|
||||
#define MATCH_WFI 0x10500073
|
||||
#define MASK_WFI 0xffffffff
|
||||
#define MATCH_CSRRW 0x1073
|
||||
@@ -457,6 +468,34 @@
|
||||
#define MASK_FCVT_D_S 0xfff0007f
|
||||
#define MATCH_FSQRT_D 0x5a000053
|
||||
#define MASK_FSQRT_D 0xfff0007f
|
||||
#define MATCH_FADD_Q 0x6000053
|
||||
#define MASK_FADD_Q 0xfe00007f
|
||||
#define MATCH_FSUB_Q 0xe000053
|
||||
#define MASK_FSUB_Q 0xfe00007f
|
||||
#define MATCH_FMUL_Q 0x16000053
|
||||
#define MASK_FMUL_Q 0xfe00007f
|
||||
#define MATCH_FDIV_Q 0x1e000053
|
||||
#define MASK_FDIV_Q 0xfe00007f
|
||||
#define MATCH_FSGNJ_Q 0x26000053
|
||||
#define MASK_FSGNJ_Q 0xfe00707f
|
||||
#define MATCH_FSGNJN_Q 0x26001053
|
||||
#define MASK_FSGNJN_Q 0xfe00707f
|
||||
#define MATCH_FSGNJX_Q 0x26002053
|
||||
#define MASK_FSGNJX_Q 0xfe00707f
|
||||
#define MATCH_FMIN_Q 0x2e000053
|
||||
#define MASK_FMIN_Q 0xfe00707f
|
||||
#define MATCH_FMAX_Q 0x2e001053
|
||||
#define MASK_FMAX_Q 0xfe00707f
|
||||
#define MATCH_FCVT_S_Q 0x40300053
|
||||
#define MASK_FCVT_S_Q 0xfff0007f
|
||||
#define MATCH_FCVT_Q_S 0x46000053
|
||||
#define MASK_FCVT_Q_S 0xfff0007f
|
||||
#define MATCH_FCVT_D_Q 0x42300053
|
||||
#define MASK_FCVT_D_Q 0xfff0007f
|
||||
#define MATCH_FCVT_Q_D 0x46100053
|
||||
#define MASK_FCVT_Q_D 0xfff0007f
|
||||
#define MATCH_FSQRT_Q 0x5e000053
|
||||
#define MASK_FSQRT_Q 0xfff0007f
|
||||
#define MATCH_FLE_S 0xa0000053
|
||||
#define MASK_FLE_S 0xfe00707f
|
||||
#define MATCH_FLT_S 0xa0001053
|
||||
@@ -469,6 +508,12 @@
|
||||
#define MASK_FLT_D 0xfe00707f
|
||||
#define MATCH_FEQ_D 0xa2002053
|
||||
#define MASK_FEQ_D 0xfe00707f
|
||||
#define MATCH_FLE_Q 0xa6000053
|
||||
#define MASK_FLE_Q 0xfe00707f
|
||||
#define MATCH_FLT_Q 0xa6001053
|
||||
#define MASK_FLT_Q 0xfe00707f
|
||||
#define MATCH_FEQ_Q 0xa6002053
|
||||
#define MASK_FEQ_Q 0xfe00707f
|
||||
#define MATCH_FCVT_W_S 0xc0000053
|
||||
#define MASK_FCVT_W_S 0xfff0007f
|
||||
#define MATCH_FCVT_WU_S 0xc0100053
|
||||
@@ -477,8 +522,8 @@
|
||||
#define MASK_FCVT_L_S 0xfff0007f
|
||||
#define MATCH_FCVT_LU_S 0xc0300053
|
||||
#define MASK_FCVT_LU_S 0xfff0007f
|
||||
#define MATCH_FMV_X_S 0xe0000053
|
||||
#define MASK_FMV_X_S 0xfff0707f
|
||||
#define MATCH_FMV_X_W 0xe0000053
|
||||
#define MASK_FMV_X_W 0xfff0707f
|
||||
#define MATCH_FCLASS_S 0xe0001053
|
||||
#define MASK_FCLASS_S 0xfff0707f
|
||||
#define MATCH_FCVT_W_D 0xc2000053
|
||||
@@ -493,6 +538,18 @@
|
||||
#define MASK_FMV_X_D 0xfff0707f
|
||||
#define MATCH_FCLASS_D 0xe2001053
|
||||
#define MASK_FCLASS_D 0xfff0707f
|
||||
#define MATCH_FCVT_W_Q 0xc6000053
|
||||
#define MASK_FCVT_W_Q 0xfff0007f
|
||||
#define MATCH_FCVT_WU_Q 0xc6100053
|
||||
#define MASK_FCVT_WU_Q 0xfff0007f
|
||||
#define MATCH_FCVT_L_Q 0xc6200053
|
||||
#define MASK_FCVT_L_Q 0xfff0007f
|
||||
#define MATCH_FCVT_LU_Q 0xc6300053
|
||||
#define MASK_FCVT_LU_Q 0xfff0007f
|
||||
#define MATCH_FMV_X_Q 0xe6000053
|
||||
#define MASK_FMV_X_Q 0xfff0707f
|
||||
#define MATCH_FCLASS_Q 0xe6001053
|
||||
#define MASK_FCLASS_Q 0xfff0707f
|
||||
#define MATCH_FCVT_S_W 0xd0000053
|
||||
#define MASK_FCVT_S_W 0xfff0007f
|
||||
#define MATCH_FCVT_S_WU 0xd0100053
|
||||
@@ -501,8 +558,8 @@
|
||||
#define MASK_FCVT_S_L 0xfff0007f
|
||||
#define MATCH_FCVT_S_LU 0xd0300053
|
||||
#define MASK_FCVT_S_LU 0xfff0007f
|
||||
#define MATCH_FMV_S_X 0xf0000053
|
||||
#define MASK_FMV_S_X 0xfff0707f
|
||||
#define MATCH_FMV_W_X 0xf0000053
|
||||
#define MASK_FMV_W_X 0xfff0707f
|
||||
#define MATCH_FCVT_D_W 0xd2000053
|
||||
#define MASK_FCVT_D_W 0xfff0007f
|
||||
#define MATCH_FCVT_D_WU 0xd2100053
|
||||
@@ -513,14 +570,28 @@
|
||||
#define MASK_FCVT_D_LU 0xfff0007f
|
||||
#define MATCH_FMV_D_X 0xf2000053
|
||||
#define MASK_FMV_D_X 0xfff0707f
|
||||
#define MATCH_FCVT_Q_W 0xd6000053
|
||||
#define MASK_FCVT_Q_W 0xfff0007f
|
||||
#define MATCH_FCVT_Q_WU 0xd6100053
|
||||
#define MASK_FCVT_Q_WU 0xfff0007f
|
||||
#define MATCH_FCVT_Q_L 0xd6200053
|
||||
#define MASK_FCVT_Q_L 0xfff0007f
|
||||
#define MATCH_FCVT_Q_LU 0xd6300053
|
||||
#define MASK_FCVT_Q_LU 0xfff0007f
|
||||
#define MATCH_FMV_Q_X 0xf6000053
|
||||
#define MASK_FMV_Q_X 0xfff0707f
|
||||
#define MATCH_FLW 0x2007
|
||||
#define MASK_FLW 0x707f
|
||||
#define MATCH_FLD 0x3007
|
||||
#define MASK_FLD 0x707f
|
||||
#define MATCH_FLQ 0x4007
|
||||
#define MASK_FLQ 0x707f
|
||||
#define MATCH_FSW 0x2027
|
||||
#define MASK_FSW 0x707f
|
||||
#define MATCH_FSD 0x3027
|
||||
#define MASK_FSD 0x707f
|
||||
#define MATCH_FSQ 0x4027
|
||||
#define MASK_FSQ 0x707f
|
||||
#define MATCH_FMADD_S 0x43
|
||||
#define MASK_FMADD_S 0x600007f
|
||||
#define MATCH_FMSUB_S 0x47
|
||||
@@ -537,6 +608,14 @@
|
||||
#define MASK_FNMSUB_D 0x600007f
|
||||
#define MATCH_FNMADD_D 0x200004f
|
||||
#define MASK_FNMADD_D 0x600007f
|
||||
#define MATCH_FMADD_Q 0x6000043
|
||||
#define MASK_FMADD_Q 0x600007f
|
||||
#define MATCH_FMSUB_Q 0x6000047
|
||||
#define MASK_FMSUB_Q 0x600007f
|
||||
#define MATCH_FNMSUB_Q 0x600004b
|
||||
#define MASK_FNMSUB_Q 0x600007f
|
||||
#define MATCH_FNMADD_Q 0x600004f
|
||||
#define MASK_FNMADD_Q 0x600007f
|
||||
#define MATCH_C_NOP 0x1
|
||||
#define MASK_C_NOP 0xffff
|
||||
#define MATCH_C_ADDI16SP 0x6101
|
||||
@@ -707,23 +786,45 @@
|
||||
#define CSR_SSTATUS 0x100
|
||||
#define CSR_SIE 0x104
|
||||
#define CSR_STVEC 0x105
|
||||
#define CSR_SCOUNTEREN 0x106
|
||||
#define CSR_SSCRATCH 0x140
|
||||
#define CSR_SEPC 0x141
|
||||
#define CSR_SCAUSE 0x142
|
||||
#define CSR_SBADADDR 0x143
|
||||
#define CSR_STVAL 0x143
|
||||
#define CSR_SIP 0x144
|
||||
#define CSR_SPTBR 0x180
|
||||
#define CSR_SATP 0x180
|
||||
#define CSR_MSTATUS 0x300
|
||||
#define CSR_MISA 0x301
|
||||
#define CSR_MEDELEG 0x302
|
||||
#define CSR_MIDELEG 0x303
|
||||
#define CSR_MIE 0x304
|
||||
#define CSR_MTVEC 0x305
|
||||
#define CSR_MCOUNTEREN 0x306
|
||||
#define CSR_MSCRATCH 0x340
|
||||
#define CSR_MEPC 0x341
|
||||
#define CSR_MCAUSE 0x342
|
||||
#define CSR_MBADADDR 0x343
|
||||
#define CSR_MTVAL 0x343
|
||||
#define CSR_MIP 0x344
|
||||
#define CSR_PMPCFG0 0x3a0
|
||||
#define CSR_PMPCFG1 0x3a1
|
||||
#define CSR_PMPCFG2 0x3a2
|
||||
#define CSR_PMPCFG3 0x3a3
|
||||
#define CSR_PMPADDR0 0x3b0
|
||||
#define CSR_PMPADDR1 0x3b1
|
||||
#define CSR_PMPADDR2 0x3b2
|
||||
#define CSR_PMPADDR3 0x3b3
|
||||
#define CSR_PMPADDR4 0x3b4
|
||||
#define CSR_PMPADDR5 0x3b5
|
||||
#define CSR_PMPADDR6 0x3b6
|
||||
#define CSR_PMPADDR7 0x3b7
|
||||
#define CSR_PMPADDR8 0x3b8
|
||||
#define CSR_PMPADDR9 0x3b9
|
||||
#define CSR_PMPADDR10 0x3ba
|
||||
#define CSR_PMPADDR11 0x3bb
|
||||
#define CSR_PMPADDR12 0x3bc
|
||||
#define CSR_PMPADDR13 0x3bd
|
||||
#define CSR_PMPADDR14 0x3be
|
||||
#define CSR_PMPADDR15 0x3bf
|
||||
#define CSR_TSELECT 0x7a0
|
||||
#define CSR_TDATA1 0x7a1
|
||||
#define CSR_TDATA2 0x7a2
|
||||
@@ -762,8 +863,6 @@
|
||||
#define CSR_MHPMCOUNTER29 0xb1d
|
||||
#define CSR_MHPMCOUNTER30 0xb1e
|
||||
#define CSR_MHPMCOUNTER31 0xb1f
|
||||
#define CSR_MUCOUNTEREN 0x320
|
||||
#define CSR_MSCOUNTEREN 0x321
|
||||
#define CSR_MHPMEVENT3 0x323
|
||||
#define CSR_MHPMEVENT4 0x324
|
||||
#define CSR_MHPMEVENT5 0x325
|
||||
@@ -861,17 +960,20 @@
|
||||
#define CSR_MHPMCOUNTER30H 0xb9e
|
||||
#define CSR_MHPMCOUNTER31H 0xb9f
|
||||
#define CAUSE_MISALIGNED_FETCH 0x0
|
||||
#define CAUSE_FAULT_FETCH 0x1
|
||||
#define CAUSE_FETCH_ACCESS 0x1
|
||||
#define CAUSE_ILLEGAL_INSTRUCTION 0x2
|
||||
#define CAUSE_BREAKPOINT 0x3
|
||||
#define CAUSE_MISALIGNED_LOAD 0x4
|
||||
#define CAUSE_FAULT_LOAD 0x5
|
||||
#define CAUSE_LOAD_ACCESS 0x5
|
||||
#define CAUSE_MISALIGNED_STORE 0x6
|
||||
#define CAUSE_FAULT_STORE 0x7
|
||||
#define CAUSE_STORE_ACCESS 0x7
|
||||
#define CAUSE_USER_ECALL 0x8
|
||||
#define CAUSE_SUPERVISOR_ECALL 0x9
|
||||
#define CAUSE_HYPERVISOR_ECALL 0xa
|
||||
#define CAUSE_MACHINE_ECALL 0xb
|
||||
#define CAUSE_FETCH_PAGE_FAULT 0xc
|
||||
#define CAUSE_LOAD_PAGE_FAULT 0xd
|
||||
#define CAUSE_STORE_PAGE_FAULT 0xf
|
||||
#endif
|
||||
#ifdef DECLARE_INSN
|
||||
DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)
|
||||
@@ -964,10 +1066,9 @@ DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL)
|
||||
DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK)
|
||||
DECLARE_INSN(uret, MATCH_URET, MASK_URET)
|
||||
DECLARE_INSN(sret, MATCH_SRET, MASK_SRET)
|
||||
DECLARE_INSN(hret, MATCH_HRET, MASK_HRET)
|
||||
DECLARE_INSN(mret, MATCH_MRET, MASK_MRET)
|
||||
DECLARE_INSN(dret, MATCH_DRET, MASK_DRET)
|
||||
DECLARE_INSN(sfence_vm, MATCH_SFENCE_VM, MASK_SFENCE_VM)
|
||||
DECLARE_INSN(sfence_vma, MATCH_SFENCE_VMA, MASK_SFENCE_VMA)
|
||||
DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI)
|
||||
DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW)
|
||||
DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS)
|
||||
@@ -997,17 +1098,34 @@ DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D)
|
||||
DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D)
|
||||
DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S)
|
||||
DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D)
|
||||
DECLARE_INSN(fadd_q, MATCH_FADD_Q, MASK_FADD_Q)
|
||||
DECLARE_INSN(fsub_q, MATCH_FSUB_Q, MASK_FSUB_Q)
|
||||
DECLARE_INSN(fmul_q, MATCH_FMUL_Q, MASK_FMUL_Q)
|
||||
DECLARE_INSN(fdiv_q, MATCH_FDIV_Q, MASK_FDIV_Q)
|
||||
DECLARE_INSN(fsgnj_q, MATCH_FSGNJ_Q, MASK_FSGNJ_Q)
|
||||
DECLARE_INSN(fsgnjn_q, MATCH_FSGNJN_Q, MASK_FSGNJN_Q)
|
||||
DECLARE_INSN(fsgnjx_q, MATCH_FSGNJX_Q, MASK_FSGNJX_Q)
|
||||
DECLARE_INSN(fmin_q, MATCH_FMIN_Q, MASK_FMIN_Q)
|
||||
DECLARE_INSN(fmax_q, MATCH_FMAX_Q, MASK_FMAX_Q)
|
||||
DECLARE_INSN(fcvt_s_q, MATCH_FCVT_S_Q, MASK_FCVT_S_Q)
|
||||
DECLARE_INSN(fcvt_q_s, MATCH_FCVT_Q_S, MASK_FCVT_Q_S)
|
||||
DECLARE_INSN(fcvt_d_q, MATCH_FCVT_D_Q, MASK_FCVT_D_Q)
|
||||
DECLARE_INSN(fcvt_q_d, MATCH_FCVT_Q_D, MASK_FCVT_Q_D)
|
||||
DECLARE_INSN(fsqrt_q, MATCH_FSQRT_Q, MASK_FSQRT_Q)
|
||||
DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S)
|
||||
DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S)
|
||||
DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S)
|
||||
DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D)
|
||||
DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D)
|
||||
DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D)
|
||||
DECLARE_INSN(fle_q, MATCH_FLE_Q, MASK_FLE_Q)
|
||||
DECLARE_INSN(flt_q, MATCH_FLT_Q, MASK_FLT_Q)
|
||||
DECLARE_INSN(feq_q, MATCH_FEQ_Q, MASK_FEQ_Q)
|
||||
DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S)
|
||||
DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S)
|
||||
DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S)
|
||||
DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S)
|
||||
DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S)
|
||||
DECLARE_INSN(fmv_x_w, MATCH_FMV_X_W, MASK_FMV_X_W)
|
||||
DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S)
|
||||
DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D)
|
||||
DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D)
|
||||
@@ -1015,20 +1133,33 @@ DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D)
|
||||
DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D)
|
||||
DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D)
|
||||
DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D)
|
||||
DECLARE_INSN(fcvt_w_q, MATCH_FCVT_W_Q, MASK_FCVT_W_Q)
|
||||
DECLARE_INSN(fcvt_wu_q, MATCH_FCVT_WU_Q, MASK_FCVT_WU_Q)
|
||||
DECLARE_INSN(fcvt_l_q, MATCH_FCVT_L_Q, MASK_FCVT_L_Q)
|
||||
DECLARE_INSN(fcvt_lu_q, MATCH_FCVT_LU_Q, MASK_FCVT_LU_Q)
|
||||
DECLARE_INSN(fmv_x_q, MATCH_FMV_X_Q, MASK_FMV_X_Q)
|
||||
DECLARE_INSN(fclass_q, MATCH_FCLASS_Q, MASK_FCLASS_Q)
|
||||
DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W)
|
||||
DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU)
|
||||
DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L)
|
||||
DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU)
|
||||
DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X)
|
||||
DECLARE_INSN(fmv_w_x, MATCH_FMV_W_X, MASK_FMV_W_X)
|
||||
DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W)
|
||||
DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU)
|
||||
DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L)
|
||||
DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU)
|
||||
DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X)
|
||||
DECLARE_INSN(fcvt_q_w, MATCH_FCVT_Q_W, MASK_FCVT_Q_W)
|
||||
DECLARE_INSN(fcvt_q_wu, MATCH_FCVT_Q_WU, MASK_FCVT_Q_WU)
|
||||
DECLARE_INSN(fcvt_q_l, MATCH_FCVT_Q_L, MASK_FCVT_Q_L)
|
||||
DECLARE_INSN(fcvt_q_lu, MATCH_FCVT_Q_LU, MASK_FCVT_Q_LU)
|
||||
DECLARE_INSN(fmv_q_x, MATCH_FMV_Q_X, MASK_FMV_Q_X)
|
||||
DECLARE_INSN(flw, MATCH_FLW, MASK_FLW)
|
||||
DECLARE_INSN(fld, MATCH_FLD, MASK_FLD)
|
||||
DECLARE_INSN(flq, MATCH_FLQ, MASK_FLQ)
|
||||
DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW)
|
||||
DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD)
|
||||
DECLARE_INSN(fsq, MATCH_FSQ, MASK_FSQ)
|
||||
DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S)
|
||||
DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S)
|
||||
DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S)
|
||||
@@ -1037,6 +1168,10 @@ DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D)
|
||||
DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D)
|
||||
DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D)
|
||||
DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D)
|
||||
DECLARE_INSN(fmadd_q, MATCH_FMADD_Q, MASK_FMADD_Q)
|
||||
DECLARE_INSN(fmsub_q, MATCH_FMSUB_Q, MASK_FMSUB_Q)
|
||||
DECLARE_INSN(fnmsub_q, MATCH_FNMSUB_Q, MASK_FNMSUB_Q)
|
||||
DECLARE_INSN(fnmadd_q, MATCH_FNMADD_Q, MASK_FNMADD_Q)
|
||||
DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP)
|
||||
DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP)
|
||||
DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR)
|
||||
@@ -1143,23 +1278,45 @@ DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31)
|
||||
DECLARE_CSR(sstatus, CSR_SSTATUS)
|
||||
DECLARE_CSR(sie, CSR_SIE)
|
||||
DECLARE_CSR(stvec, CSR_STVEC)
|
||||
DECLARE_CSR(scounteren, CSR_SCOUNTEREN)
|
||||
DECLARE_CSR(sscratch, CSR_SSCRATCH)
|
||||
DECLARE_CSR(sepc, CSR_SEPC)
|
||||
DECLARE_CSR(scause, CSR_SCAUSE)
|
||||
DECLARE_CSR(sbadaddr, CSR_SBADADDR)
|
||||
DECLARE_CSR(stval, CSR_STVAL)
|
||||
DECLARE_CSR(sip, CSR_SIP)
|
||||
DECLARE_CSR(sptbr, CSR_SPTBR)
|
||||
DECLARE_CSR(satp, CSR_SATP)
|
||||
DECLARE_CSR(mstatus, CSR_MSTATUS)
|
||||
DECLARE_CSR(misa, CSR_MISA)
|
||||
DECLARE_CSR(medeleg, CSR_MEDELEG)
|
||||
DECLARE_CSR(mideleg, CSR_MIDELEG)
|
||||
DECLARE_CSR(mie, CSR_MIE)
|
||||
DECLARE_CSR(mtvec, CSR_MTVEC)
|
||||
DECLARE_CSR(mcounteren, CSR_MCOUNTEREN)
|
||||
DECLARE_CSR(mscratch, CSR_MSCRATCH)
|
||||
DECLARE_CSR(mepc, CSR_MEPC)
|
||||
DECLARE_CSR(mcause, CSR_MCAUSE)
|
||||
DECLARE_CSR(mbadaddr, CSR_MBADADDR)
|
||||
DECLARE_CSR(mtval, CSR_MTVAL)
|
||||
DECLARE_CSR(mip, CSR_MIP)
|
||||
DECLARE_CSR(pmpcfg0, CSR_PMPCFG0)
|
||||
DECLARE_CSR(pmpcfg1, CSR_PMPCFG1)
|
||||
DECLARE_CSR(pmpcfg2, CSR_PMPCFG2)
|
||||
DECLARE_CSR(pmpcfg3, CSR_PMPCFG3)
|
||||
DECLARE_CSR(pmpaddr0, CSR_PMPADDR0)
|
||||
DECLARE_CSR(pmpaddr1, CSR_PMPADDR1)
|
||||
DECLARE_CSR(pmpaddr2, CSR_PMPADDR2)
|
||||
DECLARE_CSR(pmpaddr3, CSR_PMPADDR3)
|
||||
DECLARE_CSR(pmpaddr4, CSR_PMPADDR4)
|
||||
DECLARE_CSR(pmpaddr5, CSR_PMPADDR5)
|
||||
DECLARE_CSR(pmpaddr6, CSR_PMPADDR6)
|
||||
DECLARE_CSR(pmpaddr7, CSR_PMPADDR7)
|
||||
DECLARE_CSR(pmpaddr8, CSR_PMPADDR8)
|
||||
DECLARE_CSR(pmpaddr9, CSR_PMPADDR9)
|
||||
DECLARE_CSR(pmpaddr10, CSR_PMPADDR10)
|
||||
DECLARE_CSR(pmpaddr11, CSR_PMPADDR11)
|
||||
DECLARE_CSR(pmpaddr12, CSR_PMPADDR12)
|
||||
DECLARE_CSR(pmpaddr13, CSR_PMPADDR13)
|
||||
DECLARE_CSR(pmpaddr14, CSR_PMPADDR14)
|
||||
DECLARE_CSR(pmpaddr15, CSR_PMPADDR15)
|
||||
DECLARE_CSR(tselect, CSR_TSELECT)
|
||||
DECLARE_CSR(tdata1, CSR_TDATA1)
|
||||
DECLARE_CSR(tdata2, CSR_TDATA2)
|
||||
@@ -1198,8 +1355,6 @@ DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28)
|
||||
DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29)
|
||||
DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30)
|
||||
DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31)
|
||||
DECLARE_CSR(mucounteren, CSR_MUCOUNTEREN)
|
||||
DECLARE_CSR(mscounteren, CSR_MSCOUNTEREN)
|
||||
DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3)
|
||||
DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4)
|
||||
DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5)
|
||||
@@ -1299,15 +1454,18 @@ DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H)
|
||||
#endif
|
||||
#ifdef DECLARE_CAUSE
|
||||
DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH)
|
||||
DECLARE_CAUSE("fault fetch", CAUSE_FAULT_FETCH)
|
||||
DECLARE_CAUSE("fetch access", CAUSE_FETCH_ACCESS)
|
||||
DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION)
|
||||
DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT)
|
||||
DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD)
|
||||
DECLARE_CAUSE("fault load", CAUSE_FAULT_LOAD)
|
||||
DECLARE_CAUSE("load access", CAUSE_LOAD_ACCESS)
|
||||
DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE)
|
||||
DECLARE_CAUSE("fault store", CAUSE_FAULT_STORE)
|
||||
DECLARE_CAUSE("store access", CAUSE_STORE_ACCESS)
|
||||
DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL)
|
||||
DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL)
|
||||
DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL)
|
||||
DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL)
|
||||
DECLARE_CAUSE("fetch page fault", CAUSE_FETCH_PAGE_FAULT)
|
||||
DECLARE_CAUSE("load page fault", CAUSE_LOAD_PAGE_FAULT)
|
||||
DECLARE_CAUSE("store page fault", CAUSE_STORE_PAGE_FAULT)
|
||||
#endif
|
||||
|
||||
@@ -1,18 +1,79 @@
|
||||
#ifndef TARGET__RISCV__GDB_REGS_H
|
||||
#define TARGET__RISCV__GDB_REGS_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.
|
||||
/* 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 {
|
||||
GDB_REGNO_XPR0 = 0,
|
||||
GDB_REGNO_X0 = GDB_REGNO_XPR0 + 0,
|
||||
GDB_REGNO_ZERO = GDB_REGNO_XPR0 + 0,
|
||||
GDB_REGNO_S0 = GDB_REGNO_XPR0 + 8,
|
||||
GDB_REGNO_S1 = GDB_REGNO_XPR0 + 9,
|
||||
GDB_REGNO_XPR31 = GDB_REGNO_XPR0 + 31,
|
||||
GDB_REGNO_ZERO = 0, /* Read-only register, always 0. */
|
||||
GDB_REGNO_RA = 1, /* Return Address. */
|
||||
GDB_REGNO_SP = 2, /* Stack Pointer. */
|
||||
GDB_REGNO_GP = 3, /* Global Pointer. */
|
||||
GDB_REGNO_TP = 4, /* Thread Pointer. */
|
||||
GDB_REGNO_T0,
|
||||
GDB_REGNO_T1,
|
||||
GDB_REGNO_T2,
|
||||
GDB_REGNO_S0 = 8,
|
||||
GDB_REGNO_FP = 8, /* Frame Pointer. */
|
||||
GDB_REGNO_S1,
|
||||
GDB_REGNO_A0 = 10, /* First argument. */
|
||||
GDB_REGNO_A1 = 11, /* Second argument. */
|
||||
GDB_REGNO_A2,
|
||||
GDB_REGNO_A3,
|
||||
GDB_REGNO_A4,
|
||||
GDB_REGNO_A5,
|
||||
GDB_REGNO_A6,
|
||||
GDB_REGNO_A7,
|
||||
GDB_REGNO_S2,
|
||||
GDB_REGNO_S3,
|
||||
GDB_REGNO_S4,
|
||||
GDB_REGNO_S5,
|
||||
GDB_REGNO_S6,
|
||||
GDB_REGNO_S7,
|
||||
GDB_REGNO_S8,
|
||||
GDB_REGNO_S9,
|
||||
GDB_REGNO_S10,
|
||||
GDB_REGNO_S11,
|
||||
GDB_REGNO_T3,
|
||||
GDB_REGNO_T4,
|
||||
GDB_REGNO_T5,
|
||||
GDB_REGNO_T6,
|
||||
GDB_REGNO_XPR31 = GDB_REGNO_T6,
|
||||
|
||||
GDB_REGNO_PC = 32,
|
||||
GDB_REGNO_FPR0 = 33,
|
||||
GDB_REGNO_FPR31 = GDB_REGNO_FPR0 + 31,
|
||||
GDB_REGNO_FT0 = GDB_REGNO_FPR0,
|
||||
GDB_REGNO_FT1,
|
||||
GDB_REGNO_FT2,
|
||||
GDB_REGNO_FT3,
|
||||
GDB_REGNO_FT4,
|
||||
GDB_REGNO_FT5,
|
||||
GDB_REGNO_FT6,
|
||||
GDB_REGNO_FT7,
|
||||
GDB_REGNO_FS0,
|
||||
GDB_REGNO_FS1,
|
||||
GDB_REGNO_FA0,
|
||||
GDB_REGNO_FA1,
|
||||
GDB_REGNO_FA2,
|
||||
GDB_REGNO_FA3,
|
||||
GDB_REGNO_FA4,
|
||||
GDB_REGNO_FA5,
|
||||
GDB_REGNO_FA6,
|
||||
GDB_REGNO_FA7,
|
||||
GDB_REGNO_FS2,
|
||||
GDB_REGNO_FS3,
|
||||
GDB_REGNO_FS4,
|
||||
GDB_REGNO_FS5,
|
||||
GDB_REGNO_FS6,
|
||||
GDB_REGNO_FS7,
|
||||
GDB_REGNO_FS8,
|
||||
GDB_REGNO_FS9,
|
||||
GDB_REGNO_FS10,
|
||||
GDB_REGNO_FS11,
|
||||
GDB_REGNO_FT8,
|
||||
GDB_REGNO_FT9,
|
||||
GDB_REGNO_FT10,
|
||||
GDB_REGNO_FT11,
|
||||
GDB_REGNO_FPR31 = GDB_REGNO_FT11,
|
||||
GDB_REGNO_CSR0 = 65,
|
||||
GDB_REGNO_TSELECT = CSR_TSELECT + GDB_REGNO_CSR0,
|
||||
GDB_REGNO_TDATA1 = CSR_TDATA1 + GDB_REGNO_CSR0,
|
||||
|
||||
+32
-17
@@ -5,16 +5,19 @@
|
||||
#define S0 8
|
||||
#define S1 9
|
||||
|
||||
static uint32_t bits(uint32_t value, unsigned int hi, unsigned int lo) {
|
||||
static uint32_t bits(uint32_t value, unsigned int hi, unsigned int lo)
|
||||
{
|
||||
return (value >> lo) & ((1 << (hi+1-lo)) - 1);
|
||||
}
|
||||
|
||||
static uint32_t bit(uint32_t value, unsigned int b) {
|
||||
static uint32_t bit(uint32_t value, unsigned int b)
|
||||
{
|
||||
return (value >> b) & 1;
|
||||
}
|
||||
|
||||
static uint32_t jal(unsigned int rd, uint32_t imm) __attribute__ ((unused));
|
||||
static uint32_t jal(unsigned int rd, uint32_t imm) {
|
||||
static uint32_t jal(unsigned int rd, uint32_t imm)
|
||||
{
|
||||
return (bit(imm, 20) << 31) |
|
||||
(bits(imm, 10, 1) << 21) |
|
||||
(bit(imm, 11) << 20) |
|
||||
@@ -24,7 +27,8 @@ static uint32_t jal(unsigned int rd, uint32_t imm) {
|
||||
}
|
||||
|
||||
static uint32_t csrsi(unsigned int csr, uint16_t imm) __attribute__ ((unused));
|
||||
static uint32_t csrsi(unsigned int csr, uint16_t imm) {
|
||||
static uint32_t csrsi(unsigned int csr, uint16_t imm)
|
||||
{
|
||||
return (csr << 20) |
|
||||
(bits(imm, 4, 0) << 15) |
|
||||
MATCH_CSRRSI;
|
||||
@@ -107,7 +111,8 @@ static uint32_t lb(unsigned int rd, unsigned int base, uint16_t offset)
|
||||
}
|
||||
|
||||
static uint32_t csrw(unsigned int source, unsigned int csr) __attribute__ ((unused));
|
||||
static uint32_t csrw(unsigned int source, unsigned int csr) {
|
||||
static uint32_t csrw(unsigned int source, unsigned int csr)
|
||||
{
|
||||
return (csr << 20) | (source << 15) | MATCH_CSRRW;
|
||||
}
|
||||
|
||||
@@ -121,17 +126,20 @@ static uint32_t addi(unsigned int dest, unsigned int src, uint16_t imm)
|
||||
}
|
||||
|
||||
static uint32_t csrr(unsigned int rd, unsigned int csr) __attribute__ ((unused));
|
||||
static uint32_t csrr(unsigned int rd, unsigned int csr) {
|
||||
static uint32_t csrr(unsigned int rd, unsigned int csr)
|
||||
{
|
||||
return (csr << 20) | (rd << 7) | MATCH_CSRRS;
|
||||
}
|
||||
|
||||
static uint32_t csrrs(unsigned int rd, unsigned int rs, unsigned int csr) __attribute__ ((unused));
|
||||
static uint32_t csrrs(unsigned int rd, unsigned int rs, unsigned int csr) {
|
||||
static uint32_t csrrs(unsigned int rd, unsigned int rs, unsigned int csr)
|
||||
{
|
||||
return (csr << 20) | (rs << 15) | (rd << 7) | MATCH_CSRRS;
|
||||
}
|
||||
|
||||
static uint32_t csrrw(unsigned int rd, unsigned int rs, unsigned int csr) __attribute__ ((unused));
|
||||
static uint32_t csrrw(unsigned int rd, unsigned int rs, unsigned int csr) {
|
||||
static uint32_t csrrw(unsigned int rd, unsigned int rs, unsigned int csr)
|
||||
{
|
||||
return (csr << 20) | (rs << 15) | (rd << 7) | MATCH_CSRRW;
|
||||
}
|
||||
|
||||
@@ -173,12 +181,12 @@ static uint32_t fld(unsigned int dest, unsigned int base, uint16_t offset)
|
||||
MATCH_FLD;
|
||||
}
|
||||
|
||||
static uint32_t fmv_x_s(unsigned dest, unsigned src) __attribute__ ((unused));
|
||||
static uint32_t fmv_x_s(unsigned dest, unsigned src)
|
||||
static uint32_t fmv_x_w(unsigned dest, unsigned src) __attribute__ ((unused));
|
||||
static uint32_t fmv_x_w(unsigned dest, unsigned src)
|
||||
{
|
||||
return src << 15 |
|
||||
dest << 7 |
|
||||
MATCH_FMV_X_S;
|
||||
MATCH_FMV_X_W;
|
||||
}
|
||||
|
||||
static uint32_t fmv_x_d(unsigned dest, unsigned src) __attribute__ ((unused));
|
||||
@@ -189,12 +197,12 @@ static uint32_t fmv_x_d(unsigned dest, unsigned src)
|
||||
MATCH_FMV_X_D;
|
||||
}
|
||||
|
||||
static uint32_t fmv_s_x(unsigned dest, unsigned src) __attribute__ ((unused));
|
||||
static uint32_t fmv_s_x(unsigned dest, unsigned src)
|
||||
static uint32_t fmv_w_x(unsigned dest, unsigned src) __attribute__ ((unused));
|
||||
static uint32_t fmv_w_x(unsigned dest, unsigned src)
|
||||
{
|
||||
return src << 15 |
|
||||
dest << 7 |
|
||||
MATCH_FMV_S_X;
|
||||
MATCH_FMV_W_X;
|
||||
}
|
||||
|
||||
static uint32_t fmv_d_x(unsigned dest, unsigned src) __attribute__ ((unused));
|
||||
@@ -206,9 +214,15 @@ static uint32_t fmv_d_x(unsigned dest, unsigned src)
|
||||
}
|
||||
|
||||
static uint32_t ebreak(void) __attribute__ ((unused));
|
||||
static uint32_t ebreak(void) { return MATCH_EBREAK; }
|
||||
static uint32_t ebreak(void)
|
||||
{
|
||||
return MATCH_EBREAK;
|
||||
}
|
||||
static uint32_t ebreak_c(void) __attribute__ ((unused));
|
||||
static uint32_t ebreak_c(void) { return MATCH_C_EBREAK; }
|
||||
static uint32_t ebreak_c(void)
|
||||
{
|
||||
return MATCH_C_EBREAK;
|
||||
}
|
||||
|
||||
static uint32_t wfi(void) __attribute__ ((unused));
|
||||
static uint32_t wfi(void) { return MATCH_WFI; }
|
||||
@@ -229,7 +243,8 @@ static uint32_t lui(unsigned int dest, uint32_t imm)
|
||||
|
||||
/*
|
||||
static uint32_t csrci(unsigned int csr, uint16_t imm) __attribute__ ((unused));
|
||||
static uint32_t csrci(unsigned int csr, uint16_t imm) {
|
||||
static uint32_t csrci(unsigned int csr, uint16_t imm)
|
||||
{
|
||||
return (csr << 20) |
|
||||
(bits(imm, 4, 0) << 15) |
|
||||
MATCH_CSRRCI;
|
||||
|
||||
+33
-388
@@ -11,78 +11,57 @@
|
||||
#include "asm.h"
|
||||
#include "encoding.h"
|
||||
|
||||
riscv_addr_t riscv_program_gal(struct riscv_program *p, riscv_addr_t addr);
|
||||
int riscv_program_lah(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr);
|
||||
int riscv_program_lal(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr);
|
||||
|
||||
/* Program interface. */
|
||||
int riscv_program_init(struct riscv_program *p, struct target *target)
|
||||
{
|
||||
memset(p, 0, sizeof(*p));
|
||||
p->target = target;
|
||||
p->instruction_count = 0;
|
||||
p->data_count = 0;
|
||||
p->writes_memory = 0;
|
||||
p->target_xlen = riscv_xlen(target);
|
||||
for (size_t i = 0; i < RISCV_REGISTER_COUNT; ++i) {
|
||||
for (size_t i = 0; i < RISCV_REGISTER_COUNT; ++i)
|
||||
p->writes_xreg[i] = 0;
|
||||
p->in_use[i] = 0;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < RISCV_MAX_DEBUG_BUFFER_SIZE; ++i)
|
||||
for (size_t i = 0; i < RISCV_MAX_DEBUG_BUFFER_SIZE; ++i)
|
||||
p->debug_buffer[i] = -1;
|
||||
|
||||
if (riscv_debug_buffer_enter(target, p) != ERROR_OK) {
|
||||
LOG_ERROR("unable to write progam buffer enter code");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int riscv_program_write(struct riscv_program *program)
|
||||
{
|
||||
for (unsigned i = 0; i < program->instruction_count; ++i) {
|
||||
LOG_DEBUG("%p: debug_buffer[%02x] = DASM(0x%08x)", program, i, program->debug_buffer[i]);
|
||||
if (riscv_write_debug_buffer(program->target, i,
|
||||
program->debug_buffer[i]) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/** Add ebreak and execute the program. */
|
||||
int riscv_program_exec(struct riscv_program *p, struct target *t)
|
||||
{
|
||||
keep_alive();
|
||||
|
||||
if (riscv_debug_buffer_leave(t, p) != ERROR_OK) {
|
||||
LOG_ERROR("unable to write program buffer exit code");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
riscv_reg_t saved_registers[GDB_REGNO_XPR31 + 1];
|
||||
for (size_t i = GDB_REGNO_XPR0 + 1; i <= GDB_REGNO_XPR31; ++i) {
|
||||
for (size_t i = GDB_REGNO_ZERO + 1; i <= GDB_REGNO_XPR31; ++i) {
|
||||
if (p->writes_xreg[i]) {
|
||||
LOG_DEBUG("Saving register %d as used by program", (int)i);
|
||||
saved_registers[i] = riscv_get_register(t, i);
|
||||
int result = riscv_get_register(t, &saved_registers[i], i);
|
||||
if (result != ERROR_OK)
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->writes_memory && (riscv_program_fence(p) != ERROR_OK)) {
|
||||
LOG_ERROR("Unable to write fence");
|
||||
for(size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)
|
||||
LOG_ERROR("ram[%02x]: DASM(0x%08lx) [0x%08lx]", (int)i, (long)p->debug_buffer[i], (long)p->debug_buffer[i]);
|
||||
abort();
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
if (riscv_program_ebreak(p) != ERROR_OK) {
|
||||
LOG_ERROR("Unable to write ebreak");
|
||||
for(size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)
|
||||
for (size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)
|
||||
LOG_ERROR("ram[%02x]: DASM(0x%08lx) [0x%08lx]", (int)i, (long)p->debug_buffer[i], (long)p->debug_buffer[i]);
|
||||
abort();
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < riscv_debug_buffer_size(p->target); ++i) {
|
||||
if (i < p->instruction_count) {
|
||||
LOG_DEBUG("%p: debug_buffer[%02x] = DASM(0x%08x)", p, i, p->debug_buffer[i]);
|
||||
riscv_write_debug_buffer(t, i, p->debug_buffer[i]);
|
||||
}
|
||||
if (i >= riscv_debug_buffer_size(p->target) - p->data_count) {
|
||||
LOG_DEBUG("%p: debug_buffer[%02x] = 0x%08x", p, i, p->debug_buffer[i]);
|
||||
riscv_write_debug_buffer(t, i, p->debug_buffer[i]);
|
||||
}
|
||||
}
|
||||
if (riscv_program_write(p) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (riscv_execute_debug_buffer(t) != ERROR_OK) {
|
||||
LOG_ERROR("Unable to execute program %p", p);
|
||||
@@ -90,259 +69,56 @@ int riscv_program_exec(struct riscv_program *p, struct target *t)
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < riscv_debug_buffer_size(p->target); ++i)
|
||||
if (i >= riscv_debug_buffer_size(p->target) - p->data_count)
|
||||
if (i >= riscv_debug_buffer_size(p->target))
|
||||
p->debug_buffer[i] = riscv_read_debug_buffer(t, i);
|
||||
|
||||
for (size_t i = GDB_REGNO_XPR0; i <= GDB_REGNO_XPR31; ++i)
|
||||
for (size_t i = GDB_REGNO_ZERO; i <= GDB_REGNO_XPR31; ++i)
|
||||
if (p->writes_xreg[i])
|
||||
riscv_set_register(t, i, saved_registers[i]);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
riscv_addr_t riscv_program_alloc_data(struct riscv_program *p, size_t bytes)
|
||||
{
|
||||
riscv_addr_t addr =
|
||||
riscv_debug_buffer_addr(p->target)
|
||||
+ riscv_debug_buffer_size(p->target) * sizeof(p->debug_buffer[0])
|
||||
- p->data_count * sizeof(p->debug_buffer[0])
|
||||
- bytes;
|
||||
while (addr % bytes != 0) addr--;
|
||||
|
||||
riscv_addr_t ptop =
|
||||
riscv_debug_buffer_addr(p->target)
|
||||
+ p->instruction_count * sizeof(p->debug_buffer[0]);
|
||||
|
||||
if (addr <= ptop) {
|
||||
LOG_ERROR("unable to allocate %d bytes", (int)bytes);
|
||||
return RISCV_PROGRAM_ALLOC_FAIL;
|
||||
}
|
||||
|
||||
p->data_count =
|
||||
+ riscv_debug_buffer_size(p->target)
|
||||
- (addr - riscv_debug_buffer_addr(p->target)) / sizeof(p->debug_buffer[0]);
|
||||
return addr;
|
||||
}
|
||||
|
||||
riscv_addr_t riscv_program_alloc_x(struct riscv_program *p)
|
||||
{
|
||||
return riscv_program_alloc_data(p, p->target_xlen / 8);
|
||||
}
|
||||
|
||||
riscv_addr_t riscv_program_alloc_d(struct riscv_program *p)
|
||||
{
|
||||
return riscv_program_alloc_data(p, 8);
|
||||
}
|
||||
|
||||
riscv_addr_t riscv_program_alloc_w(struct riscv_program *p)
|
||||
{
|
||||
return riscv_program_alloc_data(p, 4);
|
||||
}
|
||||
|
||||
riscv_addr_t riscv_program_alloc_h(struct riscv_program *p)
|
||||
{
|
||||
return riscv_program_alloc_data(p, 2);
|
||||
}
|
||||
|
||||
riscv_addr_t riscv_program_alloc_b(struct riscv_program *p)
|
||||
{
|
||||
return riscv_program_alloc_data(p, 1);
|
||||
}
|
||||
|
||||
riscv_insn_t riscv_program_read_ram(struct riscv_program *p, riscv_addr_t addr)
|
||||
{
|
||||
if (addr < riscv_debug_buffer_addr(p->target))
|
||||
return -1;
|
||||
if ((size_t)addr > riscv_debug_buffer_addr(p->target) + (riscv_debug_buffer_size(p->target) * sizeof(p->debug_buffer[0])))
|
||||
return -1;
|
||||
|
||||
int off = (addr - riscv_debug_buffer_addr(p->target)) / sizeof(p->debug_buffer[0]);
|
||||
return p->debug_buffer[off];
|
||||
}
|
||||
|
||||
void riscv_program_write_ram(struct riscv_program *p, riscv_addr_t addr, uint64_t d)
|
||||
{
|
||||
if (addr < riscv_debug_buffer_addr(p->target))
|
||||
return;
|
||||
if ((size_t)addr > riscv_debug_buffer_addr(p->target) + (riscv_debug_buffer_size(p->target) * sizeof(p->debug_buffer[0])))
|
||||
return;
|
||||
|
||||
int off = (addr - riscv_debug_buffer_addr(p->target)) / sizeof(p->debug_buffer[0]);
|
||||
p->debug_buffer[off] = d;
|
||||
}
|
||||
|
||||
int riscv_program_swr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
|
||||
{
|
||||
p->writes_memory = 1;
|
||||
return riscv_program_insert(p, sw(d, b, offset));
|
||||
}
|
||||
|
||||
int riscv_program_shr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
|
||||
{
|
||||
p->writes_memory = 1;
|
||||
return riscv_program_insert(p, sh(d, b, offset));
|
||||
}
|
||||
|
||||
int riscv_program_sbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
|
||||
{
|
||||
p->writes_memory = 1;
|
||||
return riscv_program_insert(p, sb(d, b, offset));
|
||||
}
|
||||
|
||||
int riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
|
||||
{
|
||||
p->writes_memory = 1;
|
||||
return riscv_program_insert(p, lw(d, b, offset));
|
||||
}
|
||||
|
||||
int riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
|
||||
{
|
||||
p->writes_memory = 1;
|
||||
return riscv_program_insert(p, lh(d, b, offset));
|
||||
}
|
||||
|
||||
int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno b, int offset)
|
||||
{
|
||||
p->writes_memory = 1;
|
||||
return riscv_program_insert(p, lb(d, b, offset));
|
||||
}
|
||||
|
||||
int riscv_program_lx(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
switch (p->target_xlen) {
|
||||
case 64: return riscv_program_ld(p, d, addr);
|
||||
case 32: return riscv_program_lw(p, d, addr);
|
||||
}
|
||||
|
||||
LOG_ERROR("unknown xlen %d", p->target_xlen);
|
||||
abort();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int riscv_program_ld(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
enum gdb_regno t = riscv_program_gah(p, addr) == 0 ? GDB_REGNO_X0 : d;
|
||||
if (riscv_program_lah(p, d, addr) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
if (riscv_program_insert(p, ld(d, t, riscv_program_gal(p, addr))) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int riscv_program_lw(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
enum gdb_regno t = riscv_program_gah(p, addr) == 0 ? GDB_REGNO_X0 : d;
|
||||
if (riscv_program_lah(p, d, addr) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
if (riscv_program_insert(p, lw(d, t, riscv_program_gal(p, addr))) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int riscv_program_lh(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
enum gdb_regno t = riscv_program_gah(p, addr) == 0 ? GDB_REGNO_X0 : d;
|
||||
if (riscv_program_lah(p, d, addr) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
if (riscv_program_insert(p, lh(d, t, riscv_program_gal(p, addr))) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int riscv_program_lb(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
enum gdb_regno t = riscv_program_gah(p, addr) == 0 ? GDB_REGNO_X0 : d;
|
||||
if (riscv_program_lah(p, t, addr) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
if (riscv_program_insert(p, lb(d, t, riscv_program_gal(p, addr))) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int riscv_program_sx(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
switch (p->target_xlen) {
|
||||
case 64: return riscv_program_sd(p, d, addr);
|
||||
case 32: return riscv_program_sw(p, d, addr);
|
||||
}
|
||||
|
||||
LOG_ERROR("unknown xlen %d", p->target_xlen);
|
||||
abort();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int riscv_program_sd(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
enum gdb_regno t = riscv_program_gah(p, addr) == 0
|
||||
? GDB_REGNO_X0
|
||||
: riscv_program_gettemp(p);
|
||||
if (riscv_program_lah(p, t, addr) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
if (riscv_program_insert(p, sd(d, t, riscv_program_gal(p, addr))) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
riscv_program_puttemp(p, t);
|
||||
p->writes_memory = true;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int riscv_program_sw(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
enum gdb_regno t = riscv_program_gah(p, addr) == 0
|
||||
? GDB_REGNO_X0
|
||||
: riscv_program_gettemp(p);
|
||||
if (riscv_program_lah(p, t, addr) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
if (riscv_program_insert(p, sw(d, t, riscv_program_gal(p, addr))) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
riscv_program_puttemp(p, t);
|
||||
p->writes_memory = true;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int riscv_program_sh(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
enum gdb_regno t = riscv_program_gah(p, addr) == 0
|
||||
? GDB_REGNO_X0
|
||||
: riscv_program_gettemp(p);
|
||||
if (riscv_program_lah(p, t, addr) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
if (riscv_program_insert(p, sh(d, t, riscv_program_gal(p, addr))) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
riscv_program_puttemp(p, t);
|
||||
p->writes_memory = true;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int riscv_program_sb(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
enum gdb_regno t = riscv_program_gah(p, addr) == 0
|
||||
? GDB_REGNO_X0
|
||||
: riscv_program_gettemp(p);
|
||||
if (riscv_program_lah(p, t, addr) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
if (riscv_program_insert(p, sb(d, t, riscv_program_gal(p, addr))) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
riscv_program_puttemp(p, t);
|
||||
p->writes_memory = true;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno csr)
|
||||
{
|
||||
assert(csr >= GDB_REGNO_CSR0);
|
||||
return riscv_program_insert(p, csrrs(d, GDB_REGNO_X0, csr - GDB_REGNO_CSR0));
|
||||
assert(csr >= GDB_REGNO_CSR0 && csr <= GDB_REGNO_CSR4095);
|
||||
return riscv_program_insert(p, csrrs(d, GDB_REGNO_ZERO, csr - GDB_REGNO_CSR0));
|
||||
}
|
||||
|
||||
int riscv_program_csrw(struct riscv_program *p, enum gdb_regno s, enum gdb_regno csr)
|
||||
{
|
||||
assert(csr >= GDB_REGNO_CSR0);
|
||||
return riscv_program_insert(p, csrrw(GDB_REGNO_X0, s, csr - GDB_REGNO_CSR0));
|
||||
}
|
||||
|
||||
int riscv_program_csrrw(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, enum gdb_regno csr)
|
||||
{
|
||||
assert(csr >= GDB_REGNO_CSR0);
|
||||
return riscv_program_insert(p, csrrw(d, s, csr - GDB_REGNO_CSR0));
|
||||
return riscv_program_insert(p, csrrw(GDB_REGNO_ZERO, s, csr - GDB_REGNO_CSR0));
|
||||
}
|
||||
|
||||
int riscv_program_fence_i(struct riscv_program *p)
|
||||
@@ -357,156 +133,25 @@ int riscv_program_fence(struct riscv_program *p)
|
||||
|
||||
int riscv_program_ebreak(struct riscv_program *p)
|
||||
{
|
||||
struct target *target = p->target;
|
||||
RISCV_INFO(r);
|
||||
if (p->instruction_count == riscv_debug_buffer_size(p->target) &&
|
||||
r->impebreak) {
|
||||
return ERROR_OK;
|
||||
}
|
||||
return riscv_program_insert(p, ebreak());
|
||||
}
|
||||
|
||||
int riscv_program_lui(struct riscv_program *p, enum gdb_regno d, int32_t u)
|
||||
{
|
||||
return riscv_program_insert(p, lui(d, u));
|
||||
}
|
||||
|
||||
int riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t u)
|
||||
{
|
||||
return riscv_program_insert(p, addi(d, s, u));
|
||||
}
|
||||
|
||||
int riscv_program_fsx(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
assert(d >= GDB_REGNO_FPR0);
|
||||
assert(d <= GDB_REGNO_FPR31);
|
||||
enum gdb_regno t = riscv_program_gah(p, addr) == 0
|
||||
? GDB_REGNO_X0
|
||||
: riscv_program_gettemp(p);
|
||||
if (riscv_program_lah(p, t, addr) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
uint32_t instruction;
|
||||
switch (p->target->reg_cache->reg_list[GDB_REGNO_FPR0].size) {
|
||||
case 64:
|
||||
instruction = fsd(d - GDB_REGNO_FPR0, t, riscv_program_gal(p, addr));
|
||||
break;
|
||||
case 32:
|
||||
instruction = fsw(d - GDB_REGNO_FPR0, t, riscv_program_gal(p, addr));
|
||||
break;
|
||||
default:
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
if (riscv_program_insert(p, instruction) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
riscv_program_puttemp(p, t);
|
||||
p->writes_memory = true;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int riscv_program_flx(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
assert(d >= GDB_REGNO_FPR0);
|
||||
assert(d <= GDB_REGNO_FPR31);
|
||||
enum gdb_regno t = riscv_program_gah(p, addr) == 0 ? GDB_REGNO_X0 : d;
|
||||
if (riscv_program_lah(p, t, addr) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
uint32_t instruction;
|
||||
switch (p->target->reg_cache->reg_list[GDB_REGNO_FPR0].size) {
|
||||
case 64:
|
||||
instruction = fld(d - GDB_REGNO_FPR0, t, riscv_program_gal(p, addr));
|
||||
break;
|
||||
case 32:
|
||||
instruction = flw(d - GDB_REGNO_FPR0, t, riscv_program_gal(p, addr));
|
||||
break;
|
||||
default:
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
if (riscv_program_insert(p, instruction) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int riscv_program_li(struct riscv_program *p, enum gdb_regno d, riscv_reg_t c)
|
||||
{
|
||||
if (riscv_program_lui(p, d, c >> 12) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
if (riscv_program_addi(p, d, d, c & 0xFFF) != ERROR_OK)
|
||||
return ERROR_FAIL;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int riscv_program_dont_restore_register(struct riscv_program *p, enum gdb_regno r)
|
||||
{
|
||||
assert(r < RISCV_REGISTER_COUNT);
|
||||
p->writes_xreg[r] = 0;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int riscv_program_do_restore_register(struct riscv_program *p, enum gdb_regno r)
|
||||
{
|
||||
assert(r < RISCV_REGISTER_COUNT);
|
||||
p->writes_xreg[r] = 1;
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
void riscv_program_reserve_register(struct riscv_program *p, enum gdb_regno r)
|
||||
{
|
||||
assert(r < RISCV_REGISTER_COUNT);
|
||||
assert(p->in_use[r] == 0);
|
||||
p->in_use[r] = 1;
|
||||
}
|
||||
|
||||
enum gdb_regno riscv_program_gettemp(struct riscv_program *p)
|
||||
{
|
||||
for (size_t i = GDB_REGNO_S0; i <= GDB_REGNO_XPR31; ++i) {
|
||||
if (p->in_use[i]) continue;
|
||||
|
||||
riscv_program_do_restore_register(p, i);
|
||||
p->in_use[i] = 1;
|
||||
return i;
|
||||
}
|
||||
|
||||
LOG_ERROR("You've run out of temporary registers. This is impossible.");
|
||||
abort();
|
||||
}
|
||||
|
||||
void riscv_program_puttemp(struct riscv_program *p, enum gdb_regno r)
|
||||
{
|
||||
assert(r < RISCV_REGISTER_COUNT);
|
||||
p->in_use[r] = 0;
|
||||
}
|
||||
|
||||
/* Helper functions. */
|
||||
riscv_addr_t riscv_program_gah(struct riscv_program *p, riscv_addr_t addr)
|
||||
{
|
||||
return addr >> 12;
|
||||
}
|
||||
|
||||
riscv_addr_t riscv_program_gal(struct riscv_program *p, riscv_addr_t addr)
|
||||
{
|
||||
if (addr > 0) {
|
||||
return (addr & 0x7FF);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int riscv_program_lah(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
riscv_addr_t ah = riscv_program_gah(p, addr);
|
||||
if (ah == 0)
|
||||
return ERROR_OK;
|
||||
return riscv_program_lui(p, d, ah);
|
||||
}
|
||||
|
||||
int riscv_program_lal(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr)
|
||||
{
|
||||
riscv_addr_t al = riscv_program_gal(p, addr);
|
||||
if (al == 0)
|
||||
return ERROR_OK;
|
||||
return riscv_program_addi(p, d, d, al);
|
||||
}
|
||||
|
||||
int riscv_program_insert(struct riscv_program *p, riscv_insn_t i)
|
||||
{
|
||||
if (p->instruction_count + p->data_count + 1 > riscv_debug_buffer_size(p->target)) {
|
||||
if (p->instruction_count >= riscv_debug_buffer_size(p->target)) {
|
||||
LOG_ERROR("Unable to insert instruction:");
|
||||
LOG_ERROR(" instruction_count=%d", (int)p->instruction_count);
|
||||
LOG_ERROR(" data_count =%d", (int)p->data_count);
|
||||
LOG_ERROR(" buffer size =%d", (int)riscv_debug_buffer_size(p->target));
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
@@ -15,23 +15,12 @@ struct riscv_program {
|
||||
|
||||
uint32_t debug_buffer[RISCV_MAX_DEBUG_BUFFER_SIZE];
|
||||
|
||||
/* The debug buffer is allocated in two directions: instructions go at
|
||||
* the start, while data goes at the end. When they meet in the middle
|
||||
* this blows up. */
|
||||
/* Number of 32-bit instructions in the program. */
|
||||
size_t instruction_count;
|
||||
size_t data_count;
|
||||
|
||||
/* Side effects of executing this program. These must be accounted for
|
||||
* in order to maintain correct executing of the target system. */
|
||||
bool writes_xreg[RISCV_REGISTER_COUNT];
|
||||
bool writes_memory;
|
||||
|
||||
/* When a register is used it will be set in this array. */
|
||||
bool in_use[RISCV_REGISTER_COUNT];
|
||||
|
||||
/* Remembers the registers that have been saved into dscratch
|
||||
* registers. These are restored */
|
||||
enum gdb_regno dscratch_saved[RISCV_DSCRATCH_COUNT];
|
||||
|
||||
/* XLEN on the target. */
|
||||
int target_xlen;
|
||||
@@ -40,6 +29,9 @@ struct riscv_program {
|
||||
/* Initializes a program with the header. */
|
||||
int riscv_program_init(struct riscv_program *p, struct target *t);
|
||||
|
||||
/* Write the program to the program buffer. */
|
||||
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
|
||||
@@ -60,83 +52,24 @@ int riscv_program_insert(struct riscv_program *p, riscv_insn_t i);
|
||||
* memory. */
|
||||
int riscv_program_save_to_dscratch(struct riscv_program *p, enum gdb_regno to_save);
|
||||
|
||||
/* Allocates data of various sizes. Either returns the absolute physical
|
||||
* address or RISCV_PROGRAM_ALLOC_FAIL on failure. */
|
||||
riscv_addr_t riscv_program_alloc_data(struct riscv_program *p, size_t bytes);
|
||||
riscv_addr_t riscv_program_alloc_x(struct riscv_program *p);
|
||||
riscv_addr_t riscv_program_alloc_d(struct riscv_program *p);
|
||||
riscv_addr_t riscv_program_alloc_w(struct riscv_program *p);
|
||||
riscv_addr_t riscv_program_alloc_h(struct riscv_program *p);
|
||||
riscv_addr_t riscv_program_alloc_b(struct riscv_program *p);
|
||||
#define RISCV_PROGRAM_ALLOC_FAIL ((riscv_addr_t)(-1))
|
||||
|
||||
/* Reads a word of memory from this program's internal view of the debug RAM.
|
||||
* This is what you want to use to get data back from the program after it
|
||||
* executes. */
|
||||
riscv_insn_t riscv_program_read_ram(struct riscv_program *p, riscv_addr_t addr);
|
||||
void riscv_program_write_ram(struct riscv_program *p, riscv_addr_t a, uint64_t d);
|
||||
|
||||
/* Helpers to assembly various instructions. Return 0 on success. These might
|
||||
* assembly into a multi-instruction sequence that overwrites some other
|
||||
* register, but those will be properly saved and restored. */
|
||||
int riscv_program_lx(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr);
|
||||
int riscv_program_ld(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr);
|
||||
int riscv_program_lw(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr);
|
||||
int riscv_program_lh(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr);
|
||||
int riscv_program_lb(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr);
|
||||
|
||||
int riscv_program_sx(struct riscv_program *p, enum gdb_regno s, riscv_addr_t addr);
|
||||
int riscv_program_sd(struct riscv_program *p, enum gdb_regno s, riscv_addr_t addr);
|
||||
int riscv_program_sw(struct riscv_program *p, enum gdb_regno s, riscv_addr_t addr);
|
||||
int riscv_program_sh(struct riscv_program *p, enum gdb_regno s, riscv_addr_t addr);
|
||||
int riscv_program_sb(struct riscv_program *p, enum gdb_regno s, riscv_addr_t addr);
|
||||
|
||||
int riscv_program_lxr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);
|
||||
int riscv_program_ldr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);
|
||||
int riscv_program_lwr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);
|
||||
int riscv_program_lhr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);
|
||||
int riscv_program_lbr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno a, int o);
|
||||
|
||||
int riscv_program_sxr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);
|
||||
int riscv_program_sdr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);
|
||||
int riscv_program_swr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);
|
||||
int riscv_program_shr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);
|
||||
int riscv_program_sbr(struct riscv_program *p, enum gdb_regno s, enum gdb_regno a, int o);
|
||||
|
||||
int riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno csr);
|
||||
int riscv_program_csrw(struct riscv_program *p, enum gdb_regno s, enum gdb_regno csr);
|
||||
int riscv_program_csrrw(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, enum gdb_regno csr);
|
||||
|
||||
int riscv_program_fence_i(struct riscv_program *p);
|
||||
int riscv_program_fence(struct riscv_program *p);
|
||||
int riscv_program_ebreak(struct riscv_program *p);
|
||||
|
||||
int riscv_program_lui(struct riscv_program *p, enum gdb_regno d, int32_t u);
|
||||
int riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t i);
|
||||
|
||||
int riscv_program_fsx(struct riscv_program *p, enum gdb_regno s, riscv_addr_t addr);
|
||||
int riscv_program_flx(struct riscv_program *p, enum gdb_regno d, riscv_addr_t addr);
|
||||
|
||||
/* Assembler macros. */
|
||||
int riscv_program_li(struct riscv_program *p, enum gdb_regno d, riscv_reg_t c);
|
||||
int riscv_program_la(struct riscv_program *p, enum gdb_regno d, riscv_addr_t a);
|
||||
|
||||
/* Register allocation. The user is expected to have obtained temporary
|
||||
* registers using these fuctions. Additionally, there is an interface for
|
||||
* reserving registers -- it's expected that this has been called as the first
|
||||
* thing in the program's execution to reserve registers that can't be touched
|
||||
* by the program's execution. */
|
||||
void riscv_program_reserve_register(struct riscv_program *p, enum gdb_regno r);
|
||||
enum gdb_regno riscv_program_gettemp(struct riscv_program *p);
|
||||
void riscv_program_puttemp(struct riscv_program *p, enum gdb_regno r);
|
||||
|
||||
/* Executing a program usually causes the registers that get overwritten to be
|
||||
* saved and restored. Calling this prevents the given register from actually
|
||||
* being restored as a result of all activity in this program. */
|
||||
int riscv_program_dont_restore_register(struct riscv_program *p, enum gdb_regno r);
|
||||
int riscv_program_do_restore_register(struct riscv_program *p, enum gdb_regno r);
|
||||
|
||||
/* Addressing functions. */
|
||||
riscv_addr_t riscv_program_gah(struct riscv_program *p, riscv_addr_t addr);
|
||||
|
||||
#endif
|
||||
|
||||
+343
-413
File diff suppressed because it is too large
Load Diff
+901
-783
File diff suppressed because it is too large
Load Diff
+707
-206
File diff suppressed because it is too large
Load Diff
+33
-26
@@ -30,6 +30,7 @@ enum riscv_halt_reason {
|
||||
RISCV_HALT_INTERRUPT,
|
||||
RISCV_HALT_BREAKPOINT,
|
||||
RISCV_HALT_SINGLESTEP,
|
||||
RISCV_HALT_UNKNOWN
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@@ -59,7 +60,11 @@ typedef struct {
|
||||
|
||||
/* The register cache points into here. */
|
||||
uint64_t reg_cache_values[RISCV_MAX_REGISTERS];
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
/* It's possible that each core has a different supported ISA set. */
|
||||
int xlen[RISCV_MAX_HARTS];
|
||||
|
||||
@@ -72,32 +77,31 @@ typedef struct {
|
||||
* target controls, while otherwise only a single hart is controlled. */
|
||||
int trigger_unique_id[RISCV_MAX_HWBPS];
|
||||
|
||||
/* The address of the debug RAM buffer. */
|
||||
riscv_addr_t debug_buffer_addr[RISCV_MAX_HARTS];
|
||||
|
||||
/* The number of entries in the debug buffer. */
|
||||
int debug_buffer_size[RISCV_MAX_HARTS];
|
||||
|
||||
/* This avoids invalidating the register cache too often. */
|
||||
bool registers_initialized;
|
||||
|
||||
/* This hart contains an implicit ebreak at the end of the program buffer. */
|
||||
bool impebreak;
|
||||
|
||||
/* Helper functions that target the various RISC-V debug spec
|
||||
* implementations. */
|
||||
riscv_reg_t (*get_register)(struct target *, int hartid, int regid);
|
||||
void (*set_register)(struct target *, int hartid, int regid,
|
||||
int (*get_register)(struct target *target,
|
||||
riscv_reg_t *value, int hid, int rid);
|
||||
int (*set_register)(struct target *, int hartid, int regid,
|
||||
uint64_t value);
|
||||
void (*select_current_hart)(struct target *);
|
||||
bool (*is_halted)(struct target *target);
|
||||
void (*halt_current_hart)(struct target *);
|
||||
void (*resume_current_hart)(struct target *target);
|
||||
void (*step_current_hart)(struct target *target);
|
||||
void (*on_halt)(struct target *target);
|
||||
void (*on_resume)(struct target *target);
|
||||
void (*on_step)(struct target *target);
|
||||
int (*halt_current_hart)(struct target *);
|
||||
int (*resume_current_hart)(struct target *target);
|
||||
int (*step_current_hart)(struct target *target);
|
||||
int (*on_halt)(struct target *target);
|
||||
int (*on_resume)(struct target *target);
|
||||
int (*on_step)(struct target *target);
|
||||
enum riscv_halt_reason (*halt_reason)(struct target *target);
|
||||
void (*debug_buffer_enter)(struct target *target, struct riscv_program *program);
|
||||
void (*debug_buffer_leave)(struct target *target, struct riscv_program *program);
|
||||
void (*write_debug_buffer)(struct target *target, unsigned index,
|
||||
int (*write_debug_buffer)(struct target *target, unsigned index,
|
||||
riscv_insn_t d);
|
||||
riscv_insn_t (*read_debug_buffer)(struct target *target, unsigned index);
|
||||
int (*execute_debug_buffer)(struct target *target);
|
||||
@@ -115,6 +119,9 @@ 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_use_scratch_ram;
|
||||
extern uint64_t riscv_scratch_ram_address;
|
||||
|
||||
/* Everything needs the RISC-V specific info structure, so here's a nice macro
|
||||
* that provides that. */
|
||||
static inline riscv_info_t *riscv_info(const struct target *target) __attribute__((unused));
|
||||
@@ -138,7 +145,7 @@ int riscv_openocd_resume(
|
||||
struct target *target,
|
||||
int current,
|
||||
target_addr_t address,
|
||||
int handle_breakpoints,
|
||||
int handle_breakpoints,
|
||||
int debug_execution
|
||||
);
|
||||
|
||||
@@ -169,6 +176,8 @@ int riscv_resume_one_hart(struct target *target, int hartid);
|
||||
* then the only hart. */
|
||||
int riscv_step_rtos_hart(struct target *target);
|
||||
|
||||
bool riscv_supports_extension(struct target *target, char letter);
|
||||
|
||||
/* Returns XLEN for the given (or current) hart. */
|
||||
int riscv_xlen(const struct target *target);
|
||||
int riscv_xlen_of_hart(const struct target *target, int hartid);
|
||||
@@ -197,10 +206,12 @@ bool riscv_has_register(struct target *target, int hartid, int regid);
|
||||
|
||||
/* Returns the value of the given register on the given hart. 32-bit registers
|
||||
* are zero extended to 64 bits. */
|
||||
void riscv_set_register(struct target *target, enum gdb_regno i, riscv_reg_t v);
|
||||
void riscv_set_register_on_hart(struct target *target, int hid, enum gdb_regno rid, uint64_t v);
|
||||
riscv_reg_t riscv_get_register(struct target *target, enum gdb_regno i);
|
||||
riscv_reg_t riscv_get_register_on_hart(struct target *target, int hid, enum gdb_regno rid);
|
||||
int riscv_set_register(struct target *target, enum gdb_regno i, riscv_reg_t v);
|
||||
int riscv_set_register_on_hart(struct target *target, int hid, enum gdb_regno rid, uint64_t v);
|
||||
int riscv_get_register(struct target *target, riscv_reg_t *value,
|
||||
enum gdb_regno r);
|
||||
int riscv_get_register_on_hart(struct target *target, riscv_reg_t *value,
|
||||
int hartid, enum gdb_regno regid);
|
||||
|
||||
/* Checks the state of the current hart -- "is_halted" checks the actual
|
||||
* on-device register. */
|
||||
@@ -215,15 +226,9 @@ int riscv_count_triggers_of_hart(struct target *target, int hartid);
|
||||
/* These helper functions let the generic program interface get target-specific
|
||||
* information. */
|
||||
size_t riscv_debug_buffer_size(struct target *target);
|
||||
riscv_addr_t riscv_debug_buffer_addr(struct target *target);
|
||||
|
||||
int riscv_debug_buffer_enter(struct target *target, struct riscv_program *program);
|
||||
int riscv_debug_buffer_leave(struct target *target, struct riscv_program *program);
|
||||
|
||||
riscv_insn_t riscv_read_debug_buffer(struct target *target, int index);
|
||||
riscv_addr_t riscv_read_debug_buffer_x(struct target *target, int index);
|
||||
int riscv_write_debug_buffer(struct target *target, int index, riscv_insn_t insn);
|
||||
int riscv_write_debug_buffer_x(struct target *target, int index, riscv_addr_t data);
|
||||
int riscv_execute_debug_buffer(struct target *target);
|
||||
|
||||
void riscv_fill_dmi_nop_u64(struct target *target, char *buf);
|
||||
@@ -246,4 +251,6 @@ 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);
|
||||
|
||||
#endif
|
||||
|
||||
+2219
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
OpenOCD STM8 target driver
|
||||
Copyright (C) 2017 Ake Rehnman
|
||||
ake.rehnman(at)gmail.com
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef OPENOCD_TARGET_STM8_H
|
||||
#define OPENOCD_TARGET_STM8_H
|
||||
|
||||
struct target;
|
||||
|
||||
#define STM8_COMMON_MAGIC 0x53544D38
|
||||
#define STM8_NUM_CORE_REGS 6
|
||||
|
||||
struct stm8_common {
|
||||
uint32_t common_magic;
|
||||
void *arch_info;
|
||||
struct reg_cache *core_cache;
|
||||
uint32_t core_regs[STM8_NUM_CORE_REGS];
|
||||
|
||||
/* working area for fastdata access */
|
||||
struct working_area *fast_data_area;
|
||||
|
||||
bool swim_configured;
|
||||
bool bp_scanned;
|
||||
uint8_t num_hw_bpoints;
|
||||
uint8_t num_hw_bpoints_avail;
|
||||
struct stm8_comparator *hw_break_list;
|
||||
uint32_t blocksize;
|
||||
uint32_t flashstart;
|
||||
uint32_t flashend;
|
||||
uint32_t eepromstart;
|
||||
uint32_t eepromend;
|
||||
uint32_t optionstart;
|
||||
uint32_t optionend;
|
||||
bool enable_step_irq;
|
||||
|
||||
bool enable_stm8l;
|
||||
uint32_t flash_cr2;
|
||||
uint32_t flash_ncr2;
|
||||
uint32_t flash_iapsr;
|
||||
uint32_t flash_dukr;
|
||||
uint32_t flash_pukr;
|
||||
|
||||
/* cc value used for interrupt flags restore */
|
||||
uint32_t cc;
|
||||
bool cc_valid;
|
||||
|
||||
/* register cache to processor synchronization */
|
||||
int (*read_core_reg)(struct target *target, unsigned int num);
|
||||
int (*write_core_reg)(struct target *target, unsigned int num);
|
||||
};
|
||||
|
||||
static inline struct stm8_common *
|
||||
target_to_stm8(struct target *target)
|
||||
{
|
||||
return target->arch_info;
|
||||
}
|
||||
|
||||
const struct command_registration stm8_command_handlers[];
|
||||
|
||||
#endif /* OPENOCD_TARGET_STM8_H */
|
||||
+20
-20
@@ -105,6 +105,7 @@ extern struct target_type nds32_v3m_target;
|
||||
extern struct target_type or1k_target;
|
||||
extern struct target_type quark_x10xx_target;
|
||||
extern struct target_type quark_d20xx_target;
|
||||
extern struct target_type stm8_target;
|
||||
extern struct target_type riscv_target;
|
||||
|
||||
static struct target_type *target_types[] = {
|
||||
@@ -137,6 +138,7 @@ static struct target_type *target_types[] = {
|
||||
&or1k_target,
|
||||
&quark_x10xx_target,
|
||||
&quark_d20xx_target,
|
||||
&stm8_target,
|
||||
&riscv_target,
|
||||
#if BUILD_TARGET64
|
||||
&aarch64_target,
|
||||
@@ -204,10 +206,6 @@ static const Jim_Nvp nvp_target_event[] = {
|
||||
{ .value = TARGET_EVENT_RESET_ASSERT_POST, .name = "reset-assert-post" },
|
||||
{ .value = TARGET_EVENT_RESET_DEASSERT_PRE, .name = "reset-deassert-pre" },
|
||||
{ .value = TARGET_EVENT_RESET_DEASSERT_POST, .name = "reset-deassert-post" },
|
||||
{ .value = TARGET_EVENT_RESET_HALT_PRE, .name = "reset-halt-pre" },
|
||||
{ .value = TARGET_EVENT_RESET_HALT_POST, .name = "reset-halt-post" },
|
||||
{ .value = TARGET_EVENT_RESET_WAIT_PRE, .name = "reset-wait-pre" },
|
||||
{ .value = TARGET_EVENT_RESET_WAIT_POST, .name = "reset-wait-post" },
|
||||
{ .value = TARGET_EVENT_RESET_INIT, .name = "reset-init" },
|
||||
{ .value = TARGET_EVENT_RESET_END, .name = "reset-end" },
|
||||
|
||||
@@ -2742,21 +2740,23 @@ COMMAND_HANDLER(handle_reg_command)
|
||||
i < cache->num_regs;
|
||||
i++, reg++, count++) {
|
||||
/* only print cached values if they are valid */
|
||||
if (reg->valid) {
|
||||
value = buf_to_str(reg->value,
|
||||
reg->size, 16);
|
||||
command_print(CMD_CTX,
|
||||
"(%i) %s (/%" PRIu32 "): 0x%s%s",
|
||||
count, reg->name,
|
||||
reg->size, value,
|
||||
reg->dirty
|
||||
if (reg->exist) {
|
||||
if (reg->valid) {
|
||||
value = buf_to_str(reg->value,
|
||||
reg->size, 16);
|
||||
command_print(CMD_CTX,
|
||||
"(%i) %s (/%" PRIu32 "): 0x%s%s",
|
||||
count, reg->name,
|
||||
reg->size, value,
|
||||
reg->dirty
|
||||
? " (dirty)"
|
||||
: "");
|
||||
free(value);
|
||||
} else {
|
||||
command_print(CMD_CTX, "(%i) %s (/%" PRIu32 ")",
|
||||
count, reg->name,
|
||||
reg->size) ;
|
||||
free(value);
|
||||
} else {
|
||||
command_print(CMD_CTX, "(%i) %s (/%" PRIu32 ")",
|
||||
count, reg->name,
|
||||
reg->size) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
cache = cache->next;
|
||||
@@ -2830,8 +2830,8 @@ COMMAND_HANDLER(handle_reg_command)
|
||||
|
||||
retval = reg->type->set(reg, buf);
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_DEBUG("Couldn't set register %s.", reg->name);
|
||||
free (buf);
|
||||
LOG_DEBUG("Couldn't set register %s.", reg->name);
|
||||
free(buf);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -3697,7 +3697,7 @@ COMMAND_HANDLER(handle_bp_command)
|
||||
addr = 0;
|
||||
return handle_bp_command_set(CMD_CTX, addr, asid, length, hw);
|
||||
}
|
||||
|
||||
/* fallthrough */
|
||||
case 4:
|
||||
hw = BKPT_HARD;
|
||||
COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
|
||||
|
||||
@@ -253,10 +253,6 @@ enum target_event {
|
||||
TARGET_EVENT_RESET_ASSERT_POST,
|
||||
TARGET_EVENT_RESET_DEASSERT_PRE,
|
||||
TARGET_EVENT_RESET_DEASSERT_POST,
|
||||
TARGET_EVENT_RESET_HALT_PRE,
|
||||
TARGET_EVENT_RESET_HALT_POST,
|
||||
TARGET_EVENT_RESET_WAIT_PRE,
|
||||
TARGET_EVENT_RESET_WAIT_POST,
|
||||
TARGET_EVENT_RESET_INIT,
|
||||
TARGET_EVENT_RESET_END,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user