gem5  v20.0.0.3
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);
130  tc->setMiscReg(MISCREG_STATUS, status);
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;
150  tc->setMiscReg(MISCREG_STATUS, status);
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  Fault *fault = NoFault;
198  tc->syscall(fault);
199 }
200 
201 } // namespace RiscvISA
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:163
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:195
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual System * getSystemPtr()=0
decltype(nullptr) constexpr NoFault
Definition: types.hh:243
void invoke(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:54
virtual void syscall(Fault *fault)=0
ExceptionCode _code
Definition: faults.hh:97
virtual TheISA::PCState pcState() const =0
void set(Addr val)
Definition: types.hh:216
ip6_addr_t addr
Definition: inet.hh:330
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:132
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr) override
Definition: faults.cc:144
virtual BaseCPU * getCpuPtr()=0
virtual RegVal trap_value() const
Definition: faults.hh:106
ThreadContext is the external interface to all thread state for anything outside of the CPU...
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:160
#define DPRINTFS(x,...)
Definition: trace.hh:226
virtual void invokeSE(ThreadContext *tc, const StaticInstPtr &inst)
Definition: faults.cc:48
Bitfield< 5, 0 > status
const ExtMachInst machInst
The binary machine instruction.
Definition: static_inst.hh:231
Bitfield< 4 > pc
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:189
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:167
Workload * workload
OS kernel.
Definition: system.hh:213
virtual Addr instAddr() const =0
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:140
PrivilegeMode
Definition: isa.hh:56
bool isInterrupt() const
Definition: faults.hh:104
FaultName name() const override
Definition: faults.hh:103
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:174
void schedRelBreak(Tick delta)
Cause the simulator to execute a breakpoint relative to the current tick.
Definition: debug.cc:92
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:182
T mbits(T val, int first, int last)
Mask off the given bits in place like bits() but without shifting.
Definition: bitfield.hh:95
T bits(T val, int first, int last)
Extract the bitfield from position &#39;first&#39; to &#39;last&#39; (inclusive) from &#39;val&#39; and right justify it...
Definition: bitfield.hh:71
virtual RegVal readMiscReg(RegIndex misc_reg)=0
std::shared_ptr< FaultBase > Fault
Definition: types.hh:238
void advancePC(PCState &pc, const StaticInstPtr &inst)
Definition: utility.hh:164

Generated on Fri Jul 3 2020 15:42:38 for gem5 by doxygen 1.8.13