Clear errors that we see.

Also WIP towards handling busy errors, but I'm putting that on hold
while I change the spec...

Change-Id: Iccf47048da46e75b0d769e56004fd783bba1dbf0
This commit is contained in:
Tim Newsome 2018-01-18 19:25:12 -08:00
parent b67379700b
commit 5184c32125
1 changed files with 64 additions and 40 deletions

View File

@ -1487,6 +1487,21 @@ static uint32_t sb_sbaccess(unsigned size_bytes)
assert(0); assert(0);
} }
static target_addr_t sb_read_address(struct target *target)
{
RISCV013_INFO(info);
unsigned sbasize = get_field(info->sbcs, DMI_SBCS_SBASIZE);
target_addr_t address = 0;
if (sbasize > 32) {
#if BUILD_TARGET64
address |= dmi_read(target, DMI_SBADDRESS1);
address <<= 32;
#endif
}
address |= dmi_read(target, DMI_SBADDRESS0);
return address;
}
static int sb_write_address(struct target *target, target_addr_t address) static int sb_write_address(struct target *target, target_addr_t address)
{ {
RISCV013_INFO(info); RISCV013_INFO(info);
@ -1538,6 +1553,7 @@ static int read_memory_bus(struct target *target, target_addr_t address,
return ERROR_OK; return ERROR_OK;
} else if (error == 1 || error == 2 || error == 3) { } else if (error == 1 || error == 2 || error == 3) {
/* Bus timeout, bus error, other bus error. */ /* Bus timeout, bus error, other bus error. */
dmi_write(target, DMI_SBCS, DMI_SBCS_SBERROR);
return ERROR_FAIL; return ERROR_FAIL;
} else if (error == 4) { } else if (error == 4) {
assert(0); assert(0);
@ -1809,9 +1825,12 @@ static int write_memory_bus(struct target *target, target_addr_t address,
sbcs = set_field(sbcs, DMI_SBCS_SBAUTOINCREMENT, 1); sbcs = set_field(sbcs, DMI_SBCS_SBAUTOINCREMENT, 1);
dmi_write(target, DMI_SBCS, sbcs); dmi_write(target, DMI_SBCS, sbcs);
sb_write_address(target, address); target_addr_t next_address = address;
target_addr_t end_address = address + count * size;
for (uint32_t i = 0; i < count; i++) { sb_write_address(target, next_address);
while (next_address < end_address) {
for (uint32_t i = (next_address - address) / size; i < count; i++) {
const uint8_t *p = buffer + i * size; const uint8_t *p = buffer + i * size;
if (size > 12) if (size > 12)
dmi_write(target, DMI_SBDATA3, dmi_write(target, DMI_SBDATA3,
@ -1844,15 +1863,20 @@ static int write_memory_bus(struct target *target, target_addr_t address,
sbcs = dmi_read(target, DMI_SBCS); sbcs = dmi_read(target, DMI_SBCS);
unsigned error = get_field(sbcs, DMI_SBCS_SBERROR); unsigned error = get_field(sbcs, DMI_SBCS_SBERROR);
if (error == 0) { if (error == 0) {
return ERROR_OK; next_address = end_address;
} else if (error == 1 || error == 2 || error == 3) { } else if (error == 1 || error == 2 || error == 3) {
/* Bus timeout, bus error, other bus error. */ /* Bus timeout, bus error, other bus error. */
dmi_write(target, DMI_SBCS, DMI_SBCS_SBERROR);
return ERROR_FAIL; return ERROR_FAIL;
} else if (error == 4) { } else if (error == 4) {
assert(0); /* We wrote while the target was busy. Slow down and try again. */
/* TODO: Reading too fast. We should deal with this properly. */ next_address = sb_read_address(target);
dmi_write(target, DMI_SBCS, DMI_SBCS_SBERROR);
// <<< TODO: slow down
} }
return ERROR_FAIL; }
return ERROR_OK;
} }
static int write_memory_progbuf(struct target *target, target_addr_t address, static int write_memory_progbuf(struct target *target, target_addr_t address,