summaryrefslogtreecommitdiff
path: root/src/arch/riscv/isa.cc
diff options
context:
space:
mode:
authorAlec Roelke <ar4jc@virginia.edu>2017-12-10 14:15:51 -0500
committerAlec Roelke <ar4jc@virginia.edu>2018-05-12 19:13:05 +0000
commitce00e6042d996a9255960917f99009d9826b3885 (patch)
tree3edaebe9648e7083a6e8e68c008147b476cefd5b /src/arch/riscv/isa.cc
parente89e83529ad17bc1ae7ae23d337fd4067db01708 (diff)
downloadgem5-ce00e6042d996a9255960917f99009d9826b3885.tar.xz
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 <gabeblack@google.com> Maintainer: Alec Roelke <ar4jc@virginia.edu>
Diffstat (limited to 'src/arch/riscv/isa.cc')
-rw-r--r--src/arch/riscv/isa.cc161
1 files changed, 88 insertions, 73 deletions
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