Only write to existing dram. Clear dbus error.
Old code would write 64 bytes of DRAM if the dbus was busy in cache_write(). New code clears the dbus error condition when the bus is busy. (This part is untested.) Change-Id: Ia396fe819fa1828bb75726d85513b113cc9e13f0__archive__
parent
54c65a9a4b
commit
c67850b63d
|
@ -46,9 +46,10 @@
|
|||
|
||||
/*** JTAG registers. ***/
|
||||
|
||||
#define DTMINFO 0x10
|
||||
#define DTMINFO_ADDRBITS (0xf<<4)
|
||||
#define DTMINFO_VERSION (0xf)
|
||||
#define DTMCONTROL 0x10
|
||||
#define DTMCONTROL_DBUS_RESET (1<<16)
|
||||
#define DTMCONTROL_ADDRBITS (0xf<<4)
|
||||
#define DTMCONTROL_VERSION (0xf)
|
||||
|
||||
#define DBUS 0x11
|
||||
#define DBUS_OP_START 0
|
||||
|
@ -197,10 +198,10 @@ static int poll_target(struct target *target, bool announce);
|
|||
|
||||
/*** Utility functions. ***/
|
||||
|
||||
static uint8_t ir_dtminfo[1] = {DTMINFO};
|
||||
static struct scan_field select_dtminfo = {
|
||||
static uint8_t ir_dtmcontrol[1] = {DTMCONTROL};
|
||||
static struct scan_field select_dtmcontrol = {
|
||||
.in_value = NULL,
|
||||
.out_value = ir_dtminfo
|
||||
.out_value = ir_dtmcontrol
|
||||
};
|
||||
static uint8_t ir_dbus[1] = {DBUS};
|
||||
static struct scan_field select_dbus = {
|
||||
|
@ -284,11 +285,43 @@ static uint16_t dram_address(unsigned int index)
|
|||
return 0x40 + index - 0x10;
|
||||
}
|
||||
|
||||
static uint32_t dtmcontrol_scan(struct target *target, uint32_t out)
|
||||
{
|
||||
struct scan_field field;
|
||||
uint8_t in_value[4];
|
||||
uint8_t out_value[4];
|
||||
|
||||
buf_set_u32(out_value, 0, 32, out);
|
||||
|
||||
jtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE);
|
||||
|
||||
field.num_bits = 32;
|
||||
field.out_value = out_value;
|
||||
field.in_value = in_value;
|
||||
jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);
|
||||
|
||||
int retval = jtag_execute_queue();
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("failed jtag scan: %d", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Always return to dbus. */
|
||||
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
|
||||
|
||||
uint32_t in = buf_get_u32(field.in_value, 0, 32);
|
||||
LOG_DEBUG("DTMCONTROL: 0x%x -> 0x%x", out, in);
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
static void increase_dbus_busy_delay(struct target *target)
|
||||
{
|
||||
riscv_info_t *info = (riscv_info_t *) target->arch_info;
|
||||
info->dbus_busy_delay++;
|
||||
LOG_INFO("Increment dbus_busy_delay to %d", info->dbus_busy_delay);
|
||||
|
||||
dtmcontrol_scan(target, DTMCONTROL_DBUS_RESET);
|
||||
}
|
||||
|
||||
static void increase_interrupt_high_delay(struct target *target)
|
||||
|
@ -314,7 +347,7 @@ static void add_dbus_scan(const struct target *target, struct scan_field *field,
|
|||
|
||||
jtag_add_dr_scan(target->tap, 1, field, TAP_IDLE);
|
||||
|
||||
// TODO: 1 should come from the dtminfo register
|
||||
// TODO: 1 should come from the dtmcontrol register
|
||||
int idle_count = 1 + info->dbus_busy_delay;
|
||||
if (data & DMCONTROL_INTERRUPT) {
|
||||
idle_count += info->interrupt_high_delay;
|
||||
|
@ -480,7 +513,7 @@ static int scans_execute(scans_t *scans)
|
|||
{
|
||||
int retval = jtag_execute_queue();
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("dtminfo_read failed jtag scan");
|
||||
LOG_ERROR("failed jtag scan: %d", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -563,30 +596,6 @@ static uint64_t scans_get_u64(scans_t *scans, unsigned int index,
|
|||
|
||||
/*** end of scans class ***/
|
||||
|
||||
static uint32_t dtminfo_read(struct target *target)
|
||||
{
|
||||
struct scan_field field;
|
||||
uint8_t in[4];
|
||||
|
||||
jtag_add_ir_scan(target->tap, &select_dtminfo, TAP_IDLE);
|
||||
|
||||
field.num_bits = 32;
|
||||
field.out_value = NULL;
|
||||
field.in_value = in;
|
||||
jtag_add_dr_scan(target->tap, 1, &field, TAP_IDLE);
|
||||
|
||||
int retval = jtag_execute_queue();
|
||||
if (retval != ERROR_OK) {
|
||||
LOG_ERROR("dtminfo_read failed jtag scan");
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Always return to dbus. */
|
||||
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
|
||||
|
||||
return buf_get_u32(field.in_value, 0, 32);
|
||||
}
|
||||
|
||||
static uint32_t dram_read32(struct target *target, unsigned int index)
|
||||
{
|
||||
uint16_t address = dram_address(index);
|
||||
|
@ -825,7 +834,8 @@ static int cache_write(struct target *target, unsigned int address, bool run)
|
|||
increase_dbus_busy_delay(target);
|
||||
|
||||
// Try again, using the slow careful code.
|
||||
for (unsigned int i = 0; i < DRAM_CACHE_SIZE; i++) {
|
||||
// Write all RAM, just to be extra cautious.
|
||||
for (unsigned int i = 0; i < info->dramsize; i++) {
|
||||
if (i == last && run) {
|
||||
dram_write32(target, last, info->dram_cache[last].data, true);
|
||||
} else {
|
||||
|
@ -1245,7 +1255,7 @@ static int riscv_init_target(struct command_context *cmd_ctx,
|
|||
return ERROR_FAIL;
|
||||
riscv_info_t *info = (riscv_info_t *) target->arch_info;
|
||||
|
||||
select_dtminfo.num_bits = target->tap->ir_length;
|
||||
select_dtmcontrol.num_bits = target->tap->ir_length;
|
||||
select_dbus.num_bits = target->tap->ir_length;
|
||||
select_debug.num_bits = target->tap->ir_length;
|
||||
|
||||
|
@ -1617,26 +1627,26 @@ static int riscv_examine(struct target *target)
|
|||
return ERROR_OK;
|
||||
}
|
||||
|
||||
// Don't need to select dbus, since the first thing we do is read dtminfo.
|
||||
// Don't need to select dbus, since the first thing we do is read dtmcontrol.
|
||||
|
||||
uint32_t dtminfo = dtminfo_read(target);
|
||||
LOG_DEBUG("dtminfo=0x%x", dtminfo);
|
||||
LOG_DEBUG(" addrbits=%d", get_field(dtminfo, DTMINFO_ADDRBITS));
|
||||
LOG_DEBUG(" version=%d", get_field(dtminfo, DTMINFO_VERSION));
|
||||
uint32_t dtmcontrol = dtmcontrol_scan(target, 0);
|
||||
LOG_DEBUG("dtmcontrol=0x%x", dtmcontrol);
|
||||
LOG_DEBUG(" addrbits=%d", get_field(dtmcontrol, DTMCONTROL_ADDRBITS));
|
||||
LOG_DEBUG(" version=%d", get_field(dtmcontrol, DTMCONTROL_VERSION));
|
||||
// TODO: Add support for the idle field, once it's implemented in the FPGA
|
||||
// image.
|
||||
if (dtminfo == 0) {
|
||||
LOG_ERROR("dtminfo is 0. Check JTAG connectivity/board power.");
|
||||
if (dtmcontrol == 0) {
|
||||
LOG_ERROR("dtmcontrol is 0. Check JTAG connectivity/board power.");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
if (get_field(dtminfo, DTMINFO_VERSION) != 0) {
|
||||
LOG_ERROR("Unsupported DTM version %d. (dtminfo=0x%x)",
|
||||
get_field(dtminfo, DTMINFO_VERSION), dtminfo);
|
||||
if (get_field(dtmcontrol, DTMCONTROL_VERSION) != 0) {
|
||||
LOG_ERROR("Unsupported DTM version %d. (dtmcontrol=0x%x)",
|
||||
get_field(dtmcontrol, DTMCONTROL_VERSION), dtmcontrol);
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
riscv_info_t *info = (riscv_info_t *) target->arch_info;
|
||||
info->addrbits = get_field(dtminfo, DTMINFO_ADDRBITS);
|
||||
info->addrbits = get_field(dtmcontrol, DTMCONTROL_ADDRBITS);
|
||||
|
||||
uint32_t dminfo = dbus_read(target, DMINFO);
|
||||
LOG_DEBUG("dminfo: 0x%08x", dminfo);
|
||||
|
|
Loading…
Reference in New Issue