gem5  v20.1.0.0
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/registers.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 
44 namespace RiscvISA
45 {
46 
47 void
49 {
50  panic("Fault %s encountered at pc 0x%016llx.", name(), tc->pcState().pc());
51 }
52 
53 void
55 {
56  PCState pcState = tc->pcState();
57 
58  DPRINTFS(Fault, tc->getCpuPtr(), "Fault (%s) at PC: %s\n",
59  name(), pcState);
60 
61  if (FullSystem) {
63  PrivilegeMode prv = PRV_M;
64  STATUS status = tc->readMiscReg(MISCREG_STATUS);
65 
66  // Set fault handler privilege mode
67  if (isInterrupt()) {
68  if (pp != PRV_M &&
69  bits(tc->readMiscReg(MISCREG_MIDELEG), _code) != 0) {
70  prv = PRV_S;
71  }
72  if (pp == PRV_U &&
73  bits(tc->readMiscReg(MISCREG_SIDELEG), _code) != 0) {
74  prv = PRV_U;
75  }
76  } else {
77  if (pp != PRV_M &&
78  bits(tc->readMiscReg(MISCREG_MEDELEG), _code) != 0) {
79  prv = PRV_S;
80  }
81  if (pp == PRV_U &&
82  bits(tc->readMiscReg(MISCREG_SEDELEG), _code) != 0) {
83  prv = PRV_U;
84  }
85  }
86 
87  // Set fault registers and status
88  MiscRegIndex cause, epc, tvec, tval;
89  switch (prv) {
90  case PRV_U:
91  cause = MISCREG_UCAUSE;
92  epc = MISCREG_UEPC;
93  tvec = MISCREG_UTVEC;
94  tval = MISCREG_UTVAL;
95 
96  status.upie = status.uie;
97  status.uie = 0;
98  break;
99  case PRV_S:
100  cause = MISCREG_SCAUSE;
101  epc = MISCREG_SEPC;
102  tvec = MISCREG_STVEC;
103  tval = MISCREG_STVAL;
104 
105  status.spp = pp;
106  status.spie = status.sie;
107  status.sie = 0;
108  break;
109  case PRV_M:
110  cause = MISCREG_MCAUSE;
111  epc = MISCREG_MEPC;
112  tvec = MISCREG_MTVEC;
113  tval = MISCREG_MTVAL;
114 
115  status.mpp = pp;
116  status.mpie = status.sie;
117  status.mie = 0;
118  break;
119  default:
120  panic("Unknown privilege mode %d.", prv);
121  break;
122  }
123 
124  // Set fault cause, privilege, and return PC
125  tc->setMiscReg(cause,
126  (isInterrupt() << (sizeof(uint64_t) * 4 - 1)) | _code);
127  tc->setMiscReg(epc, tc->instAddr());
128  tc->setMiscReg(tval, trap_value());
129  tc->setMiscReg(MISCREG_PRV, prv);
131 
132  // Set PC to fault handler address
133  Addr addr = mbits(tc->readMiscReg(tvec), 63, 2);
134  if (isInterrupt() && bits(tc->readMiscReg(tvec), 1, 0) == 1)
135  addr += 4 * _code;
136  pcState.set(addr);
137  } else {
138  invokeSE(tc, inst);
139  advancePC(pcState, inst);
140  }
141  tc->pcState(pcState);
142 }
143 
145 {
147  STATUS status = tc->readMiscReg(MISCREG_STATUS);
148  status.mie = 0;
149  status.mprv = 0;
151  tc->setMiscReg(MISCREG_MCAUSE, 0);
152 
153  // Advance the PC to the implementation-defined reset vector
154  auto workload = dynamic_cast<FsWorkload *>(tc->getSystemPtr()->workload);
155  PCState pc = workload->resetVect();
156  tc->pcState(pc);
157 }
158 
159 void
161 {
162  panic("Unknown instruction 0x%08x at pc 0x%016llx", inst->machInst,
163  tc->pcState().pc());
164 }
165 
166 void
168 {
169  panic("Illegal instruction 0x%08x at pc 0x%016llx: %s", inst->machInst,
170  tc->pcState().pc(), reason.c_str());
171 }
172 
173 void
175  const StaticInstPtr &inst)
176 {
177  panic("Unimplemented instruction %s at pc 0x%016llx", instName,
178  tc->pcState().pc());
179 }
180 
181 void
183 {
184  panic("Illegal floating-point rounding mode 0x%x at pc 0x%016llx.",
185  frm, tc->pcState().pc());
186 }
187 
188 void
190 {
191  schedRelBreak(0);
192 }
193 
194 void
196 {
197  tc->syscall();
198 }
199 
200 } // namespace RiscvISA
RiscvISA::MISCREG_PRV
@ MISCREG_PRV
Definition: registers.hh:129
ArmISA::status
Bitfield< 5, 0 > status
Definition: miscregs_types.hh:417
RiscvISA::IllegalInstFault::invokeSE
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:167
RiscvISA::SyscallFault::invokeSE
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:195
RiscvISA::PCState
Definition: types.hh:53
RiscvISA::Reset::invoke
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr) override
Definition: faults.cc:144
faults.hh
RiscvISA::MISCREG_UEPC
@ MISCREG_UEPC
Definition: registers.hh:248
GenericISA::UPCState::set
void set(Addr val)
Definition: types.hh:228
RiscvISA::MISCREG_MCAUSE
@ MISCREG_MCAUSE
Definition: registers.hh:213
RiscvISA::UnknownInstFault::invokeSE
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:160
RiscvISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:240
RiscvISA::IllegalFrmFault::frm
const uint8_t frm
Definition: faults.hh:185
RiscvISA::BreakpointFault::invokeSE
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:189
RiscvISA::MISCREG_MTVEC
@ MISCREG_MTVEC
Definition: registers.hh:209
RiscvISA::MISCREG_MEPC
@ MISCREG_MEPC
Definition: registers.hh:212
RiscvISA::MISCREG_SEDELEG
@ MISCREG_SEDELEG
Definition: registers.hh:236
RiscvISA::UnimplementedFault::instName
const std::string instName
Definition: faults.hh:171
RiscvISA::MISCREG_STVAL
@ MISCREG_STVAL
Definition: registers.hh:243
RiscvISA::PRV_S
@ PRV_S
Definition: isa.hh:59
RiscvISA::FsWorkload
Definition: fs_workload.hh:40
RiscvISA::RiscvFault::invokeSE
virtual void invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
Definition: faults.cc:48
RiscvISA::MISCREG_UTVAL
@ MISCREG_UTVAL
Definition: registers.hh:250
FullSystem
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:132
RiscvISA::MISCREG_SIDELEG
@ MISCREG_SIDELEG
Definition: registers.hh:237
RiscvISA::RiscvFault::_code
ExceptionCode _code
Definition: faults.hh:97
RiscvISA::RiscvFault::name
FaultName name() const override
Definition: faults.hh:103
mbits
T mbits(T val, int first, int last)
Mask off the given bits in place like bits() but without shifting.
Definition: bitfield.hh:104
RiscvISA::MISCREG_STATUS
@ MISCREG_STATUS
Definition: registers.hh:135
isa.hh
RiscvISA
Definition: fs_workload.cc:36
RiscvISA::MISCREG_SCAUSE
@ MISCREG_SCAUSE
Definition: registers.hh:242
System::workload
Workload * workload
OS kernel.
Definition: system.hh:327
ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
RiscvISA::IllegalFrmFault::invokeSE
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:182
RiscvISA::MISCREG_UTVEC
@ MISCREG_UTVEC
Definition: registers.hh:246
Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
debug.hh
schedRelBreak
void schedRelBreak(Tick delta)
Cause the simulator to execute a breakpoint relative to the current tick.
Definition: debug.cc:92
RiscvISA::MiscRegIndex
MiscRegIndex
Definition: registers.hh:128
RiscvISA::MISCREG_UCAUSE
@ MISCREG_UCAUSE
Definition: registers.hh:249
RiscvISA::PrivilegeMode
PrivilegeMode
Definition: isa.hh:56
RiscvISA::PRV_U
@ PRV_U
Definition: isa.hh:58
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
registers.hh
RiscvISA::IllegalInstFault::reason
const std::string reason
Definition: faults.hh:158
full_system.hh
ThreadContext::pcState
virtual TheISA::PCState pcState() const =0
fs_workload.hh
ThreadContext::syscall
virtual void syscall()=0
RiscvISA::RiscvFault::invoke
void invoke(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:54
base.hh
StaticInst::machInst
const ExtMachInst machInst
The binary machine instruction.
Definition: static_inst.hh:243
RiscvISA::RiscvFault::trap_value
virtual RegVal trap_value() const
Definition: faults.hh:106
ThreadContext::readMiscReg
virtual RegVal readMiscReg(RegIndex misc_reg)=0
ThreadContext::setMiscReg
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
addr
ip6_addr_t addr
Definition: inet.hh:423
RiscvISA::MISCREG_MEDELEG
@ MISCREG_MEDELEG
Definition: registers.hh:207
DPRINTFS
#define DPRINTFS(x,...)
Definition: trace.hh:235
utility.hh
RefCountingPtr< StaticInst >
RiscvISA::MISCREG_MTVAL
@ MISCREG_MTVAL
Definition: registers.hh:214
RiscvISA::PRV_M
@ PRV_M
Definition: isa.hh:60
RiscvISA::advancePC
void advancePC(PCState &pc, const StaticInstPtr &inst)
Definition: utility.hh:168
RiscvISA::MISCREG_STVEC
@ MISCREG_STVEC
Definition: registers.hh:238
ThreadContext::getCpuPtr
virtual BaseCPU * getCpuPtr()=0
ThreadContext::instAddr
virtual Addr instAddr() const =0
RiscvISA::MISCREG_SEPC
@ MISCREG_SEPC
Definition: registers.hh:241
thread_context.hh
ThreadContext::getSystemPtr
virtual System * getSystemPtr()=0
RiscvISA::UnimplementedFault::invokeSE
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:174
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
RiscvISA::RiscvFault::isInterrupt
bool isInterrupt() const
Definition: faults.hh:104
RiscvISA::MISCREG_MIDELEG
@ MISCREG_MIDELEG
Definition: registers.hh:208
bits
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:75

Generated on Wed Sep 30 2020 14:01:59 for gem5 by doxygen 1.8.17