arch-riscv: implement sfence.vma to flush TLBs.
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>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user