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:
parent
b67379700b
commit
5184c32125
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue