Workaround for fp register access in case fp unit is disabled (#766)

On some boards there is a HW bug: if fp unit is disabled (fs in mstatus
set to 0), accessing any fp register results in a hang (any abstract
command timeouts, untill the board is rebooted).

Signed-off-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
Change-Id: I0c0d1033889f15dcc326c4078bf9cbb5a8558565

Signed-off-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com>
This commit is contained in:
Evgeniy Naydanov 2022-11-15 19:52:13 +03:00 committed by GitHub
parent 57dbcb1d02
commit dc49ed8ae2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 11 additions and 11 deletions

View File

@ -1304,6 +1304,10 @@ static int register_write_direct(struct target *target, unsigned number,
{
LOG_TARGET_DEBUG(target, "%s <- 0x%" PRIx64, gdb_regno_name(number), value);
uint64_t mstatus;
if (prep_for_register_access(target, &mstatus, number) != ERROR_OK)
return ERROR_FAIL;
int result = register_write_abstract(target, number, value,
register_size(target, number));
if (result == ERROR_OK || !has_sufficient_progbuf(target, 2))
@ -1315,10 +1319,6 @@ static int register_write_direct(struct target *target, unsigned number,
if (riscv_save_register(target, GDB_REGNO_S0) != ERROR_OK)
return ERROR_FAIL;
uint64_t mstatus;
if (prep_for_register_access(target, &mstatus, number) != ERROR_OK)
return ERROR_FAIL;
scratch_mem_t scratch;
bool use_scratch = false;
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31 &&
@ -1406,6 +1406,10 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
if (dm013_select_target(target) != ERROR_OK)
return ERROR_FAIL;
uint64_t mstatus;
if (prep_for_register_access(target, &mstatus, number) != ERROR_OK)
return ERROR_FAIL;
int result = register_read_abstract(target, value, number,
register_size(target, number));
@ -1423,10 +1427,6 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
/* Write program to move data into s0. */
uint64_t mstatus;
if (prep_for_register_access(target, &mstatus, number) != ERROR_OK)
return ERROR_FAIL;
if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
if (riscv_supports_extension(target, 'D')
&& riscv_xlen(target) < 64) {
@ -1475,11 +1475,11 @@ static int register_read_direct(struct target *target, uint64_t *value, uint32_t
if (register_read_direct(target, value, GDB_REGNO_S0) != ERROR_OK)
return ERROR_FAIL;
}
if (cleanup_after_register_access(target, mstatus, number) != ERROR_OK)
return ERROR_FAIL;
}
if (cleanup_after_register_access(target, mstatus, number) != ERROR_OK)
return ERROR_FAIL;
if (result == ERROR_OK)
LOG_TARGET_DEBUG(target, "%s = 0x%" PRIx64, gdb_regno_name(number), *value);