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 |