diff --git a/src/arch/riscv/gdb-xml/SConscript b/src/arch/riscv/gdb-xml/SConscript
index 722137408b..bafea174d2 100644
--- a/src/arch/riscv/gdb-xml/SConscript
+++ b/src/arch/riscv/gdb-xml/SConscript
@@ -43,6 +43,10 @@
Import('*')
+GdbXml('riscv-32bit.xml', 'gdb_xml_riscv_32bit_target', tags='riscv isa')
+GdbXml('riscv-32bit-cpu.xml', 'gdb_xml_riscv_32bit_cpu', tags='riscv isa')
+GdbXml('riscv-32bit-fpu.xml', 'gdb_xml_riscv_32bit_fpu', tags='riscv isa')
+GdbXml('riscv-32bit-csr.xml', 'gdb_xml_riscv_32bit_csr', tags='riscv isa')
GdbXml('riscv-64bit.xml', 'gdb_xml_riscv_64bit_target', tags='riscv isa')
GdbXml('riscv-64bit-cpu.xml', 'gdb_xml_riscv_64bit_cpu', tags='riscv isa')
GdbXml('riscv-64bit-fpu.xml', 'gdb_xml_riscv_64bit_fpu', tags='riscv isa')
diff --git a/src/arch/riscv/gdb-xml/riscv-32bit-cpu.xml b/src/arch/riscv/gdb-xml/riscv-32bit-cpu.xml
new file mode 100644
index 0000000000..c48f770ded
--- /dev/null
+++ b/src/arch/riscv/gdb-xml/riscv-32bit-cpu.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arch/riscv/gdb-xml/riscv-32bit-csr.xml b/src/arch/riscv/gdb-xml/riscv-32bit-csr.xml
new file mode 100644
index 0000000000..7cf7bc05b4
--- /dev/null
+++ b/src/arch/riscv/gdb-xml/riscv-32bit-csr.xml
@@ -0,0 +1,249 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arch/riscv/gdb-xml/riscv-32bit-fpu.xml b/src/arch/riscv/gdb-xml/riscv-32bit-fpu.xml
new file mode 100644
index 0000000000..9661b0e004
--- /dev/null
+++ b/src/arch/riscv/gdb-xml/riscv-32bit-fpu.xml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/arch/riscv/gdb-xml/riscv-32bit.xml b/src/arch/riscv/gdb-xml/riscv-32bit.xml
new file mode 100644
index 0000000000..982e6b0674
--- /dev/null
+++ b/src/arch/riscv/gdb-xml/riscv-32bit.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ riscv
+
+
+
+
diff --git a/src/arch/riscv/remote_gdb.cc b/src/arch/riscv/remote_gdb.cc
index 4bdd88fde6..54ecde061f 100644
--- a/src/arch/riscv/remote_gdb.cc
+++ b/src/arch/riscv/remote_gdb.cc
@@ -135,6 +135,10 @@
#include
+#include "arch/riscv/gdb-xml/gdb_xml_riscv_32bit_cpu.hh"
+#include "arch/riscv/gdb-xml/gdb_xml_riscv_32bit_csr.hh"
+#include "arch/riscv/gdb-xml/gdb_xml_riscv_32bit_fpu.hh"
+#include "arch/riscv/gdb-xml/gdb_xml_riscv_32bit_target.hh"
#include "arch/riscv/gdb-xml/gdb_xml_riscv_64bit_cpu.hh"
#include "arch/riscv/gdb-xml/gdb_xml_riscv_64bit_csr.hh"
#include "arch/riscv/gdb-xml/gdb_xml_riscv_64bit_fpu.hh"
@@ -163,8 +167,31 @@ getRvType(ThreadContext* tc)
return isa->rvType();
}
+template
+static void
+setRegNoEffectWithMask(
+ ThreadContext *context, RiscvType type, CSRIndex idx, xint val)
+{
+ RegVal oldVal, newVal;
+ RegVal mask = CSRMasks[type].at(idx);
+ oldVal = context->readMiscRegNoEffect(CSRData.at(idx).physIndex);
+ newVal = (oldVal & ~mask) | (val & mask);
+ context->setMiscRegNoEffect(CSRData.at(idx).physIndex, newVal);
+}
+
+template
+static void
+setRegWithMask(ThreadContext *context, RiscvType type, CSRIndex idx, xint val)
+{
+ RegVal oldVal, newVal;
+ RegVal mask = CSRMasks[type].at(idx);
+ oldVal = context->readMiscReg(CSRData.at(idx).physIndex);
+ newVal = (oldVal & ~mask) | (val & mask);
+ context->setMiscReg(CSRData.at(idx).physIndex, newVal);
+}
+
RemoteGDB::RemoteGDB(System *_system, int _port)
- : BaseRemoteGDB(_system, _port), regCache64(this)
+ : BaseRemoteGDB(_system, _port), regCache32(this), regCache64(this)
{
}
@@ -193,6 +220,201 @@ RemoteGDB::acc(Addr va, size_t len)
return context()->getProcessPtr()->pTable->lookup(va) != nullptr;
}
+void
+RemoteGDB::Riscv32GdbRegCache::getRegs(ThreadContext *context)
+{
+ DPRINTF(GDBAcc, "getregs in remotegdb, size %lu\n", size());
+ auto& RVxCSRMasks = CSRMasks[RV32];
+
+ // General registers
+ for (int i = 0; i < int_reg::NumArchRegs; i++) {
+ r.gpr[i] = context->getReg(intRegClass[i]);
+ }
+ r.pc = context->pcState().instAddr();
+
+ // Floating point registers
+ for (int i = 0; i < float_reg::NumRegs; i++)
+ r.fpu[i] = context->getReg(floatRegClass[i]);
+ r.fflags = context->readMiscRegNoEffect(
+ CSRData.at(CSR_FFLAGS).physIndex) & RVxCSRMasks.at(CSR_FFLAGS);
+ r.frm = context->readMiscRegNoEffect(
+ CSRData.at(CSR_FRM).physIndex) & RVxCSRMasks.at(CSR_FRM);
+ r.fcsr = context->readMiscRegNoEffect(
+ CSRData.at(CSR_FCSR).physIndex) & RVxCSRMasks.at(CSR_FCSR);
+
+ // CSR registers
+ r.cycle = context->readMiscRegNoEffect(
+ CSRData.at(CSR_CYCLE).physIndex);
+ r.cycleh = context->readMiscRegNoEffect(
+ CSRData.at(CSR_CYCLEH).physIndex);
+ r.time = context->readMiscRegNoEffect(
+ CSRData.at(CSR_TIME).physIndex);
+ r.timeh = context->readMiscRegNoEffect(
+ CSRData.at(CSR_TIMEH).physIndex);
+
+ // U mode CSR
+ r.ustatus = context->readMiscReg(
+ CSRData.at(CSR_USTATUS).physIndex) & RVxCSRMasks.at(CSR_USTATUS);
+ r.uie = context->readMiscReg(
+ CSRData.at(CSR_UIE).physIndex) & RVxCSRMasks.at(CSR_UIE);
+ r.utvec = context->readMiscRegNoEffect(
+ CSRData.at(CSR_UTVEC).physIndex);
+ r.uscratch = context->readMiscRegNoEffect(
+ CSRData.at(CSR_USCRATCH).physIndex);
+ r.uepc = context->readMiscRegNoEffect(
+ CSRData.at(CSR_UEPC).physIndex);
+ r.ucause = context->readMiscRegNoEffect(
+ CSRData.at(CSR_UCAUSE).physIndex);
+ r.utval = context->readMiscRegNoEffect(
+ CSRData.at(CSR_UTVAL).physIndex);
+ r.uip = context->readMiscReg(
+ CSRData.at(CSR_UIP).physIndex) & RVxCSRMasks.at(CSR_UIP);
+
+ // S mode CSR
+ r.sstatus = context->readMiscReg(
+ CSRData.at(CSR_SSTATUS).physIndex) & RVxCSRMasks.at(CSR_SSTATUS);
+ r.sedeleg = context->readMiscRegNoEffect(
+ CSRData.at(CSR_SEDELEG).physIndex);
+ r.sideleg = context->readMiscRegNoEffect(
+ CSRData.at(CSR_SIDELEG).physIndex);
+ r.sie = context->readMiscReg(
+ CSRData.at(CSR_SIE).physIndex) & RVxCSRMasks.at(CSR_SIE);
+ r.stvec = context->readMiscRegNoEffect(
+ CSRData.at(CSR_STVEC).physIndex);
+ r.scounteren = context->readMiscRegNoEffect(
+ CSRData.at(CSR_SCOUNTEREN).physIndex);
+ r.sscratch = context->readMiscRegNoEffect(
+ CSRData.at(CSR_SSCRATCH).physIndex);
+ r.sepc = context->readMiscReg(
+ CSRData.at(CSR_SEPC).physIndex);
+ r.scause = context->readMiscRegNoEffect(
+ CSRData.at(CSR_SCAUSE).physIndex);
+ r.stval = context->readMiscRegNoEffect(
+ CSRData.at(CSR_STVAL).physIndex);
+ r.sip = context->readMiscReg(
+ CSRData.at(CSR_SIP).physIndex) & RVxCSRMasks.at(CSR_SIP);
+ r.satp = context->readMiscRegNoEffect(
+ CSRData.at(CSR_SATP).physIndex);
+
+ // M mode CSR
+ r.mvendorid = context->readMiscRegNoEffect(
+ CSRData.at(CSR_MVENDORID).physIndex);
+ r.marchid = context->readMiscRegNoEffect(
+ CSRData.at(CSR_MARCHID).physIndex);
+ r.mimpid = context->readMiscRegNoEffect(
+ CSRData.at(CSR_MIMPID).physIndex);
+ r.mhartid = context->contextId();
+ r.mstatus = context->readMiscReg(
+ CSRData.at(CSR_MSTATUS).physIndex) & RVxCSRMasks.at(CSR_MSTATUS);
+ r.misa = context->readMiscRegNoEffect(
+ CSRData.at(CSR_MISA).physIndex) & RVxCSRMasks.at(CSR_MISA);
+ r.medeleg = context->readMiscRegNoEffect(
+ CSRData.at(CSR_MEDELEG).physIndex);
+ r.mideleg = context->readMiscRegNoEffect(
+ CSRData.at(CSR_MIDELEG).physIndex);
+ r.mie = context->readMiscReg(
+ CSRData.at(CSR_MIE).physIndex) & RVxCSRMasks.at(CSR_MIE);
+ r.mtvec = context->readMiscRegNoEffect(
+ CSRData.at(CSR_MTVEC).physIndex);
+ r.mcounteren = context->readMiscRegNoEffect(
+ CSRData.at(CSR_MCOUNTEREN).physIndex);
+ r.mstatush = context->readMiscReg(
+ CSRData.at(CSR_MSTATUSH).physIndex) & RVxCSRMasks.at(CSR_MSTATUSH);
+ r.mscratch = context->readMiscRegNoEffect(
+ CSRData.at(CSR_MSCRATCH).physIndex);
+ r.mepc = context->readMiscReg(
+ CSRData.at(CSR_MEPC).physIndex);
+ r.mcause = context->readMiscRegNoEffect(
+ CSRData.at(CSR_MCAUSE).physIndex);
+ r.mtval = context->readMiscRegNoEffect(
+ CSRData.at(CSR_MTVAL).physIndex);
+ r.mip = context->readMiscReg(
+ CSRData.at(CSR_MIP).physIndex) & RVxCSRMasks.at(CSR_MIP);
+
+ // H mode CSR (to be implemented)
+}
+
+void
+RemoteGDB::Riscv32GdbRegCache::setRegs(ThreadContext *context) const
+{
+ DPRINTF(GDBAcc, "setregs in remotegdb \n");
+ for (int i = 0; i < int_reg::NumArchRegs; i++)
+ context->setReg(intRegClass[i], r.gpr[i]);
+ context->pcState(r.pc);
+
+ // Floating point registers
+ for (int i = 0; i < float_reg::NumRegs; i++)
+ context->setReg(floatRegClass[i], r.fpu[i]);
+
+ setRegNoEffectWithMask(context, RV32, CSR_FFLAGS, r.fflags);
+ setRegNoEffectWithMask(context, RV32, CSR_FRM, r.frm);
+ setRegNoEffectWithMask(context, RV32, CSR_FCSR, r.fcsr);
+
+ // TODO: implement CSR counter registers for mcycle(h), minstret(h)
+
+ // U mode CSR
+ setRegNoEffectWithMask(context, RV32, CSR_USTATUS, r.ustatus);
+ setRegWithMask(context, RV32, CSR_UIE, r.uie);
+ setRegWithMask(context, RV32, CSR_UIP, r.uip);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_UTVEC).physIndex, r.utvec);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_USCRATCH).physIndex, r.uscratch);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_UEPC).physIndex, r.uepc);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_UCAUSE).physIndex, r.ucause);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_UTVAL).physIndex, r.utval);
+
+ // S mode CSR
+ setRegNoEffectWithMask(context, RV32, CSR_SSTATUS, r.sstatus);
+ setRegWithMask(context, RV32, CSR_SIE, r.sie);
+ setRegWithMask(context, RV32, CSR_SIP, r.sip);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_SEDELEG).physIndex, r.sedeleg);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_SIDELEG).physIndex, r.sideleg);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_STVEC).physIndex, r.stvec);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_SCOUNTEREN).physIndex, r.scounteren);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_SSCRATCH).physIndex, r.sscratch);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_SEPC).physIndex, r.sepc);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_SCAUSE).physIndex, r.scause);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_STVAL).physIndex, r.stval);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_SATP).physIndex, r.satp);
+
+ // M mode CSR
+ setRegNoEffectWithMask(context, RV32, CSR_MSTATUS, r.mstatus);
+ setRegNoEffectWithMask(context, RV32, CSR_MISA, r.misa);
+ setRegWithMask(context, RV32, CSR_MIE, r.mie);
+ setRegWithMask(context, RV32, CSR_MIP, r.mip);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_MEDELEG).physIndex, r.medeleg);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_MIDELEG).physIndex, r.mideleg);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_MTVEC).physIndex, r.mtvec);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_MCOUNTEREN).physIndex, r.mcounteren);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_MSCRATCH).physIndex, r.mscratch);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_MEPC).physIndex, r.mepc);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_MCAUSE).physIndex, r.mcause);
+ context->setMiscRegNoEffect(
+ CSRData.at(CSR_MTVAL).physIndex, r.mtval);
+
+ // H mode CSR (to be implemented)
+}
+
void
RemoteGDB::Riscv64GdbRegCache::getRegs(ThreadContext *context)
{
@@ -222,7 +444,7 @@ RemoteGDB::Riscv64GdbRegCache::getRegs(ThreadContext *context)
CSRData.at(CSR_TIME).physIndex);
// U mode CSR
- r.ustatus = context->readMiscRegNoEffect(
+ r.ustatus = context->readMiscReg(
CSRData.at(CSR_USTATUS).physIndex) & RVxCSRMasks.at(CSR_USTATUS);
r.uie = context->readMiscReg(
CSRData.at(CSR_UIE).physIndex) & RVxCSRMasks.at(CSR_UIE);
@@ -240,7 +462,7 @@ RemoteGDB::Riscv64GdbRegCache::getRegs(ThreadContext *context)
CSRData.at(CSR_UIP).physIndex) & RVxCSRMasks.at(CSR_UIP);
// S mode CSR
- r.sstatus = context->readMiscRegNoEffect(
+ r.sstatus = context->readMiscReg(
CSRData.at(CSR_SSTATUS).physIndex) & RVxCSRMasks.at(CSR_SSTATUS);
r.sedeleg = context->readMiscRegNoEffect(
CSRData.at(CSR_SEDELEG).physIndex);
@@ -254,7 +476,7 @@ RemoteGDB::Riscv64GdbRegCache::getRegs(ThreadContext *context)
CSRData.at(CSR_SCOUNTEREN).physIndex);
r.sscratch = context->readMiscRegNoEffect(
CSRData.at(CSR_SSCRATCH).physIndex);
- r.sepc = context->readMiscRegNoEffect(
+ r.sepc = context->readMiscReg(
CSRData.at(CSR_SEPC).physIndex);
r.scause = context->readMiscRegNoEffect(
CSRData.at(CSR_SCAUSE).physIndex);
@@ -272,9 +494,8 @@ RemoteGDB::Riscv64GdbRegCache::getRegs(ThreadContext *context)
CSRData.at(CSR_MARCHID).physIndex);
r.mimpid = context->readMiscRegNoEffect(
CSRData.at(CSR_MIMPID).physIndex);
- r.mhartid = context->readMiscRegNoEffect(
- CSRData.at(CSR_MHARTID).physIndex);
- r.mstatus = context->readMiscRegNoEffect(
+ r.mhartid = context->contextId();
+ r.mstatus = context->readMiscReg(
CSRData.at(CSR_MSTATUS).physIndex) & RVxCSRMasks.at(CSR_MSTATUS);
r.misa = context->readMiscRegNoEffect(
CSRData.at(CSR_MISA).physIndex) & RVxCSRMasks.at(CSR_MISA);
@@ -290,7 +511,7 @@ RemoteGDB::Riscv64GdbRegCache::getRegs(ThreadContext *context)
CSRData.at(CSR_MCOUNTEREN).physIndex);
r.mscratch = context->readMiscRegNoEffect(
CSRData.at(CSR_MSCRATCH).physIndex);
- r.mepc = context->readMiscRegNoEffect(
+ r.mepc = context->readMiscReg(
CSRData.at(CSR_MEPC).physIndex);
r.mcause = context->readMiscRegNoEffect(
CSRData.at(CSR_MCAUSE).physIndex);
@@ -305,11 +526,6 @@ RemoteGDB::Riscv64GdbRegCache::getRegs(ThreadContext *context)
void
RemoteGDB::Riscv64GdbRegCache::setRegs(ThreadContext *context) const
{
- // NOTE: no error will be reported for attempting to set masked bits.
- RegVal oldVal;
- int mask;
- RegVal newVal;
-
DPRINTF(GDBAcc, "setregs in remotegdb \n");
for (int i = 0; i < int_reg::NumArchRegs; i++)
context->setReg(intRegClass[i], r.gpr[i]);
@@ -319,48 +535,16 @@ RemoteGDB::Riscv64GdbRegCache::setRegs(ThreadContext *context) const
for (int i = 0; i < float_reg::NumRegs; i++)
context->setReg(floatRegClass[i], r.fpu[i]);
- auto& RVxCSRMasks = CSRMasks[RV64];
+ setRegNoEffectWithMask(context, RV64, CSR_FFLAGS, r.fflags);
+ setRegNoEffectWithMask(context, RV64, CSR_FRM, r.frm);
+ setRegNoEffectWithMask(context, RV64, CSR_FCSR, r.fcsr);
- oldVal = context->readMiscRegNoEffect(
- CSRData.at(CSR_FFLAGS).physIndex);
- mask = RVxCSRMasks.at(CSR_FFLAGS);
- newVal = (oldVal & ~mask) | (r.fflags & mask);
- context->setMiscRegNoEffect(
- CSRData.at(CSR_FFLAGS).physIndex, newVal);
-
- oldVal = context->readMiscRegNoEffect(
- CSRData.at(CSR_FRM).physIndex);
- mask = RVxCSRMasks.at(CSR_FRM);
- newVal = (oldVal & ~mask) | (r.frm & mask);
- context->setMiscRegNoEffect(
- CSRData.at(CSR_FRM).physIndex, newVal);
-
- oldVal = context->readMiscRegNoEffect(
- CSRData.at(CSR_FCSR).physIndex);
- mask = RVxCSRMasks.at(CSR_FCSR);
- newVal = (oldVal & ~mask) | (r.fcsr & mask);
- context->setMiscRegNoEffect(
- CSRData.at(CSR_FCSR).physIndex, newVal);
-
- // CSR registers
- context->setMiscRegNoEffect(
- CSRData.at(CSR_CYCLE).physIndex, r.cycle);
- context->setMiscRegNoEffect(
- CSRData.at(CSR_TIME).physIndex, r.time);
+ // TODO: implement CSR counter registers for mcycle, minstret
// U mode CSR
- oldVal = context->readMiscRegNoEffect(
- CSRData.at(CSR_USTATUS).physIndex);
- mask = RVxCSRMasks.at(CSR_USTATUS);
- newVal = (oldVal & ~mask) | (r.ustatus & mask);
- context->setMiscRegNoEffect(
- CSRData.at(CSR_USTATUS).physIndex, newVal);
- oldVal = context->readMiscReg(
- CSRData.at(CSR_UIE).physIndex);
- mask = RVxCSRMasks.at(CSR_UIE);
- newVal = (oldVal & ~mask) | (r.uie & mask);
- context->setMiscReg(
- CSRData.at(CSR_UIE).physIndex, newVal);
+ setRegNoEffectWithMask(context, RV64, CSR_USTATUS, r.ustatus);
+ setRegWithMask(context, RV64, CSR_UIE, r.uie);
+ setRegWithMask(context, RV64, CSR_UIP, r.uip);
context->setMiscRegNoEffect(
CSRData.at(CSR_UTVEC).physIndex, r.utvec);
context->setMiscRegNoEffect(
@@ -371,30 +555,15 @@ RemoteGDB::Riscv64GdbRegCache::setRegs(ThreadContext *context) const
CSRData.at(CSR_UCAUSE).physIndex, r.ucause);
context->setMiscRegNoEffect(
CSRData.at(CSR_UTVAL).physIndex, r.utval);
- oldVal = context->readMiscReg(
- CSRData.at(CSR_UIP).physIndex);
- mask = RVxCSRMasks.at(CSR_UIP);
- newVal = (oldVal & ~mask) | (r.uip & mask);
- context->setMiscReg(
- CSRData.at(CSR_UIP).physIndex, newVal);
// S mode CSR
- oldVal = context->readMiscRegNoEffect(
- CSRData.at(CSR_SSTATUS).physIndex);
- mask = RVxCSRMasks.at(CSR_SSTATUS);
- newVal = (oldVal & ~mask) | (r.sstatus & mask);
- context->setMiscRegNoEffect(
- CSRData.at(CSR_SSTATUS).physIndex, newVal);
+ setRegNoEffectWithMask(context, RV64, CSR_SSTATUS, r.sstatus);
+ setRegWithMask(context, RV64, CSR_SIE, r.sie);
+ setRegWithMask(context, RV64, CSR_SIP, r.sip);
context->setMiscRegNoEffect(
CSRData.at(CSR_SEDELEG).physIndex, r.sedeleg);
context->setMiscRegNoEffect(
CSRData.at(CSR_SIDELEG).physIndex, r.sideleg);
- oldVal = context->readMiscReg(
- CSRData.at(CSR_SIE).physIndex);
- mask = RVxCSRMasks.at(CSR_SIE);
- newVal = (oldVal & ~mask) | (r.sie & mask);
- context->setMiscReg(
- CSRData.at(CSR_SIE).physIndex, newVal);
context->setMiscRegNoEffect(
CSRData.at(CSR_STVEC).physIndex, r.stvec);
context->setMiscRegNoEffect(
@@ -407,46 +576,18 @@ RemoteGDB::Riscv64GdbRegCache::setRegs(ThreadContext *context) const
CSRData.at(CSR_SCAUSE).physIndex, r.scause);
context->setMiscRegNoEffect(
CSRData.at(CSR_STVAL).physIndex, r.stval);
- oldVal = context->readMiscReg(
- CSRData.at(CSR_SIP).physIndex);
- mask = RVxCSRMasks.at(CSR_SIP);
- newVal = (oldVal & ~mask) | (r.sip & mask);
- context->setMiscReg(
- CSRData.at(CSR_SIP).physIndex, newVal);
context->setMiscRegNoEffect(
CSRData.at(CSR_SATP).physIndex, r.satp);
// M mode CSR
- context->setMiscRegNoEffect(
- CSRData.at(CSR_MVENDORID).physIndex, r.mvendorid);
- context->setMiscRegNoEffect(
- CSRData.at(CSR_MARCHID).physIndex, r.marchid);
- context->setMiscRegNoEffect(
- CSRData.at(CSR_MIMPID).physIndex, r.mimpid);
- context->setMiscRegNoEffect(
- CSRData.at(CSR_MHARTID).physIndex, r.mhartid);
- oldVal = context->readMiscRegNoEffect(
- CSRData.at(CSR_MSTATUS).physIndex);
- mask = RVxCSRMasks.at(CSR_MSTATUS);
- newVal = (oldVal & ~mask) | (r.mstatus & mask);
- context->setMiscRegNoEffect(
- CSRData.at(CSR_MSTATUS).physIndex, newVal);
- oldVal = context->readMiscRegNoEffect(
- CSRData.at(CSR_MISA).physIndex);
- mask = RVxCSRMasks.at(CSR_MISA);
- newVal = (oldVal & ~mask) | (r.misa & mask);
- context->setMiscRegNoEffect(
- CSRData.at(CSR_MISA).physIndex, newVal);
+ setRegNoEffectWithMask(context, RV64, CSR_MSTATUS, r.mstatus);
+ setRegNoEffectWithMask(context, RV64, CSR_MISA, r.misa);
+ setRegWithMask(context, RV64, CSR_MIE, r.mie);
+ setRegWithMask(context, RV64, CSR_MIP, r.mip);
context->setMiscRegNoEffect(
CSRData.at(CSR_MEDELEG).physIndex, r.medeleg);
context->setMiscRegNoEffect(
CSRData.at(CSR_MIDELEG).physIndex, r.mideleg);
- oldVal = context->readMiscReg(
- CSRData.at(CSR_MIE).physIndex);
- mask = RVxCSRMasks.at(CSR_MIE);
- newVal = (oldVal & ~mask) | (r.mie & mask);
- context->setMiscReg(
- CSRData.at(CSR_MIE).physIndex, newVal);
context->setMiscRegNoEffect(
CSRData.at(CSR_MTVEC).physIndex, r.mtvec);
context->setMiscRegNoEffect(
@@ -459,12 +600,6 @@ RemoteGDB::Riscv64GdbRegCache::setRegs(ThreadContext *context) const
CSRData.at(CSR_MCAUSE).physIndex, r.mcause);
context->setMiscRegNoEffect(
CSRData.at(CSR_MTVAL).physIndex, r.mtval);
- oldVal = context->readMiscReg(
- CSRData.at(CSR_MIP).physIndex);
- mask = RVxCSRMasks.at(CSR_MIP);
- newVal = (oldVal & ~mask) | (r.mip & mask);
- context->setMiscReg(
- CSRData.at(CSR_MIP).physIndex, newVal);
// H mode CSR (to be implemented)
}
@@ -483,14 +618,17 @@ RemoteGDB::getXferFeaturesRead(const std::string &annex, std::string &output)
x, std::string(reinterpret_cast(Blobs::s), \
Blobs::s##_len) \
}
- static const std::map annexMap{
- GDB_XML("riscv-64bit.xml", gdb_xml_riscv_64bit_target),
- GDB_XML("riscv-64bit-cpu.xml", gdb_xml_riscv_64bit_cpu),
- GDB_XML("riscv-64bit-fpu.xml", gdb_xml_riscv_64bit_fpu),
- GDB_XML("riscv-64bit-csr.xml", gdb_xml_riscv_64bit_csr)};
-#undef GDB_XML
- if (getRvType(context()) == RV32)
- return false;
+ static const std::map annexMaps[enums::Num_RiscvType] = {
+ [RV32] = {GDB_XML("target.xml", gdb_xml_riscv_32bit_target),
+ GDB_XML("riscv-32bit-cpu.xml", gdb_xml_riscv_32bit_cpu),
+ GDB_XML("riscv-32bit-fpu.xml", gdb_xml_riscv_32bit_fpu),
+ GDB_XML("riscv-32bit-csr.xml", gdb_xml_riscv_32bit_csr)},
+ [RV64] = {GDB_XML("target.xml", gdb_xml_riscv_64bit_target),
+ GDB_XML("riscv-64bit-cpu.xml", gdb_xml_riscv_64bit_cpu),
+ GDB_XML("riscv-64bit-fpu.xml", gdb_xml_riscv_64bit_fpu),
+ GDB_XML("riscv-64bit-csr.xml", gdb_xml_riscv_64bit_csr)},
+ };
+ auto& annexMap = annexMaps[getRvType(context())];
auto it = annexMap.find(annex);
if (it == annexMap.end())
return false;
@@ -501,7 +639,11 @@ RemoteGDB::getXferFeaturesRead(const std::string &annex, std::string &output)
BaseGdbRegCache *
RemoteGDB::gdbRegs()
{
- return ®Cache64;
+ BaseGdbRegCache* regs[enums::Num_RiscvType] = {
+ [RV32] = ®Cache32,
+ [RV64] = ®Cache64,
+ };
+ return regs[getRvType(context())];
}
} // namespace gem5
diff --git a/src/arch/riscv/remote_gdb.hh b/src/arch/riscv/remote_gdb.hh
index a8262a6a2a..8f8abb0587 100644
--- a/src/arch/riscv/remote_gdb.hh
+++ b/src/arch/riscv/remote_gdb.hh
@@ -58,6 +58,92 @@ class RemoteGDB : public BaseRemoteGDB
// A breakpoint will be 2 bytes if it is compressed and 4 if not
bool checkBpKind(size_t kind) override { return kind == 2 || kind == 4; }
+ class Riscv32GdbRegCache : public BaseGdbRegCache
+ {
+ using BaseGdbRegCache::BaseGdbRegCache;
+ private:
+ /**
+ * RISC-V Register Cache
+ * Order and sizes of registers found in ext/gdb-xml/riscv.xml
+ * To add support for more CSRs:
+ * 1. Uncomment relevant lines in ext/gdb-xml/riscv-32bit-csr.xml
+ * 2. Add register to struct below
+ * 3. Modify RiscvGdbRegCache::getRegs and setRegs
+ */
+ struct GEM5_PACKED
+ {
+ uint32_t gpr[int_reg::NumArchRegs];
+ uint32_t pc;
+ uint64_t fpu[float_reg::NumRegs];
+ uint32_t fflags;
+ uint32_t frm;
+ uint32_t fcsr;
+ // Placeholder for byte alignment
+ uint32_t placeholder;
+ uint32_t cycle;
+ uint32_t time;
+ uint32_t cycleh;
+ uint32_t timeh;
+ uint32_t ustatus;
+ uint32_t uie;
+ uint32_t utvec;
+ uint32_t uscratch;
+ uint32_t uepc;
+ uint32_t ucause;
+ uint32_t utval;
+ uint32_t uip;
+ uint32_t sstatus;
+ uint32_t sedeleg;
+ uint32_t sideleg;
+ uint32_t sie;
+ uint32_t stvec;
+ uint32_t scounteren;
+ uint32_t sscratch;
+ uint32_t sepc;
+ uint32_t scause;
+ uint32_t stval;
+ uint32_t sip;
+ uint32_t satp;
+ uint32_t mvendorid;
+ uint32_t marchid;
+ uint32_t mimpid;
+ uint32_t mhartid;
+ uint32_t mstatus;
+ uint32_t misa;
+ uint32_t medeleg;
+ uint32_t mideleg;
+ uint32_t mie;
+ uint32_t mtvec;
+ uint32_t mcounteren;
+ uint32_t mstatush;
+ uint32_t mscratch;
+ uint32_t mepc;
+ uint32_t mcause;
+ uint32_t mtval;
+ uint32_t mip;
+ uint32_t hstatus;
+ uint32_t hedeleg;
+ uint32_t hideleg;
+ uint32_t hie;
+ uint32_t htvec;
+ uint32_t hscratch;
+ uint32_t hepc;
+ uint32_t hcause;
+ uint32_t hbadaddr;
+ uint32_t hip;
+ } r;
+ public:
+ char *data() const { return (char *)&r; }
+ size_t size() const { return sizeof(r); }
+ void getRegs(ThreadContext*);
+ void setRegs(ThreadContext*) const;
+
+ const std::string
+ name() const
+ {
+ return gdb->name() + ".RiscvGdbRegCache";
+ }
+ };
class Riscv64GdbRegCache : public BaseGdbRegCache
{
using BaseGdbRegCache::BaseGdbRegCache;
@@ -70,7 +156,7 @@ class RemoteGDB : public BaseRemoteGDB
* 2. Add register to struct below
* 3. Modify RiscvGdbRegCache::getRegs and setRegs
*/
- struct
+ struct GEM5_PACKED
{
uint64_t gpr[int_reg::NumArchRegs];
uint64_t pc;
@@ -142,6 +228,7 @@ class RemoteGDB : public BaseRemoteGDB
}
};
+ Riscv32GdbRegCache regCache32;
Riscv64GdbRegCache regCache64;
public: