From ad107116a1d01aca2535e4c2f191278249177083 Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Mon, 28 Nov 2022 08:28:12 +0000 Subject: [PATCH] arch-riscv: Support RV32 to remote gdb support rv32 cpu, fpu, csr registers to remote gdb. Change-Id: Ib821a35ff2e95f6f47569b1f4cb35cd98fcca77d Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/66131 Tested-by: kokoro Maintainer: Gabe Black Reviewed-by: Gabe Black Reviewed-by: Jason Lowe-Power --- src/arch/riscv/gdb-xml/SConscript | 4 + src/arch/riscv/gdb-xml/riscv-32bit-cpu.xml | 48 +++ src/arch/riscv/gdb-xml/riscv-32bit-csr.xml | 249 ++++++++++++++ src/arch/riscv/gdb-xml/riscv-32bit-fpu.xml | 58 ++++ src/arch/riscv/gdb-xml/riscv-32bit.xml | 13 + src/arch/riscv/remote_gdb.cc | 376 ++++++++++++++------- src/arch/riscv/remote_gdb.hh | 89 ++++- 7 files changed, 719 insertions(+), 118 deletions(-) create mode 100644 src/arch/riscv/gdb-xml/riscv-32bit-cpu.xml create mode 100644 src/arch/riscv/gdb-xml/riscv-32bit-csr.xml create mode 100644 src/arch/riscv/gdb-xml/riscv-32bit-fpu.xml create mode 100644 src/arch/riscv/gdb-xml/riscv-32bit.xml 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: