summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/riscv/faults.cc6
-rw-r--r--src/arch/riscv/faults.hh64
-rw-r--r--src/arch/riscv/insts/unknown.hh2
-rw-r--r--src/arch/riscv/isa/decoder.isa73
-rw-r--r--src/arch/riscv/isa/formats/fp.isa9
-rw-r--r--src/arch/riscv/isa/formats/standard.isa4
6 files changed, 110 insertions, 48 deletions
diff --git a/src/arch/riscv/faults.cc b/src/arch/riscv/faults.cc
index efab6c444..b5f3d078b 100644
--- a/src/arch/riscv/faults.cc
+++ b/src/arch/riscv/faults.cc
@@ -71,12 +71,13 @@ RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
}
// Set fault registers and status
- MiscRegIndex cause, epc, tvec;
+ MiscRegIndex cause, epc, tvec, tval;
switch (prv) {
case PRV_U:
cause = MISCREG_UCAUSE;
epc = MISCREG_UEPC;
tvec = MISCREG_UTVEC;
+ tval = MISCREG_UTVAL;
status.upie = status.uie;
status.uie = 0;
@@ -85,6 +86,7 @@ RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
cause = MISCREG_SCAUSE;
epc = MISCREG_SEPC;
tvec = MISCREG_STVEC;
+ tval = MISCREG_STVAL;
status.spp = pp;
status.spie = status.sie;
@@ -94,6 +96,7 @@ RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
cause = MISCREG_MCAUSE;
epc = MISCREG_MEPC;
tvec = MISCREG_MTVEC;
+ tval = MISCREG_MTVAL;
status.mpp = pp;
status.mpie = status.sie;
@@ -108,6 +111,7 @@ RiscvFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
tc->setMiscReg(cause,
(isInterrupt() << (sizeof(MiscReg) * 4 - 1)) | _code);
tc->setMiscReg(epc, tc->instAddr());
+ tc->setMiscReg(tval, trap_value());
tc->setMiscReg(MISCREG_PRV, prv);
tc->setMiscReg(MISCREG_STATUS, status);
diff --git a/src/arch/riscv/faults.hh b/src/arch/riscv/faults.hh
index ef0fdb6e3..6d3fdebbe 100644
--- a/src/arch/riscv/faults.hh
+++ b/src/arch/riscv/faults.hh
@@ -129,9 +129,10 @@ class RiscvFault : public FaultBase
: _name(n), _interrupt(i), _code(c)
{}
- FaultName name() const { return _name; }
+ FaultName name() const override { return _name; }
bool isInterrupt() const { return _interrupt; }
ExceptionCode exception() const { return _code; }
+ virtual MiscReg trap_value() const { return 0; }
virtual void invokeSE(ThreadContext *tc, const StaticInstPtr &inst);
void invoke(ThreadContext *tc, const StaticInstPtr &inst) override;
@@ -159,61 +160,94 @@ class Reset : public FaultBase
const FaultName _name;
};
-class UnknownInstFault : public RiscvFault
+class InstFault : public RiscvFault
+{
+ protected:
+ const ExtMachInst _inst;
+
+ public:
+ InstFault(FaultName n, const ExtMachInst inst)
+ : RiscvFault(n, false, INST_ILLEGAL), _inst(inst)
+ {}
+
+ MiscReg trap_value() const override { return _inst; }
+};
+
+class UnknownInstFault : public InstFault
{
public:
- UnknownInstFault() : RiscvFault("Unknown instruction", false, INST_ILLEGAL)
+ UnknownInstFault(const ExtMachInst inst)
+ : InstFault("Unknown instruction", inst)
{}
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
};
-class IllegalInstFault : public RiscvFault
+class IllegalInstFault : public InstFault
{
private:
const std::string reason;
public:
- IllegalInstFault(std::string r)
- : RiscvFault("Illegal instruction", false, INST_ILLEGAL)
+ IllegalInstFault(std::string r, const ExtMachInst inst)
+ : InstFault("Illegal instruction", inst)
{}
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
};
-class UnimplementedFault : public RiscvFault
+class UnimplementedFault : public InstFault
{
private:
const std::string instName;
public:
- UnimplementedFault(std::string name)
- : RiscvFault("Unimplemented instruction", false, INST_ILLEGAL),
+ UnimplementedFault(std::string name, const ExtMachInst inst)
+ : InstFault("Unimplemented instruction", inst),
instName(name)
{}
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
};
-class IllegalFrmFault: public RiscvFault
+class IllegalFrmFault: public InstFault
{
private:
const uint8_t frm;
public:
- IllegalFrmFault(uint8_t r)
- : RiscvFault("Illegal floating-point rounding mode", false,
- INST_ILLEGAL),
+ IllegalFrmFault(uint8_t r, const ExtMachInst inst)
+ : InstFault("Illegal floating-point rounding mode", inst),
frm(r)
{}
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
};
+class AddressFault : public RiscvFault
+{
+ private:
+ const Addr _addr;
+
+ public:
+ AddressFault(const Addr addr, ExceptionCode code)
+ : RiscvFault("Address", false, code), _addr(addr)
+ {}
+
+ MiscReg trap_value() const override { return _addr; }
+};
+
class BreakpointFault : public RiscvFault
{
+ private:
+ const PCState pcState;
+
public:
- BreakpointFault() : RiscvFault("Breakpoint", false, BREAKPOINT) {}
+ BreakpointFault(const PCState &pc)
+ : RiscvFault("Breakpoint", false, BREAKPOINT), pcState(pc)
+ {}
+
+ MiscReg trap_value() const override { return pcState.pc(); }
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override;
};
@@ -228,4 +262,4 @@ class SyscallFault : public RiscvFault
} // namespace RiscvISA
-#endif // __ARCH_RISCV_FAULTS_HH__
+#endif // __ARCH_RISCV_FAULTS_HH__ \ No newline at end of file
diff --git a/src/arch/riscv/insts/unknown.hh b/src/arch/riscv/insts/unknown.hh
index 049f879de..a96474aec 100644
--- a/src/arch/riscv/insts/unknown.hh
+++ b/src/arch/riscv/insts/unknown.hh
@@ -59,7 +59,7 @@ class Unknown : public RiscvStaticInst
Fault
execute(ExecContext *, Trace::InstRecord *) const override
{
- return std::make_shared<UnknownInstFault>();
+ return std::make_shared<UnknownInstFault>(machInst);
}
std::string
diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa
index b4bf3854b..a0e3ad19d 100644
--- a/src/arch/riscv/isa/decoder.isa
+++ b/src/arch/riscv/isa/decoder.isa
@@ -43,7 +43,8 @@ decode QUADRANT default Unknown::unknown() {
CIMM8<5:2> << 6;
}}, {{
if (machInst == 0)
- fault = make_shared<IllegalInstFault>("zero instruction");
+ fault = make_shared<IllegalInstFault>("zero instruction",
+ machInst);
Rp2 = sp + imm;
}}, uint64_t);
format CompressedLoad {
@@ -106,9 +107,11 @@ decode QUADRANT default Unknown::unknown() {
}}, {{
if ((RC1 == 0) != (imm == 0)) {
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0");
+ fault = make_shared<IllegalInstFault>("source reg x0",
+ machInst);
} else // imm == 0
- fault = make_shared<IllegalInstFault>("immediate = 0");
+ fault = make_shared<IllegalInstFault>("immediate = 0",
+ machInst);
}
Rc1_sd = Rc1_sd + imm;
}});
@@ -118,7 +121,8 @@ decode QUADRANT default Unknown::unknown() {
imm |= ~((uint64_t)0x1F);
}}, {{
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0");
+ fault = make_shared<IllegalInstFault>("source reg x0",
+ machInst);
}
Rc1_sd = (int32_t)Rc1_sd + imm;
}});
@@ -128,7 +132,8 @@ decode QUADRANT default Unknown::unknown() {
imm |= ~((uint64_t)0x1F);
}}, {{
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0");
+ fault = make_shared<IllegalInstFault>("source reg x0",
+ machInst);
}
Rc1_sd = imm;
}});
@@ -142,7 +147,8 @@ decode QUADRANT default Unknown::unknown() {
imm |= ~((int64_t)0x1FF);
}}, {{
if (imm == 0) {
- fault = make_shared<IllegalInstFault>("immediate = 0");
+ fault = make_shared<IllegalInstFault>("immediate = 0",
+ machInst);
}
sp_sd = sp_sd + imm;
}});
@@ -152,10 +158,12 @@ decode QUADRANT default Unknown::unknown() {
imm |= ~((uint64_t)0x1FFFF);
}}, {{
if (RC1 == 0 || RC1 == 2) {
- fault = make_shared<IllegalInstFault>("source reg x0");
+ fault = make_shared<IllegalInstFault>("source reg x0",
+ machInst);
}
if (imm == 0) {
- fault = make_shared<IllegalInstFault>("immediate = 0");
+ fault = make_shared<IllegalInstFault>("immediate = 0",
+ machInst);
}
Rc1_sd = imm;
}});
@@ -167,7 +175,8 @@ decode QUADRANT default Unknown::unknown() {
imm = CIMM5 | (CIMM1 << 5);
}}, {{
if (imm == 0) {
- fault = make_shared<IllegalInstFault>("immediate = 0");
+ fault = make_shared<IllegalInstFault>("immediate = 0",
+ machInst);
}
Rp1 = Rp1 >> imm;
}}, uint64_t);
@@ -175,7 +184,8 @@ decode QUADRANT default Unknown::unknown() {
imm = CIMM5 | (CIMM1 << 5);
}}, {{
if (imm == 0) {
- fault = make_shared<IllegalInstFault>("immediate = 0");
+ fault = make_shared<IllegalInstFault>("immediate = 0",
+ machInst);
}
Rp1_sd = Rp1_sd >> imm;
}}, uint64_t);
@@ -246,10 +256,12 @@ decode QUADRANT default Unknown::unknown() {
imm = CIMM5 | (CIMM1 << 5);
}}, {{
if (imm == 0) {
- fault = make_shared<IllegalInstFault>("immediate = 0");
+ fault = make_shared<IllegalInstFault>("immediate = 0",
+ machInst);
}
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0");
+ fault = make_shared<IllegalInstFault>("source reg x0",
+ machInst);
}
Rc1 = Rc1 << imm;
}}, uint64_t);
@@ -269,7 +281,8 @@ decode QUADRANT default Unknown::unknown() {
CIMM5<1:0> << 6;
}}, {{
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0");
+ fault = make_shared<IllegalInstFault>("source reg x0",
+ machInst);
}
Rc1_sd = Mem_sw;
}}, {{
@@ -281,7 +294,8 @@ decode QUADRANT default Unknown::unknown() {
CIMM5<2:0> << 6;
}}, {{
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0");
+ fault = make_shared<IllegalInstFault>("source reg x0",
+ machInst);
}
Rc1_sd = Mem_sd;
}}, {{
@@ -292,13 +306,15 @@ decode QUADRANT default Unknown::unknown() {
0x0: decode RC2 {
0x0: Jump::c_jr({{
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0");
+ fault = make_shared<IllegalInstFault>("source reg x0",
+ machInst);
}
NPC = Rc1;
}}, IsIndirectControl, IsUncondControl, IsCall);
default: CROp::c_mv({{
if (RC1 == 0) {
- fault = make_shared<IllegalInstFault>("source reg x0");
+ fault = make_shared<IllegalInstFault>("source reg x0",
+ machInst);
}
Rc1 = Rc2;
}});
@@ -306,15 +322,17 @@ decode QUADRANT default Unknown::unknown() {
0x1: decode RC1 {
0x0: SystemOp::c_ebreak({{
if (RC2 != 0) {
- fault = make_shared<IllegalInstFault>("source reg x1");
+ fault = make_shared<IllegalInstFault>("source reg x1",
+ machInst);
}
- fault = make_shared<BreakpointFault>();
+ fault = make_shared<BreakpointFault>(xc->pcState());
}}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
default: decode RC2 {
0x0: Jump::c_jalr({{
if (RC1 == 0) {
fault = make_shared<IllegalInstFault>
- ("source reg x0");
+ ("source reg x0",
+ machInst);
}
ra = NPC;
NPC = Rc1;
@@ -1250,7 +1268,8 @@ decode QUADRANT default Unknown::unknown() {
}
0x20: fcvt_s_d({{
if (CONV_SGN != 1) {
- fault = make_shared<IllegalInstFault>("CONV_SGN != 1");
+ fault = make_shared<IllegalInstFault>("CONV_SGN != 1",
+ machInst);
}
float fd;
if (issignalingnan(Fs1)) {
@@ -1263,7 +1282,8 @@ decode QUADRANT default Unknown::unknown() {
}}, FloatCvtOp);
0x21: fcvt_d_s({{
if (CONV_SGN != 0) {
- fault = make_shared<IllegalInstFault>("CONV_SGN != 0");
+ fault = make_shared<IllegalInstFault>("CONV_SGN != 0",
+ machInst);
}
uint32_t temp;
float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
@@ -1277,7 +1297,8 @@ decode QUADRANT default Unknown::unknown() {
}}, FloatCvtOp);
0x2c: fsqrt_s({{
if (RS2 != 0) {
- fault = make_shared<IllegalInstFault>("source reg x1");
+ fault = make_shared<IllegalInstFault>("source reg x1",
+ machInst);
}
uint32_t temp;
float fs1 = reinterpret_cast<float&>(temp = Fs1_bits);
@@ -1291,7 +1312,8 @@ decode QUADRANT default Unknown::unknown() {
}}, FloatSqrtOp);
0x2d: fsqrt_d({{
if (RS2 != 0) {
- fault = make_shared<IllegalInstFault>("source reg x1");
+ fault = make_shared<IllegalInstFault>("source reg x1",
+ machInst);
}
Fd = sqrt(Fs1);
}}, FloatSqrtOp);
@@ -1690,10 +1712,11 @@ decode QUADRANT default Unknown::unknown() {
}}, IsSerializeAfter, IsNonSpeculative, IsSyscall,
No_OpClass);
0x1: ebreak({{
- fault = make_shared<BreakpointFault>();
+ fault = make_shared<BreakpointFault>(xc->pcState());
}}, IsSerializeAfter, IsNonSpeculative, No_OpClass);
0x100: eret({{
- fault = make_shared<UnimplementedFault>("eret");
+ fault = make_shared<UnimplementedFault>("eret",
+ machInst);
}}, No_OpClass);
}
}
diff --git a/src/arch/riscv/isa/formats/fp.isa b/src/arch/riscv/isa/formats/fp.isa
index 1f08ca512..5f067218c 100644
--- a/src/arch/riscv/isa/formats/fp.isa
+++ b/src/arch/riscv/isa/formats/fp.isa
@@ -57,7 +57,7 @@ def template FloatExecute {{
break;
case 0x4:
// Round to nearest, ties to max magnitude not implemented
- fault = make_shared<IllegalFrmFault>(ROUND_MODE);
+ fault = make_shared<IllegalFrmFault>(ROUND_MODE, machInst);
break;
case 0x7: {
uint8_t frm = xc->readMiscReg(MISCREG_FRM);
@@ -76,16 +76,17 @@ def template FloatExecute {{
break;
case 0x4:
// Round to nearest, ties to max magnitude not implemented
- fault = make_shared<IllegalFrmFault>(ROUND_MODE);
+ fault = make_shared<IllegalFrmFault>(ROUND_MODE, machInst);
break;
default:
- fault = std::make_shared<IllegalFrmFault>(frm);
+ fault = std::make_shared<IllegalFrmFault>(frm, machInst);
break;
}
break;
}
default:
- fault = std::make_shared<IllegalFrmFault>(ROUND_MODE);
+ fault = std::make_shared<IllegalFrmFault>(ROUND_MODE,
+ machInst);
break;
}
diff --git a/src/arch/riscv/isa/formats/standard.isa b/src/arch/riscv/isa/formats/standard.isa
index e69ad7ee5..e9539fe52 100644
--- a/src/arch/riscv/isa/formats/standard.isa
+++ b/src/arch/riscv/isa/formats/standard.isa
@@ -231,7 +231,7 @@ def template CSRExecute {{
olddata = xc->readMiscReg(CSRData.at(csr).physIndex);
} else {
std::string error = csprintf("Illegal CSR index %#x\n", csr);
- fault = make_shared<IllegalInstFault>(error);
+ fault = make_shared<IllegalInstFault>(error, machInst);
olddata = 0;
}
break;
@@ -252,7 +252,7 @@ def template CSRExecute {{
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);
+ fault = make_shared<IllegalInstFault>(error, machInst);
} else {
DPRINTF(RiscvMisc, "Writing %#x to CSR %s.\n", data,
CSRData.at(csr).name);