We can run to a software breakpoint, but
gdb doesn't notice we're halted once we hit it, even though riscv_poll() is setting the target state to halted.__archive__
parent
04cfc35147
commit
c364bd0ab5
|
@ -838,6 +838,7 @@ int default_interface_jtag_execute_queue(void)
|
||||||
|
|
||||||
int result = jtag->execute_queue();
|
int result = jtag->execute_queue();
|
||||||
|
|
||||||
|
#if 0
|
||||||
// TODO: I like these better than some of the other JTAG debug statements,
|
// TODO: I like these better than some of the other JTAG debug statements,
|
||||||
// but having both is silly.
|
// but having both is silly.
|
||||||
struct jtag_command *cmd = jtag_command_queue;
|
struct jtag_command *cmd = jtag_command_queue;
|
||||||
|
@ -946,6 +947,7 @@ int default_interface_jtag_execute_queue(void)
|
||||||
}
|
}
|
||||||
cmd = cmd->next;
|
cmd = cmd->next;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,12 +79,6 @@ static uint32_t lb(unsigned int rd, unsigned int base, uint16_t offset)
|
||||||
MATCH_LB;
|
MATCH_LB;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t csrci(unsigned int csr, uint16_t imm) {
|
|
||||||
return (csr << 20) |
|
|
||||||
(bits(imm, 4, 0) << 15) |
|
|
||||||
MATCH_CSRRCI;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
return (csr << 20) | (source << 15) | MATCH_CSRRW;
|
||||||
}
|
}
|
||||||
|
@ -119,12 +113,10 @@ static uint32_t flw(unsigned int src, unsigned int base, uint16_t offset)
|
||||||
MATCH_FLW;
|
MATCH_FLW;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static uint32_t ebreak(void) { return MATCH_EBREAK; }
|
||||||
static uint32_t li(unsigned int dest, uint16_t imm)
|
static uint32_t ebreak_c(void) { return MATCH_C_EBREAK; }
|
||||||
{
|
|
||||||
return addi(dest, 0, imm);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/*
|
||||||
static uint32_t lui(unsigned int dest, uint32_t imm)
|
static uint32_t lui(unsigned int dest, uint32_t imm)
|
||||||
{
|
{
|
||||||
return (bits(imm, 19, 0) << 12) |
|
return (bits(imm, 19, 0) << 12) |
|
||||||
|
@ -132,6 +124,17 @@ static uint32_t lui(unsigned int dest, uint32_t imm)
|
||||||
MATCH_LUI;
|
MATCH_LUI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t csrci(unsigned int csr, uint16_t imm) {
|
||||||
|
return (csr << 20) |
|
||||||
|
(bits(imm, 4, 0) << 15) |
|
||||||
|
MATCH_CSRRCI;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t li(unsigned int dest, uint16_t imm)
|
||||||
|
{
|
||||||
|
return addi(dest, 0, imm);
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t fence_i(void)
|
static uint32_t fence_i(void)
|
||||||
{
|
{
|
||||||
return MATCH_FENCE_I;
|
return MATCH_FENCE_I;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "jtag/jtag.h"
|
#include "jtag/jtag.h"
|
||||||
#include "opcodes.h"
|
#include "opcodes.h"
|
||||||
#include "register.h"
|
#include "register.h"
|
||||||
|
#include "breakpoints.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Since almost everything can be accomplish by scanning the dbus register, all
|
* Since almost everything can be accomplish by scanning the dbus register, all
|
||||||
|
@ -28,6 +29,8 @@
|
||||||
#define DEBUG_ROM_EXCEPTION (DEBUG_ROM_START + 8)
|
#define DEBUG_ROM_EXCEPTION (DEBUG_ROM_START + 8)
|
||||||
#define DEBUG_RAM_START 0x400
|
#define DEBUG_RAM_START 0x400
|
||||||
|
|
||||||
|
#define SETHALTNOT 0x10c
|
||||||
|
|
||||||
/*** JTAG registers. ***/
|
/*** JTAG registers. ***/
|
||||||
|
|
||||||
#define DTMINFO 0x10
|
#define DTMINFO 0x10
|
||||||
|
@ -230,7 +233,6 @@ static dbus_status_t dbus_scan(struct target *target, uint64_t *data_in,
|
||||||
|
|
||||||
static const char *op_string[] = {"nop", "r", "w", "cw"};
|
static const char *op_string[] = {"nop", "r", "w", "cw"};
|
||||||
static const char *status_string[] = {"+", "nw", "F", "b"};
|
static const char *status_string[] = {"+", "nw", "F", "b"};
|
||||||
/*
|
|
||||||
LOG_DEBUG("vvv $display(\"hardware: dbus scan %db %s %01x:%08x @%02x -> %s %01x:%08x @%02x\");",
|
LOG_DEBUG("vvv $display(\"hardware: dbus scan %db %s %01x:%08x @%02x -> %s %01x:%08x @%02x\");",
|
||||||
field.num_bits,
|
field.num_bits,
|
||||||
op_string[buf_get_u32(out, 0, 2)],
|
op_string[buf_get_u32(out, 0, 2)],
|
||||||
|
@ -239,7 +241,7 @@ static dbus_status_t dbus_scan(struct target *target, uint64_t *data_in,
|
||||||
status_string[buf_get_u32(in, 0, 2)],
|
status_string[buf_get_u32(in, 0, 2)],
|
||||||
buf_get_u32(in, 34, 2), buf_get_u32(in, 2, 32),
|
buf_get_u32(in, 34, 2), buf_get_u32(in, 2, 32),
|
||||||
buf_get_u32(in, 36, info->addrbits));
|
buf_get_u32(in, 36, info->addrbits));
|
||||||
*/
|
/*
|
||||||
LOG_DEBUG("dbus scan %db %s %01x:%08x @%02x -> %s %01x:%08x @%02x",
|
LOG_DEBUG("dbus scan %db %s %01x:%08x @%02x -> %s %01x:%08x @%02x",
|
||||||
field.num_bits,
|
field.num_bits,
|
||||||
op_string[buf_get_u32(out, 0, 2)],
|
op_string[buf_get_u32(out, 0, 2)],
|
||||||
|
@ -248,6 +250,7 @@ static dbus_status_t dbus_scan(struct target *target, uint64_t *data_in,
|
||||||
status_string[buf_get_u32(in, 0, 2)],
|
status_string[buf_get_u32(in, 0, 2)],
|
||||||
buf_get_u32(in, 34, 2), buf_get_u32(in, 2, 32),
|
buf_get_u32(in, 34, 2), buf_get_u32(in, 2, 32),
|
||||||
buf_get_u32(in, 36, info->addrbits));
|
buf_get_u32(in, 36, info->addrbits));
|
||||||
|
*/
|
||||||
|
|
||||||
//debug_scan(target);
|
//debug_scan(target);
|
||||||
|
|
||||||
|
@ -327,7 +330,9 @@ static void dram_write32(struct target *target, unsigned int index, uint32_t val
|
||||||
{
|
{
|
||||||
riscv_info_t *info = (riscv_info_t *) target->arch_info;
|
riscv_info_t *info = (riscv_info_t *) target->arch_info;
|
||||||
|
|
||||||
if (info->dram_valid & (1<<index) && info->dram[index] == value) {
|
if (!set_interrupt &&
|
||||||
|
info->dram_valid & (1<<index) &&
|
||||||
|
info->dram[index] == value) {
|
||||||
LOG_DEBUG("DRAM cache hit: 0x%x @%d", value, index);
|
LOG_DEBUG("DRAM cache hit: 0x%x @%d", value, index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -430,6 +435,21 @@ static int wait_for_debugint_clear(struct target *target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int read_csr(struct target *target, uint32_t *value, uint32_t csr)
|
||||||
|
{
|
||||||
|
dram_write32(target, 0, csrr(S0, csr), false);
|
||||||
|
dram_write32(target, 1, sw(S0, ZERO, DEBUG_RAM_START + 16), false);
|
||||||
|
dram_write_jump(target, 2, true);
|
||||||
|
|
||||||
|
if (wait_for_debugint_clear(target) != ERROR_OK) {
|
||||||
|
LOG_ERROR("Debug interrupt didn't clear.");
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
*value = dram_read32(target, 4);
|
||||||
|
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static int resume(struct target *target, int current, uint32_t address,
|
static int resume(struct target *target, int current, uint32_t address,
|
||||||
int handle_breakpoints, int debug_execution, bool step)
|
int handle_breakpoints, int debug_execution, bool step)
|
||||||
{
|
{
|
||||||
|
@ -453,13 +473,37 @@ static int resume(struct target *target, int current, uint32_t address,
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dram_write32(target, 0, csrsi(CSR_DCSR, DCSR_HALT), false);
|
uint32_t dcsr;
|
||||||
if (step) {
|
if (read_csr(target, &dcsr, CSR_DCSR) != ERROR_OK) {
|
||||||
dram_write32(target, 1, csrsi(CSR_DCSR, DCSR_STEP), false);
|
return ERROR_FAIL;
|
||||||
} else {
|
|
||||||
dram_write32(target, 1, csrci(CSR_DCSR, DCSR_STEP), false);
|
|
||||||
}
|
}
|
||||||
dram_write_jump(target, 2, true);
|
|
||||||
|
LOG_DEBUG("DCSR=0x%x", dcsr);
|
||||||
|
dcsr |= DCSR_EBREAKM | DCSR_EBREAKH | DCSR_EBREAKS | DCSR_EBREAKU;
|
||||||
|
dcsr &= ~DCSR_HALT;
|
||||||
|
|
||||||
|
if (step) {
|
||||||
|
dcsr |= DCSR_STEP;
|
||||||
|
} else {
|
||||||
|
dcsr &= ~DCSR_STEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
dram_write32(target, 0, lw(S0, ZERO, DEBUG_RAM_START + 16), false);
|
||||||
|
dram_write32(target, 1, csrw(S0, CSR_DCSR), false);
|
||||||
|
dram_write_jump(target, 2, false);
|
||||||
|
|
||||||
|
// Write DCSR value, set interrupt and clear haltnot.
|
||||||
|
uint64_t dbus_value = DMCONTROL_INTERRUPT | dcsr;
|
||||||
|
dbus_write(target, dram_address(4), dbus_value);
|
||||||
|
info->dram_valid |= (1<<4);
|
||||||
|
info->dram[4] = dcsr;
|
||||||
|
|
||||||
|
if (wait_for_debugint_clear(target) != ERROR_OK) {
|
||||||
|
LOG_ERROR("Debug interrupt didn't clear.");
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
target->state = TARGET_RUNNING;
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
@ -633,96 +677,6 @@ static void riscv_deinit_target(struct target *target)
|
||||||
target->arch_info = NULL;
|
target->arch_info = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void megan_sequence(struct target *target)
|
|
||||||
{
|
|
||||||
uint64_t data;
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 11, Data: 3aaaaaaaa Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 00xxxxxxxxx (Addr: 00, Data: xxxxxxxxx Res: x)
|
|
||||||
dbus_scan(target, &data, DBUS_OP_READ, 0x11, 0x3aaaaaaaa);
|
|
||||||
// [RISCV]: Reading DMINFO
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 11, Data: 3aaaaaaaa Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 1100000f084 (Addr: 11, Data: 000003c21 Res: 0)
|
|
||||||
dbus_scan(target, &data, DBUS_OP_READ, 0x11, 0x3aaaaaaaa);
|
|
||||||
|
|
||||||
// extra, to actually read dminfo
|
|
||||||
dbus_scan(target, &data, DBUS_OP_READ, 0x11, 0x3aaaaaaaa);
|
|
||||||
|
|
||||||
// [RISCV]:WRITING Debug RAM (interrupt is not set)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 00, Data: 0fff04493 Op: 2)
|
|
||||||
// [RISCV]: DBUS Result = 1100000f084 (Addr: 11, Data: 000003c21 Res: 0)
|
|
||||||
dbus_scan(target, &data, DBUS_OP_WRITE, 0, 0x0fff04493);
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 01, Data: 001f4d493 Op: 2)
|
|
||||||
// [RISCV]: DBUS Result = 003ee1643dc (Addr: 00, Data: 0fb8590f7 Res: 0)
|
|
||||||
dbus_scan(target, &data, DBUS_OP_WRITE, 1, 0x001f4d493);
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 02, Data: 040902023 Op: 2)
|
|
||||||
// [RISCV]: DBUS Result = 013ee1643dc (Addr: 01, Data: 0fb8590f7 Res: 0)
|
|
||||||
dbus_scan(target, &data, DBUS_OP_WRITE, 2, 0x040902023);
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 03, Data: 001f4d493 Op: 2)
|
|
||||||
// [RISCV]: DBUS Result = 023ee1643dc (Addr: 02, Data: 0fb8590f7 Res: 0)
|
|
||||||
dbus_scan(target, &data, DBUS_OP_WRITE, 3, 0x001f4d493);
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 04, Data: 040902223 Op: 2)
|
|
||||||
// [RISCV]: DBUS Result = 033ee1643dc (Addr: 03, Data: 0fb8590f7 Res: 0)
|
|
||||||
dbus_scan(target, &data, DBUS_OP_WRITE, 4, 0x040902223);
|
|
||||||
// [RISCV]:On last write to Debug RAM, interrupt is set.
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 05, Data: 23f00006f Op: 2)
|
|
||||||
// [RISCV]: DBUS Result = 043ee1643dc (Addr: 04, Data: 0fb8590f7 Res: 0)
|
|
||||||
dbus_scan(target, &data, DBUS_OP_WRITE, 5, 0x23f00006f);
|
|
||||||
// [RISCV]: Performing "priming" read from Debug RAM
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 00, Data: 000000000 Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 053ee1643dc (Addr: 05, Data: 0fb8590f7 Res: 0)
|
|
||||||
dbus_scan(target, &data, DBUS_OP_READ, 0, 0);
|
|
||||||
// [RISCV]: Polling until INTERRUPT is not set
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 00, Data: 000000000 Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 00fffc1124c (Addr: 00, Data: 3fff04493 Res: 0)
|
|
||||||
dbus_scan(target, &data, DBUS_OP_READ, 0, 0);
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 00, Data: 000000000 Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 00fffc1124c (Addr: 00, Data: 3fff04493 Res: 0)
|
|
||||||
dbus_scan(target, &data, DBUS_OP_READ, 0, 0);
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 00, Data: 000000000 Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 00c00000004 (Addr: 00, Data: 300000001 Res: 0)
|
|
||||||
dbus_scan(target, &data, DBUS_OP_READ, 0, 0);
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 00, Data: 000000000 Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 00400000004 (Addr: 00, Data: 100000001 Res: 0)
|
|
||||||
dbus_scan(target, &data, DBUS_OP_READ, 0, 0);
|
|
||||||
// [RISCV]:READING Debug RAM (interrupt is not set)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 00, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 00400000004 (Addr: 00, Data: 100000001 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 01, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 00400000004 (Addr: 00, Data: 100000001 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 02, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 01400000000 (Addr: 01, Data: 100000000 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 03, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 0250240808c (Addr: 02, Data: 140902023 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 04, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 03407d3524c (Addr: 03, Data: 101f4d493 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 05, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 0450240888c (Addr: 04, Data: 140902223 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 06, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 054fc0001bc (Addr: 05, Data: 13f00006f Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 07, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 0642a1643dc (Addr: 06, Data: 10a8590f7 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 08, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 077ee17e7dc (Addr: 07, Data: 1fb85f9f7 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 09, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 087ee1643dc (Addr: 08, Data: 1fb8590f7 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 0a, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 097ee1643dc (Addr: 09, Data: 1fb8590f7 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 0b, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 0a7ee1643dc (Addr: 0a, Data: 1fb8590f7 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 0c, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 0b7ee1643dc (Addr: 0b, Data: 1fb8590f7 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 0d, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 0c7ee1643dc (Addr: 0c, Data: 1fb8590f7 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 0e, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 0d7ee1643dc (Addr: 0d, Data: 1fb8590f7 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 0f, Data: 0babecafe Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 0e7ee1643dc (Addr: 0e, Data: 1fb8590f7 Res: 0)
|
|
||||||
// [RISCV]: DBUS Input = (Addr: 00, Data: 000000000 Op: 1)
|
|
||||||
// [RISCV]: DBUS Result = 0f56cfc76d8 (Addr: 0f, Data: 15b3f1db6 Res: 0)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static void dram_test(struct target *target)
|
static void dram_test(struct target *target)
|
||||||
{
|
{
|
||||||
|
@ -743,6 +697,50 @@ static void dram_test(struct target *target)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static void light_leds(struct target *target)
|
||||||
|
{
|
||||||
|
dram_write32(target, 0, lui(S0, 0x70002), false);
|
||||||
|
dram_write32(target, 1, lui(S1, 0xccccc), false);
|
||||||
|
dram_write32(target, 2, sw(S1, S0, 0xa0), false);
|
||||||
|
dram_write32(target, 3, jal(ZERO, 0), true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void dump_debug_ram(struct target *target)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < 16; i++) {
|
||||||
|
uint32_t value = dram_read32(target, i);
|
||||||
|
LOG_ERROR("Debug RAM 0x%x: 0x%08x", i, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static void write_constants(struct target *target)
|
||||||
|
{
|
||||||
|
dram_write32(target, 0, lui(S0, 0x70002), false);
|
||||||
|
dram_write32(target, 1, lui(S1, 0xccccc), false);
|
||||||
|
dram_write32(target, 2, sw(S0, ZERO, DEBUG_RAM_START + 0), false);
|
||||||
|
dram_write32(target, 3, sw(S1, ZERO, DEBUG_RAM_START + 4), false);
|
||||||
|
dram_write_jump(target, 4, true);
|
||||||
|
|
||||||
|
if (wait_for_debugint_clear(target) != ERROR_OK) {
|
||||||
|
LOG_ERROR("Debug interrupt didn't clear.");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t word0 = dram_read32(target, 0);
|
||||||
|
uint32_t word1 = dram_read32(target, 1);
|
||||||
|
if (word0 != 0x70002000) {
|
||||||
|
LOG_ERROR("Value at word 0 should be 0x%x but is 0x%x",
|
||||||
|
0x70002000, word0);
|
||||||
|
}
|
||||||
|
if (word1 != 0x70002000) {
|
||||||
|
LOG_ERROR("Value at word 1 should be 0x%x but is 0x%x",
|
||||||
|
0x70002000, word1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int riscv_examine(struct target *target)
|
static int riscv_examine(struct target *target)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("riscv_examine()");
|
LOG_DEBUG("riscv_examine()");
|
||||||
|
@ -791,6 +789,8 @@ static int riscv_examine(struct target *target)
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//write_constants(target);
|
||||||
|
//light_leds(target);
|
||||||
//dram_test(target);
|
//dram_test(target);
|
||||||
|
|
||||||
// Figure out XLEN.
|
// Figure out XLEN.
|
||||||
|
@ -811,6 +811,7 @@ static int riscv_examine(struct target *target)
|
||||||
error += dram_check32(target, 3, srli(S1, S1, 31));
|
error += dram_check32(target, 3, srli(S1, S1, 31));
|
||||||
error += dram_check32(target, 4, sw(S1, ZERO, DEBUG_RAM_START + 4));
|
error += dram_check32(target, 4, sw(S1, ZERO, DEBUG_RAM_START + 4));
|
||||||
if (error != 5 * ERROR_OK) {
|
if (error != 5 * ERROR_OK) {
|
||||||
|
dump_debug_ram(target);
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -823,8 +824,6 @@ static int riscv_examine(struct target *target)
|
||||||
dram_write_jump(target, 5, true);
|
dram_write_jump(target, 5, true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dram_write32(target, info->dramsize - 1, 0xdeadbeef, false);
|
|
||||||
|
|
||||||
if (wait_for_debugint_clear(target) != ERROR_OK) {
|
if (wait_for_debugint_clear(target) != ERROR_OK) {
|
||||||
LOG_ERROR("Debug interrupt didn't clear.");
|
LOG_ERROR("Debug interrupt didn't clear.");
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
|
@ -864,7 +863,13 @@ static int riscv_poll(struct target *target)
|
||||||
LOG_DEBUG("debug running");
|
LOG_DEBUG("debug running");
|
||||||
} else if (bits.haltnot && !bits.interrupt) {
|
} else if (bits.haltnot && !bits.interrupt) {
|
||||||
target->state = TARGET_HALTED;
|
target->state = TARGET_HALTED;
|
||||||
LOG_DEBUG("halted");
|
|
||||||
|
uint32_t dpc;
|
||||||
|
if (read_csr(target, &dpc, CSR_DPC) != ERROR_OK) {
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG("halted at 0x%x", dpc);
|
||||||
} else if (!bits.haltnot && bits.interrupt) {
|
} else if (!bits.haltnot && bits.interrupt) {
|
||||||
// Target is halting. There is no state for that, so don't change anything.
|
// Target is halting. There is no state for that, so don't change anything.
|
||||||
LOG_DEBUG("halting");
|
LOG_DEBUG("halting");
|
||||||
|
@ -880,8 +885,16 @@ static int riscv_halt(struct target *target)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("riscv_halt()");
|
LOG_DEBUG("riscv_halt()");
|
||||||
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
|
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
|
||||||
|
|
||||||
dram_write32(target, 0, csrsi(CSR_DCSR, DCSR_HALT), false);
|
dram_write32(target, 0, csrsi(CSR_DCSR, DCSR_HALT), false);
|
||||||
dram_write_jump(target, 1, true);
|
dram_write32(target, 1, csrr(S0, CSR_MHARTID), false);
|
||||||
|
dram_write32(target, 2, sw(S0, ZERO, SETHALTNOT), false);
|
||||||
|
dram_write_jump(target, 3, true);
|
||||||
|
|
||||||
|
if (wait_for_debugint_clear(target) != ERROR_OK) {
|
||||||
|
LOG_ERROR("Debug interrupt didn't clear.");
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
@ -1059,10 +1072,11 @@ static int riscv_read_memory(struct target *target, uint32_t address,
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
static int riscv_write_memory(struct target *target, uint32_t address,
|
static int riscv_write_memory(struct target *target, uint32_t address,
|
||||||
uint32_t size, uint32_t count, const uint8_t *buffer)
|
uint32_t size, uint32_t count, const uint8_t *buffer)
|
||||||
{
|
{
|
||||||
|
riscv_info_t *info = (riscv_info_t *) target->arch_info;
|
||||||
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
|
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
|
||||||
// TODO: save/restore T0
|
// TODO: save/restore T0
|
||||||
|
|
||||||
|
@ -1132,6 +1146,8 @@ static int riscv_write_memory(struct target *target, uint32_t address,
|
||||||
LOG_ERROR("dbus write failed!");
|
LOG_ERROR("dbus write failed!");
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
info->dram_valid |= (1<<4);
|
||||||
|
info->dram[4] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
|
@ -1230,7 +1246,39 @@ static int riscv_get_gdb_reg_list(struct target *target,
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct target_type riscv_target = {
|
int riscv_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
|
||||||
|
{
|
||||||
|
if (breakpoint->type != BKPT_SOFT) {
|
||||||
|
LOG_INFO("OpenOCD only supports software breakpoints.");
|
||||||
|
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_read_memory(target, breakpoint->address, breakpoint->length, 1,
|
||||||
|
breakpoint->orig_instr) != ERROR_OK) {
|
||||||
|
LOG_ERROR("Failed to read original instruction at 0x%x",
|
||||||
|
breakpoint->address);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int retval;
|
||||||
|
if (breakpoint->length == 4) {
|
||||||
|
retval = target_write_u32(target, breakpoint->address, ebreak());
|
||||||
|
} else {
|
||||||
|
retval = target_write_u16(target, breakpoint->address, ebreak_c());
|
||||||
|
}
|
||||||
|
if (retval != ERROR_OK) {
|
||||||
|
LOG_ERROR("Failed to write %d-byte breakpoint instruction at 0x%x",
|
||||||
|
breakpoint->length, breakpoint->address);
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
breakpoint->set = true;
|
||||||
|
|
||||||
|
return ERROR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct target_type riscv_target =
|
||||||
|
{
|
||||||
.name = "riscv",
|
.name = "riscv",
|
||||||
|
|
||||||
.init_target = riscv_init_target,
|
.init_target = riscv_init_target,
|
||||||
|
@ -1251,4 +1299,6 @@ struct target_type riscv_target = {
|
||||||
.write_memory = riscv_write_memory,
|
.write_memory = riscv_write_memory,
|
||||||
|
|
||||||
.get_gdb_reg_list = riscv_get_gdb_reg_list,
|
.get_gdb_reg_list = riscv_get_gdb_reg_list,
|
||||||
|
|
||||||
|
.add_breakpoint = riscv_add_breakpoint,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue