WIP. Hide FPRs if the hart doesn't support F/D.
Change-Id: I988c0c36f2de8157d76874a697b3c054773b787d
This commit is contained in:
parent
e648856a41
commit
a5cb0b2270
|
@ -1149,40 +1149,47 @@ static int init_registers(struct target *target)
|
||||||
.id = "ieee_double"
|
.id = "ieee_double"
|
||||||
};
|
};
|
||||||
|
|
||||||
for (unsigned int i = 0; i < GDB_REGNO_COUNT; i++) {
|
// When gdb request register N, gdb_get_register_packet() assumes that this
|
||||||
struct reg *r = &target->reg_cache->reg_list[i];
|
// is register at index N in reg_list. So if there are certain registers
|
||||||
r->number = i;
|
// that don't exist, we need to leave holes in the list (or renumber, but
|
||||||
|
// it would be nice not to have yet another set of numbers to translate
|
||||||
|
// between).
|
||||||
|
for (uint32_t number = 0; number < GDB_REGNO_COUNT; number++) {
|
||||||
|
struct reg *r = &target->reg_cache->reg_list[number];
|
||||||
r->caller_save = true;
|
r->caller_save = true;
|
||||||
r->dirty = false;
|
r->dirty = false;
|
||||||
r->valid = false;
|
r->valid = false;
|
||||||
r->exist = true;
|
r->exist = true;
|
||||||
r->type = &riscv_reg_arch_type;
|
r->type = &riscv_reg_arch_type;
|
||||||
r->arch_info = target;
|
r->arch_info = target;
|
||||||
|
r->number = number;
|
||||||
// r->size is set in riscv_invalidate_register_cache, maybe because the
|
// r->size is set in riscv_invalidate_register_cache, maybe because the
|
||||||
// target is in theory allowed to change XLEN on us. But I expect a lot
|
// target is in theory allowed to change XLEN on us. But I expect a lot
|
||||||
// of other things to break in that case as well.
|
// of other things to break in that case as well.
|
||||||
if (i <= GDB_REGNO_XPR31) {
|
if (number <= GDB_REGNO_XPR31) {
|
||||||
sprintf(reg_name, "x%d", i);
|
sprintf(reg_name, "x%d", number);
|
||||||
r->group = "general";
|
r->group = "general";
|
||||||
r->feature = &feature_cpu;
|
r->feature = &feature_cpu;
|
||||||
} else if (i == GDB_REGNO_PC) {
|
} else if (number == GDB_REGNO_PC) {
|
||||||
sprintf(reg_name, "pc");
|
sprintf(reg_name, "pc");
|
||||||
r->group = "general";
|
r->group = "general";
|
||||||
r->feature = &feature_cpu;
|
r->feature = &feature_cpu;
|
||||||
} else if (i >= GDB_REGNO_FPR0 && i <= GDB_REGNO_FPR31) {
|
} else if (number >= GDB_REGNO_FPR0 && number <= GDB_REGNO_FPR31) {
|
||||||
sprintf(reg_name, "f%d", i - GDB_REGNO_FPR0);
|
|
||||||
r->group = "float";
|
|
||||||
r->feature = &feature_fpu;
|
|
||||||
if (riscv_supports_extension(target, 'D')) {
|
if (riscv_supports_extension(target, 'D')) {
|
||||||
r->reg_data_type = &type_ieee_double;
|
r->reg_data_type = &type_ieee_double;
|
||||||
} else if (riscv_supports_extension(target, 'F')) {
|
} else if (riscv_supports_extension(target, 'F')) {
|
||||||
r->reg_data_type = &type_ieee_single;
|
r->reg_data_type = &type_ieee_single;
|
||||||
|
} else {
|
||||||
|
r->exist = false;
|
||||||
}
|
}
|
||||||
} else if (i >= GDB_REGNO_CSR0 && i <= GDB_REGNO_CSR4095) {
|
sprintf(reg_name, "f%d", number - GDB_REGNO_FPR0);
|
||||||
sprintf(reg_name, "csr%d", i - GDB_REGNO_CSR0);
|
r->group = "float";
|
||||||
|
r->feature = &feature_fpu;
|
||||||
|
} else if (number >= GDB_REGNO_CSR0 && number <= GDB_REGNO_CSR4095) {
|
||||||
|
sprintf(reg_name, "csr%d", number - GDB_REGNO_CSR0);
|
||||||
r->group = "csr";
|
r->group = "csr";
|
||||||
r->feature = &feature_csr;
|
r->feature = &feature_csr;
|
||||||
} else if (i == GDB_REGNO_PRIV) {
|
} else if (number == GDB_REGNO_PRIV) {
|
||||||
sprintf(reg_name, "priv");
|
sprintf(reg_name, "priv");
|
||||||
r->group = "general";
|
r->group = "general";
|
||||||
r->feature = &feature_virtual;
|
r->feature = &feature_virtual;
|
||||||
|
|
|
@ -760,6 +760,11 @@ static int riscv_get_gdb_reg_list(struct target *target,
|
||||||
LOG_DEBUG("reg_class=%d", reg_class);
|
LOG_DEBUG("reg_class=%d", reg_class);
|
||||||
LOG_DEBUG("rtos_hartid=%d current_hartid=%d", r->rtos_hartid, r->current_hartid);
|
LOG_DEBUG("rtos_hartid=%d current_hartid=%d", r->rtos_hartid, r->current_hartid);
|
||||||
|
|
||||||
|
if (!target->reg_cache) {
|
||||||
|
LOG_ERROR("Target not initialized. Return ERROR_FAIL.");
|
||||||
|
return ERROR_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
if (r->rtos_hartid != -1 && riscv_rtos_enabled(target))
|
if (r->rtos_hartid != -1 && riscv_rtos_enabled(target))
|
||||||
riscv_set_current_hartid(target, r->rtos_hartid);
|
riscv_set_current_hartid(target, r->rtos_hartid);
|
||||||
else
|
else
|
||||||
|
@ -770,7 +775,7 @@ static int riscv_get_gdb_reg_list(struct target *target,
|
||||||
*reg_list_size = 32;
|
*reg_list_size = 32;
|
||||||
break;
|
break;
|
||||||
case REG_CLASS_ALL:
|
case REG_CLASS_ALL:
|
||||||
*reg_list_size = REG_COUNT;
|
*reg_list_size = GDB_REGNO_COUNT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR("Unsupported reg_class: %d", reg_class);
|
LOG_ERROR("Unsupported reg_class: %d", reg_class);
|
||||||
|
@ -782,13 +787,9 @@ static int riscv_get_gdb_reg_list(struct target *target,
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target->reg_cache) {
|
|
||||||
LOG_ERROR("Target not initialized. Return ERROR_FAIL.");
|
|
||||||
return ERROR_FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < *reg_list_size; i++) {
|
for (int i = 0; i < *reg_list_size; i++) {
|
||||||
assert(target->reg_cache->reg_list[i].size > 0);
|
assert(!target->reg_cache->reg_list[i].valid ||
|
||||||
|
target->reg_cache->reg_list[i].size > 0);
|
||||||
(*reg_list)[i] = &target->reg_cache->reg_list[i];
|
(*reg_list)[i] = &target->reg_cache->reg_list[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1424,9 +1425,9 @@ void riscv_invalidate_register_cache(struct target *target)
|
||||||
reg->value = &r->reg_cache_values[i];
|
reg->value = &r->reg_cache_values[i];
|
||||||
reg->valid = false;
|
reg->valid = false;
|
||||||
|
|
||||||
if (i == GDB_REGNO_PRIV) {
|
if (reg->number == GDB_REGNO_PRIV) {
|
||||||
reg->size = 8;
|
reg->size = 8;
|
||||||
} else if (i >= GDB_REGNO_FPR0 && i <= GDB_REGNO_FPR31) {
|
} else if (reg->number >= GDB_REGNO_FPR0 && reg->number <= GDB_REGNO_FPR31) {
|
||||||
if (riscv_supports_extension(target, 'D')) {
|
if (riscv_supports_extension(target, 'D')) {
|
||||||
reg->size = 64;
|
reg->size = 64;
|
||||||
} else if (riscv_supports_extension(target, 'F')) {
|
} else if (riscv_supports_extension(target, 'F')) {
|
||||||
|
|
Loading…
Reference in New Issue