diff options
author | Alec Roelke <ar4jc@virginia.edu> | 2017-12-10 14:15:51 -0500 |
---|---|---|
committer | Alec Roelke <ar4jc@virginia.edu> | 2018-05-12 19:13:05 +0000 |
commit | ce00e6042d996a9255960917f99009d9826b3885 (patch) | |
tree | 3edaebe9648e7083a6e8e68c008147b476cefd5b /src/arch/riscv/isa/formats | |
parent | e89e83529ad17bc1ae7ae23d337fd4067db01708 (diff) | |
download | gem5-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/formats')
-rw-r--r-- | src/arch/riscv/isa/formats/standard.isa | 68 |
1 files changed, 67 insertions, 1 deletions
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<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) }}; |