arch-riscv: Update CSR implementations
authorAlec Roelke <ar4jc@virginia.edu>
Sun, 10 Dec 2017 19:15:51 +0000 (14:15 -0500)
committerAlec Roelke <ar4jc@virginia.edu>
Sat, 12 May 2018 19:13:05 +0000 (19:13 +0000)
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 <gabeblack@google.com>
Maintainer: Alec Roelke <ar4jc@virginia.edu>

src/arch/riscv/insts/standard.cc
src/arch/riscv/isa.cc
src/arch/riscv/isa.hh
src/arch/riscv/isa/decoder.isa
src/arch/riscv/isa/formats/standard.isa
src/arch/riscv/isa/includes.isa
src/arch/riscv/process.cc
src/arch/riscv/registers.hh
src/arch/riscv/remote_gdb.cc

index 60cf4fc2b6c096ba11c5467d63805808206b56fe..9354a542f47f3c664703a6f86715a47affca415b 100644 (file)
@@ -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
+}
index 6091068efeeb0c3c8b7a47eb3dedf10991fcd441..6824e703429b041cba5f34baa74e25c064f27d0a 100644 (file)
@@ -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
index 4f8b4dc7ae6e432c21429ca98001988463753fe6..f96b07275d837bfaed7d8bc7b10d040d6f024726 100644 (file)
@@ -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<MiscReg> 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 &regId) 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 &regId) 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);
 };
index e3992d712ce6b24966251011445f164a71c2e3ac..d8f3395e398e80b9bd232dd1a6880b6bb74cde6c 100644 (file)
@@ -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);
             }
         }
index 2e0e3edd4948a6c10c6befc38c5ba940b6a205d4..e69ad7ee5c848f21ea7c2494b21edcd255af5d04 100644 (file)
@@ -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<IllegalInstFault>(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<IllegalInstFault>(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)
 }};
index 9f3d99fb5300f17650cf9c21d17f02dee4a15d6d..d992685e1429618178f4efb775038650592556bf 100644 (file)
@@ -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"
index b3e98aefbda5ead4bba8a70920f3339faefe240e..4afc72147ad071cc6ee72bda38c4167f725bc03f 100644 (file)
@@ -41,7 +41,9 @@
 #include <string>
 #include <vector>
 
+#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<uint64_t>(PageBytes);
+    for (ContextID ctx: contextIds)
+        system->getThreadContext(ctx)->setMiscRegNoEffect(MISCREG_PRV, PRV_U);
 }
 
 template<class IntType> void
index a61554c132e206b79df03a47d01e316fecaa68ef..e1d57ee53296eeaa1bd621ef4c2df7b19f85a2f3 100644 (file)
@@ -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<std::string> 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<int, CSRMetadata> 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<int, std::string> 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<int, MiscReg> 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}
 };
 
 }
index f4e606e275af1f9f2306dd3ae5d3068a7cec367f..6d56a93b6c3f934d8a99178941f2adf7f296c665 100644 (file)
@@ -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]);
 }