diff --git a/src/arch/riscv/RiscvCPU.py b/src/arch/riscv/RiscvCPU.py index 1c77045c67..678c3295c6 100644 --- a/src/arch/riscv/RiscvCPU.py +++ b/src/arch/riscv/RiscvCPU.py @@ -23,6 +23,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import functools + from m5.objects.BaseAtomicSimpleCPU import BaseAtomicSimpleCPU from m5.objects.BaseNonCachingSimpleCPU import BaseNonCachingSimpleCPU from m5.objects.BaseTimingSimpleCPU import BaseTimingSimpleCPU @@ -41,6 +43,13 @@ class RiscvCPU: ArchISA = RiscvISA +class Riscv32CPU: + ArchDecoder = RiscvDecoder + ArchMMU = RiscvMMU + ArchInterrupts = RiscvInterrupts + ArchISA = functools.partial(RiscvISA, riscv_type="RV32") + + class RiscvAtomicSimpleCPU(BaseAtomicSimpleCPU, RiscvCPU): mmu = RiscvMMU() @@ -59,3 +68,23 @@ class RiscvO3CPU(BaseO3CPU, RiscvCPU): class RiscvMinorCPU(BaseMinorCPU, RiscvCPU): mmu = RiscvMMU() + + +class Riscv32AtomicSimpleCPU(BaseAtomicSimpleCPU, Riscv32CPU): + mmu = RiscvMMU() + + +class Riscv32NonCachingSimpleCPU(BaseNonCachingSimpleCPU, Riscv32CPU): + mmu = RiscvMMU() + + +class Riscv32TimingSimpleCPU(BaseTimingSimpleCPU, Riscv32CPU): + mmu = RiscvMMU() + + +class Riscv32O3CPU(BaseO3CPU, Riscv32CPU): + mmu = RiscvMMU() + + +class Riscv32MinorCPU(BaseMinorCPU, Riscv32CPU): + mmu = RiscvMMU() diff --git a/src/arch/riscv/RiscvISA.py b/src/arch/riscv/RiscvISA.py index ee98a5b95d..e2381fd158 100644 --- a/src/arch/riscv/RiscvISA.py +++ b/src/arch/riscv/RiscvISA.py @@ -38,10 +38,15 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +from m5.params import Enum from m5.params import Param from m5.objects.BaseISA import BaseISA +class RiscvType(Enum): + vals = ["RV32", "RV64"] + + class RiscvISA(BaseISA): type = "RiscvISA" cxx_class = "gem5::RiscvISA::ISA" @@ -50,3 +55,4 @@ class RiscvISA(BaseISA): check_alignment = Param.Bool( False, "whether to check memory access alignment" ) + riscv_type = Param.RiscvType("RV64", "RV32 or RV64") diff --git a/src/arch/riscv/SConscript b/src/arch/riscv/SConscript index dd4e9aed17..924bba5915 100644 --- a/src/arch/riscv/SConscript +++ b/src/arch/riscv/SConscript @@ -70,7 +70,8 @@ SimObject('RiscvFsWorkload.py', sim_objects=['RiscvBareMetal', 'RiscvLinux'], tags='riscv isa') SimObject('RiscvInterrupts.py', sim_objects=['RiscvInterrupts'], tags='riscv isa') -SimObject('RiscvISA.py', sim_objects=['RiscvISA'], tags='riscv isa') +SimObject('RiscvISA.py', sim_objects=['RiscvISA'], + enums=['RiscvType'], tags='riscv isa') SimObject('RiscvMMU.py', sim_objects=['RiscvMMU'], tags='riscv isa') SimObject('RiscvSeWorkload.py', sim_objects=[ 'RiscvSEWorkload', 'RiscvEmuLinux'], tags='riscv isa') diff --git a/src/arch/riscv/decoder.cc b/src/arch/riscv/decoder.cc index a02415fae0..b816c17b21 100644 --- a/src/arch/riscv/decoder.cc +++ b/src/arch/riscv/decoder.cc @@ -111,6 +111,7 @@ Decoder::decode(PCStateBase &_next_pc) next_pc.compressed(false); } + emi.rv_type = static_cast(next_pc.rvType()); return decode(emi, next_pc.instAddr()); } diff --git a/src/arch/riscv/faults.cc b/src/arch/riscv/faults.cc index e609222b07..3469c71252 100644 --- a/src/arch/riscv/faults.cc +++ b/src/arch/riscv/faults.cc @@ -135,10 +135,9 @@ RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst) } // Set fault cause, privilege, and return PC - // Interrupt is indicated on the MSB of cause (bit 63 in RV64) uint64_t _cause = _code; if (isInterrupt()) { - _cause |= (1L << 63); + _cause |= CAUSE_INTERRUPT_MASKS[pc_state.rvType()]; } tc->setMiscReg(cause, _cause); tc->setMiscReg(epc, tc->pcState().instAddr()); @@ -177,8 +176,10 @@ Reset::invoke(ThreadContext *tc, const StaticInstPtr &inst) // Advance the PC to the implementation-defined reset vector auto workload = dynamic_cast(tc->getSystemPtr()->workload); - PCState pc(workload->getEntry()); - tc->pcState(pc); + std::unique_ptr new_pc(dynamic_cast( + tc->getIsaPtr()->newPCState(workload->getEntry()))); + panic_if(!new_pc, "Failed create new PCState from ISA pointer"); + tc->pcState(*new_pc); } void diff --git a/src/arch/riscv/gdb-xml/SConscript b/src/arch/riscv/gdb-xml/SConscript index a733b1eb0e..722137408b 100644 --- a/src/arch/riscv/gdb-xml/SConscript +++ b/src/arch/riscv/gdb-xml/SConscript @@ -43,7 +43,7 @@ Import('*') -GdbXml('riscv.xml', 'gdb_xml_riscv_target', tags='riscv isa') -GdbXml('riscv-64bit-cpu.xml', 'gdb_xml_riscv_cpu', tags='riscv isa') -GdbXml('riscv-64bit-fpu.xml', 'gdb_xml_riscv_fpu', tags='riscv isa') -GdbXml('riscv-64bit-csr.xml', 'gdb_xml_riscv_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') +GdbXml('riscv-64bit-csr.xml', 'gdb_xml_riscv_64bit_csr', tags='riscv isa') diff --git a/src/arch/riscv/gdb-xml/riscv.xml b/src/arch/riscv/gdb-xml/riscv-64bit.xml similarity index 100% rename from src/arch/riscv/gdb-xml/riscv.xml rename to src/arch/riscv/gdb-xml/riscv-64bit.xml diff --git a/src/arch/riscv/insts/standard.hh b/src/arch/riscv/insts/standard.hh index be3470fda4..5b0e8c2c22 100644 --- a/src/arch/riscv/insts/standard.hh +++ b/src/arch/riscv/insts/standard.hh @@ -66,7 +66,7 @@ class ImmOp : public RiscvStaticInst protected: I imm; - ImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) + ImmOp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : RiscvStaticInst(mnem, _machInst, __opClass), imm(0) {} }; @@ -93,7 +93,7 @@ class CSROp : public RiscvStaticInst uint64_t uimm; /// Constructor - CSROp(const char *mnem, MachInst _machInst, OpClass __opClass) + CSROp(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : RiscvStaticInst(mnem, _machInst, __opClass), csr(FUNCT12), uimm(CSRIMM) { diff --git a/src/arch/riscv/insts/unknown.hh b/src/arch/riscv/insts/unknown.hh index a271eb98b0..0c2f75e1e9 100644 --- a/src/arch/riscv/insts/unknown.hh +++ b/src/arch/riscv/insts/unknown.hh @@ -53,7 +53,7 @@ namespace RiscvISA class Unknown : public RiscvStaticInst { public: - Unknown(MachInst _machInst) + Unknown(ExtMachInst _machInst) : RiscvStaticInst("unknown", _machInst, No_OpClass) {} diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index c76bb2bdf3..c8eabd44ad 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -204,7 +204,7 @@ RegClass ccRegClass(CCRegClass, CCRegClassName, 0, debug::IntRegs); } // anonymous namespace ISA::ISA(const Params &p) : - BaseISA(p), checkAlignment(p.check_alignment) + BaseISA(p), rv_type(p.riscv_type), checkAlignment(p.check_alignment) { _regClasses.push_back(&intRegClass); _regClasses.push_back(&floatRegClass); @@ -243,12 +243,24 @@ void ISA::clear() std::fill(miscRegFile.begin(), miscRegFile.end(), 0); miscRegFile[MISCREG_PRV] = PRV_M; - miscRegFile[MISCREG_ISA] = (2ULL << MXL_OFFSET) | 0x14112D; miscRegFile[MISCREG_VENDORID] = 0; miscRegFile[MISCREG_ARCHID] = 0; miscRegFile[MISCREG_IMPID] = 0; - miscRegFile[MISCREG_STATUS] = (2ULL << UXL_OFFSET) | (2ULL << SXL_OFFSET) | - (1ULL << FS_OFFSET); + // rv_type dependent init. + switch (rv_type) { + case RV32: + miscRegFile[MISCREG_ISA] = (1ULL << MXL_OFFSETS[RV32]) | 0x14112D; + miscRegFile[MISCREG_STATUS] = (1ULL << FS_OFFSET); + break; + case RV64: + miscRegFile[MISCREG_ISA] = (2ULL << MXL_OFFSETS[RV64]) | 0x14112D; + miscRegFile[MISCREG_STATUS] = (2ULL << UXL_OFFSET) | + (2ULL << SXL_OFFSET) | + (1ULL << FS_OFFSET); + break; + default: + panic("%s: Unknown rv_type: %d", name(), (int)rv_type); + } miscRegFile[MISCREG_MCOUNTEREN] = 0x7; miscRegFile[MISCREG_SCOUNTEREN] = 0x7; // don't set it to zero; software may try to determine the supported @@ -365,8 +377,18 @@ ISA::readMiscReg(RegIndex idx) STATUS status = readMiscRegNoEffect(idx); uint64_t sd_bit = \ (status.xs == 3) || (status.fs == 3) || (status.vs == 3); - // We assume RV64 here, updating the SD bit at index 63. - status.sd = sd_bit; + // For RV32, the SD bit is at index 31 + // For RV64, the SD bit is at index 63. + switch (rv_type) { + case RV32: + status.rv32_sd = sd_bit; + break; + case RV64: + status.rv64_sd = sd_bit; + break; + default: + panic("%s: Unknown rv_type: %d", name(), (int)rv_type); + } setMiscRegNoEffect(idx, status); return readMiscRegNoEffect(idx); @@ -506,10 +528,12 @@ ISA::setMiscReg(RegIndex idx, RegVal val) break; case MISCREG_STATUS: { - // SXL and UXL are hard-wired to 64 bit - auto cur = readMiscRegNoEffect(idx); - val &= ~(STATUS_SXL_MASK | STATUS_UXL_MASK); - val |= cur & (STATUS_SXL_MASK | STATUS_UXL_MASK); + if (rv_type != RV32) { + // SXL and UXL are hard-wired to 64 bit + auto cur = readMiscRegNoEffect(idx); + val &= ~(STATUS_SXL_MASK | STATUS_UXL_MASK); + val |= cur & (STATUS_SXL_MASK | STATUS_UXL_MASK); + } setMiscRegNoEffect(idx, val); } break; diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh index 97a05814fe..e332956972 100644 --- a/src/arch/riscv/isa.hh +++ b/src/arch/riscv/isa.hh @@ -70,6 +70,7 @@ enum FPUStatus class ISA : public BaseISA { protected: + RiscvType rv_type; std::vector miscRegFile; bool checkAlignment; @@ -80,10 +81,10 @@ class ISA : public BaseISA void clear() override; - PCStateBase * + PCStateBase* newPCState(Addr new_inst_addr=0) const override { - return new PCState(new_inst_addr); + return new PCState(new_inst_addr, rv_type); } public: @@ -104,7 +105,7 @@ class ISA : public BaseISA virtual const std::unordered_map& getCSRMaskMap() const { - return CSRMasks; + return CSRMasks[rv_type]; } bool alignmentCheckEnabled() const { return checkAlignment; } @@ -125,6 +126,8 @@ class ISA : public BaseISA void handleLockedSnoop(PacketPtr pkt, Addr cacheBlockMask) override; void globalClearExclusive() override; + + RiscvType rvType() const { return rv_type; } }; } // namespace RiscvISA diff --git a/src/arch/riscv/isa/bitfields.isa b/src/arch/riscv/isa/bitfields.isa index 60636c68f8..41935c5b0f 100644 --- a/src/arch/riscv/isa/bitfields.isa +++ b/src/arch/riscv/isa/bitfields.isa @@ -32,6 +32,7 @@ // // Bitfield definitions. // +def bitfield RVTYPE rv_type; def bitfield QUADRANT <1:0>; def bitfield OPCODE <6:2>; diff --git a/src/arch/riscv/isa/formats/basic.isa b/src/arch/riscv/isa/formats/basic.isa index 6dfeea851c..6bae0a6f86 100644 --- a/src/arch/riscv/isa/formats/basic.isa +++ b/src/arch/riscv/isa/formats/basic.isa @@ -39,7 +39,7 @@ def template BasicDeclare {{ public: /// Constructor. - %(class_name)s(MachInst machInst); + %(class_name)s(ExtMachInst machInst); Fault execute(ExecContext *, trace::InstRecord *) const override; using %(base_class)s::generateDisassembly; }; @@ -47,7 +47,7 @@ def template BasicDeclare {{ // Basic instruction class constructor template. def template BasicConstructor {{ - %(class_name)s::%(class_name)s(MachInst machInst) + %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) { %(set_reg_idx_arr)s; diff --git a/src/arch/riscv/isa/formats/compressed.isa b/src/arch/riscv/isa/formats/compressed.isa index 6fe899b881..d09865803e 100644 --- a/src/arch/riscv/isa/formats/compressed.isa +++ b/src/arch/riscv/isa/formats/compressed.isa @@ -125,7 +125,7 @@ def template CBasicDeclare {{ public: /// Constructor. - %(class_name)s(MachInst machInst); + %(class_name)s(ExtMachInst machInst); Fault execute(ExecContext *, trace::InstRecord *) const override; std::string generateDisassembly( Addr pc, const loader::SymbolTable *symtab) const override; diff --git a/src/arch/riscv/isa/formats/standard.isa b/src/arch/riscv/isa/formats/standard.isa index 3cad5ed0c9..5390164f10 100644 --- a/src/arch/riscv/isa/formats/standard.isa +++ b/src/arch/riscv/isa/formats/standard.isa @@ -44,7 +44,7 @@ def template ImmDeclare {{ public: /// Constructor. - %(class_name)s(MachInst machInst); + %(class_name)s(ExtMachInst machInst); Fault execute(ExecContext *, trace::InstRecord *) const override; std::string generateDisassembly(Addr pc, const loader::SymbolTable *symtab) const override; @@ -52,7 +52,7 @@ def template ImmDeclare {{ }}; def template ImmConstructor {{ - %(class_name)s::%(class_name)s(MachInst machInst) + %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) { %(set_reg_idx_arr)s; @@ -168,7 +168,7 @@ def template BranchDeclare {{ public: /// Constructor. - %(class_name)s(MachInst machInst); + %(class_name)s(ExtMachInst machInst); Fault execute(ExecContext *, trace::InstRecord *) const override; std::string @@ -198,7 +198,9 @@ def template BranchExecute {{ %(class_name)s::branchTarget(const PCStateBase &branch_pc) const { auto &rpc = branch_pc.as(); - return std::make_unique(rpc.pc() + imm); + std::unique_ptr npc(dynamic_cast(rpc.clone())); + npc->set(rpc.pc() + imm); + return npc; } std::string @@ -226,7 +228,7 @@ def template JumpDeclare {{ public: /// Constructor. - %(class_name)s(MachInst machInst); + %(class_name)s(ExtMachInst machInst); Fault execute(ExecContext *, trace::InstRecord *) const override; std::string @@ -241,7 +243,7 @@ def template JumpDeclare {{ }}; def template JumpConstructor {{ - %(class_name)s::%(class_name)s(MachInst machInst) + %(class_name)s::%(class_name)s(ExtMachInst machInst) : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s) { %(set_reg_idx_arr)s; diff --git a/src/arch/riscv/pcstate.hh b/src/arch/riscv/pcstate.hh index 0125507f96..de07145dc3 100644 --- a/src/arch/riscv/pcstate.hh +++ b/src/arch/riscv/pcstate.hh @@ -43,21 +43,29 @@ #define __ARCH_RISCV_PCSTATE_HH__ #include "arch/generic/pcstate.hh" +#include "enums/RiscvType.hh" namespace gem5 { - namespace RiscvISA { +using RiscvType = enums::RiscvType; +constexpr enums::RiscvType RV32 = enums::RV32; +constexpr enums::RiscvType RV64 = enums::RV64; + class PCState : public GenericISA::UPCState<4> { private: bool _compressed = false; - bool _rv32 = false; + RiscvType _rv_type = RV64; public: - using GenericISA::UPCState<4>::UPCState; + PCState() = default; + PCState(const PCState &other) = default; + PCState(Addr addr, RiscvType rv_type) : UPCState(addr), _rv_type(rv_type) + { + } PCStateBase *clone() const override { return new PCState(*this); } @@ -67,14 +75,14 @@ class PCState : public GenericISA::UPCState<4> Base::update(other); auto &pcstate = other.as(); _compressed = pcstate._compressed; - _rv32 = pcstate._rv32; + _rv_type = pcstate._rv_type; } void compressed(bool c) { _compressed = c; } bool compressed() const { return _compressed; } - void rv32(bool val) { _rv32 = val; } - bool rv32() const { return _rv32; } + void rvType(RiscvType rv_type) { _rv_type = rv_type; } + RiscvType rvType() const { return _rv_type; } bool branching() const override diff --git a/src/arch/riscv/process.cc b/src/arch/riscv/process.cc index 7c91b92217..dc7abae790 100644 --- a/src/arch/riscv/process.cc +++ b/src/arch/riscv/process.cc @@ -115,7 +115,7 @@ RiscvProcess32::initState() auto *tc = system->threads[ctx]; tc->setMiscRegNoEffect(MISCREG_PRV, PRV_U); PCState pc = tc->pcState().as(); - pc.rv32(true); + pc.rvType(RV32); tc->pcState(pc); } } diff --git a/src/arch/riscv/regs/misc.hh b/src/arch/riscv/regs/misc.hh index 5f074475c9..7f6fff4e00 100644 --- a/src/arch/riscv/regs/misc.hh +++ b/src/arch/riscv/regs/misc.hh @@ -51,10 +51,12 @@ #include "arch/generic/vec_pred_reg.hh" #include "arch/generic/vec_reg.hh" +#include "arch/riscv/types.hh" #include "base/bitunion.hh" #include "base/types.hh" #include "cpu/reg_class.hh" #include "debug/MiscRegs.hh" +#include "enums/RiscvType.hh" namespace gem5 { @@ -550,9 +552,10 @@ const std::unordered_map CSRData = { * the fields for higher privileges. */ BitUnion64(STATUS) - Bitfield<63> sd; + Bitfield<63> rv64_sd; Bitfield<35, 34> sxl; Bitfield<33, 32> uxl; + Bitfield<31> rv32_sd; Bitfield<22> tsr; Bitfield<21> tw; Bitfield<20> tvm; @@ -590,20 +593,34 @@ BitUnion64(INTERRUPT) Bitfield<0> usi; EndBitUnion(INTERRUPT) -const off_t MXL_OFFSET = (sizeof(uint64_t) * 8 - 2); +const off_t MXL_OFFSETS[enums::Num_RiscvType] = { + [RV32] = (sizeof(uint32_t) * 8 - 2), + [RV64] = (sizeof(uint64_t) * 8 - 2), +}; const off_t SXL_OFFSET = 34; const off_t UXL_OFFSET = 32; const off_t FS_OFFSET = 13; const off_t FRM_OFFSET = 5; -const RegVal ISA_MXL_MASK = 3ULL << MXL_OFFSET; +const RegVal ISA_MXL_MASKS[enums::Num_RiscvType] = { + [RV32] = 3ULL << MXL_OFFSETS[RV32], + [RV64] = 3ULL << MXL_OFFSETS[RV64], +}; const RegVal ISA_EXT_MASK = mask(26); const RegVal ISA_EXT_C_MASK = 1UL << ('c' - 'a'); -const RegVal MISA_MASK = ISA_MXL_MASK | ISA_EXT_MASK; +const RegVal MISA_MASKS[enums::Num_RiscvType] = { + [RV32] = ISA_MXL_MASKS[RV32] | ISA_EXT_MASK, + [RV64] = ISA_MXL_MASKS[RV64] | ISA_EXT_MASK, +}; -const RegVal STATUS_SD_MASK = 1ULL << ((sizeof(uint64_t) * 8) - 1); + +const RegVal STATUS_SD_MASKS[enums::Num_RiscvType] = { + [RV32] = 1ULL << ((sizeof(uint32_t) * 8) - 1), + [RV64] = 1ULL << ((sizeof(uint64_t) * 8) - 1), +}; const RegVal STATUS_SXL_MASK = 3ULL << SXL_OFFSET; const RegVal STATUS_UXL_MASK = 3ULL << UXL_OFFSET; + const RegVal STATUS_TSR_MASK = 1ULL << 22; const RegVal STATUS_TW_MASK = 1ULL << 21; const RegVal STATUS_TVM_MASK = 1ULL << 20; @@ -621,26 +638,39 @@ const RegVal STATUS_UPIE_MASK = 1ULL << 4; const RegVal STATUS_MIE_MASK = 1ULL << 3; const RegVal STATUS_SIE_MASK = 1ULL << 1; const RegVal STATUS_UIE_MASK = 1ULL << 0; -const RegVal MSTATUS_MASK = STATUS_SD_MASK | STATUS_SXL_MASK | - STATUS_UXL_MASK | STATUS_TSR_MASK | - STATUS_TW_MASK | STATUS_TVM_MASK | - STATUS_MXR_MASK | STATUS_SUM_MASK | - STATUS_MPRV_MASK | STATUS_XS_MASK | - STATUS_FS_MASK | STATUS_VS_MASK | - STATUS_MPP_MASK | STATUS_SPP_MASK | - STATUS_MPIE_MASK | STATUS_SPIE_MASK | - STATUS_UPIE_MASK | STATUS_MIE_MASK | - STATUS_SIE_MASK | STATUS_UIE_MASK; -const RegVal SSTATUS_MASK = STATUS_SD_MASK | STATUS_UXL_MASK | - STATUS_MXR_MASK | STATUS_SUM_MASK | - STATUS_XS_MASK | STATUS_FS_MASK | - STATUS_VS_MASK | STATUS_SPP_MASK | - STATUS_SPIE_MASK | STATUS_UPIE_MASK | - STATUS_SIE_MASK | STATUS_UIE_MASK; -const RegVal USTATUS_MASK = STATUS_SD_MASK | STATUS_MXR_MASK | - STATUS_SUM_MASK | STATUS_XS_MASK | - STATUS_FS_MASK | STATUS_VS_MASK | - STATUS_UPIE_MASK | STATUS_UIE_MASK; +const RegVal MSTATUS_MASKS[enums::Num_RiscvType] = { + [RV32] = STATUS_SD_MASKS[RV32] | STATUS_TSR_MASK | STATUS_TW_MASK | + STATUS_TVM_MASK | STATUS_MXR_MASK | STATUS_SUM_MASK | + STATUS_MPRV_MASK | STATUS_XS_MASK | STATUS_FS_MASK | + STATUS_VS_MASK | STATUS_MPP_MASK | STATUS_SPP_MASK | + STATUS_MPIE_MASK | STATUS_SPIE_MASK | STATUS_UPIE_MASK | + STATUS_MIE_MASK | STATUS_SIE_MASK | STATUS_UIE_MASK, + [RV64] = STATUS_SD_MASKS[RV64] | STATUS_SXL_MASK | STATUS_UXL_MASK | + STATUS_TSR_MASK | STATUS_TW_MASK | STATUS_TVM_MASK | + STATUS_MXR_MASK | STATUS_SUM_MASK | STATUS_MPRV_MASK | + STATUS_XS_MASK | STATUS_FS_MASK | STATUS_VS_MASK| + STATUS_MPP_MASK | STATUS_SPP_MASK | STATUS_MPIE_MASK | + STATUS_SPIE_MASK | STATUS_UPIE_MASK | STATUS_MIE_MASK | + STATUS_SIE_MASK | STATUS_UIE_MASK, +}; +const RegVal SSTATUS_MASKS[enums::Num_RiscvType] = { + [RV32] = STATUS_SD_MASKS[RV32] | STATUS_MXR_MASK | STATUS_SUM_MASK | + STATUS_XS_MASK | STATUS_FS_MASK | STATUS_VS_MASK | + STATUS_SPP_MASK | STATUS_SPIE_MASK | STATUS_UPIE_MASK | + STATUS_SIE_MASK | STATUS_UIE_MASK, + [RV64] = STATUS_SD_MASKS[RV64] | STATUS_UXL_MASK | STATUS_MXR_MASK | + STATUS_SUM_MASK | STATUS_XS_MASK | STATUS_FS_MASK | + STATUS_VS_MASK | STATUS_SPP_MASK | STATUS_SPIE_MASK | + STATUS_UPIE_MASK | STATUS_SIE_MASK | STATUS_UIE_MASK, +}; +const RegVal USTATUS_MASKS[enums::Num_RiscvType] = { + [RV32] = STATUS_SD_MASKS[RV32] | STATUS_MXR_MASK | STATUS_SUM_MASK | + STATUS_XS_MASK | STATUS_FS_MASK | STATUS_VS_MASK | + STATUS_UPIE_MASK | STATUS_UIE_MASK, + [RV64] = STATUS_SD_MASKS[RV64] | STATUS_MXR_MASK | STATUS_SUM_MASK | + STATUS_XS_MASK | STATUS_FS_MASK | STATUS_VS_MASK | + STATUS_UPIE_MASK | STATUS_UIE_MASK, +}; const RegVal MEI_MASK = 1ULL << 11; const RegVal SEI_MASK = 1ULL << 9; @@ -661,20 +691,38 @@ const RegVal UI_MASK = UEI_MASK | UTI_MASK | USI_MASK; const RegVal FFLAGS_MASK = (1 << FRM_OFFSET) - 1; const RegVal FRM_MASK = 0x7; -const std::unordered_map CSRMasks = { - {CSR_USTATUS, USTATUS_MASK}, - {CSR_UIE, UI_MASK}, - {CSR_UIP, UI_MASK}, - {CSR_FFLAGS, FFLAGS_MASK}, - {CSR_FRM, FRM_MASK}, - {CSR_FCSR, FFLAGS_MASK | (FRM_MASK << FRM_OFFSET)}, - {CSR_SSTATUS, SSTATUS_MASK}, - {CSR_SIE, SI_MASK}, - {CSR_SIP, SI_MASK}, - {CSR_MSTATUS, MSTATUS_MASK}, - {CSR_MISA, MISA_MASK}, - {CSR_MIE, MI_MASK}, - {CSR_MIP, MI_MASK} +const RegVal CAUSE_INTERRUPT_MASKS[enums::Num_RiscvType] = { + [RV32] = (1ULL << 31), + [RV64] = (1ULL << 63), +}; + +const std::unordered_map CSRMasks[enums::Num_RiscvType] = { + [RV32] = {{CSR_USTATUS, USTATUS_MASKS[RV32]}, + {CSR_UIE, UI_MASK}, + {CSR_UIP, UI_MASK}, + {CSR_FFLAGS, FFLAGS_MASK}, + {CSR_FRM, FRM_MASK}, + {CSR_FCSR, FFLAGS_MASK | (FRM_MASK << FRM_OFFSET)}, + {CSR_SSTATUS, SSTATUS_MASKS[RV32]}, + {CSR_SIE, SI_MASK}, + {CSR_SIP, SI_MASK}, + {CSR_MSTATUS, MSTATUS_MASKS[RV32]}, + {CSR_MISA, MISA_MASKS[RV32]}, + {CSR_MIE, MI_MASK}, + {CSR_MIP, MI_MASK}}, + [RV64] = {{CSR_USTATUS, USTATUS_MASKS[RV64]}, + {CSR_UIE, UI_MASK}, + {CSR_UIP, UI_MASK}, + {CSR_FFLAGS, FFLAGS_MASK}, + {CSR_FRM, FRM_MASK}, + {CSR_FCSR, FFLAGS_MASK | (FRM_MASK << FRM_OFFSET)}, + {CSR_SSTATUS, SSTATUS_MASKS[RV64]}, + {CSR_SIE, SI_MASK}, + {CSR_SIP, SI_MASK}, + {CSR_MSTATUS, MSTATUS_MASKS[RV64]}, + {CSR_MISA, MISA_MASKS[RV64]}, + {CSR_MIE, MI_MASK}, + {CSR_MIP, MI_MASK}}, }; } // namespace RiscvISA diff --git a/src/arch/riscv/remote_gdb.cc b/src/arch/riscv/remote_gdb.cc index ed700bbf8d..4bdd88fde6 100644 --- a/src/arch/riscv/remote_gdb.cc +++ b/src/arch/riscv/remote_gdb.cc @@ -135,10 +135,10 @@ #include -#include "arch/riscv/gdb-xml/gdb_xml_riscv_cpu.hh" -#include "arch/riscv/gdb-xml/gdb_xml_riscv_csr.hh" -#include "arch/riscv/gdb-xml/gdb_xml_riscv_fpu.hh" -#include "arch/riscv/gdb-xml/gdb_xml_riscv_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" +#include "arch/riscv/gdb-xml/gdb_xml_riscv_64bit_target.hh" #include "arch/riscv/mmu.hh" #include "arch/riscv/pagetable_walker.hh" #include "arch/riscv/regs/float.hh" @@ -155,8 +155,16 @@ namespace gem5 using namespace RiscvISA; +static RiscvType +getRvType(ThreadContext* tc) +{ + auto isa = dynamic_cast(tc->getIsaPtr()); + panic_if(!isa, "Cannot derive rv_type from non-riscv isa"); + return isa->rvType(); +} + RemoteGDB::RemoteGDB(System *_system, int _port) - : BaseRemoteGDB(_system, _port), regCache(this) + : BaseRemoteGDB(_system, _port), regCache64(this) { } @@ -186,9 +194,10 @@ RemoteGDB::acc(Addr va, size_t len) } void -RemoteGDB::RiscvGdbRegCache::getRegs(ThreadContext *context) +RemoteGDB::Riscv64GdbRegCache::getRegs(ThreadContext *context) { DPRINTF(GDBAcc, "getregs in remotegdb, size %lu\n", size()); + auto& RVxCSRMasks = CSRMasks[RV64]; // General registers for (int i = 0; i < int_reg::NumArchRegs; i++) { @@ -200,11 +209,11 @@ RemoteGDB::RiscvGdbRegCache::getRegs(ThreadContext *context) 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) & CSRMasks.at(CSR_FFLAGS); + CSRData.at(CSR_FFLAGS).physIndex) & RVxCSRMasks.at(CSR_FFLAGS); r.frm = context->readMiscRegNoEffect( - CSRData.at(CSR_FRM).physIndex) & CSRMasks.at(CSR_FRM); + CSRData.at(CSR_FRM).physIndex) & RVxCSRMasks.at(CSR_FRM); r.fcsr = context->readMiscRegNoEffect( - CSRData.at(CSR_FCSR).physIndex) & CSRMasks.at(CSR_FCSR); + CSRData.at(CSR_FCSR).physIndex) & RVxCSRMasks.at(CSR_FCSR); // CSR registers r.cycle = context->readMiscRegNoEffect( @@ -214,9 +223,9 @@ RemoteGDB::RiscvGdbRegCache::getRegs(ThreadContext *context) // U mode CSR r.ustatus = context->readMiscRegNoEffect( - CSRData.at(CSR_USTATUS).physIndex) & CSRMasks.at(CSR_USTATUS); + CSRData.at(CSR_USTATUS).physIndex) & RVxCSRMasks.at(CSR_USTATUS); r.uie = context->readMiscReg( - CSRData.at(CSR_UIE).physIndex) & CSRMasks.at(CSR_UIE); + CSRData.at(CSR_UIE).physIndex) & RVxCSRMasks.at(CSR_UIE); r.utvec = context->readMiscRegNoEffect( CSRData.at(CSR_UTVEC).physIndex); r.uscratch = context->readMiscRegNoEffect( @@ -228,17 +237,17 @@ RemoteGDB::RiscvGdbRegCache::getRegs(ThreadContext *context) r.utval = context->readMiscRegNoEffect( CSRData.at(CSR_UTVAL).physIndex); r.uip = context->readMiscReg( - CSRData.at(CSR_UIP).physIndex) & CSRMasks.at(CSR_UIP); + CSRData.at(CSR_UIP).physIndex) & RVxCSRMasks.at(CSR_UIP); // S mode CSR r.sstatus = context->readMiscRegNoEffect( - CSRData.at(CSR_SSTATUS).physIndex) & CSRMasks.at(CSR_SSTATUS); + 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) & CSRMasks.at(CSR_SIE); + CSRData.at(CSR_SIE).physIndex) & RVxCSRMasks.at(CSR_SIE); r.stvec = context->readMiscRegNoEffect( CSRData.at(CSR_STVEC).physIndex); r.scounteren = context->readMiscRegNoEffect( @@ -252,7 +261,7 @@ RemoteGDB::RiscvGdbRegCache::getRegs(ThreadContext *context) r.stval = context->readMiscRegNoEffect( CSRData.at(CSR_STVAL).physIndex); r.sip = context->readMiscReg( - CSRData.at(CSR_SIP).physIndex) & CSRMasks.at(CSR_SIP); + CSRData.at(CSR_SIP).physIndex) & RVxCSRMasks.at(CSR_SIP); r.satp = context->readMiscRegNoEffect( CSRData.at(CSR_SATP).physIndex); @@ -266,15 +275,15 @@ RemoteGDB::RiscvGdbRegCache::getRegs(ThreadContext *context) r.mhartid = context->readMiscRegNoEffect( CSRData.at(CSR_MHARTID).physIndex); r.mstatus = context->readMiscRegNoEffect( - CSRData.at(CSR_MSTATUS).physIndex) & CSRMasks.at(CSR_MSTATUS); + CSRData.at(CSR_MSTATUS).physIndex) & RVxCSRMasks.at(CSR_MSTATUS); r.misa = context->readMiscRegNoEffect( - CSRData.at(CSR_MISA).physIndex) & CSRMasks.at(CSR_MISA); + 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) & CSRMasks.at(CSR_MIE); + CSRData.at(CSR_MIE).physIndex) & RVxCSRMasks.at(CSR_MIE); r.mtvec = context->readMiscRegNoEffect( CSRData.at(CSR_MTVEC).physIndex); r.mcounteren = context->readMiscRegNoEffect( @@ -288,13 +297,13 @@ RemoteGDB::RiscvGdbRegCache::getRegs(ThreadContext *context) r.mtval = context->readMiscRegNoEffect( CSRData.at(CSR_MTVAL).physIndex); r.mip = context->readMiscReg( - CSRData.at(CSR_MIP).physIndex) & CSRMasks.at(CSR_MIP); + CSRData.at(CSR_MIP).physIndex) & RVxCSRMasks.at(CSR_MIP); // H mode CSR (to be implemented) } void -RemoteGDB::RiscvGdbRegCache::setRegs(ThreadContext *context) const +RemoteGDB::Riscv64GdbRegCache::setRegs(ThreadContext *context) const { // NOTE: no error will be reported for attempting to set masked bits. RegVal oldVal; @@ -310,23 +319,25 @@ RemoteGDB::RiscvGdbRegCache::setRegs(ThreadContext *context) const for (int i = 0; i < float_reg::NumRegs; i++) context->setReg(floatRegClass[i], r.fpu[i]); + auto& RVxCSRMasks = CSRMasks[RV64]; + oldVal = context->readMiscRegNoEffect( CSRData.at(CSR_FFLAGS).physIndex); - mask = CSRMasks.at(CSR_FFLAGS); + 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 = CSRMasks.at(CSR_FRM); + 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 = CSRMasks.at(CSR_FCSR); + mask = RVxCSRMasks.at(CSR_FCSR); newVal = (oldVal & ~mask) | (r.fcsr & mask); context->setMiscRegNoEffect( CSRData.at(CSR_FCSR).physIndex, newVal); @@ -340,13 +351,13 @@ RemoteGDB::RiscvGdbRegCache::setRegs(ThreadContext *context) const // U mode CSR oldVal = context->readMiscRegNoEffect( CSRData.at(CSR_USTATUS).physIndex); - mask = CSRMasks.at(CSR_USTATUS); + 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 = CSRMasks.at(CSR_UIE); + mask = RVxCSRMasks.at(CSR_UIE); newVal = (oldVal & ~mask) | (r.uie & mask); context->setMiscReg( CSRData.at(CSR_UIE).physIndex, newVal); @@ -362,7 +373,7 @@ RemoteGDB::RiscvGdbRegCache::setRegs(ThreadContext *context) const CSRData.at(CSR_UTVAL).physIndex, r.utval); oldVal = context->readMiscReg( CSRData.at(CSR_UIP).physIndex); - mask = CSRMasks.at(CSR_UIP); + mask = RVxCSRMasks.at(CSR_UIP); newVal = (oldVal & ~mask) | (r.uip & mask); context->setMiscReg( CSRData.at(CSR_UIP).physIndex, newVal); @@ -370,7 +381,7 @@ RemoteGDB::RiscvGdbRegCache::setRegs(ThreadContext *context) const // S mode CSR oldVal = context->readMiscRegNoEffect( CSRData.at(CSR_SSTATUS).physIndex); - mask = CSRMasks.at(CSR_SSTATUS); + mask = RVxCSRMasks.at(CSR_SSTATUS); newVal = (oldVal & ~mask) | (r.sstatus & mask); context->setMiscRegNoEffect( CSRData.at(CSR_SSTATUS).physIndex, newVal); @@ -380,7 +391,7 @@ RemoteGDB::RiscvGdbRegCache::setRegs(ThreadContext *context) const CSRData.at(CSR_SIDELEG).physIndex, r.sideleg); oldVal = context->readMiscReg( CSRData.at(CSR_SIE).physIndex); - mask = CSRMasks.at(CSR_SIE); + mask = RVxCSRMasks.at(CSR_SIE); newVal = (oldVal & ~mask) | (r.sie & mask); context->setMiscReg( CSRData.at(CSR_SIE).physIndex, newVal); @@ -398,7 +409,7 @@ RemoteGDB::RiscvGdbRegCache::setRegs(ThreadContext *context) const CSRData.at(CSR_STVAL).physIndex, r.stval); oldVal = context->readMiscReg( CSRData.at(CSR_SIP).physIndex); - mask = CSRMasks.at(CSR_SIP); + mask = RVxCSRMasks.at(CSR_SIP); newVal = (oldVal & ~mask) | (r.sip & mask); context->setMiscReg( CSRData.at(CSR_SIP).physIndex, newVal); @@ -416,13 +427,13 @@ RemoteGDB::RiscvGdbRegCache::setRegs(ThreadContext *context) const CSRData.at(CSR_MHARTID).physIndex, r.mhartid); oldVal = context->readMiscRegNoEffect( CSRData.at(CSR_MSTATUS).physIndex); - mask = CSRMasks.at(CSR_MSTATUS); + 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 = CSRMasks.at(CSR_MISA); + mask = RVxCSRMasks.at(CSR_MISA); newVal = (oldVal & ~mask) | (r.misa & mask); context->setMiscRegNoEffect( CSRData.at(CSR_MISA).physIndex, newVal); @@ -432,7 +443,7 @@ RemoteGDB::RiscvGdbRegCache::setRegs(ThreadContext *context) const CSRData.at(CSR_MIDELEG).physIndex, r.mideleg); oldVal = context->readMiscReg( CSRData.at(CSR_MIE).physIndex); - mask = CSRMasks.at(CSR_MIE); + mask = RVxCSRMasks.at(CSR_MIE); newVal = (oldVal & ~mask) | (r.mie & mask); context->setMiscReg( CSRData.at(CSR_MIE).physIndex, newVal); @@ -450,7 +461,7 @@ RemoteGDB::RiscvGdbRegCache::setRegs(ThreadContext *context) const CSRData.at(CSR_MTVAL).physIndex, r.mtval); oldVal = context->readMiscReg( CSRData.at(CSR_MIP).physIndex); - mask = CSRMasks.at(CSR_MIP); + mask = RVxCSRMasks.at(CSR_MIP); newVal = (oldVal & ~mask) | (r.mip & mask); context->setMiscReg( CSRData.at(CSR_MIP).physIndex, newVal); @@ -473,11 +484,13 @@ RemoteGDB::getXferFeaturesRead(const std::string &annex, std::string &output) Blobs::s##_len) \ } static const std::map annexMap{ - GDB_XML("target.xml", gdb_xml_riscv_target), - GDB_XML("riscv-64bit-cpu.xml", gdb_xml_riscv_cpu), - GDB_XML("riscv-64bit-fpu.xml", gdb_xml_riscv_fpu), - GDB_XML("riscv-64bit-csr.xml", gdb_xml_riscv_csr)}; + 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; auto it = annexMap.find(annex); if (it == annexMap.end()) return false; @@ -488,7 +501,7 @@ RemoteGDB::getXferFeaturesRead(const std::string &annex, std::string &output) BaseGdbRegCache * RemoteGDB::gdbRegs() { - return ®Cache; + return ®Cache64; } } // namespace gem5 diff --git a/src/arch/riscv/remote_gdb.hh b/src/arch/riscv/remote_gdb.hh index f87481ece0..a8262a6a2a 100644 --- a/src/arch/riscv/remote_gdb.hh +++ b/src/arch/riscv/remote_gdb.hh @@ -58,7 +58,7 @@ 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 RiscvGdbRegCache : public BaseGdbRegCache + class Riscv64GdbRegCache : public BaseGdbRegCache { using BaseGdbRegCache::BaseGdbRegCache; private: @@ -142,7 +142,7 @@ class RemoteGDB : public BaseRemoteGDB } }; - RiscvGdbRegCache regCache; + Riscv64GdbRegCache regCache64; public: RemoteGDB(System *_system, int _port); diff --git a/src/arch/riscv/types.hh b/src/arch/riscv/types.hh index f06fe3eaa4..4aae1a027b 100644 --- a/src/arch/riscv/types.hh +++ b/src/arch/riscv/types.hh @@ -43,6 +43,7 @@ #define __ARCH_RISCV_TYPES_HH__ #include "arch/riscv/pcstate.hh" +#include "base/bitunion.hh" namespace gem5 { @@ -51,7 +52,13 @@ namespace RiscvISA { typedef uint32_t MachInst; -typedef uint64_t ExtMachInst; + +// This should be further extend someday when we start to support 64b+ inst. +// For now, we should be safe using the msbs to store extra information. +BitUnion64(ExtMachInst) + // Decoder state + Bitfield<63, 62> rv_type; +EndBitUnion(ExtMachInst) } // namespace RiscvISA } // namespace gem5