summaryrefslogtreecommitdiff
path: root/src/arch/riscv/isa/formats/standard.isa
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/formats/standard.isa
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/formats/standard.isa')
-rw-r--r--src/arch/riscv/isa/formats/standard.isa68
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)
}};