faults.cc (8232:b28d06a175be) faults.cc (8740:253aeee61e66)
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

--- 28 unchanged lines hidden (view full) ---

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 * Authors: Gabe Black
41 */
42
43#include "arch/x86/decoder.hh"
44#include "arch/x86/faults.hh"
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

--- 28 unchanged lines hidden (view full) ---

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 * Authors: Gabe Black
41 */
42
43#include "arch/x86/decoder.hh"
44#include "arch/x86/faults.hh"
45#include "arch/x86/isa_traits.hh"
45#include "base/trace.hh"
46#include "base/trace.hh"
46#include "config/full_system.hh"
47#include "cpu/thread_context.hh"
47#include "cpu/thread_context.hh"
48
49#if !FULL_SYSTEM
50#include "arch/x86/isa_traits.hh"
51#include "mem/page_table.hh"
52#include "sim/process.hh"
53#else
54#include "arch/x86/tlb.hh"
55#include "debug/Faults.hh"
48#include "debug/Faults.hh"
56#endif
49#include "sim/full_system.hh"
57
58namespace X86ISA
59{
50
51namespace X86ISA
52{
60#if FULL_SYSTEM
61 void X86FaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
62 {
53 void X86FaultBase::invoke(ThreadContext * tc, StaticInstPtr inst)
54 {
63 PCState pcState = tc->pcState();
64 Addr pc = pcState.pc();
65 DPRINTF(Faults, "RIP %#x: vector %d: %s\n", pc, vector, describe());
66 using namespace X86ISAInst::RomLabels;
67 HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
68 MicroPC entry;
69 if (m5reg.mode == LongMode) {
70 if (isSoft()) {
71 entry = extern_label_longModeSoftInterrupt;
55 if (FullSystem) {
56 PCState pcState = tc->pcState();
57 Addr pc = pcState.pc();
58 DPRINTF(Faults, "RIP %#x: vector %d: %s\n",
59 pc, vector, describe());
60 using namespace X86ISAInst::RomLabels;
61 HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
62 MicroPC entry;
63 if (m5reg.mode == LongMode) {
64 if (isSoft()) {
65 entry = extern_label_longModeSoftInterrupt;
66 } else {
67 entry = extern_label_longModeInterrupt;
68 }
72 } else {
69 } else {
73 entry = extern_label_longModeInterrupt;
70 entry = extern_label_legacyModeInterrupt;
74 }
71 }
72 tc->setIntReg(INTREG_MICRO(1), vector);
73 tc->setIntReg(INTREG_MICRO(7), pc);
74 if (errorCode != (uint64_t)(-1)) {
75 if (m5reg.mode == LongMode) {
76 entry = extern_label_longModeInterruptWithError;
77 } else {
78 panic("Legacy mode interrupts with error codes "
79 "aren't implementde.\n");
80 }
81 // Software interrupts shouldn't have error codes. If one
82 // does, there would need to be microcode to set it up.
83 assert(!isSoft());
84 tc->setIntReg(INTREG_MICRO(15), errorCode);
85 }
86 pcState.upc(romMicroPC(entry));
87 pcState.nupc(romMicroPC(entry) + 1);
88 tc->pcState(pcState);
75 } else {
89 } else {
76 entry = extern_label_legacyModeInterrupt;
90 FaultBase::invoke(tc, inst);
77 }
91 }
78 tc->setIntReg(INTREG_MICRO(1), vector);
79 tc->setIntReg(INTREG_MICRO(7), pc);
80 if (errorCode != (uint64_t)(-1)) {
81 if (m5reg.mode == LongMode) {
82 entry = extern_label_longModeInterruptWithError;
83 } else {
84 panic("Legacy mode interrupts with error codes "
85 "aren't implementde.\n");
86 }
87 // Software interrupts shouldn't have error codes. If one does,
88 // there would need to be microcode to set it up.
89 assert(!isSoft());
90 tc->setIntReg(INTREG_MICRO(15), errorCode);
91 }
92 pcState.upc(romMicroPC(entry));
93 pcState.nupc(romMicroPC(entry) + 1);
94 tc->pcState(pcState);
95 }
96
97 std::string
98 X86FaultBase::describe() const
99 {
100 std::stringstream ss;
101 ccprintf(ss, "%s", mnemonic());
102 if (errorCode != (uint64_t)(-1)) {
103 ccprintf(ss, "(%#x)", errorCode);
104 }
105
106 return ss.str();
107 }
108
109 void X86Trap::invoke(ThreadContext * tc, StaticInstPtr inst)
110 {
111 X86FaultBase::invoke(tc);
92 }
93
94 std::string
95 X86FaultBase::describe() const
96 {
97 std::stringstream ss;
98 ccprintf(ss, "%s", mnemonic());
99 if (errorCode != (uint64_t)(-1)) {
100 ccprintf(ss, "(%#x)", errorCode);
101 }
102
103 return ss.str();
104 }
105
106 void X86Trap::invoke(ThreadContext * tc, StaticInstPtr inst)
107 {
108 X86FaultBase::invoke(tc);
112 // This is the same as a fault, but it happens -after- the instruction.
113 PCState pc = tc->pcState();
114 pc.uEnd();
109 if (FullSystem) {
110 // This is the same as a fault, but it happens -after- the
111 // instruction.
112 PCState pc = tc->pcState();
113 pc.uEnd();
114 }
115 }
116
117 void X86Abort::invoke(ThreadContext * tc, StaticInstPtr inst)
118 {
119 panic("Abort exception!");
120 }
121
115 }
116
117 void X86Abort::invoke(ThreadContext * tc, StaticInstPtr inst)
118 {
119 panic("Abort exception!");
120 }
121
122 void
123 InvalidOpcode::invoke(ThreadContext * tc, StaticInstPtr inst)
124 {
125 if (FullSystem) {
126 X86Fault::invoke(tc, inst);
127 } else {
128 panic("Unrecognized/invalid instruction executed:\n %s",
129 inst->machInst);
130 }
131 }
132
122 void PageFault::invoke(ThreadContext * tc, StaticInstPtr inst)
123 {
133 void PageFault::invoke(ThreadContext * tc, StaticInstPtr inst)
134 {
124 HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
125 X86FaultBase::invoke(tc);
126 /*
127 * If something bad happens while trying to enter the page fault
128 * handler, I'm pretty sure that's a double fault and then all bets are
129 * off. That means it should be safe to update this state now.
130 */
131 if (m5reg.mode == LongMode) {
132 tc->setMiscReg(MISCREG_CR2, addr);
135 if (FullSystem) {
136 HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
137 X86FaultBase::invoke(tc);
138 /*
139 * If something bad happens while trying to enter the page fault
140 * handler, I'm pretty sure that's a double fault and then all
141 * bets are off. That means it should be safe to update this
142 * state now.
143 */
144 if (m5reg.mode == LongMode) {
145 tc->setMiscReg(MISCREG_CR2, addr);
146 } else {
147 tc->setMiscReg(MISCREG_CR2, (uint32_t)addr);
148 }
133 } else {
149 } else {
134 tc->setMiscReg(MISCREG_CR2, (uint32_t)addr);
150 PageFaultErrorCode code = errorCode;
151 const char *modeStr = "";
152 if (code.fetch)
153 modeStr = "execute";
154 else if (code.write)
155 modeStr = "write";
156 else
157 modeStr = "read";
158 panic("Tried to %s unmapped address %#x.\n", modeStr, addr);
135 }
136 }
137
138 std::string
139 PageFault::describe() const
140 {
141 std::stringstream ss;
142 ccprintf(ss, "%s at %#x", X86FaultBase::describe(), addr);

--- 120 unchanged lines hidden (view full) ---

263 tc->setMiscReg(MISCREG_CS, vector << 8);
264 tc->setMiscReg(MISCREG_CS_BASE, vector << 12);
265 tc->setMiscReg(MISCREG_CS_EFF_BASE, vector << 12);
266 // This has the base value pre-added.
267 tc->setMiscReg(MISCREG_CS_LIMIT, 0xffff);
268
269 tc->pcState(tc->readMiscReg(MISCREG_CS_BASE));
270 }
159 }
160 }
161
162 std::string
163 PageFault::describe() const
164 {
165 std::stringstream ss;
166 ccprintf(ss, "%s at %#x", X86FaultBase::describe(), addr);

--- 120 unchanged lines hidden (view full) ---

287 tc->setMiscReg(MISCREG_CS, vector << 8);
288 tc->setMiscReg(MISCREG_CS_BASE, vector << 12);
289 tc->setMiscReg(MISCREG_CS_EFF_BASE, vector << 12);
290 // This has the base value pre-added.
291 tc->setMiscReg(MISCREG_CS_LIMIT, 0xffff);
292
293 tc->pcState(tc->readMiscReg(MISCREG_CS_BASE));
294 }
271
272#else
273
274 void
275 InvalidOpcode::invoke(ThreadContext * tc, StaticInstPtr inst)
276 {
277 panic("Unrecognized/invalid instruction executed:\n %s",
278 inst->machInst);
279 }
280
281 void
282 PageFault::invoke(ThreadContext * tc, StaticInstPtr inst)
283 {
284 PageFaultErrorCode code = errorCode;
285 const char *modeStr = "";
286 if (code.fetch)
287 modeStr = "execute";
288 else if (code.write)
289 modeStr = "write";
290 else
291 modeStr = "read";
292 panic("Tried to %s unmapped address %#x.\n", modeStr, addr);
293 }
294
295#endif
296} // namespace X86ISA
297
295} // namespace X86ISA
296