arch-riscv: implement sfence.vma to flush TLBs.
authorNils Asmussen <nils.asmussen@barkhauseninstitut.org>
Sat, 21 Mar 2020 09:58:58 +0000 (10:58 +0100)
committerNils Asmussen <nils.asmussen@barkhauseninstitut.org>
Wed, 29 Apr 2020 11:41:55 +0000 (11:41 +0000)
Change-Id: I424123d3c94c9673269f922cd6755f0bbf5b6cc0
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/26984
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/riscv/insts/standard.cc
src/arch/riscv/insts/standard.hh
src/arch/riscv/isa/decoder.isa

index 0fcb2b589afb666a27ff159ac237023d44443e7c..bb621ae7a6abcdb8ad6fd94c3723d79936f6af3b 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2015 RISC-V Foundation
  * Copyright (c) 2017 The University of Virginia
+ * Copyright (c) 2020 Barkhausen Institut
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -66,4 +67,17 @@ CSROp::generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
     return ss.str();
 }
 
+string
+SystemOp::generateDisassembly(Addr pc, const Loader::SymbolTable *symtab) const
+{
+    if (strcmp(mnemonic, "fence_vma") == 0) {
+        stringstream ss;
+        ss << mnemonic << ' ' << registerName(_srcRegIdx[0]) << ", " <<
+            registerName(_srcRegIdx[1]);
+        return ss.str();
+    }
+
+    return mnemonic;
+}
+
 }
index a68010e06790968fc34ab488c8fa199b22b1682d..aa949422c6d6fb677e591e8a0d82f594962fbd39 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (c) 2015 RISC-V Foundation
  * Copyright (c) 2017 The University of Virginia
+ * Copyright (c) 2020 Barkhausen Institut
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -74,12 +75,8 @@ class SystemOp : public RiscvStaticInst
   protected:
     using RiscvStaticInst::RiscvStaticInst;
 
-    std::string
-    generateDisassembly(
-            Addr pc, const Loader::SymbolTable *symtab) const override
-    {
-        return mnemonic;
-    }
+    std::string generateDisassembly(
+        Addr pc, const Loader::SymbolTable *symtab) const override;
 };
 
 /**
index 4f8fea2f9ce6ea0ff5b3a9c8bc7f0d2b26ab6ce2..04f0319428d1392ac5375dad0078cab441558955 100644 (file)
@@ -1758,38 +1758,48 @@ decode QUADRANT default Unknown::unknown() {
 
         0x1c: decode FUNCT3 {
             format SystemOp {
-                0x0: decode FUNCT12 {
-                    0x0: ecall({{
-                        fault = make_shared<SyscallFault>(
+                0x0: decode FUNCT7 {
+                    0x0: decode RS2 {
+                        0x0: ecall({{
+                            fault = make_shared<SyscallFault>(
                                 (PrivilegeMode)xc->readMiscReg(MISCREG_PRV));
-                    }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
-                        No_OpClass);
-                    0x1: ebreak({{
-                        fault = make_shared<BreakpointFault>(xc->pcState());
-                    }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
-                    0x2: uret({{
-                        STATUS status = xc->readMiscReg(MISCREG_STATUS);
-                        status.uie = status.upie;
-                        status.upie = 1;
-                        xc->setMiscReg(MISCREG_STATUS, status);
-                        NPC = xc->readMiscReg(MISCREG_UEPC);
-                    }}, IsReturn);
-                    0x102: sret({{
-                        if (xc->readMiscReg(MISCREG_PRV) == PRV_U) {
-                            fault = make_shared<IllegalInstFault>(
-                                        "sret in user mode", machInst);
-                            NPC = NPC;
-                        } else {
+                        }}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
+                            No_OpClass);
+                        0x1: ebreak({{
+                            fault = make_shared<BreakpointFault>(
+                                xc->pcState());
+                        }}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
+                        0x2: uret({{
                             STATUS status = xc->readMiscReg(MISCREG_STATUS);
-                            xc->setMiscReg(MISCREG_PRV, status.spp);
-                            status.sie = status.spie;
-                            status.spie = 1;
-                            status.spp = PRV_U;
+                            status.uie = status.upie;
+                            status.upie = 1;
                             xc->setMiscReg(MISCREG_STATUS, status);
-                            NPC = xc->readMiscReg(MISCREG_SEPC);
-                        }
-                    }}, IsReturn);
-                    0x302: mret({{
+                            NPC = xc->readMiscReg(MISCREG_UEPC);
+                        }}, IsReturn);
+                    }
+                    0x8: decode RS2 {
+                        0x2: sret({{
+                            if (xc->readMiscReg(MISCREG_PRV) == PRV_U) {
+                                fault = make_shared<IllegalInstFault>(
+                                            "sret in user mode", machInst);
+                                NPC = NPC;
+                            } else {
+                                STATUS status = xc->readMiscReg(
+                                    MISCREG_STATUS);
+                                xc->setMiscReg(MISCREG_PRV, status.spp);
+                                status.sie = status.spie;
+                                status.spie = 1;
+                                status.spp = PRV_U;
+                                xc->setMiscReg(MISCREG_STATUS, status);
+                                NPC = xc->readMiscReg(MISCREG_SEPC);
+                            }
+                        }}, IsReturn);
+                    }
+                    0x9: sfence_vma({{
+                        xc->tcBase()->getITBPtr()->demapPage(Rs1, Rs2);
+                        xc->tcBase()->getDTBPtr()->demapPage(Rs1, Rs2);
+                    }}, IsNonSpeculative, IsSerializeAfter, No_OpClass);
+                    0x18: mret({{
                         if (xc->readMiscReg(MISCREG_PRV) != PRV_M) {
                             fault = make_shared<IllegalInstFault>(
                                         "mret at lower privilege", machInst);