From ce00e6042d996a9255960917f99009d9826b3885 Mon Sep 17 00:00:00 2001 From: Alec Roelke Date: Sun, 10 Dec 2017 14:15:51 -0500 Subject: [PATCH] arch-riscv: Update CSR implementations This patch updates the CSRs to match the RISC-V privileged specification version 1.10. As interrupts, faults, and privilege levels are not yet supported, there are no meaninful side effects that are implemented. Performance counters are also not yet implemented, as they do not have specifications. Currently they act as cycle counters. Note that this implementation trusts software to use the registers properly. Access protection, readability, and writeability of registers based on privilege will come in a future patch. Change-Id: I1de89bdbe369b5027911b2e6bc0425d3acaa708a Reviewed-on: https://gem5-review.googlesource.com/7441 Reviewed-by: Gabe Black Maintainer: Alec Roelke --- src/arch/riscv/insts/standard.cc | 8 +- src/arch/riscv/isa.cc | 161 ++--- src/arch/riscv/isa.hh | 83 +-- src/arch/riscv/isa/decoder.isa | 32 +- src/arch/riscv/isa/formats/standard.isa | 68 +- src/arch/riscv/isa/includes.isa | 1 + src/arch/riscv/process.cc | 4 + src/arch/riscv/registers.hh | 814 ++++++++++++++++-------- src/arch/riscv/remote_gdb.cc | 12 +- 9 files changed, 748 insertions(+), 435 deletions(-) diff --git a/src/arch/riscv/insts/standard.cc b/src/arch/riscv/insts/standard.cc index 60cf4fc2b..9354a542f 100644 --- a/src/arch/riscv/insts/standard.cc +++ b/src/arch/riscv/insts/standard.cc @@ -60,12 +60,12 @@ CSROp::generateDisassembly(Addr pc, const SymbolTable *symtab) const ss << mnemonic << ' ' << registerName(_destRegIdx[0]) << ", "; if (_numSrcRegs > 0) ss << registerName(_srcRegIdx[0]) << ", "; - auto name = MiscRegNames.find(csr); - if (name != MiscRegNames.end()) - ss << name->second; + auto data = CSRData.find(csr); + if (data != CSRData.end()) + ss << data->second.name; else ss << "?? (" << hex << "0x" << csr << ")"; return ss.str(); } -} \ No newline at end of file +} diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index 6091068ef..6824e7034 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -61,72 +61,98 @@ void ISA::clear() { std::fill(miscRegFile.begin(), miscRegFile.end(), 0); - miscRegFile[MISCREG_MVENDORID] = 0; - miscRegFile[MISCREG_MARCHID] = 0; - miscRegFile[MISCREG_MIMPID] = 0; - miscRegFile[MISCREG_MISA] = 0x8000000000101129ULL; + 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); + miscRegFile[MISCREG_MCOUNTEREN] = 0x7; + miscRegFile[MISCREG_SCOUNTEREN] = 0x7; } +bool +ISA::hpmCounterEnabled(int misc_reg) const +{ + int hpmcounter = misc_reg - MISCREG_CYCLE; + if (hpmcounter < 0 || hpmcounter > 31) + panic("Illegal HPM counter %d\n", hpmcounter); + int counteren; + switch (readMiscRegNoEffect(MISCREG_PRV)) { + case PRV_M: + return true; + case PRV_S: + counteren = MISCREG_MCOUNTEREN; + break; + case PRV_U: + counteren = MISCREG_SCOUNTEREN; + break; + default: + panic("Unknown privilege level %d\n", miscRegFile[MISCREG_PRV]); + return false; + } + return (miscRegFile[counteren] & (1ULL << (hpmcounter))) > 0; +} MiscReg ISA::readMiscRegNoEffect(int misc_reg) const { - DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n", - MiscRegNames.at(misc_reg), miscRegFile[misc_reg]); - switch (misc_reg) { - case MISCREG_FFLAGS: - return bits(miscRegFile[MISCREG_FCSR], 4, 0); - case MISCREG_FRM: - return bits(miscRegFile[MISCREG_FCSR], 7, 5); - case MISCREG_FCSR: - return bits(miscRegFile[MISCREG_FCSR], 31, 0); - case MISCREG_CYCLE: - warn("Use readMiscReg to read the cycle CSR."); - return 0; - case MISCREG_TIME: - return std::time(nullptr); - case MISCREG_INSTRET: - warn("Use readMiscReg to read the instret CSR."); - return 0; - case MISCREG_CYCLEH: - warn("Use readMiscReg to read the cycleh CSR."); - return 0; - case MISCREG_TIMEH: - return std::time(nullptr) >> 32; - case MISCREG_INSTRETH: - warn("Use readMiscReg to read the instreth CSR."); - return 0; - case MISCREG_MHARTID: - warn("Use readMiscReg to read the mhartid CSR."); - return 0; - default: - return miscRegFile[misc_reg]; + if (misc_reg > NumMiscRegs || misc_reg < 0) { + // Illegal CSR + panic("Illegal CSR index %#x\n", misc_reg); + return -1; } + DPRINTF(RiscvMisc, "Reading MiscReg %d: %#llx.\n", misc_reg, + miscRegFile[misc_reg]); + return miscRegFile[misc_reg]; } MiscReg ISA::readMiscReg(int misc_reg, ThreadContext *tc) { switch (misc_reg) { - case MISCREG_INSTRET: - DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n", - MiscRegNames.at(misc_reg), miscRegFile[misc_reg]); - return tc->getCpuPtr()->totalInsts(); case MISCREG_CYCLE: - DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n", - MiscRegNames.at(misc_reg), miscRegFile[misc_reg]); - return tc->getCpuPtr()->curCycle(); - case MISCREG_INSTRETH: - DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n", - MiscRegNames.at(misc_reg), miscRegFile[misc_reg]); - return tc->getCpuPtr()->totalInsts() >> 32; - case MISCREG_CYCLEH: - DPRINTF(RiscvMisc, "Reading CSR %s (0x%016llx).\n", - MiscRegNames.at(misc_reg), miscRegFile[misc_reg]); - return tc->getCpuPtr()->curCycle() >> 32; - case MISCREG_MHARTID: - return 0; // TODO: make this the hardware thread or cpu id + if (hpmCounterEnabled(MISCREG_CYCLE)) { + DPRINTF(RiscvMisc, "Cycle counter at: %llu.\n", + tc->getCpuPtr()->curCycle()); + return tc->getCpuPtr()->curCycle(); + } else { + warn("Cycle counter disabled.\n"); + return 0; + } + case MISCREG_TIME: + if (hpmCounterEnabled(MISCREG_TIME)) { + DPRINTF(RiscvMisc, "Wall-clock counter at: %llu.\n", + std::time(nullptr)); + return std::time(nullptr); + } else { + warn("Wall clock disabled.\n"); + return 0; + } + case MISCREG_INSTRET: + if (hpmCounterEnabled(MISCREG_INSTRET)) { + DPRINTF(RiscvMisc, "Instruction counter at: %llu.\n", + tc->getCpuPtr()->totalInsts()); + return tc->getCpuPtr()->totalInsts(); + } else { + warn("Instruction counter disabled.\n"); + return 0; + } default: + // Try reading HPM counters + // As a placeholder, all HPM counters are just cycle counters + if (misc_reg >= MISCREG_HPMCOUNTER03 && + misc_reg <= MISCREG_HPMCOUNTER31) { + if (hpmCounterEnabled(misc_reg)) { + DPRINTF(RiscvMisc, "HPM counter %d: %llu.\n", + misc_reg - MISCREG_CYCLE, tc->getCpuPtr()->curCycle()); + return tc->getCpuPtr()->curCycle(); + } else { + warn("HPM counter %d disabled.\n", misc_reg - MISCREG_CYCLE); + return 0; + } + } return readMiscRegNoEffect(misc_reg); } } @@ -134,34 +160,23 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc) void ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val) { - DPRINTF(RiscvMisc, "Setting CSR %s to 0x%016llx.\n", - MiscRegNames.at(misc_reg), val); - switch (misc_reg) { - case MISCREG_FFLAGS: - miscRegFile[MISCREG_FCSR] &= ~0x1F; - miscRegFile[MISCREG_FCSR] |= bits(val, 4, 0); - break; - case MISCREG_FRM: - miscRegFile[MISCREG_FCSR] &= ~0x70; - miscRegFile[MISCREG_FCSR] |= bits(val, 2, 0) << 5; - break; - case MISCREG_FCSR: - miscRegFile[MISCREG_FCSR] = bits(val, 7, 0); - break; - default: - miscRegFile[misc_reg] = val; - break; + if (misc_reg > NumMiscRegs || misc_reg < 0) { + // Illegal CSR + panic("Illegal CSR index %#x\n", misc_reg); } + DPRINTF(RiscvMisc, "Setting MiscReg %d to %#x.\n", misc_reg, val); + miscRegFile[misc_reg] = val; } void ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc) { - if (bits((unsigned)misc_reg, 11, 10) == 0x3) { - warn("Ignoring write to read-only CSR."); - return; + if (misc_reg >= MISCREG_CYCLE && misc_reg <= MISCREG_HPMCOUNTER31) { + // Ignore writes to HPM counters for now + warn("Ignoring write to %s.\n", CSRData.at(misc_reg).name); + } else { + setMiscRegNoEffect(misc_reg, val); } - setMiscRegNoEffect(misc_reg, val); } } @@ -170,4 +185,4 @@ RiscvISA::ISA * RiscvISAParams::create() { return new RiscvISA::ISA(this); -} +} \ No newline at end of file diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh index 4f8b4dc7a..f96b07275 100644 --- a/src/arch/riscv/isa.hh +++ b/src/arch/riscv/isa.hh @@ -43,6 +43,7 @@ #include "arch/riscv/registers.hh" #include "arch/riscv/types.hh" +#include "base/bitfield.hh" #include "base/logging.hh" #include "cpu/reg_class.hh" #include "sim/sim_object.hh" @@ -55,79 +56,43 @@ class EventManager; namespace RiscvISA { +enum PrivilegeMode { + PRV_U = 0, + PRV_S = 1, + PRV_M = 3 +}; + class ISA : public SimObject { protected: std::vector miscRegFile; + bool hpmCounterEnabled(int counter) const; + public: typedef RiscvISAParams Params; - void - clear(); - - MiscReg - readMiscRegNoEffect(int misc_reg) const; - - MiscReg - readMiscReg(int misc_reg, ThreadContext *tc); - - void - setMiscRegNoEffect(int misc_reg, const MiscReg &val); - - void - setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc); - - RegId - flattenRegId(const RegId ®Id) const - { - return regId; - } - - int - flattenIntIndex(int reg) const - { - return reg; - } - - int - flattenFloatIndex(int reg) const - { - return reg; - } - - int - flattenVecIndex(int reg) const - { - return reg; - } - - int - flattenVecElemIndex(int reg) const - { - return reg; - } - - // dummy - int - flattenCCIndex(int reg) const - { - return reg; - } - - int - flattenMiscIndex(int reg) const - { - return reg; - } + void clear(); + + MiscReg readMiscRegNoEffect(int misc_reg) const; + MiscReg readMiscReg(int misc_reg, ThreadContext *tc); + void setMiscRegNoEffect(int misc_reg, const MiscReg &val); + void setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc); + + RegId flattenRegId(const RegId ®Id) const { return regId; } + int flattenIntIndex(int reg) const { return reg; } + int flattenFloatIndex(int reg) const { return reg; } + int flattenVecIndex(int reg) const { return reg; } + int flattenVecElemIndex(int reg) const { return reg; } + int flattenCCIndex(int reg) const { return reg; } + int flattenMiscIndex(int reg) const { return reg; } void startup(ThreadContext *tc) {} /// Explicitly import the otherwise hidden startup using SimObject::startup; - const Params * - params() const; + const Params *params() const; ISA(Params *p); }; diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index e3992d712..d8f3395e3 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -1699,36 +1699,28 @@ decode QUADRANT default Unknown::unknown() { } format CSROp { 0x1: csrrw({{ - Rd = xc->readMiscReg(csr); - xc->setMiscReg(csr, Rs1); + Rd = data; + data = Rs1; }}, IsNonSpeculative, No_OpClass); 0x2: csrrs({{ - Rd = xc->readMiscReg(csr); - if (Rs1 != 0) { - xc->setMiscReg(csr, Rd | Rs1); - } + Rd = data; + data |= Rs1; }}, IsNonSpeculative, No_OpClass); 0x3: csrrc({{ - Rd = xc->readMiscReg(csr); - if (Rs1 != 0) { - xc->setMiscReg(csr, Rd & ~Rs1); - } + Rd = data; + data &= ~Rs1; }}, IsNonSpeculative, No_OpClass); 0x5: csrrwi({{ - Rd = xc->readMiscReg(csr); - xc->setMiscReg(csr, uimm); + Rd = data; + data = uimm; }}, IsNonSpeculative, No_OpClass); 0x6: csrrsi({{ - Rd = xc->readMiscReg(csr); - if (uimm != 0) { - xc->setMiscReg(csr, Rd | uimm); - } + Rd = data; + data |= uimm; }}, IsNonSpeculative, No_OpClass); 0x7: csrrci({{ - Rd = xc->readMiscReg(csr); - if (uimm != 0) { - xc->setMiscReg(csr, Rd & ~uimm); - } + Rd = data; + data &= ~uimm; }}, IsNonSpeculative, No_OpClass); } } diff --git a/src/arch/riscv/isa/formats/standard.isa b/src/arch/riscv/isa/formats/standard.isa index 2e0e3edd4..e69ad7ee5 100644 --- a/src/arch/riscv/isa/formats/standard.isa +++ b/src/arch/riscv/isa/formats/standard.isa @@ -210,6 +210,72 @@ def template JumpExecute {{ } }}; +def template CSRExecute {{ + Fault + %(class_name)s::execute(ExecContext *xc, + Trace::InstRecord *traceData) const + { + Fault fault = NoFault; + + %(op_decl)s; + %(op_rd)s; + + MiscReg data, olddata; + switch (csr) { + case CSR_FCSR: + olddata = xc->readMiscReg(MISCREG_FFLAGS) | + (xc->readMiscReg(MISCREG_FRM) << FRM_OFFSET); + break; + default: + if (CSRData.find(csr) != CSRData.end()) { + olddata = xc->readMiscReg(CSRData.at(csr).physIndex); + } else { + std::string error = csprintf("Illegal CSR index %#x\n", csr); + fault = make_shared(error); + olddata = 0; + } + break; + } + auto mask = CSRMasks.find(csr); + if (mask != CSRMasks.end()) + olddata &= mask->second; + DPRINTF(RiscvMisc, "Reading CSR %s: %#x\n", CSRData.at(csr).name, + olddata); + data = olddata; + + if (fault == NoFault) { + %(code)s; + if (fault == NoFault) { + if (mask != CSRMasks.end()) + data &= mask->second; + if (data != olddata) { + if (bits(csr, 11, 10) == 0x3) { + std::string error = csprintf("CSR %s is read-only\n", + CSRData.at(csr).name); + fault = make_shared(error); + } else { + DPRINTF(RiscvMisc, "Writing %#x to CSR %s.\n", data, + CSRData.at(csr).name); + switch (csr) { + case CSR_FCSR: + xc->setMiscReg(MISCREG_FFLAGS, bits(data, 4, 0)); + xc->setMiscReg(MISCREG_FRM, bits(data, 7, 5)); + break; + default: + xc->setMiscReg(CSRData.at(csr).physIndex, data); + break; + } + } + } + } + if (fault == NoFault) { + %(op_wb)s; + } + } + return fault; + } +}}; + def format ROp(code, *opt_flags) {{ iop = InstObjParams(name, Name, 'RegOp', code, opt_flags) header_output = BasicDeclare.subst(iop) @@ -301,5 +367,5 @@ def format CSROp(code, *opt_flags) {{ header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) decode_block = BasicDecode.subst(iop) - exec_output = BasicExecute.subst(iop) + exec_output = CSRExecute.subst(iop) }}; diff --git a/src/arch/riscv/isa/includes.isa b/src/arch/riscv/isa/includes.isa index 9f3d99fb5..d992685e1 100644 --- a/src/arch/riscv/isa/includes.isa +++ b/src/arch/riscv/isa/includes.isa @@ -87,6 +87,7 @@ output exec {{ #include "base/condcodes.hh" #include "cpu/base.hh" #include "cpu/exetrace.hh" +#include "debug/RiscvMisc.hh" #include "mem/packet.hh" #include "mem/packet_access.hh" #include "mem/request.hh" diff --git a/src/arch/riscv/process.cc b/src/arch/riscv/process.cc index b3e98aefb..4afc72147 100644 --- a/src/arch/riscv/process.cc +++ b/src/arch/riscv/process.cc @@ -41,7 +41,9 @@ #include #include +#include "arch/riscv/isa.hh" #include "arch/riscv/isa_traits.hh" +#include "arch/riscv/registers.hh" #include "base/loader/elf_object.hh" #include "base/loader/object_file.hh" #include "base/logging.hh" @@ -81,6 +83,8 @@ RiscvProcess::initState() Process::initState(); argsInit(PageBytes); + for (ContextID ctx: contextIds) + system->getThreadContext(ctx)->setMiscRegNoEffect(MISCREG_PRV, PRV_U); } template void diff --git a/src/arch/riscv/registers.hh b/src/arch/riscv/registers.hh index a61554c13..e1d57ee53 100644 --- a/src/arch/riscv/registers.hh +++ b/src/arch/riscv/registers.hh @@ -83,7 +83,6 @@ const int NumFloatRegs = 32; // This has to be one to prevent warnings that are treated as errors const unsigned NumVecRegs = 1; const int NumCCRegs = 0; -const int NumMiscRegs = 4096; // Semantically meaningful register indices const int ZeroReg = 0; @@ -123,279 +122,550 @@ const std::vector FloatRegNames = { }; enum MiscRegIndex { - MISCREG_USTATUS = 0x000, - MISCREG_UIE = 0x004, - MISCREG_UTVEC = 0x005, - MISCREG_USCRATCH = 0x040, - MISCREG_UEPC = 0x041, - MISCREG_UCAUSE = 0x042, - MISCREG_UBADADDR = 0x043, - MISCREG_UIP = 0x044, - MISCREG_FFLAGS = 0x001, - MISCREG_FRM = 0x002, - MISCREG_FCSR = 0x003, - MISCREG_CYCLE = 0xC00, - MISCREG_TIME = 0xC01, - MISCREG_INSTRET = 0xC02, - MISCREG_HPMCOUNTER_BASE = 0xC03, - MISCREG_CYCLEH = 0xC80, - MISCREG_TIMEH = 0xC81, - MISCREG_INSTRETH = 0xC82, - MISCREG_HPMCOUNTERH_BASE = 0xC83, - - MISCREG_SSTATUS = 0x100, - MISCREG_SEDELEG = 0x102, - MISCREG_SIDELEG = 0x103, - MISCREG_SIE = 0x104, - MISCREG_STVEC = 0x105, - MISCREG_SSCRATCH = 0x140, - MISCREG_SEPC = 0x141, - MISCREG_SCAUSE = 0x142, - MISCREG_SBADADDR = 0x143, - MISCREG_SIP = 0x144, - MISCREG_SPTBR = 0x180, - - MISCREG_HSTATUS = 0x200, - MISCREG_HEDELEG = 0x202, - MISCREG_HIDELEG = 0x203, - MISCREG_HIE = 0x204, - MISCREG_HTVEC = 0x205, - MISCREG_HSCRATCH = 0x240, - MISCREG_HEPC = 0x241, - MISCREG_HCAUSE = 0x242, - MISCREG_HBADADDR = 0x243, - MISCREG_HIP = 0x244, - - MISCREG_MVENDORID = 0xF11, - MISCREG_MARCHID = 0xF12, - MISCREG_MIMPID = 0xF13, - MISCREG_MHARTID = 0xF14, - MISCREG_MSTATUS = 0x300, - MISCREG_MISA = 0x301, - MISCREG_MEDELEG = 0x302, - MISCREG_MIDELEG = 0x303, - MISCREG_MIE = 0x304, - MISCREG_MTVEC = 0x305, - MISCREG_MSCRATCH = 0x340, - MISCREG_MEPC = 0x341, - MISCREG_MCAUSE = 0x342, - MISCREG_MBADADDR = 0x343, - MISCREG_MIP = 0x344, - MISCREG_MBASE = 0x380, - MISCREG_MBOUND = 0x381, - MISCREG_MIBASE = 0x382, - MISCREG_MIBOUND = 0x383, - MISCREG_MDBASE = 0x384, - MISCREG_MDBOUND = 0x385, - MISCREG_MCYCLE = 0xB00, - MISCREG_MINSTRET = 0xB02, - MISCREG_MHPMCOUNTER_BASE = 0xB03, - MISCREG_MUCOUNTEREN = 0x320, - MISCREG_MSCOUNTEREN = 0x321, - MISCREG_MHCOUNTEREN = 0x322, - MISCREG_MHPMEVENT_BASE = 0x323, - - MISCREG_TSELECT = 0x7A0, - MISCREG_TDATA1 = 0x7A1, - MISCREG_TDATA2 = 0x7A2, - MISCREG_TDATA3 = 0x7A3, - MISCREG_DCSR = 0x7B0, - MISCREG_DPC = 0x7B1, - MISCREG_DSCRATCH = 0x7B2 + MISCREG_PRV = 0, + MISCREG_ISA, + MISCREG_VENDORID, + MISCREG_ARCHID, + MISCREG_IMPID, + MISCREG_HARTID, + MISCREG_STATUS, + MISCREG_IP, + MISCREG_IE, + MISCREG_CYCLE, + MISCREG_TIME, + MISCREG_INSTRET, + MISCREG_HPMCOUNTER03, + MISCREG_HPMCOUNTER04, + MISCREG_HPMCOUNTER05, + MISCREG_HPMCOUNTER06, + MISCREG_HPMCOUNTER07, + MISCREG_HPMCOUNTER08, + MISCREG_HPMCOUNTER09, + MISCREG_HPMCOUNTER10, + MISCREG_HPMCOUNTER11, + MISCREG_HPMCOUNTER12, + MISCREG_HPMCOUNTER13, + MISCREG_HPMCOUNTER14, + MISCREG_HPMCOUNTER15, + MISCREG_HPMCOUNTER16, + MISCREG_HPMCOUNTER17, + MISCREG_HPMCOUNTER18, + MISCREG_HPMCOUNTER19, + MISCREG_HPMCOUNTER20, + MISCREG_HPMCOUNTER21, + MISCREG_HPMCOUNTER22, + MISCREG_HPMCOUNTER23, + MISCREG_HPMCOUNTER24, + MISCREG_HPMCOUNTER25, + MISCREG_HPMCOUNTER26, + MISCREG_HPMCOUNTER27, + MISCREG_HPMCOUNTER28, + MISCREG_HPMCOUNTER29, + MISCREG_HPMCOUNTER30, + MISCREG_HPMCOUNTER31, + MISCREG_HPMEVENT03, + MISCREG_HPMEVENT04, + MISCREG_HPMEVENT05, + MISCREG_HPMEVENT06, + MISCREG_HPMEVENT07, + MISCREG_HPMEVENT08, + MISCREG_HPMEVENT09, + MISCREG_HPMEVENT10, + MISCREG_HPMEVENT11, + MISCREG_HPMEVENT12, + MISCREG_HPMEVENT13, + MISCREG_HPMEVENT14, + MISCREG_HPMEVENT15, + MISCREG_HPMEVENT16, + MISCREG_HPMEVENT17, + MISCREG_HPMEVENT18, + MISCREG_HPMEVENT19, + MISCREG_HPMEVENT20, + MISCREG_HPMEVENT21, + MISCREG_HPMEVENT22, + MISCREG_HPMEVENT23, + MISCREG_HPMEVENT24, + MISCREG_HPMEVENT25, + MISCREG_HPMEVENT26, + MISCREG_HPMEVENT27, + MISCREG_HPMEVENT28, + MISCREG_HPMEVENT29, + MISCREG_HPMEVENT30, + MISCREG_HPMEVENT31, + MISCREG_TSELECT, + MISCREG_TDATA1, + MISCREG_TDATA2, + MISCREG_TDATA3, + MISCREG_DCSR, + MISCREG_DPC, + MISCREG_DSCRATCH, + + MISCREG_MEDELEG, + MISCREG_MIDELEG, + MISCREG_MTVEC, + MISCREG_MCOUNTEREN, + MISCREG_MSCRATCH, + MISCREG_MEPC, + MISCREG_MCAUSE, + MISCREG_MTVAL, + MISCREG_PMPCFG0, + // pmpcfg1 rv32 only + MISCREG_PMPCFG2, + // pmpcfg3 rv32 only + MISCREG_PMPADDR00, + MISCREG_PMPADDR01, + MISCREG_PMPADDR02, + MISCREG_PMPADDR03, + MISCREG_PMPADDR04, + MISCREG_PMPADDR05, + MISCREG_PMPADDR06, + MISCREG_PMPADDR07, + MISCREG_PMPADDR08, + MISCREG_PMPADDR09, + MISCREG_PMPADDR10, + MISCREG_PMPADDR11, + MISCREG_PMPADDR12, + MISCREG_PMPADDR13, + MISCREG_PMPADDR14, + MISCREG_PMPADDR15, + + MISCREG_SEDELEG, + MISCREG_SIDELEG, + MISCREG_STVEC, + MISCREG_SCOUNTEREN, + MISCREG_SSCRATCH, + MISCREG_SEPC, + MISCREG_SCAUSE, + MISCREG_STVAL, + MISCREG_SATP, + + MISCREG_UTVEC, + MISCREG_USCRATCH, + MISCREG_UEPC, + MISCREG_UCAUSE, + MISCREG_UTVAL, + MISCREG_FFLAGS, + MISCREG_FRM, + + NUM_MISCREGS +}; +const int NumMiscRegs = NUM_MISCREGS; + +enum CSRIndex { + CSR_USTATUS = 0x000, + CSR_UIE = 0x004, + CSR_UTVEC = 0x005, + CSR_USCRATCH = 0x040, + CSR_UEPC = 0x041, + CSR_UCAUSE = 0x042, + CSR_UTVAL = 0x043, + CSR_UIP = 0x044, + CSR_FFLAGS = 0x001, + CSR_FRM = 0x002, + CSR_FCSR = 0x003, + CSR_CYCLE = 0xC00, + CSR_TIME = 0xC01, + CSR_INSTRET = 0xC02, + CSR_HPMCOUNTER03 = 0xC03, + CSR_HPMCOUNTER04 = 0xC04, + CSR_HPMCOUNTER05 = 0xC05, + CSR_HPMCOUNTER06 = 0xC06, + CSR_HPMCOUNTER07 = 0xC07, + CSR_HPMCOUNTER08 = 0xC08, + CSR_HPMCOUNTER09 = 0xC09, + CSR_HPMCOUNTER10 = 0xC0A, + CSR_HPMCOUNTER11 = 0xC0B, + CSR_HPMCOUNTER12 = 0xC0C, + CSR_HPMCOUNTER13 = 0xC0D, + CSR_HPMCOUNTER14 = 0xC0E, + CSR_HPMCOUNTER15 = 0xC0F, + CSR_HPMCOUNTER16 = 0xC10, + CSR_HPMCOUNTER17 = 0xC11, + CSR_HPMCOUNTER18 = 0xC12, + CSR_HPMCOUNTER19 = 0xC13, + CSR_HPMCOUNTER20 = 0xC14, + CSR_HPMCOUNTER21 = 0xC15, + CSR_HPMCOUNTER22 = 0xC16, + CSR_HPMCOUNTER23 = 0xC17, + CSR_HPMCOUNTER24 = 0xC18, + CSR_HPMCOUNTER25 = 0xC19, + CSR_HPMCOUNTER26 = 0xC1A, + CSR_HPMCOUNTER27 = 0xC1B, + CSR_HPMCOUNTER28 = 0xC1C, + CSR_HPMCOUNTER29 = 0xC1D, + CSR_HPMCOUNTER30 = 0xC1E, + CSR_HPMCOUNTER31 = 0xC1F, + // HPMCOUNTERH rv32 only + + CSR_SSTATUS = 0x100, + CSR_SEDELEG = 0x102, + CSR_SIDELEG = 0x103, + CSR_SIE = 0x104, + CSR_STVEC = 0x105, + CSR_SSCRATCH = 0x140, + CSR_SEPC = 0x141, + CSR_SCAUSE = 0x142, + CSR_STVAL = 0x143, + CSR_SIP = 0x144, + CSR_SATP = 0x180, + + CSR_MVENDORID = 0xF11, + CSR_MARCHID = 0xF12, + CSR_MIMPID = 0xF13, + CSR_MHARTID = 0xF14, + CSR_MSTATUS = 0x300, + CSR_MISA = 0x301, + CSR_MEDELEG = 0x302, + CSR_MIDELEG = 0x303, + CSR_MIE = 0x304, + CSR_MTVEC = 0x305, + CSR_MSCRATCH = 0x340, + CSR_MEPC = 0x341, + CSR_MCAUSE = 0x342, + CSR_MTVAL = 0x343, + CSR_MIP = 0x344, + CSR_PMPCFG0 = 0x3A0, + // pmpcfg1 rv32 only + CSR_PMPCFG2 = 0x3A2, + // pmpcfg3 rv32 only + CSR_PMPADDR00 = 0x3B0, + CSR_PMPADDR01 = 0x3B1, + CSR_PMPADDR02 = 0x3B2, + CSR_PMPADDR03 = 0x3B3, + CSR_PMPADDR04 = 0x3B4, + CSR_PMPADDR05 = 0x3B5, + CSR_PMPADDR06 = 0x3B6, + CSR_PMPADDR07 = 0x3B7, + CSR_PMPADDR08 = 0x3B8, + CSR_PMPADDR09 = 0x3B9, + CSR_PMPADDR10 = 0x3BA, + CSR_PMPADDR11 = 0x3BB, + CSR_PMPADDR12 = 0x3BC, + CSR_PMPADDR13 = 0x3BD, + CSR_PMPADDR14 = 0x3BE, + CSR_PMPADDR15 = 0x3BF, + CSR_MCYCLE = 0xB00, + CSR_MINSTRET = 0xB02, + CSR_MHPMCOUNTER03 = 0xC03, + CSR_MHPMCOUNTER04 = 0xC04, + CSR_MHPMCOUNTER05 = 0xC05, + CSR_MHPMCOUNTER06 = 0xC06, + CSR_MHPMCOUNTER07 = 0xC07, + CSR_MHPMCOUNTER08 = 0xC08, + CSR_MHPMCOUNTER09 = 0xC09, + CSR_MHPMCOUNTER10 = 0xC0A, + CSR_MHPMCOUNTER11 = 0xC0B, + CSR_MHPMCOUNTER12 = 0xC0C, + CSR_MHPMCOUNTER13 = 0xC0D, + CSR_MHPMCOUNTER14 = 0xC0E, + CSR_MHPMCOUNTER15 = 0xC0F, + CSR_MHPMCOUNTER16 = 0xC10, + CSR_MHPMCOUNTER17 = 0xC11, + CSR_MHPMCOUNTER18 = 0xC12, + CSR_MHPMCOUNTER19 = 0xC13, + CSR_MHPMCOUNTER20 = 0xC14, + CSR_MHPMCOUNTER21 = 0xC15, + CSR_MHPMCOUNTER22 = 0xC16, + CSR_MHPMCOUNTER23 = 0xC17, + CSR_MHPMCOUNTER24 = 0xC18, + CSR_MHPMCOUNTER25 = 0xC19, + CSR_MHPMCOUNTER26 = 0xC1A, + CSR_MHPMCOUNTER27 = 0xC1B, + CSR_MHPMCOUNTER28 = 0xC1C, + CSR_MHPMCOUNTER29 = 0xC1D, + CSR_MHPMCOUNTER30 = 0xC1E, + CSR_MHPMCOUNTER31 = 0xC1F, + // MHPMCOUNTERH rv32 only + CSR_MHPMEVENT03 = 0x323, + CSR_MHPMEVENT04 = 0x324, + CSR_MHPMEVENT05 = 0x325, + CSR_MHPMEVENT06 = 0x326, + CSR_MHPMEVENT07 = 0x327, + CSR_MHPMEVENT08 = 0x328, + CSR_MHPMEVENT09 = 0x329, + CSR_MHPMEVENT10 = 0x32A, + CSR_MHPMEVENT11 = 0x32B, + CSR_MHPMEVENT12 = 0x32C, + CSR_MHPMEVENT13 = 0x32D, + CSR_MHPMEVENT14 = 0x32E, + CSR_MHPMEVENT15 = 0x32F, + CSR_MHPMEVENT16 = 0x330, + CSR_MHPMEVENT17 = 0x331, + CSR_MHPMEVENT18 = 0x332, + CSR_MHPMEVENT19 = 0x333, + CSR_MHPMEVENT20 = 0x334, + CSR_MHPMEVENT21 = 0x335, + CSR_MHPMEVENT22 = 0x336, + CSR_MHPMEVENT23 = 0x337, + CSR_MHPMEVENT24 = 0x338, + CSR_MHPMEVENT25 = 0x339, + CSR_MHPMEVENT26 = 0x33A, + CSR_MHPMEVENT27 = 0x33B, + CSR_MHPMEVENT28 = 0x33C, + CSR_MHPMEVENT29 = 0x33D, + CSR_MHPMEVENT30 = 0x33E, + CSR_MHPMEVENT31 = 0x33F, + + CSR_TSELECT = 0x7A0, + CSR_TDATA1 = 0x7A1, + CSR_TDATA2 = 0x7A2, + CSR_TDATA3 = 0x7A3, + CSR_DCSR = 0x7B0, + CSR_DPC = 0x7B1, + CSR_DSCRATCH = 0x7B2 +}; + +struct CSRMetadata +{ + const std::string name; + const int physIndex; +}; + +const std::map CSRData = { + {CSR_USTATUS, {"ustatus", MISCREG_STATUS}}, + {CSR_UIE, {"uie", MISCREG_IE}}, + {CSR_UTVEC, {"utvec", MISCREG_UTVEC}}, + {CSR_USCRATCH, {"uscratch", MISCREG_USCRATCH}}, + {CSR_UEPC, {"uepc", MISCREG_UEPC}}, + {CSR_UCAUSE, {"ucause", MISCREG_UCAUSE}}, + {CSR_UTVAL, {"utval", MISCREG_UTVAL}}, + {CSR_UIP, {"uip", MISCREG_IP}}, + {CSR_FFLAGS, {"fflags", MISCREG_FFLAGS}}, + {CSR_FRM, {"frm", MISCREG_FRM}}, + {CSR_FCSR, {"fcsr", MISCREG_FFLAGS}}, // Actually FRM << 5 | FFLAGS + {CSR_CYCLE, {"cycle", MISCREG_CYCLE}}, + {CSR_TIME, {"time", MISCREG_TIME}}, + {CSR_INSTRET, {"instret", MISCREG_INSTRET}}, + {CSR_HPMCOUNTER03, {"hpmcounter03", MISCREG_HPMCOUNTER03}}, + {CSR_HPMCOUNTER04, {"hpmcounter04", MISCREG_HPMCOUNTER04}}, + {CSR_HPMCOUNTER05, {"hpmcounter05", MISCREG_HPMCOUNTER05}}, + {CSR_HPMCOUNTER06, {"hpmcounter06", MISCREG_HPMCOUNTER06}}, + {CSR_HPMCOUNTER07, {"hpmcounter07", MISCREG_HPMCOUNTER07}}, + {CSR_HPMCOUNTER08, {"hpmcounter08", MISCREG_HPMCOUNTER08}}, + {CSR_HPMCOUNTER09, {"hpmcounter09", MISCREG_HPMCOUNTER09}}, + {CSR_HPMCOUNTER10, {"hpmcounter10", MISCREG_HPMCOUNTER10}}, + {CSR_HPMCOUNTER11, {"hpmcounter11", MISCREG_HPMCOUNTER11}}, + {CSR_HPMCOUNTER12, {"hpmcounter12", MISCREG_HPMCOUNTER12}}, + {CSR_HPMCOUNTER13, {"hpmcounter13", MISCREG_HPMCOUNTER13}}, + {CSR_HPMCOUNTER14, {"hpmcounter14", MISCREG_HPMCOUNTER14}}, + {CSR_HPMCOUNTER15, {"hpmcounter15", MISCREG_HPMCOUNTER15}}, + {CSR_HPMCOUNTER16, {"hpmcounter16", MISCREG_HPMCOUNTER16}}, + {CSR_HPMCOUNTER17, {"hpmcounter17", MISCREG_HPMCOUNTER17}}, + {CSR_HPMCOUNTER18, {"hpmcounter18", MISCREG_HPMCOUNTER18}}, + {CSR_HPMCOUNTER19, {"hpmcounter19", MISCREG_HPMCOUNTER19}}, + {CSR_HPMCOUNTER20, {"hpmcounter20", MISCREG_HPMCOUNTER20}}, + {CSR_HPMCOUNTER21, {"hpmcounter21", MISCREG_HPMCOUNTER21}}, + {CSR_HPMCOUNTER22, {"hpmcounter22", MISCREG_HPMCOUNTER22}}, + {CSR_HPMCOUNTER23, {"hpmcounter23", MISCREG_HPMCOUNTER23}}, + {CSR_HPMCOUNTER24, {"hpmcounter24", MISCREG_HPMCOUNTER24}}, + {CSR_HPMCOUNTER25, {"hpmcounter25", MISCREG_HPMCOUNTER25}}, + {CSR_HPMCOUNTER26, {"hpmcounter26", MISCREG_HPMCOUNTER26}}, + {CSR_HPMCOUNTER27, {"hpmcounter27", MISCREG_HPMCOUNTER27}}, + {CSR_HPMCOUNTER28, {"hpmcounter28", MISCREG_HPMCOUNTER28}}, + {CSR_HPMCOUNTER29, {"hpmcounter29", MISCREG_HPMCOUNTER29}}, + {CSR_HPMCOUNTER30, {"hpmcounter30", MISCREG_HPMCOUNTER30}}, + {CSR_HPMCOUNTER31, {"hpmcounter31", MISCREG_HPMCOUNTER31}}, + + {CSR_SSTATUS, {"sstatus", MISCREG_STATUS}}, + {CSR_SEDELEG, {"sedeleg", MISCREG_SEDELEG}}, + {CSR_SIDELEG, {"sideleg", MISCREG_SIDELEG}}, + {CSR_SIE, {"sie", MISCREG_IE}}, + {CSR_STVEC, {"stvec", MISCREG_STVEC}}, + {CSR_SSCRATCH, {"sscratch", MISCREG_SSCRATCH}}, + {CSR_SEPC, {"sepc", MISCREG_SEPC}}, + {CSR_SCAUSE, {"scause", MISCREG_SCAUSE}}, + {CSR_STVAL, {"stval", MISCREG_STVAL}}, + {CSR_SIP, {"sip", MISCREG_IP}}, + {CSR_SATP, {"satp", MISCREG_SATP}}, + + {CSR_MVENDORID, {"mvendorid", MISCREG_VENDORID}}, + {CSR_MARCHID, {"marchid", MISCREG_ARCHID}}, + {CSR_MIMPID, {"mimpid", MISCREG_IMPID}}, + {CSR_MHARTID, {"mhartid", MISCREG_HARTID}}, + {CSR_MSTATUS, {"mstatus", MISCREG_STATUS}}, + {CSR_MISA, {"misa", MISCREG_ISA}}, + {CSR_MEDELEG, {"medeleg", MISCREG_MEDELEG}}, + {CSR_MIDELEG, {"mideleg", MISCREG_MIDELEG}}, + {CSR_MIE, {"mie", MISCREG_IE}}, + {CSR_MTVEC, {"mtvec", MISCREG_MTVEC}}, + {CSR_MSCRATCH, {"mscratch", MISCREG_MSCRATCH}}, + {CSR_MEPC, {"mepc", MISCREG_MEPC}}, + {CSR_MCAUSE, {"mcause", MISCREG_MCAUSE}}, + {CSR_MTVAL, {"mtval", MISCREG_MTVAL}}, + {CSR_MIP, {"mip", MISCREG_IP}}, + {CSR_PMPCFG0, {"pmpcfg0", MISCREG_PMPCFG0}}, + // pmpcfg1 rv32 only + {CSR_PMPCFG2, {"pmpcfg2", MISCREG_PMPCFG2}}, + // pmpcfg3 rv32 only + {CSR_PMPADDR00, {"pmpaddr0", MISCREG_PMPADDR00}}, + {CSR_PMPADDR01, {"pmpaddr1", MISCREG_PMPADDR01}}, + {CSR_PMPADDR02, {"pmpaddr2", MISCREG_PMPADDR02}}, + {CSR_PMPADDR03, {"pmpaddr3", MISCREG_PMPADDR03}}, + {CSR_PMPADDR04, {"pmpaddr4", MISCREG_PMPADDR04}}, + {CSR_PMPADDR05, {"pmpaddr5", MISCREG_PMPADDR05}}, + {CSR_PMPADDR06, {"pmpaddr6", MISCREG_PMPADDR06}}, + {CSR_PMPADDR07, {"pmpaddr7", MISCREG_PMPADDR07}}, + {CSR_PMPADDR08, {"pmpaddr8", MISCREG_PMPADDR08}}, + {CSR_PMPADDR09, {"pmpaddr9", MISCREG_PMPADDR09}}, + {CSR_PMPADDR10, {"pmpaddr10", MISCREG_PMPADDR10}}, + {CSR_PMPADDR11, {"pmpaddr11", MISCREG_PMPADDR11}}, + {CSR_PMPADDR12, {"pmpaddr12", MISCREG_PMPADDR12}}, + {CSR_PMPADDR13, {"pmpaddr13", MISCREG_PMPADDR13}}, + {CSR_PMPADDR14, {"pmpaddr14", MISCREG_PMPADDR14}}, + {CSR_PMPADDR15, {"pmpaddr15", MISCREG_PMPADDR15}}, + {CSR_MCYCLE, {"mcycle", MISCREG_CYCLE}}, + {CSR_MINSTRET, {"minstret", MISCREG_INSTRET}}, + {CSR_MHPMCOUNTER03, {"mhpmcounter03", MISCREG_HPMCOUNTER03}}, + {CSR_MHPMCOUNTER04, {"mhpmcounter04", MISCREG_HPMCOUNTER04}}, + {CSR_MHPMCOUNTER05, {"mhpmcounter05", MISCREG_HPMCOUNTER05}}, + {CSR_MHPMCOUNTER06, {"mhpmcounter06", MISCREG_HPMCOUNTER06}}, + {CSR_MHPMCOUNTER07, {"mhpmcounter07", MISCREG_HPMCOUNTER07}}, + {CSR_MHPMCOUNTER08, {"mhpmcounter08", MISCREG_HPMCOUNTER08}}, + {CSR_MHPMCOUNTER09, {"mhpmcounter09", MISCREG_HPMCOUNTER09}}, + {CSR_MHPMCOUNTER10, {"mhpmcounter10", MISCREG_HPMCOUNTER10}}, + {CSR_MHPMCOUNTER11, {"mhpmcounter11", MISCREG_HPMCOUNTER11}}, + {CSR_MHPMCOUNTER12, {"mhpmcounter12", MISCREG_HPMCOUNTER12}}, + {CSR_MHPMCOUNTER13, {"mhpmcounter13", MISCREG_HPMCOUNTER13}}, + {CSR_MHPMCOUNTER14, {"mhpmcounter14", MISCREG_HPMCOUNTER14}}, + {CSR_MHPMCOUNTER15, {"mhpmcounter15", MISCREG_HPMCOUNTER15}}, + {CSR_MHPMCOUNTER16, {"mhpmcounter16", MISCREG_HPMCOUNTER16}}, + {CSR_MHPMCOUNTER17, {"mhpmcounter17", MISCREG_HPMCOUNTER17}}, + {CSR_MHPMCOUNTER18, {"mhpmcounter18", MISCREG_HPMCOUNTER18}}, + {CSR_MHPMCOUNTER19, {"mhpmcounter19", MISCREG_HPMCOUNTER19}}, + {CSR_MHPMCOUNTER20, {"mhpmcounter20", MISCREG_HPMCOUNTER20}}, + {CSR_MHPMCOUNTER21, {"mhpmcounter21", MISCREG_HPMCOUNTER21}}, + {CSR_MHPMCOUNTER22, {"mhpmcounter22", MISCREG_HPMCOUNTER22}}, + {CSR_MHPMCOUNTER23, {"mhpmcounter23", MISCREG_HPMCOUNTER23}}, + {CSR_MHPMCOUNTER24, {"mhpmcounter24", MISCREG_HPMCOUNTER24}}, + {CSR_MHPMCOUNTER25, {"mhpmcounter25", MISCREG_HPMCOUNTER25}}, + {CSR_MHPMCOUNTER26, {"mhpmcounter26", MISCREG_HPMCOUNTER26}}, + {CSR_MHPMCOUNTER27, {"mhpmcounter27", MISCREG_HPMCOUNTER27}}, + {CSR_MHPMCOUNTER28, {"mhpmcounter28", MISCREG_HPMCOUNTER28}}, + {CSR_MHPMCOUNTER29, {"mhpmcounter29", MISCREG_HPMCOUNTER29}}, + {CSR_MHPMCOUNTER30, {"mhpmcounter30", MISCREG_HPMCOUNTER30}}, + {CSR_MHPMCOUNTER31, {"mhpmcounter31", MISCREG_HPMCOUNTER31}}, + {CSR_MHPMEVENT03, {"mhpmevent03", MISCREG_HPMEVENT03}}, + {CSR_MHPMEVENT04, {"mhpmevent04", MISCREG_HPMEVENT04}}, + {CSR_MHPMEVENT05, {"mhpmevent05", MISCREG_HPMEVENT05}}, + {CSR_MHPMEVENT06, {"mhpmevent06", MISCREG_HPMEVENT06}}, + {CSR_MHPMEVENT07, {"mhpmevent07", MISCREG_HPMEVENT07}}, + {CSR_MHPMEVENT08, {"mhpmevent08", MISCREG_HPMEVENT08}}, + {CSR_MHPMEVENT09, {"mhpmevent09", MISCREG_HPMEVENT09}}, + {CSR_MHPMEVENT10, {"mhpmevent10", MISCREG_HPMEVENT10}}, + {CSR_MHPMEVENT11, {"mhpmevent11", MISCREG_HPMEVENT11}}, + {CSR_MHPMEVENT12, {"mhpmevent12", MISCREG_HPMEVENT12}}, + {CSR_MHPMEVENT13, {"mhpmevent13", MISCREG_HPMEVENT13}}, + {CSR_MHPMEVENT14, {"mhpmevent14", MISCREG_HPMEVENT14}}, + {CSR_MHPMEVENT15, {"mhpmevent15", MISCREG_HPMEVENT15}}, + {CSR_MHPMEVENT16, {"mhpmevent16", MISCREG_HPMEVENT16}}, + {CSR_MHPMEVENT17, {"mhpmevent17", MISCREG_HPMEVENT17}}, + {CSR_MHPMEVENT18, {"mhpmevent18", MISCREG_HPMEVENT18}}, + {CSR_MHPMEVENT19, {"mhpmevent19", MISCREG_HPMEVENT19}}, + {CSR_MHPMEVENT20, {"mhpmevent20", MISCREG_HPMEVENT20}}, + {CSR_MHPMEVENT21, {"mhpmevent21", MISCREG_HPMEVENT21}}, + {CSR_MHPMEVENT22, {"mhpmevent22", MISCREG_HPMEVENT22}}, + {CSR_MHPMEVENT23, {"mhpmevent23", MISCREG_HPMEVENT23}}, + {CSR_MHPMEVENT24, {"mhpmevent24", MISCREG_HPMEVENT24}}, + {CSR_MHPMEVENT25, {"mhpmevent25", MISCREG_HPMEVENT25}}, + {CSR_MHPMEVENT26, {"mhpmevent26", MISCREG_HPMEVENT26}}, + {CSR_MHPMEVENT27, {"mhpmevent27", MISCREG_HPMEVENT27}}, + {CSR_MHPMEVENT28, {"mhpmevent28", MISCREG_HPMEVENT28}}, + {CSR_MHPMEVENT29, {"mhpmevent29", MISCREG_HPMEVENT29}}, + {CSR_MHPMEVENT30, {"mhpmevent30", MISCREG_HPMEVENT30}}, + {CSR_MHPMEVENT31, {"mhpmevent31", MISCREG_HPMEVENT31}}, + + {CSR_TSELECT, {"tselect", MISCREG_TSELECT}}, + {CSR_TDATA1, {"tdata1", MISCREG_TDATA1}}, + {CSR_TDATA2, {"tdata2", MISCREG_TDATA2}}, + {CSR_TDATA3, {"tdata3", MISCREG_TDATA3}}, + {CSR_DCSR, {"dcsr", MISCREG_DCSR}}, + {CSR_DPC, {"dpc", MISCREG_DPC}}, + {CSR_DSCRATCH, {"dscratch", MISCREG_DSCRATCH}} }; -const std::map MiscRegNames = { - {MISCREG_USTATUS, "ustatus"}, - {MISCREG_UIE, "uie"}, - {MISCREG_UTVEC, "utvec"}, - {MISCREG_USCRATCH, "uscratch"}, - {MISCREG_UEPC, "uepc"}, - {MISCREG_UCAUSE, "ucause"}, - {MISCREG_UBADADDR, "ubadaddr"}, - {MISCREG_UIP, "uip"}, - {MISCREG_FFLAGS, "fflags"}, - {MISCREG_FRM, "frm"}, - {MISCREG_FCSR, "fcsr"}, - {MISCREG_CYCLE, "cycle"}, - {MISCREG_TIME, "time"}, - {MISCREG_INSTRET, "instret"}, - {MISCREG_HPMCOUNTER_BASE + 0, "hpmcounter03"}, - {MISCREG_HPMCOUNTER_BASE + 1, "hpmcounter04"}, - {MISCREG_HPMCOUNTER_BASE + 2, "hpmcounter05"}, - {MISCREG_HPMCOUNTER_BASE + 3, "hpmcounter06"}, - {MISCREG_HPMCOUNTER_BASE + 4, "hpmcounter07"}, - {MISCREG_HPMCOUNTER_BASE + 5, "hpmcounter08"}, - {MISCREG_HPMCOUNTER_BASE + 6, "hpmcounter09"}, - {MISCREG_HPMCOUNTER_BASE + 7, "hpmcounter10"}, - {MISCREG_HPMCOUNTER_BASE + 8, "hpmcounter11"}, - {MISCREG_HPMCOUNTER_BASE + 9, "hpmcounter12"}, - {MISCREG_HPMCOUNTER_BASE + 10, "hpmcounter13"}, - {MISCREG_HPMCOUNTER_BASE + 11, "hpmcounter14"}, - {MISCREG_HPMCOUNTER_BASE + 12, "hpmcounter15"}, - {MISCREG_HPMCOUNTER_BASE + 13, "hpmcounter16"}, - {MISCREG_HPMCOUNTER_BASE + 14, "hpmcounter17"}, - {MISCREG_HPMCOUNTER_BASE + 15, "hpmcounter18"}, - {MISCREG_HPMCOUNTER_BASE + 16, "hpmcounter19"}, - {MISCREG_HPMCOUNTER_BASE + 17, "hpmcounter20"}, - {MISCREG_HPMCOUNTER_BASE + 18, "hpmcounter21"}, - {MISCREG_HPMCOUNTER_BASE + 19, "hpmcounter22"}, - {MISCREG_HPMCOUNTER_BASE + 20, "hpmcounter23"}, - {MISCREG_HPMCOUNTER_BASE + 21, "hpmcounter24"}, - {MISCREG_HPMCOUNTER_BASE + 22, "hpmcounter25"}, - {MISCREG_HPMCOUNTER_BASE + 23, "hpmcounter26"}, - {MISCREG_HPMCOUNTER_BASE + 24, "hpmcounter27"}, - {MISCREG_HPMCOUNTER_BASE + 25, "hpmcounter28"}, - {MISCREG_HPMCOUNTER_BASE + 26, "hpmcounter29"}, - {MISCREG_HPMCOUNTER_BASE + 27, "hpmcounter30"}, - {MISCREG_HPMCOUNTER_BASE + 28, "hpmcounter31"}, - {MISCREG_CYCLEH, "cycleh"}, - {MISCREG_TIMEH, "timeh"}, - {MISCREG_INSTRETH, "instreth"}, - {MISCREG_HPMCOUNTERH_BASE + 0, "hpmcounterh03"}, - {MISCREG_HPMCOUNTERH_BASE + 1, "hpmcounterh04"}, - {MISCREG_HPMCOUNTERH_BASE + 2, "hpmcounterh05"}, - {MISCREG_HPMCOUNTERH_BASE + 3, "hpmcounterh06"}, - {MISCREG_HPMCOUNTERH_BASE + 4, "hpmcounterh07"}, - {MISCREG_HPMCOUNTERH_BASE + 5, "hpmcounterh08"}, - {MISCREG_HPMCOUNTERH_BASE + 6, "hpmcounterh09"}, - {MISCREG_HPMCOUNTERH_BASE + 7, "hpmcounterh10"}, - {MISCREG_HPMCOUNTERH_BASE + 8, "hpmcounterh11"}, - {MISCREG_HPMCOUNTERH_BASE + 9, "hpmcounterh12"}, - {MISCREG_HPMCOUNTERH_BASE + 10, "hpmcounterh13"}, - {MISCREG_HPMCOUNTERH_BASE + 11, "hpmcounterh14"}, - {MISCREG_HPMCOUNTERH_BASE + 12, "hpmcounterh15"}, - {MISCREG_HPMCOUNTERH_BASE + 13, "hpmcounterh16"}, - {MISCREG_HPMCOUNTERH_BASE + 14, "hpmcounterh17"}, - {MISCREG_HPMCOUNTERH_BASE + 15, "hpmcounterh18"}, - {MISCREG_HPMCOUNTERH_BASE + 16, "hpmcounterh19"}, - {MISCREG_HPMCOUNTERH_BASE + 17, "hpmcounterh20"}, - {MISCREG_HPMCOUNTERH_BASE + 18, "hpmcounterh21"}, - {MISCREG_HPMCOUNTERH_BASE + 19, "hpmcounterh22"}, - {MISCREG_HPMCOUNTERH_BASE + 20, "hpmcounterh23"}, - {MISCREG_HPMCOUNTERH_BASE + 21, "hpmcounterh24"}, - {MISCREG_HPMCOUNTERH_BASE + 22, "hpmcounterh25"}, - {MISCREG_HPMCOUNTERH_BASE + 23, "hpmcounterh26"}, - {MISCREG_HPMCOUNTERH_BASE + 24, "hpmcounterh27"}, - {MISCREG_HPMCOUNTERH_BASE + 25, "hpmcounterh28"}, - {MISCREG_HPMCOUNTERH_BASE + 26, "hpmcounterh29"}, - {MISCREG_HPMCOUNTERH_BASE + 27, "hpmcounterh30"}, - {MISCREG_HPMCOUNTERH_BASE + 28, "hpmcounterh31"}, - - {MISCREG_SSTATUS, "sstatus"}, - {MISCREG_SEDELEG, "sedeleg"}, - {MISCREG_SIDELEG, "sideleg"}, - {MISCREG_SIE, "sie"}, - {MISCREG_STVEC, "stvec"}, - {MISCREG_SSCRATCH, "sscratch"}, - {MISCREG_SEPC, "sepc"}, - {MISCREG_SCAUSE, "scause"}, - {MISCREG_SBADADDR, "sbadaddr"}, - {MISCREG_SIP, "sip"}, - {MISCREG_SPTBR, "sptbr"}, - - {MISCREG_HSTATUS, "hstatus"}, - {MISCREG_HEDELEG, "hedeleg"}, - {MISCREG_HIDELEG, "hideleg"}, - {MISCREG_HIE, "hie"}, - {MISCREG_HTVEC, "htvec"}, - {MISCREG_HSCRATCH, "hscratch"}, - {MISCREG_HEPC, "hepc"}, - {MISCREG_HCAUSE, "hcause"}, - {MISCREG_HBADADDR, "hbadaddr"}, - {MISCREG_HIP, "hip"}, - - {MISCREG_MVENDORID, "mvendorid"}, - {MISCREG_MARCHID, "marchid"}, - {MISCREG_MIMPID, "mimpid"}, - {MISCREG_MHARTID, "mhartid"}, - {MISCREG_MSTATUS, "mstatus"}, - {MISCREG_MISA, "misa"}, - {MISCREG_MEDELEG, "medeleg"}, - {MISCREG_MIDELEG, "mideleg"}, - {MISCREG_MIE, "mie"}, - {MISCREG_MTVEC, "mtvec"}, - {MISCREG_MSCRATCH, "mscratch"}, - {MISCREG_MEPC, "mepc"}, - {MISCREG_MCAUSE, "mcause"}, - {MISCREG_MBADADDR, "mbadaddr"}, - {MISCREG_MIP, "mip"}, - {MISCREG_MBASE, "mbase"}, - {MISCREG_MBOUND, "mbound"}, - {MISCREG_MIBASE, "mibase"}, - {MISCREG_MIBOUND, "mibound"}, - {MISCREG_MDBASE, "mdbase"}, - {MISCREG_MDBOUND, "mdbound"}, - {MISCREG_MCYCLE, "mcycle"}, - {MISCREG_MINSTRET, "minstret"}, - {MISCREG_MHPMCOUNTER_BASE + 0, "mhpmcounter03"}, - {MISCREG_MHPMCOUNTER_BASE + 1, "mhpmcounter04"}, - {MISCREG_MHPMCOUNTER_BASE + 2, "mhpmcounter05"}, - {MISCREG_MHPMCOUNTER_BASE + 3, "mhpmcounter06"}, - {MISCREG_MHPMCOUNTER_BASE + 4, "mhpmcounter07"}, - {MISCREG_MHPMCOUNTER_BASE + 5, "mhpmcounter08"}, - {MISCREG_MHPMCOUNTER_BASE + 6, "mhpmcounter09"}, - {MISCREG_MHPMCOUNTER_BASE + 7, "mhpmcounter10"}, - {MISCREG_MHPMCOUNTER_BASE + 8, "mhpmcounter11"}, - {MISCREG_MHPMCOUNTER_BASE + 9, "mhpmcounter12"}, - {MISCREG_MHPMCOUNTER_BASE + 10, "mhpmcounter13"}, - {MISCREG_MHPMCOUNTER_BASE + 11, "mhpmcounter14"}, - {MISCREG_MHPMCOUNTER_BASE + 12, "mhpmcounter15"}, - {MISCREG_MHPMCOUNTER_BASE + 13, "mhpmcounter16"}, - {MISCREG_MHPMCOUNTER_BASE + 14, "mhpmcounter17"}, - {MISCREG_MHPMCOUNTER_BASE + 15, "mhpmcounter18"}, - {MISCREG_MHPMCOUNTER_BASE + 16, "mhpmcounter19"}, - {MISCREG_MHPMCOUNTER_BASE + 17, "mhpmcounter20"}, - {MISCREG_MHPMCOUNTER_BASE + 18, "mhpmcounter21"}, - {MISCREG_MHPMCOUNTER_BASE + 19, "mhpmcounter22"}, - {MISCREG_MHPMCOUNTER_BASE + 20, "mhpmcounter23"}, - {MISCREG_MHPMCOUNTER_BASE + 21, "mhpmcounter24"}, - {MISCREG_MHPMCOUNTER_BASE + 22, "mhpmcounter25"}, - {MISCREG_MHPMCOUNTER_BASE + 23, "mhpmcounter26"}, - {MISCREG_MHPMCOUNTER_BASE + 24, "mhpmcounter27"}, - {MISCREG_MHPMCOUNTER_BASE + 25, "mhpmcounter28"}, - {MISCREG_MHPMCOUNTER_BASE + 26, "mhpmcounter29"}, - {MISCREG_MHPMCOUNTER_BASE + 27, "mhpmcounter30"}, - {MISCREG_MHPMCOUNTER_BASE + 28, "mhpmcounter31"}, - {MISCREG_MUCOUNTEREN, "mucounteren"}, - {MISCREG_MSCOUNTEREN, "mscounteren"}, - {MISCREG_MHCOUNTEREN, "mhcounteren"}, - {MISCREG_MHPMEVENT_BASE + 0, "mhpmevent03"}, - {MISCREG_MHPMEVENT_BASE + 1, "mhpmevent04"}, - {MISCREG_MHPMEVENT_BASE + 2, "mhpmevent05"}, - {MISCREG_MHPMEVENT_BASE + 3, "mhpmevent06"}, - {MISCREG_MHPMEVENT_BASE + 4, "mhpmevent07"}, - {MISCREG_MHPMEVENT_BASE + 5, "mhpmevent08"}, - {MISCREG_MHPMEVENT_BASE + 6, "mhpmevent09"}, - {MISCREG_MHPMEVENT_BASE + 7, "mhpmevent10"}, - {MISCREG_MHPMEVENT_BASE + 8, "mhpmevent11"}, - {MISCREG_MHPMEVENT_BASE + 9, "mhpmevent12"}, - {MISCREG_MHPMEVENT_BASE + 10, "mhpmevent13"}, - {MISCREG_MHPMEVENT_BASE + 11, "mhpmevent14"}, - {MISCREG_MHPMEVENT_BASE + 12, "mhpmevent15"}, - {MISCREG_MHPMEVENT_BASE + 13, "mhpmevent16"}, - {MISCREG_MHPMEVENT_BASE + 14, "mhpmevent17"}, - {MISCREG_MHPMEVENT_BASE + 15, "mhpmevent18"}, - {MISCREG_MHPMEVENT_BASE + 16, "mhpmevent19"}, - {MISCREG_MHPMEVENT_BASE + 17, "mhpmevent20"}, - {MISCREG_MHPMEVENT_BASE + 18, "mhpmevent21"}, - {MISCREG_MHPMEVENT_BASE + 19, "mhpmevent22"}, - {MISCREG_MHPMEVENT_BASE + 20, "mhpmevent23"}, - {MISCREG_MHPMEVENT_BASE + 21, "mhpmevent24"}, - {MISCREG_MHPMEVENT_BASE + 22, "mhpmevent25"}, - {MISCREG_MHPMEVENT_BASE + 23, "mhpmevent26"}, - {MISCREG_MHPMEVENT_BASE + 24, "mhpmevent27"}, - {MISCREG_MHPMEVENT_BASE + 25, "mhpmevent28"}, - {MISCREG_MHPMEVENT_BASE + 26, "mhpmevent29"}, - {MISCREG_MHPMEVENT_BASE + 27, "mhpmevent30"}, - {MISCREG_MHPMEVENT_BASE + 28, "mhpmevent31"}, - - {MISCREG_TSELECT, "tselect"}, - {MISCREG_TDATA1, "tdata1"}, - {MISCREG_TDATA2, "tdata2"}, - {MISCREG_TDATA3, "tdata3"}, - {MISCREG_DCSR, "dcsr"}, - {MISCREG_DPC, "dpc"}, - {MISCREG_DSCRATCH, "dscratch"} +const off_t MXL_OFFSET = (sizeof(MiscReg) * 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 MiscReg ISA_MXL_MASK = 3ULL << MXL_OFFSET; +const MiscReg ISA_EXT_MASK = mask(26); +const MiscReg MISA_MASK = ISA_MXL_MASK | ISA_EXT_MASK; + +const MiscReg STATUS_SD_MASK = 1ULL << ((sizeof(MiscReg) * 8) - 1); +const MiscReg STATUS_SXL_MASK = 3ULL << SXL_OFFSET; +const MiscReg STATUS_UXL_MASK = 3ULL << UXL_OFFSET; +const MiscReg STATUS_TSR_MASK = 1ULL << 22; +const MiscReg STATUS_TW_MASK = 1ULL << 21; +const MiscReg STATUS_TVM_MASK = 1ULL << 20; +const MiscReg STATUS_MXR_MASK = 1ULL << 19; +const MiscReg STATUS_SUM_MASK = 1ULL << 18; +const MiscReg STATUS_MPRV_MASK = 1ULL << 17; +const MiscReg STATUS_XS_MASK = 3ULL << 15; +const MiscReg STATUS_FS_MASK = 3ULL << FS_OFFSET; +const MiscReg STATUS_MPP_MASK = 3ULL << 11; +const MiscReg STATUS_SPP_MASK = 1ULL << 8; +const MiscReg STATUS_MPIE_MASK = 1ULL << 7; +const MiscReg STATUS_SPIE_MASK = 1ULL << 5; +const MiscReg STATUS_UPIE_MASK = 1ULL << 4; +const MiscReg STATUS_MIE_MASK = 1ULL << 3; +const MiscReg STATUS_SIE_MASK = 1ULL << 1; +const MiscReg STATUS_UIE_MASK = 1ULL << 0; +const MiscReg 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_MPP_MASK | + STATUS_SPP_MASK | STATUS_MPIE_MASK | + STATUS_SPIE_MASK | STATUS_UPIE_MASK | + STATUS_MIE_MASK | STATUS_SIE_MASK | + STATUS_UIE_MASK; +const MiscReg SSTATUS_MASK = STATUS_SD_MASK | STATUS_UXL_MASK | + STATUS_MXR_MASK | STATUS_SUM_MASK | + STATUS_XS_MASK | STATUS_FS_MASK | + STATUS_SPP_MASK | STATUS_SPIE_MASK | + STATUS_UPIE_MASK | STATUS_SIE_MASK | + STATUS_UIE_MASK; +const MiscReg USTATUS_MASK = STATUS_SD_MASK | STATUS_MXR_MASK | + STATUS_SUM_MASK | STATUS_XS_MASK | + STATUS_FS_MASK | STATUS_UPIE_MASK | + STATUS_UIE_MASK; + +const MiscReg MEI_MASK = 1ULL << 11; +const MiscReg SEI_MASK = 1ULL << 9; +const MiscReg UEI_MASK = 1ULL << 8; +const MiscReg MTI_MASK = 1ULL << 7; +const MiscReg STI_MASK = 1ULL << 5; +const MiscReg UTI_MASK = 1ULL << 4; +const MiscReg MSI_MASK = 1ULL << 3; +const MiscReg SSI_MASK = 1ULL << 1; +const MiscReg USI_MASK = 1ULL << 0; +const MiscReg MI_MASK = MEI_MASK | SEI_MASK | UEI_MASK | + MTI_MASK | STI_MASK | UTI_MASK | + MSI_MASK | SSI_MASK | USI_MASK; +const MiscReg SI_MASK = SEI_MASK | UEI_MASK | + STI_MASK | UTI_MASK | + SSI_MASK | USI_MASK; +const MiscReg UI_MASK = UEI_MASK | UTI_MASK | USI_MASK; +const MiscReg FFLAGS_MASK = (1 << FRM_OFFSET) - 1; +const MiscReg FRM_MASK = 0x7; + +const std::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} }; } diff --git a/src/arch/riscv/remote_gdb.cc b/src/arch/riscv/remote_gdb.cc index f4e606e27..6d56a93b6 100644 --- a/src/arch/riscv/remote_gdb.cc +++ b/src/arch/riscv/remote_gdb.cc @@ -171,9 +171,9 @@ RemoteGDB::RiscvGdbRegCache::getRegs(ThreadContext *context) r.fpr[i] = context->readFloatRegBits(i); r.csr_base = context->readMiscReg(0); - r.fflags = context->readMiscReg(MISCREG_FFLAGS); - r.frm = context->readMiscReg(MISCREG_FRM); - r.fcsr = context->readMiscReg(MISCREG_FCSR); + r.fflags = context->readMiscReg(CSR_FFLAGS); + r.frm = context->readMiscReg(CSR_FRM); + r.fcsr = context->readMiscReg(CSR_FCSR); for (int i = ExplicitCSRs; i < NumMiscRegs; i++) r.csr[i - ExplicitCSRs] = context->readMiscReg(i); } @@ -189,9 +189,9 @@ RemoteGDB::RiscvGdbRegCache::setRegs(ThreadContext *context) const context->setFloatRegBits(i, r.fpr[i]); context->setMiscReg(0, r.csr_base); - context->setMiscReg(MISCREG_FFLAGS, r.fflags); - context->setMiscReg(MISCREG_FRM, r.frm); - context->setMiscReg(MISCREG_FCSR, r.fcsr); + context->setMiscReg(CSR_FFLAGS, r.fflags); + context->setMiscReg(CSR_FRM, r.frm); + context->setMiscReg(CSR_FCSR, r.fcsr); for (int i = ExplicitCSRs; i < NumMiscRegs; i++) context->setMiscReg(i, r.csr[i - ExplicitCSRs]); } -- 2.30.2