gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are
9  * met: redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer;
11  * redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution;
14  * neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * Authors: Alec Roelke
31  * Robert Scheffel
32  */
33 #include "arch/riscv/faults.hh"
34 
35 #include "arch/riscv/isa.hh"
36 #include "arch/riscv/registers.hh"
37 #include "arch/riscv/system.hh"
38 #include "arch/riscv/utility.hh"
39 #include "cpu/base.hh"
40 #include "cpu/thread_context.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  if (FullSystem) {
60  PrivilegeMode prv = PRV_M;
61  STATUS status = tc->readMiscReg(MISCREG_STATUS);
62 
63  // Set fault handler privilege mode
64  if (isInterrupt()) {
65  if (pp != PRV_M &&
66  bits(tc->readMiscReg(MISCREG_MIDELEG), _code) != 0) {
67  prv = PRV_S;
68  }
69  if (pp == PRV_U &&
70  bits(tc->readMiscReg(MISCREG_SIDELEG), _code) != 0) {
71  prv = PRV_U;
72  }
73  } else {
74  if (pp != PRV_M &&
75  bits(tc->readMiscReg(MISCREG_MEDELEG), _code) != 0) {
76  prv = PRV_S;
77  }
78  if (pp == PRV_U &&
79  bits(tc->readMiscReg(MISCREG_SEDELEG), _code) != 0) {
80  prv = PRV_U;
81  }
82  }
83 
84  // Set fault registers and status
85  MiscRegIndex cause, epc, tvec, tval;
86  switch (prv) {
87  case PRV_U:
88  cause = MISCREG_UCAUSE;
89  epc = MISCREG_UEPC;
90  tvec = MISCREG_UTVEC;
91  tval = MISCREG_UTVAL;
92 
93  status.upie = status.uie;
94  status.uie = 0;
95  break;
96  case PRV_S:
97  cause = MISCREG_SCAUSE;
98  epc = MISCREG_SEPC;
99  tvec = MISCREG_STVEC;
100  tval = MISCREG_STVAL;
101 
102  status.spp = pp;
103  status.spie = status.sie;
104  status.sie = 0;
105  break;
106  case PRV_M:
107  cause = MISCREG_MCAUSE;
108  epc = MISCREG_MEPC;
109  tvec = MISCREG_MTVEC;
110  tval = MISCREG_MTVAL;
111 
112  status.mpp = pp;
113  status.mpie = status.sie;
114  status.mie = 0;
115  break;
116  default:
117  panic("Unknown privilege mode %d.", prv);
118  break;
119  }
120 
121  // Set fault cause, privilege, and return PC
122  tc->setMiscReg(cause,
123  (isInterrupt() << (sizeof(uint64_t) * 4 - 1)) | _code);
124  tc->setMiscReg(epc, tc->instAddr());
125  tc->setMiscReg(tval, trap_value());
126  tc->setMiscReg(MISCREG_PRV, prv);
127  tc->setMiscReg(MISCREG_STATUS, status);
128 
129  // Set PC to fault handler address
130  Addr addr = tc->readMiscReg(tvec) >> 2;
131  if (isInterrupt() && bits(tc->readMiscReg(tvec), 1, 0) == 1)
132  addr += 4 * _code;
133  pcState.set(addr);
134  } else {
135  invokeSE(tc, inst);
136  advancePC(pcState, inst);
137  }
138  tc->pcState(pcState);
139 }
140 
142 {
144  STATUS status = tc->readMiscReg(MISCREG_STATUS);
145  status.mie = 0;
146  status.mprv = 0;
147  tc->setMiscReg(MISCREG_STATUS, status);
148  tc->setMiscReg(MISCREG_MCAUSE, 0);
149 
150  // Advance the PC to the implementation-defined reset vector
151  PCState pc = static_cast<RiscvSystem *>(tc->getSystemPtr())->resetVect();
152  tc->pcState(pc);
153 }
154 
155 void
157 {
158  panic("Unknown instruction 0x%08x at pc 0x%016llx", inst->machInst,
159  tc->pcState().pc());
160 }
161 
162 void
164 {
165  panic("Illegal instruction 0x%08x at pc 0x%016llx: %s", inst->machInst,
166  tc->pcState().pc(), reason.c_str());
167 }
168 
169 void
171  const StaticInstPtr &inst)
172 {
173  panic("Unimplemented instruction %s at pc 0x%016llx", instName,
174  tc->pcState().pc());
175 }
176 
177 void
179 {
180  panic("Illegal floating-point rounding mode 0x%x at pc 0x%016llx.",
181  frm, tc->pcState().pc());
182 }
183 
184 void
186 {
187  schedRelBreak(0);
188 }
189 
190 void
192 {
193  Fault *fault = NoFault;
194  tc->syscall(fault);
195 }
196 
197 } // namespace RiscvISA
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:191
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual System * getSystemPtr()=0
decltype(nullptr) constexpr NoFault
Definition: types.hh:245
void invoke(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:54
virtual void syscall(Fault *fault)=0
ExceptionCode _code
Definition: faults.hh:100
virtual TheISA::PCState pcState() const =0
void set(Addr val)
Definition: types.hh:218
ip6_addr_t addr
Definition: inet.hh:335
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:136
void invoke(ThreadContext *tc, const StaticInstPtr &inst=StaticInst::nullStaticInstPtr) override
Definition: faults.cc:141
virtual RegVal trap_value() const
Definition: faults.hh:109
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:156
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:229
Bitfield< 4 > pc
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:185
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:163
virtual Addr instAddr() const =0
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
PrivilegeMode
Definition: isa.hh:60
bool isInterrupt() const
Definition: faults.hh:107
FaultName name() const override
Definition: faults.hh:106
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:170
void schedRelBreak(Tick delta)
Cause the simulator to execute a breakpoint relative to the current tick.
Definition: debug.cc:94
void invokeSE(ThreadContext *tc, const StaticInstPtr &inst) override
Definition: faults.cc:178
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:72
virtual RegVal readMiscReg(RegIndex misc_reg)=0
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
void advancePC(PCState &pc, const StaticInstPtr &inst)
Definition: utility.hh:167

Generated on Fri Feb 28 2020 16:26:55 for gem5 by doxygen 1.8.13