gem5 v24.0.0.0
Loading...
Searching...
No Matches
faults.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 The Hewlett-Packard Development Company
3 * All rights reserved.
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2003-2007 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41#include "arch/x86/faults.hh"
42
43#include "arch/x86/generated/decoder.hh"
45#include "arch/x86/mmu.hh"
46#include "arch/x86/regs/int.hh"
47#include "arch/x86/regs/misc.hh"
48#include "base/loader/symtab.hh"
49#include "base/trace.hh"
50#include "cpu/thread_context.hh"
51#include "debug/Faults.hh"
52#include "sim/full_system.hh"
53#include "sim/process.hh"
54
55namespace gem5
56{
57
58namespace X86ISA
59{
60
61void
63{
64 if (!FullSystem) {
65 FaultBase::invoke(tc, inst);
66 return;
67 }
68
69 PCState pc = tc->pcState().as<PCState>();
70 DPRINTF(Faults, "RIP %#x: vector %d: %s\n", pc.pc(), vector, describe());
71 using namespace X86ISAInst::rom_labels;
72 HandyM5Reg m5reg = tc->readMiscRegNoEffect(misc_reg::M5Reg);
73 MicroPC entry;
74 if (m5reg.mode == LongMode) {
75 entry = extern_label_longModeInterrupt;
76 } else {
77 if (m5reg.submode == RealMode)
78 entry = extern_label_realModeInterrupt;
79 else
80 entry = extern_label_legacyModeInterrupt;
81 }
82 tc->setReg(intRegMicro(1), vector);
84 tc->setReg(intRegMicro(7), pc.pc() - cs_base);
85 if (errorCode != (uint64_t)(-1)) {
86 if (m5reg.mode == LongMode) {
87 entry = extern_label_longModeInterruptWithError;
88 } else {
89 panic("Legacy mode interrupts with error codes "
90 "aren't implemented.");
91 }
93 }
94 pc.upc(romMicroPC(entry));
95 pc.nupc(romMicroPC(entry) + 1);
96 tc->pcState(pc);
97}
98
99std::string
101{
102 std::stringstream ss;
103 ccprintf(ss, "%s", mnemonic());
104 if (errorCode != (uint64_t)(-1))
105 ccprintf(ss, "(%#x)", errorCode);
106
107 return ss.str();
108}
109
110void
112{
113 // This is the same as a fault, but it happens -after- the
114 // instruction.
116}
117
118void
120{
121 panic("Abort exception!");
122}
123
124void
126{
127 if (FullSystem) {
128 X86Fault::invoke(tc, inst);
129 } else {
130 auto *xsi = static_cast<X86StaticInst *>(inst.get());
131 panic("Unrecognized/invalid instruction executed:\n %s",
132 xsi->machInst);
133 }
134}
135
136void
138{
139 if (FullSystem) {
140 // Invalidate any matching TLB entries before handling the page fault.
141 tc->getMMUPtr()->demapPage(addr, 0);
142 HandyM5Reg m5reg = tc->readMiscRegNoEffect(misc_reg::M5Reg);
144 // If something bad happens while trying to enter the page fault
145 // handler, I'm pretty sure that's a double fault and then all
146 // bets are off. That means it should be safe to update this
147 // state now.
148 if (m5reg.mode == LongMode)
150 else
151 tc->setMiscReg(misc_reg::Cr2, (uint32_t)addr);
152 } else if (!tc->getProcessPtr()->fixupFault(addr)) {
153 PageFaultErrorCode code = errorCode;
154 const char *modeStr = "";
155 if (code.fetch)
156 modeStr = "execute";
157 else if (code.write)
158 modeStr = "write";
159 else
160 modeStr = "read";
161
162 // print information about what we are panic'ing on
163 if (!inst) {
164 panic("Tried to %s unmapped address %#x.", modeStr, addr);
165 } else {
166 panic("Tried to %s unmapped address %#x.\nPC: %#x, Instr: %s",
167 modeStr, addr, tc->pcState(),
168 inst->disassemble(tc->pcState().instAddr(),
170 }
171 }
172}
173
174std::string
176{
177 std::stringstream ss;
178 ccprintf(ss, "%s at %#x", X86FaultBase::describe(), addr);
179 return ss.str();
180}
181
182void
184{
185 DPRINTF(Faults, "Init interrupt.\n");
186 // The otherwise unmodified integer registers should be set to 0.
187 for (int index = 0; index < int_reg::NumArchRegs; index++) {
188 tc->setReg(intRegClass[index], (RegVal)0);
189 }
190
191 CR0 cr0 = tc->readMiscReg(misc_reg::Cr0);
192 CR0 newCR0 = 1 << 4;
193 newCR0.cd = cr0.cd;
194 newCR0.nw = cr0.nw;
195 tc->setMiscReg(misc_reg::Cr0, newCR0);
199
200 tc->setMiscReg(misc_reg::Rflags, 0x0000000000000002ULL);
201
203
204 SegAttr dataAttr = 0;
205 dataAttr.dpl = 0;
206 dataAttr.unusable = 0;
207 dataAttr.defaultSize = 0;
208 dataAttr.longMode = 0;
209 dataAttr.avl = 0;
210 dataAttr.granularity = 0;
211 dataAttr.present = 1;
212 dataAttr.type = 3;
213 dataAttr.writable = 1;
214 dataAttr.readable = 1;
215 dataAttr.expandDown = 0;
216 dataAttr.system = 1;
217
218 for (int seg = 0; seg != segment_idx::NumIdxs; seg++) {
222 tc->setMiscReg(misc_reg::segLimit(seg), 0xffff);
223 tc->setMiscReg(misc_reg::segAttr(seg), dataAttr);
224 }
225
226 SegAttr codeAttr = 0;
227 codeAttr.dpl = 0;
228 codeAttr.unusable = 0;
229 codeAttr.defaultSize = 0;
230 codeAttr.longMode = 0;
231 codeAttr.avl = 0;
232 codeAttr.granularity = 0;
233 codeAttr.present = 1;
234 codeAttr.type = 10;
235 codeAttr.writable = 0;
236 codeAttr.readable = 1;
237 codeAttr.expandDown = 0;
238 codeAttr.system = 1;
239
240 tc->setMiscReg(misc_reg::Cs, 0xf000);
241 tc->setMiscReg(misc_reg::CsBase, 0x00000000ffff0000ULL);
242 tc->setMiscReg(misc_reg::CsEffBase, 0x00000000ffff0000ULL);
243 // This has the base value pre-added.
244 tc->setMiscReg(misc_reg::CsLimit, 0xffffffff);
245 tc->setMiscReg(misc_reg::CsAttr, codeAttr);
246
247 PCState pc(0x000000000000fff0ULL + tc->readMiscReg(misc_reg::CsBase));
248 tc->pcState(pc);
249
251 tc->setMiscReg(misc_reg::TsgLimit, 0xffff);
252
254 tc->setMiscReg(misc_reg::IdtrLimit, 0xffff);
255
256 SegAttr tslAttr = 0;
257 tslAttr.unusable = 1;
258 tslAttr.present = 1;
259 tslAttr.type = 2; // LDT
262 tc->setMiscReg(misc_reg::TslLimit, 0xffff);
263 tc->setMiscReg(misc_reg::TslAttr, tslAttr);
264
265 SegAttr trAttr = 0;
266 trAttr.unusable = 0;
267 trAttr.present = 1;
268 trAttr.type = 3; // Busy 16-bit TSS
269 tc->setMiscReg(misc_reg::Tr, 0);
271 tc->setMiscReg(misc_reg::TrLimit, 0xffff);
272 tc->setMiscReg(misc_reg::TrAttr, trAttr);
273
274 // This value should be the family/model/stepping of the processor.
275 // (page 418). It should be consistent with the value from CPUID, but
276 // the actual value probably doesn't matter much.
277 tc->setReg(int_reg::Rdx, (RegVal)0);
278
283
284 tc->setMiscReg(misc_reg::Dr6, 0x00000000ffff0ff0ULL);
285 tc->setMiscReg(misc_reg::Dr7, 0x0000000000000400ULL);
286
287 tc->setMiscReg(misc_reg::Mxcsr, 0x1f80);
288
289 // Flag all elements on the x87 stack as empty.
290 tc->setMiscReg(misc_reg::Ftw, 0xFFFF);
291
292 // Update the handy M5 Reg.
294 MicroPC entry = X86ISAInst::rom_labels::extern_label_initIntHalt;
295 pc.upc(romMicroPC(entry));
296 pc.nupc(romMicroPC(entry) + 1);
297 tc->pcState(pc);
298}
299
300void
302{
303 DPRINTF(Faults, "Startup interrupt with vector %#x.\n", vector);
304 HandyM5Reg m5Reg = tc->readMiscReg(misc_reg::M5Reg);
305 if (m5Reg.mode != LegacyMode || m5Reg.submode != RealMode) {
306 panic("Startup IPI recived outside of real mode. "
307 "Don't know what to do. %d, %d", m5Reg.mode, m5Reg.submode);
308 }
309
310 tc->setMiscReg(misc_reg::Cs, vector << 8);
313 // This has the base value pre-added.
314 tc->setMiscReg(misc_reg::CsLimit, 0xffff);
315
317}
318
319} // namespace X86ISA
320} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
void demapPage(Addr vaddr, uint64_t asn)
Definition mmu.cc:97
virtual void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:58
Target & as()
Definition pcstate.hh:73
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
Definition pcstate.hh:108
bool fixupFault(Addr vaddr)
Attempt to fix up a fault at vaddr by allocating a page on the stack.
Definition process.cc:365
T * get() const
Directly access the pointer itself without taking a reference.
Definition refcnt.hh:227
virtual const std::string & disassemble(Addr pc, const loader::SymbolTable *symtab=nullptr) const
Return string representation of disassembled instruction.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
virtual void setReg(const RegId &reg, RegVal val)
virtual const PCStateBase & pcState() const =0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
virtual BaseMMU * getMMUPtr()=0
virtual Process * getProcessPtr()=0
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:183
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:125
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr)
Definition faults.cc:137
virtual std::string describe() const
Definition faults.cc:175
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:301
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:119
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:62
virtual const char * mnemonic() const
Definition faults.hh:72
virtual std::string describe() const
Definition faults.cc:100
Base class for all X86 static instructions.
void invoke(ThreadContext *tc, const StaticInstPtr &inst=nullStaticInstPtr) override
Definition faults.cc:111
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
Bitfield< 21 > ss
Definition misc_types.hh:60
constexpr RegId Rdx
Definition int.hh:134
static RegIndex segSel(int index)
Definition misc.hh:515
static RegIndex segAttr(int index)
Definition misc.hh:543
static RegIndex segBase(int index)
Definition misc.hh:522
static RegIndex segLimit(int index)
Definition misc.hh:536
static RegIndex segEffBase(int index)
Definition misc.hh:529
Bitfield< 19 > pc
Definition misc.hh:840
static constexpr RegId intRegMicro(int index)
Definition int.hh:181
constexpr RegClass intRegClass
Definition int.hh:123
Bitfield< 3 > addr
Definition types.hh:84
Bitfield< 2, 0 > seg
Definition types.hh:87
Bitfield< 5, 3 > index
Definition types.hh:98
SymbolTable debugSymbolTable
Global unified debugging symbol table (for target).
Definition symtab.cc:55
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint64_t RegVal
Definition types.hh:173
static MicroPC romMicroPC(MicroPC upc)
Definition types.hh:154
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition root.cc:220
uint16_t MicroPC
Definition types.hh:149
void ccprintf(cp::Print &print)
Definition cprintf.hh:130

Generated on Tue Jun 18 2024 16:23:57 for gem5 by doxygen 1.11.0