2 * Copyright (c) 2003-2007 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * Copyright (c) 2007 The Hewlett-Packard Development Company
33 * All rights reserved.
35 * Redistribution and use of this software in source and binary forms,
36 * with or without modification, are permitted provided that the
37 * following conditions are met:
39 * The software must be used only for Non-Commercial Use which means any
40 * use which is NOT directed to receiving any direct monetary
41 * compensation for, or commercial advantage from such use. Illustrative
42 * examples of non-commercial use are academic research, personal study,
43 * teaching, education and corporate research & development.
44 * Illustrative examples of commercial use are distributing products for
45 * commercial advantage and providing services using the software for
46 * commercial advantage.
48 * If you wish to use this software or functionality therein that may be
49 * covered by patents for commercial use, please contact:
50 * Director of Intellectual Property Licensing
51 * Office of Strategy and Technology
52 * Hewlett-Packard Company
54 * Palo Alto, California 94304
56 * Redistributions of source code must retain the above copyright notice,
57 * this list of conditions and the following disclaimer. Redistributions
58 * in binary form must reproduce the above copyright notice, this list of
59 * conditions and the following disclaimer in the documentation and/or
60 * other materials provided with the distribution. Neither the name of
61 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
62 * contributors may be used to endorse or promote products derived from
63 * this software without specific prior written permission. No right of
64 * sublicense is granted herewith. Derivatives of the software and
65 * output created using the software may be prepared, but only for
66 * Non-Commercial Uses. Derivatives of the software may be shared with
67 * others provided: (i) the others agree to abide by the list of
68 * conditions herein which includes the Non-Commercial Use restrictions;
69 * and (ii) such Derivatives of the software include the above copyright
70 * notice to acknowledge the contribution from this software where
71 * applicable, this list of conditions and the disclaimer below.
73 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
74 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
75 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
76 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
77 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
78 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
79 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
80 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
81 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
82 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
83 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
88 #include "arch/x86/decoder.hh"
89 #include "arch/x86/faults.hh"
90 #include "base/trace.hh"
91 #include "config/full_system.hh"
92 #include "cpu/thread_context.hh"
94 #include "arch/x86/isa_traits.hh"
95 #include "mem/page_table.hh"
96 #include "sim/process.hh"
98 #include "arch/x86/tlb.hh"
104 void X86FaultBase::invoke(ThreadContext
* tc
)
106 Addr pc
= tc
->readPC();
107 DPRINTF(Faults
, "RIP %#x: vector %d: %s\n", pc
, vector
, describe());
108 using namespace X86ISAInst::RomLabels
;
109 HandyM5Reg m5reg
= tc
->readMiscRegNoEffect(MISCREG_M5_REG
);
111 if (m5reg
.mode
== LongMode
) {
113 entry
= extern_label_longModeSoftInterrupt
;
115 entry
= extern_label_longModeInterrupt
;
118 entry
= extern_label_legacyModeInterrupt
;
120 tc
->setIntReg(INTREG_MICRO(1), vector
);
121 tc
->setIntReg(INTREG_MICRO(7), pc
);
122 if (errorCode
!= (uint64_t)(-1)) {
123 if (m5reg
.mode
== LongMode
) {
124 entry
= extern_label_longModeInterruptWithError
;
126 panic("Legacy mode interrupts with error codes "
127 "aren't implementde.\n");
129 // Software interrupts shouldn't have error codes. If one does,
130 // there would need to be microcode to set it up.
132 tc
->setIntReg(INTREG_MICRO(15), errorCode
);
134 tc
->setMicroPC(romMicroPC(entry
));
135 tc
->setNextMicroPC(romMicroPC(entry
) + 1);
139 X86FaultBase::describe() const
141 std::stringstream ss
;
142 ccprintf(ss
, "%s", mnemonic());
143 if (errorCode
!= (uint64_t)(-1)) {
144 ccprintf(ss
, "(%#x)", errorCode
);
150 void X86Trap::invoke(ThreadContext
* tc
)
152 X86FaultBase::invoke(tc
);
153 // This is the same as a fault, but it happens -after- the instruction.
154 tc
->setPC(tc
->readNextPC());
155 tc
->setNextPC(tc
->readNextNPC());
156 tc
->setNextNPC(tc
->readNextNPC() + sizeof(MachInst
));
159 void X86Abort::invoke(ThreadContext
* tc
)
161 panic("Abort exception!");
164 void PageFault::invoke(ThreadContext
* tc
)
166 HandyM5Reg m5reg
= tc
->readMiscRegNoEffect(MISCREG_M5_REG
);
167 X86FaultBase::invoke(tc
);
169 * If something bad happens while trying to enter the page fault
170 * handler, I'm pretty sure that's a double fault and then all bets are
171 * off. That means it should be safe to update this state now.
173 if (m5reg
.mode
== LongMode
) {
174 tc
->setMiscReg(MISCREG_CR2
, addr
);
176 tc
->setMiscReg(MISCREG_CR2
, (uint32_t)addr
);
181 PageFault::describe() const
183 std::stringstream ss
;
184 ccprintf(ss
, "%s at %#x", X86FaultBase::describe(), addr
);
189 InitInterrupt::invoke(ThreadContext
*tc
)
191 DPRINTF(Faults
, "Init interrupt.\n");
192 // The otherwise unmodified integer registers should be set to 0.
193 for (int index
= 0; index
< NUM_INTREGS
; index
++) {
194 tc
->setIntReg(index
, 0);
197 CR0 cr0
= tc
->readMiscReg(MISCREG_CR0
);
201 tc
->setMiscReg(MISCREG_CR0
, newCR0
);
202 tc
->setMiscReg(MISCREG_CR2
, 0);
203 tc
->setMiscReg(MISCREG_CR3
, 0);
204 tc
->setMiscReg(MISCREG_CR4
, 0);
206 tc
->setMiscReg(MISCREG_RFLAGS
, 0x0000000000000002ULL
);
208 tc
->setMiscReg(MISCREG_EFER
, 0);
210 SegAttr dataAttr
= 0;
212 dataAttr
.unusable
= 0;
213 dataAttr
.defaultSize
= 0;
214 dataAttr
.longMode
= 0;
216 dataAttr
.granularity
= 0;
217 dataAttr
.present
= 1;
219 dataAttr
.writable
= 1;
220 dataAttr
.readable
= 1;
221 dataAttr
.expandDown
= 0;
224 for (int seg
= 0; seg
!= NUM_SEGMENTREGS
; seg
++) {
225 tc
->setMiscReg(MISCREG_SEG_SEL(seg
), 0);
226 tc
->setMiscReg(MISCREG_SEG_BASE(seg
), 0);
227 tc
->setMiscReg(MISCREG_SEG_EFF_BASE(seg
), 0);
228 tc
->setMiscReg(MISCREG_SEG_LIMIT(seg
), 0xffff);
229 tc
->setMiscReg(MISCREG_SEG_ATTR(seg
), dataAttr
);
232 SegAttr codeAttr
= 0;
234 codeAttr
.unusable
= 0;
235 codeAttr
.defaultSize
= 0;
236 codeAttr
.longMode
= 0;
238 codeAttr
.granularity
= 0;
239 codeAttr
.present
= 1;
241 codeAttr
.writable
= 0;
242 codeAttr
.readable
= 1;
243 codeAttr
.expandDown
= 0;
246 tc
->setMiscReg(MISCREG_CS
, 0xf000);
247 tc
->setMiscReg(MISCREG_CS_BASE
,
248 0x00000000ffff0000ULL
);
249 tc
->setMiscReg(MISCREG_CS_EFF_BASE
,
250 0x00000000ffff0000ULL
);
251 // This has the base value pre-added.
252 tc
->setMiscReg(MISCREG_CS_LIMIT
, 0xffffffff);
253 tc
->setMiscReg(MISCREG_CS_ATTR
, codeAttr
);
255 tc
->setPC(0x000000000000fff0ULL
+
256 tc
->readMiscReg(MISCREG_CS_BASE
));
257 tc
->setNextPC(tc
->readPC() + sizeof(MachInst
));
259 tc
->setMiscReg(MISCREG_TSG_BASE
, 0);
260 tc
->setMiscReg(MISCREG_TSG_LIMIT
, 0xffff);
262 tc
->setMiscReg(MISCREG_IDTR_BASE
, 0);
263 tc
->setMiscReg(MISCREG_IDTR_LIMIT
, 0xffff);
265 tc
->setMiscReg(MISCREG_TSL
, 0);
266 tc
->setMiscReg(MISCREG_TSL_BASE
, 0);
267 tc
->setMiscReg(MISCREG_TSL_LIMIT
, 0xffff);
268 tc
->setMiscReg(MISCREG_TSL_ATTR
, 0);
270 tc
->setMiscReg(MISCREG_TR
, 0);
271 tc
->setMiscReg(MISCREG_TR_BASE
, 0);
272 tc
->setMiscReg(MISCREG_TR_LIMIT
, 0xffff);
273 tc
->setMiscReg(MISCREG_TR_ATTR
, 0);
275 // This value should be the family/model/stepping of the processor.
276 // (page 418). It should be consistent with the value from CPUID, but
277 // the actual value probably doesn't matter much.
278 tc
->setIntReg(INTREG_RDX
, 0);
280 tc
->setMiscReg(MISCREG_DR0
, 0);
281 tc
->setMiscReg(MISCREG_DR1
, 0);
282 tc
->setMiscReg(MISCREG_DR2
, 0);
283 tc
->setMiscReg(MISCREG_DR3
, 0);
285 tc
->setMiscReg(MISCREG_DR6
, 0x00000000ffff0ff0ULL
);
286 tc
->setMiscReg(MISCREG_DR7
, 0x0000000000000400ULL
);
288 // Update the handy M5 Reg.
289 tc
->setMiscReg(MISCREG_M5_REG
, 0);
290 MicroPC entry
= X86ISAInst::RomLabels::extern_label_initIntHalt
;
291 tc
->setMicroPC(romMicroPC(entry
));
292 tc
->setNextMicroPC(romMicroPC(entry
) + 1);
296 StartupInterrupt::invoke(ThreadContext
*tc
)
298 DPRINTF(Faults
, "Startup interrupt with vector %#x.\n", vector
);
299 HandyM5Reg m5Reg
= tc
->readMiscReg(MISCREG_M5_REG
);
300 if (m5Reg
.mode
!= LegacyMode
|| m5Reg
.submode
!= RealMode
) {
301 panic("Startup IPI recived outside of real mode. "
302 "Don't know what to do. %d, %d", m5Reg
.mode
, m5Reg
.submode
);
305 tc
->setMiscReg(MISCREG_CS
, vector
<< 8);
306 tc
->setMiscReg(MISCREG_CS_BASE
, vector
<< 12);
307 tc
->setMiscReg(MISCREG_CS_EFF_BASE
, vector
<< 12);
308 // This has the base value pre-added.
309 tc
->setMiscReg(MISCREG_CS_LIMIT
, 0xffff);
311 tc
->setPC(tc
->readMiscReg(MISCREG_CS_BASE
));
312 tc
->setNextPC(tc
->readPC() + sizeof(MachInst
));
316 } // namespace X86ISA