diff options
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/riscv/faults.cc | 6 | ||||
-rw-r--r-- | src/arch/riscv/faults.hh | 64 | ||||
-rw-r--r-- | src/arch/riscv/insts/unknown.hh | 2 | ||||
-rw-r--r-- | src/arch/riscv/isa/decoder.isa | 73 | ||||
-rw-r--r-- | src/arch/riscv/isa/formats/fp.isa | 9 | ||||
-rw-r--r-- | src/arch/riscv/isa/formats/standard.isa | 4 |
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); |