Reading registers appears to work.

This commit is contained in:
Tim Newsome 2016-06-04 10:26:32 -07:00
parent 84944ded87
commit 9f22176618
3 changed files with 53 additions and 26 deletions

View File

@ -33,7 +33,7 @@
#define SSTATUS32_SD 0x80000000 #define SSTATUS32_SD 0x80000000
#define SSTATUS64_SD 0x8000000000000000 #define SSTATUS64_SD 0x8000000000000000
#define DCSR_XDEBUGVER (3<<30) #define DCSR_XDEBUGVER (3U<<30)
#define DCSR_NDRESET (1<<29) #define DCSR_NDRESET (1<<29)
#define DCSR_FULLRESET (1<<28) #define DCSR_FULLRESET (1<<28)
#define DCSR_HWBPCOUNT (0xfff<<16) #define DCSR_HWBPCOUNT (0xfff<<16)
@ -49,12 +49,12 @@
#define DCSR_STEP (1<<2) #define DCSR_STEP (1<<2)
#define DCSR_PRV (3<<0) #define DCSR_PRV (3<<0)
#define DCSR_CAUSE_NONE (0<<6) #define DCSR_CAUSE_NONE 0
#define DCSR_CAUSE_SWBP (1<<6) #define DCSR_CAUSE_SWBP 1
#define DCSR_CAUSE_HWBP (2<<6) #define DCSR_CAUSE_HWBP 2
#define DCSR_CAUSE_DEBUGINT (3<<6) #define DCSR_CAUSE_DEBUGINT 3
#define DCSR_CAUSE_STEP (4<<6) #define DCSR_CAUSE_STEP 4
#define DCSR_CAUSE_HALT (5<<6) #define DCSR_CAUSE_HALT 5
#define MIP_SSIP (1 << IRQ_S_SOFT) #define MIP_SSIP (1 << IRQ_S_SOFT)
#define MIP_HSIP (1 << IRQ_H_SOFT) #define MIP_HSIP (1 << IRQ_H_SOFT)
@ -62,6 +62,9 @@
#define MIP_STIP (1 << IRQ_S_TIMER) #define MIP_STIP (1 << IRQ_S_TIMER)
#define MIP_HTIP (1 << IRQ_H_TIMER) #define MIP_HTIP (1 << IRQ_H_TIMER)
#define MIP_MTIP (1 << IRQ_M_TIMER) #define MIP_MTIP (1 << IRQ_M_TIMER)
#define MIP_SEIP (1 << IRQ_S_EXT)
#define MIP_HEIP (1 << IRQ_H_EXT)
#define MIP_MEIP (1 << IRQ_M_EXT)
#define SIP_SSIP MIP_SSIP #define SIP_SSIP MIP_SSIP
#define SIP_STIP MIP_STIP #define SIP_STIP MIP_STIP
@ -84,9 +87,9 @@
#define IRQ_S_TIMER 5 #define IRQ_S_TIMER 5
#define IRQ_H_TIMER 6 #define IRQ_H_TIMER 6
#define IRQ_M_TIMER 7 #define IRQ_M_TIMER 7
#define IRQ_S_DEV 9 #define IRQ_S_EXT 9
#define IRQ_H_DEV 10 #define IRQ_H_EXT 10
#define IRQ_M_DEV 11 #define IRQ_M_EXT 11
#define IRQ_COP 12 #define IRQ_COP 12
#define IRQ_HOST 13 #define IRQ_HOST 13
@ -383,7 +386,7 @@
#define MASK_HRET 0xffffffff #define MASK_HRET 0xffffffff
#define MATCH_MRET 0x30200073 #define MATCH_MRET 0x30200073
#define MASK_MRET 0xffffffff #define MASK_MRET 0xffffffff
#define MATCH_DRET 0x79200073 #define MATCH_DRET 0x7b200073
#define MASK_DRET 0xffffffff #define MASK_DRET 0xffffffff
#define MATCH_SFENCE_VM 0x10400073 #define MATCH_SFENCE_VM 0x10400073
#define MASK_SFENCE_VM 0xfff07fff #define MASK_SFENCE_VM 0xfff07fff
@ -686,7 +689,6 @@
#define CSR_MCAUSE 0x342 #define CSR_MCAUSE 0x342
#define CSR_MBADADDR 0x343 #define CSR_MBADADDR 0x343
#define CSR_MIP 0x344 #define CSR_MIP 0x344
#define CSR_MIPI 0x345
#define CSR_MUCOUNTEREN 0x310 #define CSR_MUCOUNTEREN 0x310
#define CSR_MSCOUNTEREN 0x311 #define CSR_MSCOUNTEREN 0x311
#define CSR_MUCYCLE_DELTA 0x700 #define CSR_MUCYCLE_DELTA 0x700
@ -695,9 +697,9 @@
#define CSR_MSCYCLE_DELTA 0x704 #define CSR_MSCYCLE_DELTA 0x704
#define CSR_MSTIME_DELTA 0x705 #define CSR_MSTIME_DELTA 0x705
#define CSR_MSINSTRET_DELTA 0x706 #define CSR_MSINSTRET_DELTA 0x706
#define CSR_DCSR 0x790 #define CSR_DCSR 0x7b0
#define CSR_DPC 0x791 #define CSR_DPC 0x7b1
#define CSR_DSCRATCH 0x792 #define CSR_DSCRATCH 0x7b2
#define CSR_MCYCLE 0xf00 #define CSR_MCYCLE 0xf00
#define CSR_MTIME 0xf01 #define CSR_MTIME 0xf01
#define CSR_MINSTRET 0xf02 #define CSR_MINSTRET 0xf02
@ -706,8 +708,6 @@
#define CSR_MARCHID 0xf12 #define CSR_MARCHID 0xf12
#define CSR_MIMPID 0xf13 #define CSR_MIMPID 0xf13
#define CSR_MHARTID 0xf14 #define CSR_MHARTID 0xf14
#define CSR_MTOHOST 0x7c0
#define CSR_MFROMHOST 0x7c1
#define CSR_MRESET 0x7c2 #define CSR_MRESET 0x7c2
#define CSR_CYCLEH 0xc80 #define CSR_CYCLEH 0xc80
#define CSR_TIMEH 0xc81 #define CSR_TIMEH 0xc81
@ -995,7 +995,6 @@ DECLARE_CSR(mepc, CSR_MEPC)
DECLARE_CSR(mcause, CSR_MCAUSE) DECLARE_CSR(mcause, CSR_MCAUSE)
DECLARE_CSR(mbadaddr, CSR_MBADADDR) DECLARE_CSR(mbadaddr, CSR_MBADADDR)
DECLARE_CSR(mip, CSR_MIP) DECLARE_CSR(mip, CSR_MIP)
DECLARE_CSR(mipi, CSR_MIPI)
DECLARE_CSR(mucounteren, CSR_MUCOUNTEREN) DECLARE_CSR(mucounteren, CSR_MUCOUNTEREN)
DECLARE_CSR(mscounteren, CSR_MSCOUNTEREN) DECLARE_CSR(mscounteren, CSR_MSCOUNTEREN)
DECLARE_CSR(mucycle_delta, CSR_MUCYCLE_DELTA) DECLARE_CSR(mucycle_delta, CSR_MUCYCLE_DELTA)
@ -1015,8 +1014,6 @@ DECLARE_CSR(mvendorid, CSR_MVENDORID)
DECLARE_CSR(marchid, CSR_MARCHID) DECLARE_CSR(marchid, CSR_MARCHID)
DECLARE_CSR(mimpid, CSR_MIMPID) DECLARE_CSR(mimpid, CSR_MIMPID)
DECLARE_CSR(mhartid, CSR_MHARTID) DECLARE_CSR(mhartid, CSR_MHARTID)
DECLARE_CSR(mtohost, CSR_MTOHOST)
DECLARE_CSR(mfromhost, CSR_MFROMHOST)
DECLARE_CSR(mreset, CSR_MRESET) DECLARE_CSR(mreset, CSR_MRESET)
DECLARE_CSR(cycleh, CSR_CYCLEH) DECLARE_CSR(cycleh, CSR_CYCLEH)
DECLARE_CSR(timeh, CSR_TIMEH) DECLARE_CSR(timeh, CSR_TIMEH)

View File

@ -117,6 +117,15 @@ static uint32_t csrr(unsigned int rd, unsigned int csr) {
return (csr << 20) | (rd << 7) | MATCH_CSRRS; return (csr << 20) | (rd << 7) | MATCH_CSRRS;
} }
static uint32_t fsw(unsigned int src, unsigned int base, uint16_t offset)
{
return (bits(offset, 11, 5) << 25) |
(bits(src, 4, 0) << 20) |
(base << 15) |
(bits(offset, 4, 0) << 7) |
MATCH_FSW;
}
/* /*
static uint32_t li(unsigned int dest, uint16_t imm) static uint32_t li(unsigned int dest, uint16_t imm)
{ {

View File

@ -294,14 +294,18 @@ static int dram_check32(struct target *target, unsigned int index,
static bits_t read_bits(struct target *target) static bits_t read_bits(struct target *target)
{ {
riscv_info_t *info = (riscv_info_t *) target->arch_info; riscv_info_t *info = (riscv_info_t *) target->arch_info;
static int next_address = 0;
uint64_t value; uint64_t value;
if (info->dbus_address < 0x10 || info->dbus_address == DMCONTROL) { if (info->dbus_address < 0x10 || info->dbus_address == DMCONTROL) {
value = dbus_read(target, info->dbus_address, 0); value = dbus_read(target, info->dbus_address, next_address);
} else { } else {
value = dbus_read(target, 0, 0); value = dbus_read(target, 0, next_address);
} }
// Cycle through addresses, so we have more debug info.
next_address = (next_address + 1) % (info->dramsize + 1);
bits_t result = { bits_t result = {
.haltnot = get_field(value, DMCONTROL_HALTNOT), .haltnot = get_field(value, DMCONTROL_HALTNOT),
.interrupt = get_field(value, DMCONTROL_INTERRUPT) .interrupt = get_field(value, DMCONTROL_INTERRUPT)
@ -415,11 +419,22 @@ static int register_get(struct reg *reg)
{ {
struct target *target = (struct target *) reg->arch_info; struct target *target = (struct target *) reg->arch_info;
if (reg->number == REG_PC) { if (reg->number <= REG_XPR31) {
dram_write32(target, 0, sw(reg->number - REG_XPR0, ZERO, DEBUG_RAM_START), false);
dram_write_jump(target, 1, true);
} else if (reg->number == REG_PC) {
dram_write32(target, 0, csrr(S0, CSR_DPC), false); dram_write32(target, 0, csrr(S0, CSR_DPC), false);
dram_write32(target, 1, sw(S0, ZERO, DEBUG_RAM_START), false); dram_write32(target, 1, sw(S0, ZERO, DEBUG_RAM_START), false);
dram_write_jump(target, 2, true); dram_write_jump(target, 2, true);
} else if (reg->number >= REG_FPR0 && reg->number <= REG_FPR31) {
dram_write32(target, 0, fsw(reg->number - REG_FPR0, 0, DEBUG_RAM_START), false);
dram_write_jump(target, 1, true);
} else if (reg->number >= REG_CSR0 && reg->number <= REG_CSR4095) {
dram_write32(target, 0, csrr(S0, reg->number - REG_CSR0), false);
dram_write32(target, 1, sw(S0, ZERO, DEBUG_RAM_START), false);
dram_write_jump(target, 2, true);
} else { } else {
LOG_ERROR("Don't know how to read register %d (%s)", reg->number, reg->name);
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -428,7 +443,9 @@ static int register_get(struct reg *reg)
return ERROR_FAIL; return ERROR_FAIL;
} }
buf_set_u32(reg->value, 0, 32, dram_read32(target, 0)); uint32_t value = dram_read32(target, 0);
LOG_DEBUG("%s=0x%x", reg->name, value);
buf_set_u32(reg->value, 0, 32, value);
return ERROR_OK; return ERROR_OK;
} }
@ -664,10 +681,14 @@ static int riscv_examine(struct target *target)
return ERROR_FAIL; return ERROR_FAIL;
} }
// TODO: Doesn't work with this extra nop.
dram_write32(target, 5, nop(), false);
// Execute. // Execute.
#if 1
// TODO: Doesn't work without this extra nop.
dram_write32(target, 5, nop(), false);
dram_write_jump(target, 6, true); dram_write_jump(target, 6, true);
#else
dram_write_jump(target, 5, true);
#endif
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.");