WIP, blind coding.

This commit is contained in:
Tim Newsome 2016-05-23 16:27:43 -07:00
parent 413ab49dfd
commit ea6836c5f6
4 changed files with 110 additions and 30 deletions

View File

@ -33,28 +33,28 @@
#define SSTATUS32_SD 0x80000000 #define SSTATUS32_SD 0x80000000
#define SSTATUS64_SD 0x8000000000000000 #define SSTATUS64_SD 0x8000000000000000
#define DCSR_XDEBUGVER (3<<29) #define DCSR_XDEBUGVER (3<<30)
#define DCSR_HWBPCOUNT (0xfff<<17) #define DCSR_NDRESET (1<<29)
#define DCSR_PRV (3<<14) #define DCSR_FULLRESET (1<<28)
#define DCSR_NDRESET (1<<13) #define DCSR_HWBPCOUNT (0xfff<<16)
#define DCSR_FULLRESET (1<<12) #define DCSR_EBREAKM (1<<15)
#define DCSR_STEP (1<<11) #define DCSR_EBREAKH (1<<14)
#define DCSR_DEBUGINT (1<<10) #define DCSR_EBREAKS (1<<13)
#define DCSR_STOPCYCLE (1<<9) #define DCSR_EBREAKU (1<<12)
#define DCSR_STOPTIME (1<<8) #define DCSR_STOPCYCLE (1<<10)
#define DCSR_EBREAKM (1<<7) #define DCSR_STOPTIME (1<<9)
#define DCSR_EBREAKH (1<<6) #define DCSR_CAUSE (7<<6)
#define DCSR_EBREAKS (1<<5) #define DCSR_DEBUGINT (1<<5)
#define DCSR_EBREAKU (1<<4)
#define DCSR_HALT (1<<3) #define DCSR_HALT (1<<3)
#define DCSR_CAUSE 7 #define DCSR_STEP (1<<2)
#define DCSR_PRV (3<<0)
#define DCSR_CAUSE_NONE 0 #define DCSR_CAUSE_NONE (0<<6)
#define DCSR_CAUSE_SWBP 1 #define DCSR_CAUSE_SWBP (1<<6)
#define DCSR_CAUSE_HWBP 2 #define DCSR_CAUSE_HWBP (2<<6)
#define DCSR_CAUSE_DEBUGINT 3 #define DCSR_CAUSE_DEBUGINT (3<<6)
#define DCSR_CAUSE_STEP 4 #define DCSR_CAUSE_STEP (4<<6)
#define DCSR_CAUSE_HALT 5 #define DCSR_CAUSE_HALT (5<<6)
#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)

View File

@ -52,13 +52,13 @@ static uint32_t srli(unsigned int dest, unsigned int src, uint8_t shamt)
MATCH_SRLI; MATCH_SRLI;
} }
/*
static uint32_t csrci(unsigned int csr, uint16_t imm) { static uint32_t csrci(unsigned int csr, uint16_t imm) {
return (csr << 20) | return (csr << 20) |
(bits(imm, 4, 0) << 15) | (bits(imm, 4, 0) << 15) |
MATCH_CSRRCI; MATCH_CSRRCI;
} }
/*
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; return (csr << 20) | (rd << 7) | MATCH_CSRRS;
} }

View File

@ -92,8 +92,13 @@ typedef struct {
* confident that the value we have matches the one in actual Debug * confident that the value we have matches the one in actual Debug
* RAM. */ * RAM. */
uint64_t dram_valid; uint64_t dram_valid;
uint32_t dcsr;
} riscv_info_t; } riscv_info_t;
/*** Necessary prototypes. ***/
static int riscv_poll(struct target *target);
/*** Utility functions. ***/ /*** Utility functions. ***/
static uint8_t ir_dtminfo[1] = {DTMINFO}; static uint8_t ir_dtminfo[1] = {DTMINFO};
@ -246,6 +251,51 @@ static void dram_write_jump(struct target *target, unsigned int index, bool set_
set_interrupt); set_interrupt);
} }
static int wait_until_halted(struct target *target)
{
do {
int result = riscv_poll(target);
if (result != ERROR_OK) {
return result;
}
} while (target->state != TARGET_HALTED);
return ERROR_OK;
}
static int resume(struct target *target, int current, uint32_t address,
int handle_breakpoints, int debug_execution, bool step)
{
riscv_info_t *info = (riscv_info_t *) target->arch_info;
if (!current) {
if (info->xlen > 32) {
LOG_WARNING("Asked to resume at 32-bit PC on %d-bit target.",
info->xlen);
}
LOG_ERROR("TODO: current is false");
return ERROR_FAIL;
}
if (handle_breakpoints) {
LOG_ERROR("TODO: handle_breakpoints is true");
return ERROR_FAIL;
}
if (debug_execution) {
LOG_ERROR("TODO: debug_execution is true");
return ERROR_FAIL;
}
dram_write32(target, 0, csrsi(CSR_DCSR, DCSR_HALT), false);
if (step) {
dram_write32(target, 1, csrsi(CSR_DCSR, DCSR_STEP), false);
} else {
dram_write32(target, 1, csrci(CSR_DCSR, DCSR_STEP), false);
}
dram_write_jump(target, 2, true);
return ERROR_OK;
}
/*** OpenOCD target functions. ***/ /*** OpenOCD target functions. ***/
static int riscv_init_target(struct command_context *cmd_ctx, static int riscv_init_target(struct command_context *cmd_ctx,
@ -301,20 +351,15 @@ static int riscv_examine(struct target *target)
return ERROR_FAIL; return ERROR_FAIL;
} }
// TODO: Figure out XLEN. // Figure out XLEN.
// xori s1, zero, -1 0xffffffff 0xffffffff:ffffffff 0xffffffff:ffffffff:ffffffff:ffffffff
// srli s1, s1, 31 0x00000001 0x00000001:ffffffff 0x00000001:ffffffff:ffffffff:ffffffff
// sw s1, debug_ram
// srli s1, s1, 31 0x00000000 0x00000000:00000003 0x00000000:00000003:ffffffff:ffffffff
// sw s1, debug_ram + 4
// jump back
dram_write32(target, 0, xori(S1, ZERO, -1), false); dram_write32(target, 0, xori(S1, ZERO, -1), false);
// 0xffffffff 0xffffffff:ffffffff 0xffffffff:ffffffff:ffffffff:ffffffff
dram_write32(target, 1, srli(S1, S1, 31), false); dram_write32(target, 1, srli(S1, S1, 31), false);
// 0x00000001 0x00000001:ffffffff 0x00000001:ffffffff:ffffffff:ffffffff
dram_write32(target, 2, sw(S1, ZERO, DEBUG_RAM_START), false); dram_write32(target, 2, sw(S1, ZERO, DEBUG_RAM_START), false);
dram_write32(target, 3, srli(S1, S1, 31), false); dram_write32(target, 3, srli(S1, S1, 31), false);
// 0x00000000 0x00000000:00000003 0x00000000:00000003:ffffffff:ffffffff
dram_write32(target, 4, sw(S1, ZERO, DEBUG_RAM_START + 4), false); dram_write32(target, 4, sw(S1, ZERO, DEBUG_RAM_START + 4), false);
dram_write_jump(target, 5, true);
// Check that we can actually read/write dram. // Check that we can actually read/write dram.
dram_check32(target, 0, xori(S1, ZERO, -1)); dram_check32(target, 0, xori(S1, ZERO, -1));
@ -323,6 +368,25 @@ static int riscv_examine(struct target *target)
dram_check32(target, 3, srli(S1, S1, 31)); dram_check32(target, 3, srli(S1, S1, 31));
dram_check32(target, 4, sw(S1, ZERO, DEBUG_RAM_START + 4)); dram_check32(target, 4, sw(S1, ZERO, DEBUG_RAM_START + 4));
// Execute.
dram_write_jump(target, 5, true);
wait_until_halted(target);
uint32_t word0 = dram_read32(target, 0, false);
uint32_t word1 = dram_read32(target, 1, false);
if (word0 == 1 && word1 == 0) {
info->xlen = 32;
} else if (word0 == 0xffffffff && word1 == 3) {
info->xlen = 64;
} else if (word0 == 0xffffffff && word1 == 0xffffffff) {
info->xlen = 128;
} else {
LOG_ERROR("Failed to discover xlen; word0=0x%x, word1=0x%x",
word0, word1);
return ERROR_FAIL;
}
target_set_examined(target); target_set_examined(target);
return ERROR_OK; return ERROR_OK;
@ -365,6 +429,19 @@ static int riscv_halt(struct target *target)
return ERROR_OK; return ERROR_OK;
} }
static int riscv_resume(struct target *target, int current, uint32_t address,
int handle_breakpoints, int debug_execution)
{
return resume(target, current, address, handle_breakpoints,
debug_execution, false);
}
static int riscv_step(struct target *target, int current, uint32_t address,
int handle_breakpoints)
{
return resume(target, current, address, handle_breakpoints, 0, true);
}
static int riscv_assert_reset(struct target *target) static int riscv_assert_reset(struct target *target)
{ {
// TODO // TODO
@ -388,6 +465,8 @@ struct target_type riscv_target = {
.poll = riscv_poll, .poll = riscv_poll,
.halt = riscv_halt, .halt = riscv_halt,
.resume = riscv_resume,
.step = riscv_step,
.assert_reset = riscv_assert_reset, .assert_reset = riscv_assert_reset,
.deassert_reset = riscv_deassert_reset, .deassert_reset = riscv_deassert_reset,

View File

@ -53,6 +53,7 @@ struct target_type {
/* halt will log a warning, but return ERROR_OK if the target is already halted. */ /* halt will log a warning, but return ERROR_OK if the target is already halted. */
int (*halt)(struct target *target); int (*halt)(struct target *target);
/* See target.c target_resume() for documentation. */
int (*resume)(struct target *target, int current, uint32_t address, int (*resume)(struct target *target, int current, uint32_t address,
int handle_breakpoints, int debug_execution); int handle_breakpoints, int debug_execution);
int (*step)(struct target *target, int current, uint32_t address, int (*step)(struct target *target, int current, uint32_t address,