Selecting dbus is sometimes necessary.

This commit is contained in:
Tim Newsome 2016-05-31 12:28:20 -07:00
parent 25e8b66b08
commit 041e0ccf9e
1 changed files with 18 additions and 3 deletions

View File

@ -12,6 +12,13 @@
#include "opcodes.h" #include "opcodes.h"
#include "register.h" #include "register.h"
/**
* Since almost everything can be accomplish by scanning the dbus register, all
* functions here assume dbus is already selected. The exception are functions
* called directly by OpenOCD, which can't assume anything about what's
* currently in IR. They should set IR to dbus explicitly.
*/
#define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1))) #define get_field(reg, mask) (((reg) & (mask)) / ((mask) & ~((mask) << 1)))
#define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask))) #define set_field(reg, mask, val) (((reg) & ~(mask)) | (((val) * ((mask) & ~((mask) << 1))) & (mask)))
@ -238,9 +245,6 @@ static uint32_t dtminfo_read(struct target *target)
} }
/* Always return to dbus. */ /* Always return to dbus. */
/* TODO: Can we rely on IR not being messed with between calls into
* RISCV code? Eg. what happens if there are multiple cores and some
* other core is accessed? */
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
return buf_get_u32(field.in_value, 0, 32); return buf_get_u32(field.in_value, 0, 32);
@ -457,6 +461,8 @@ static int riscv_examine(struct target *target)
return ERROR_OK; return ERROR_OK;
} }
// Don't need to select dbus, since the first thing we do is read dtminfo.
uint32_t dtminfo = dtminfo_read(target); uint32_t dtminfo = dtminfo_read(target);
riscv_info_t *info = (riscv_info_t *) target->arch_info; riscv_info_t *info = (riscv_info_t *) target->arch_info;
@ -523,6 +529,7 @@ static int riscv_examine(struct target *target)
static int riscv_poll(struct target *target) static int riscv_poll(struct target *target)
{ {
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
bits_t bits = read_bits(target); bits_t bits = read_bits(target);
if (bits.haltnot && bits.interrupt) { if (bits.haltnot && bits.interrupt) {
@ -541,6 +548,7 @@ static int riscv_poll(struct target *target)
static int riscv_halt(struct target *target) 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);
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_write_jump(target, 1, true);
@ -550,6 +558,7 @@ static int riscv_halt(struct target *target)
static int riscv_resume(struct target *target, int current, uint32_t address, static int riscv_resume(struct target *target, int current, uint32_t address,
int handle_breakpoints, int debug_execution) int handle_breakpoints, int debug_execution)
{ {
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
return resume(target, current, address, handle_breakpoints, return resume(target, current, address, handle_breakpoints,
debug_execution, false); debug_execution, false);
} }
@ -557,6 +566,7 @@ static int riscv_resume(struct target *target, int current, uint32_t address,
static int riscv_step(struct target *target, int current, uint32_t address, static int riscv_step(struct target *target, int current, uint32_t address,
int handle_breakpoints) int handle_breakpoints)
{ {
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
return resume(target, current, address, handle_breakpoints, 0, true); return resume(target, current, address, handle_breakpoints, 0, true);
} }
@ -564,6 +574,8 @@ static int riscv_assert_reset(struct target *target)
{ {
// TODO: Maybe what I implemented here is more like soft_reset_halt()? // TODO: Maybe what I implemented here is more like soft_reset_halt()?
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
// The only assumption we can make is that the TAP was reset. // The only assumption we can make is that the TAP was reset.
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.");
@ -592,6 +604,7 @@ static int riscv_assert_reset(struct target *target)
static int riscv_deassert_reset(struct target *target) static int riscv_deassert_reset(struct target *target)
{ {
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
if (target->reset_halt) { if (target->reset_halt) {
return wait_for_state(target, TARGET_HALTED); return wait_for_state(target, TARGET_HALTED);
} else { } else {
@ -602,6 +615,7 @@ static int riscv_deassert_reset(struct target *target)
static int riscv_read_memory(struct target *target, uint32_t address, static int riscv_read_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, uint8_t *buffer) uint32_t size, uint32_t count, uint8_t *buffer)
{ {
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
// Plain implementation, where we write the address each time. // Plain implementation, where we write the address each time.
dram_write32(target, 0, lw(S0, ZERO, DEBUG_RAM_START + 16), false); dram_write32(target, 0, lw(S0, ZERO, DEBUG_RAM_START + 16), false);
switch (size) { switch (size) {
@ -667,6 +681,7 @@ static int riscv_read_memory(struct target *target, uint32_t address,
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)
{ {
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
// TODO: save/restore T0 // TODO: save/restore T0
// Set up the address. // Set up the address.