target/riscv: Use vlenb to check whether vector registers exist (#762)

E.g. the Zve* vector extensions have all the same registers as the full
V extension, but leaves misa.V clear.

Change-Id: Ib08c3612c52bb3a6b074d9431e3396c8f2f0ff27
Signed-off-by: Tim Newsome <tim@sifive.com>

Signed-off-by: Tim Newsome <tim@sifive.com>
This commit is contained in:
Tim Newsome 2022-11-10 10:27:46 -08:00 committed by GitHub
parent 88a629c017
commit f59bb72fde
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 13 additions and 24 deletions

View File

@ -1539,24 +1539,6 @@ static int set_group(struct target *target, bool *supported, unsigned group, gro
return ERROR_OK;
}
static int discover_vlenb(struct target *target)
{
RISCV_INFO(r);
riscv_reg_t vlenb;
if (register_read_direct(target, &vlenb, GDB_REGNO_VLENB) != ERROR_OK) {
LOG_WARNING("Couldn't read vlenb for %s; vector register access won't work.",
target_name(target));
r->vlenb = 0;
return ERROR_OK;
}
r->vlenb = vlenb;
LOG_INFO("Vector support with vlenb=%d", r->vlenb);
return ERROR_OK;
}
static int examine(struct target *target)
{
/* Don't need to select dbus, since the first thing we do is read dtmcontrol. */
@ -1755,9 +1737,14 @@ static int examine(struct target *target)
return ERROR_FAIL;
}
if (riscv_supports_extension(target, 'V')) {
if (discover_vlenb(target) != ERROR_OK)
return ERROR_FAIL;
uint64_t vlenb;
if (register_read_direct(target, &vlenb, GDB_REGNO_VLENB) != ERROR_OK) {
if (riscv_supports_extension(target, 'V'))
LOG_TARGET_WARNING(target, "Couldn't read vlenb; vector register access won't work.");
r->vlenb = 0;
} else {
LOG_TARGET_INFO(target, "Vector support with vlenb=%d", r->vlenb);
r->vlenb = vlenb;
}
/* Now init registers based on what we discovered. */

View File

@ -4875,7 +4875,7 @@ int riscv_init_registers(struct target *target)
case CSR_VL:
case CSR_VTYPE:
case CSR_VLENB:
r->exist = riscv_supports_extension(target, 'V');
r->exist = (info->vlenb > 0);
break;
}
@ -4904,7 +4904,7 @@ int riscv_init_registers(struct target *target)
} else if (number >= GDB_REGNO_V0 && number <= GDB_REGNO_V31) {
r->caller_save = false;
r->exist = riscv_supports_extension(target, 'V') && info->vlenb;
r->exist = (info->vlenb > 0);
r->size = info->vlenb * 8;
sprintf(reg_name, "v%d", number - GDB_REGNO_V0);
r->group = "vector";

View File

@ -113,7 +113,9 @@ typedef struct {
/* It's possible that each core has a different supported ISA set. */
int xlen;
riscv_reg_t misa;
/* Cached value of vlenb. 0 if vlenb is not readable for some reason. */
/* Cached value of vlenb. 0 indicates there is no vector support.
* Note that you can have vector support without misa.V set, because
* Zve* extensions implement vector registers without setting misa.V. */
unsigned int vlenb;
/* The number of triggers per hart. */