aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2023-03-16 15:37:06 -0700
committerTim Newsome <tim@sifive.com>2023-03-16 15:37:06 -0700
commit2c760b6317741e98c71ac48f0a53028a4b9be9ab (patch)
treed4f4a34540fb3c9e08ef436dd4a325a731de0277 /src
parenteb8cabf821c31305ae06b2135306f1cfa483c69e (diff)
downloadriscv-openocd-2c760b6317741e98c71ac48f0a53028a4b9be9ab.zip
riscv-openocd-2c760b6317741e98c71ac48f0a53028a4b9be9ab.tar.gz
riscv-openocd-2c760b6317741e98c71ac48f0a53028a4b9be9ab.tar.bz2
Expose S?aia CSRs if they're on the target.
Untested, because I don't have a target that implements this. Change-Id: Iff82c124e7caf8e8960a9da62d8e727afb2c6b8a Signed-off-by: Tim Newsome <tim@sifive.com>
Diffstat (limited to 'src')
-rw-r--r--src/target/riscv/gdb_regs.h2
-rw-r--r--src/target/riscv/riscv-013.c20
-rw-r--r--src/target/riscv/riscv.c66
-rw-r--r--src/target/riscv/riscv.h3
4 files changed, 88 insertions, 3 deletions
diff --git a/src/target/riscv/gdb_regs.h b/src/target/riscv/gdb_regs.h
index 3a46577..08926b5 100644
--- a/src/target/riscv/gdb_regs.h
+++ b/src/target/riscv/gdb_regs.h
@@ -98,6 +98,8 @@ enum gdb_regno {
GDB_REGNO_MEPC = CSR_MEPC + GDB_REGNO_CSR0,
GDB_REGNO_MCAUSE = CSR_MCAUSE + GDB_REGNO_CSR0,
GDB_REGNO_SATP = CSR_SATP + GDB_REGNO_CSR0,
+ GDB_REGNO_MTOPI = CSR_MTOPI + GDB_REGNO_CSR0,
+ GDB_REGNO_MTOPEI = CSR_MTOPEI + GDB_REGNO_CSR0,
GDB_REGNO_CSR4095 = GDB_REGNO_CSR0 + 4095,
GDB_REGNO_PRIV = 4161,
/* It's still undecided what register numbers GDB will actually use for
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c
index 3043b06..e15384a 100644
--- a/src/target/riscv/riscv-013.c
+++ b/src/target/riscv/riscv-013.c
@@ -1725,16 +1725,30 @@ static int examine(struct target *target)
return ERROR_FAIL;
}
- uint64_t vlenb;
- if (register_read_direct(target, &vlenb, GDB_REGNO_VLENB) != ERROR_OK) {
+ uint64_t value;
+ if (register_read_direct(target, &value, 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 {
- r->vlenb = vlenb;
+ r->vlenb = value;
LOG_TARGET_INFO(target, "Vector support with vlenb=%d", r->vlenb);
}
+ if (register_read_direct(target, &value, GDB_REGNO_MTOPI) == ERROR_OK) {
+ r->mtopi_readable = true;
+
+ if (register_read_direct(target, &value, GDB_REGNO_MTOPEI) == ERROR_OK) {
+ LOG_TARGET_INFO(target, "S?aia detected with IMSIC");
+ r->mtopei_readable = true;
+ } else {
+ r->mtopei_readable = false;
+ LOG_TARGET_INFO(target, "S?aia detected without IMSIC");
+ }
+ } else {
+ r->mtopi_readable = false;
+ }
+
/* Now init registers based on what we discovered. */
if (riscv_init_registers(target) != ERROR_OK)
return ERROR_FAIL;
diff --git a/src/target/riscv/riscv.c b/src/target/riscv/riscv.c
index 5f6c2db..3e7daaf 100644
--- a/src/target/riscv/riscv.c
+++ b/src/target/riscv/riscv.c
@@ -5400,6 +5400,72 @@ int riscv_init_registers(struct target *target)
case CSR_MCOUNTEREN:
r->exist = riscv_supports_extension(target, 'U');
break;
+
+ /* Interrupts M-Mode CSRs. */
+ case CSR_MISELECT:
+ case CSR_MIREG:
+ case CSR_MTOPI:
+ case CSR_MVIEN:
+ case CSR_MVIP:
+ r->exist = info->mtopi_readable;
+ break;
+ case CSR_MTOPEI:
+ r->exist = info->mtopei_readable;
+ break;
+ case CSR_MIDELEGH:
+ case CSR_MVIENH:
+ case CSR_MVIPH:
+ r->exist = info->mtopi_readable &&
+ riscv_xlen(target) == 32 &&
+ riscv_supports_extension(target, 'S');
+ break;
+ case CSR_MIEH:
+ case CSR_MIPH:
+ r->exist = info->mtopi_readable;
+ break;
+ /* Interrupts S-Mode CSRs. */
+ case CSR_SISELECT:
+ case CSR_SIREG:
+ case CSR_STOPI:
+ r->exist = info->mtopi_readable &&
+ riscv_supports_extension(target, 'S');
+ break;
+ case CSR_STOPEI:
+ r->exist = info->mtopei_readable &&
+ riscv_supports_extension(target, 'S');
+ break;
+ case CSR_SIEH:
+ case CSR_SIPH:
+ r->exist = info->mtopi_readable &&
+ riscv_xlen(target) == 32 &&
+ riscv_supports_extension(target, 'S');
+ break;
+ /* Interrupts Hypervisor and VS CSRs. */
+ case CSR_HVIEN:
+ case CSR_HVICTL:
+ case CSR_HVIPRIO1:
+ case CSR_HVIPRIO2:
+ case CSR_VSISELECT:
+ case CSR_VSIREG:
+ case CSR_VSTOPI:
+ r->exist = info->mtopi_readable &&
+ riscv_supports_extension(target, 'V');
+ break;
+ case CSR_VSTOPEI:
+ r->exist = info->mtopei_readable &&
+ riscv_supports_extension(target, 'V');
+ break;
+ case CSR_HIDELEGH:
+ case CSR_HVIENH:
+ case CSR_HVIPH:
+ case CSR_HVIPRIO1H:
+ case CSR_HVIPRIO2H:
+ case CSR_VSIEH:
+ case CSR_VSIPH:
+ r->exist = info->mtopi_readable &&
+ riscv_xlen(target) == 32 &&
+ riscv_supports_extension(target, 'V');
+ break;
}
if (!r->exist && !list_empty(&info->expose_csr)) {
diff --git a/src/target/riscv/riscv.h b/src/target/riscv/riscv.h
index 6b4d577..a6a1f93 100644
--- a/src/target/riscv/riscv.h
+++ b/src/target/riscv/riscv.h
@@ -124,6 +124,9 @@ typedef struct {
* Zve* extensions implement vector registers without setting misa.V. */
unsigned int vlenb;
+ bool mtopi_readable;
+ bool mtopei_readable;
+
/* The number of triggers per hart. */
unsigned int trigger_count;