gem5  v21.1.0.2
faults.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 RISC-V Foundation
3  * Copyright (c) 2016 The University of Virginia
4  * Copyright (c) 2018 TU Dresden
5  * Copyright (c) 2020 Barkhausen Institut
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met: redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer;
12  * redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution;
15  * neither the name of the copyright holders nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "arch/riscv/faults.hh"
33 
35 #include "arch/riscv/isa.hh"
36 #include "arch/riscv/regs/misc.hh"
37 #include "arch/riscv/utility.hh"
38 #include "cpu/base.hh"
39 #include "cpu/thread_context.hh"
40 #include "debug/Fault.hh"
41 #include "sim/debug.hh"
42 #include "sim/full_system.hh"
43 #include "sim/workload.hh"
44 
45 namespace gem5
46 {
47 
48 namespace RiscvISA
49 {
50 
51 void
53 {
54  panic("Fault %s encountered at pc 0x%016llx.", name(), tc->pcState().pc());
55 }
56 
57 void
59 {
60  PCState pcState = tc->pcState();
61 
62  DPRINTFS(Fault, tc->getCpuPtr(), "Fault (%s) at PC: %s\n",
63  name(), pcState);
64 
65  if (FullSystem) {
67  PrivilegeMode prv = PRV_M;
68  STATUS status = tc->readMiscReg(MISCREG_STATUS);
69 
70  // Set fault handler privilege mode
71  if (isInterrupt()) {
72  if (pp != PRV_M &&
73  bits(tc->readMiscReg(MISCREG_MIDELEG), _code) != 0) {
74  prv = PRV_S;
75  }
76  if (pp == PRV_U &&
77  bits(tc->readMiscReg(MISCREG_SIDELEG), _code) != 0) {
78  prv = PRV_U;
79  }
80  } else {
81  if (pp != PRV_M &&
82  bits(tc->readMiscReg(MISCREG_MEDELEG), _code) != 0) {
83  prv = PRV_S;
84  }
85  if (pp == PRV_U &&
86  bits(tc->readMiscReg(MISCREG_SEDELEG), _code) != 0) {
87  prv = PRV_U;
88  }
89  }
90 
91  // Set fault registers and status
92  MiscRegIndex cause, epc, tvec, tval;
93  switch (prv) {
94  case PRV_U:
95  cause = MISCREG_UCAUSE;
96  epc = MISCREG_UEPC;
97  tvec = MISCREG_UTVEC;
98  tval = MISCREG_UTVAL;
99 
100  status.upie = status.uie;
101  status.uie = 0;
102  break;
103  case PRV_S:
104  cause = MISCREG_SCAUSE;
105  epc = MISCREG_SEPC;
106  tvec = MISCREG_STVEC;
107  tval = MISCREG_STVAL;
108 
109  status.spp = pp;
110  status.spie = status.sie;
111  status.sie = 0;
112  break;
113  case PRV_M:
114  cause = MISCREG_MCAUSE;
115  epc = MISCREG_MEPC;
116  tvec = MISCREG_MTVEC;
117  tval = MISCREG_MTVAL;
118 
119  status.mpp = pp;
120  status.mpie = status.mie;
121  status.mie = 0;
122  break;
123  default:
124  panic("Unknown privilege mode %d.", prv);
125  break;
126  }
127 
128  // Set fault cause, privilege, and return PC
129  // Interrupt is indicated on the MSB of cause (bit 63 in RV64)
130  uint64_t _cause = _code;
131  if (isInterrupt()) {
132  _cause |= (1L << 63);
133  }
134  tc->setMiscReg(cause, _cause);
135  tc->setMiscReg(epc, tc->instAddr());
136  tc->setMiscReg(tval, trap_value());
137  tc->setMiscReg(MISCREG_PRV, prv);
139 
140  // Set PC to fault handler address
141  Addr addr = mbits(tc->readMiscReg(tvec), 63, 2);
142  if (isInterrupt() && bits(tc->readMiscReg(tvec), 1, 0) == 1)
143  addr += 4 * _code;
144  pcState.set(addr);
145  } else {
146  invokeSE(tc, inst);
147  inst->advancePC(pcState);
148  }
149  tc->pcState(pcState);
150 }
151 
153 {
155  STATUS status = tc->readMiscReg(MISCREG_STATUS);
156  status.mie = 0;
157  status.mprv = 0;
159  tc->setMiscReg(MISCREG_MCAUSE, 0);
160 
161  // Advance the PC to the implementation-defined reset vector
162  auto workload = dynamic_cast<Workload *>(tc->getSystemPtr()->workload);
163  PCState pc = workload->getEntry();
164  tc->pcState(pc);
165 }
166 
167 void
169 {
170  auto *rsi = static_cast<RiscvStaticInst *>(inst.get());
171  panic("Unknown instruction 0x%08x at pc 0x%016llx", rsi->machInst,
172  tc->pcState().pc());
173 }
174 
175 void
177 {
178  auto *rsi = static_cast<RiscvStaticInst *>(inst.get());
179  panic("Illegal instruction 0x%08x at pc 0x%016llx: %s", rsi->machInst,
180  tc->pcState().pc(), reason.c_str());
181 }
182 
183 void
185  const StaticInstPtr &inst)
186 {
187  panic("Unimplemented instruction %s at pc 0x%016llx", instName,
188  tc->pcState().pc());
189 }
190 
191 void
193 {
194  panic("Illegal floating-point rounding mode 0x%x at pc 0x%016llx.",
195  frm, tc->pcState().pc());
196 }
197 
198 void
200 {
201  schedRelBreak(0);
202 }
203 
204 void
206 {
207  tc->getSystemPtr()->workload->syscall(tc);
208 }
209 
210 } // namespace RiscvISA
211 } // namespace gem5
gem5::RiscvISA::PRV_S
@ PRV_S
Definition: isa.hh:55
gem5::RiscvISA::MISCREG_STATUS
@ MISCREG_STATUS
Definition: misc.hh:71
gem5::RiscvISA::UnimplementedFault::instName
const std::string instName
Definition: faults.hh:178
gem5::ThreadContext::readMiscReg
virtual RegVal readMiscReg(RegIndex misc_reg)=0
gem5::ThreadContext::getSystemPtr
virtual System * getSystemPtr()=0
gem5::RiscvISA::PRV_M
@ PRV_M
Definition: isa.hh:56
faults.hh
gem5::X86ISA::L
Bitfield< 7, 0 > L
Definition: int.hh:59
gem5::RiscvISA::MISCREG_SIDELEG
@ MISCREG_SIDELEG
Definition: misc.hh:173
gem5::RiscvISA::RiscvStaticInst
Base class for all RISC-V static instructions.
Definition: static_inst.hh:49
gem5::RiscvISA::RiscvFault::invoke
void invoke(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:58
gem5::RiscvISA::PrivilegeMode
PrivilegeMode
Definition: isa.hh:52
gem5::RiscvISA::MISCREG_MTVAL
@ MISCREG_MTVAL
Definition: misc.hh:150
gem5::RiscvISA::IllegalFrmFault::frm
const uint8_t frm
Definition: faults.hh:192
gem5::RiscvISA::MISCREG_SEDELEG
@ MISCREG_SEDELEG
Definition: misc.hh:172
gem5::System::workload
Workload * workload
OS kernel.
Definition: system.hh:335
gem5::ThreadContext::instAddr
virtual Addr instAddr() const =0
workload.hh
gem5::RefCountingPtr::get
T * get() const
Directly access the pointer itself without taking a reference.
Definition: refcnt.hh:227
gem5::mbits
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
Definition: bitfield.hh:103
gem5::RiscvISA::RiscvFault::isInterrupt
bool isInterrupt() const
Definition: faults.hh:111
isa.hh
misc.hh
gem5::RefCountingPtr< StaticInst >
gem5::RiscvISA::MISCREG_SCAUSE
@ MISCREG_SCAUSE
Definition: misc.hh:178
gem5::RiscvISA::MISCREG_MEDELEG
@ MISCREG_MEDELEG
Definition: misc.hh:143
gem5::RiscvISA::PCState
Definition: pcstate.hh:53
gem5::schedRelBreak
void schedRelBreak(Tick delta)
Cause the simulator to execute a breakpoint relative to the current tick.
Definition: debug.cc:93
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:93
gem5::Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:255
gem5::RiscvISA::MISCREG_SEPC
@ MISCREG_SEPC
Definition: misc.hh:177
gem5::RiscvISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:243
debug.hh
gem5::RiscvISA::RiscvFault::name
FaultName name() const override
Definition: faults.hh:110
gem5::RiscvISA::IllegalInstFault::reason
const std::string reason
Definition: faults.hh:165
gem5::Workload
Definition: workload.hh:47
gem5::RiscvISA::MISCREG_MCAUSE
@ MISCREG_MCAUSE
Definition: misc.hh:149
gem5::RiscvISA::RiscvFault::_code
ExceptionCode _code
Definition: faults.hh:104
gem5::bits
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:76
gem5::RiscvISA::Reset::invoke
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition: faults.cc:152
gem5::ThreadContext::pcState
virtual TheISA::PCState pcState() const =0
static_inst.hh
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
DPRINTFS
#define DPRINTFS(x, s,...)
Definition: trace.hh:193
gem5::RiscvISA::MISCREG_MEPC
@ MISCREG_MEPC
Definition: misc.hh:148
full_system.hh
gem5::RiscvISA::UnknownInstFault::invokeSE
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:168
gem5::FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:223
gem5::RiscvISA::IllegalFrmFault::invokeSE
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:192
gem5::RiscvISA::MISCREG_UTVEC
@ MISCREG_UTVEC
Definition: misc.hh:182
base.hh
gem5::RiscvISA::SyscallFault::invokeSE
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:205
gem5::ThreadContext::setMiscReg
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
gem5::GenericISA::UPCState::set
void set(Addr val)
Definition: types.hh:221
gem5::RiscvISA::BreakpointFault::invokeSE
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:199
gem5::RiscvISA::IllegalInstFault::invokeSE
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:176
gem5::RiscvISA::MISCREG_UEPC
@ MISCREG_UEPC
Definition: misc.hh:184
gem5::RiscvISA::MISCREG_MIDELEG
@ MISCREG_MIDELEG
Definition: misc.hh:144
utility.hh
gem5::ThreadContext::getCpuPtr
virtual BaseCPU * getCpuPtr()=0
gem5::RiscvISA::MISCREG_STVAL
@ MISCREG_STVAL
Definition: misc.hh:179
gem5::RiscvISA::PRV_U
@ PRV_U
Definition: isa.hh:54
gem5::RiscvISA::RiscvFault::trap_value
virtual RegVal trap_value() const
Definition: faults.hh:113
gem5::RiscvISA::MISCREG_UCAUSE
@ MISCREG_UCAUSE
Definition: misc.hh:185
gem5::RiscvISA::MiscRegIndex
MiscRegIndex
Definition: misc.hh:63
gem5::RiscvISA::MISCREG_UTVAL
@ MISCREG_UTVAL
Definition: misc.hh:186
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::RiscvISA::MISCREG_PRV
@ MISCREG_PRV
Definition: misc.hh:65
gem5::RiscvISA::UnimplementedFault::invokeSE
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:184
gem5::RiscvISA::MISCREG_STVEC
@ MISCREG_STVEC
Definition: misc.hh:174
thread_context.hh
gem5::RiscvISA::RiscvFault::invokeSE
virtual void invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
Definition: faults.cc:52
gem5::RiscvISA::MISCREG_MTVEC
@ MISCREG_MTVEC
Definition: misc.hh:145
gem5::StaticInst::advancePC
virtual void advancePC(TheISA::PCState &pc_state) const =0
gem5::Workload::syscall
virtual void syscall(ThreadContext *tc)
Definition: workload.hh:106
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::ArmISA::status
Bitfield< 5, 0 > status
Definition: misc_types.hh:422
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84

Generated on Tue Sep 21 2021 12:24:29 for gem5 by doxygen 1.8.17