faults.cc revision 6222
12292SN/A/* 22329SN/A * Copyright (c) 2003-2007 The Regents of The University of Michigan 32292SN/A * All rights reserved. 42292SN/A * 52292SN/A * Redistribution and use in source and binary forms, with or without 62292SN/A * modification, are permitted provided that the following conditions are 72292SN/A * met: redistributions of source code must retain the above copyright 82292SN/A * notice, this list of conditions and the following disclaimer; 92292SN/A * redistributions in binary form must reproduce the above copyright 102292SN/A * notice, this list of conditions and the following disclaimer in the 112292SN/A * documentation and/or other materials provided with the distribution; 122292SN/A * neither the name of the copyright holders nor the names of its 132292SN/A * contributors may be used to endorse or promote products derived from 142292SN/A * this software without specific prior written permission. 152292SN/A * 162292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 172292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 182292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 192292SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 202292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 212292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 222292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 232292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 242292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 252292SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 262292SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272689Sktlim@umich.edu * 282689Sktlim@umich.edu * Authors: Gabe Black 292689Sktlim@umich.edu */ 302292SN/A 312292SN/A/* 322292SN/A * Copyright (c) 2007 The Hewlett-Packard Development Company 332292SN/A * All rights reserved. 342292SN/A * 352329SN/A * Redistribution and use of this software in source and binary forms, 362292SN/A * with or without modification, are permitted provided that the 372292SN/A * following conditions are met: 382292SN/A * 392329SN/A * The software must be used only for Non-Commercial Use which means any 403326Sktlim@umich.edu * use which is NOT directed to receiving any direct monetary 412292SN/A * compensation for, or commercial advantage from such use. Illustrative 422292SN/A * examples of non-commercial use are academic research, personal study, 432292SN/A * teaching, education and corporate research & development. 443348Sbinkertn@umich.edu * Illustrative examples of commercial use are distributing products for 452669Sktlim@umich.edu * commercial advantage and providing services using the software for 462292SN/A * commercial advantage. 472292SN/A * 482329SN/A * If you wish to use this software or functionality therein that may be 492329SN/A * covered by patents for commercial use, please contact: 502329SN/A * Director of Intellectual Property Licensing 512329SN/A * Office of Strategy and Technology 522329SN/A * Hewlett-Packard Company 532329SN/A * 1501 Page Mill Road 542329SN/A * Palo Alto, California 94304 552329SN/A * 562329SN/A * Redistributions of source code must retain the above copyright notice, 572329SN/A * this list of conditions and the following disclaimer. Redistributions 582292SN/A * in binary form must reproduce the above copyright notice, this list of 592292SN/A * conditions and the following disclaimer in the documentation and/or 602292SN/A * other materials provided with the distribution. Neither the name of 612292SN/A * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its 622292SN/A * contributors may be used to endorse or promote products derived from 632292SN/A * this software without specific prior written permission. No right of 642292SN/A * sublicense is granted herewith. Derivatives of the software and 652733Sktlim@umich.edu * output created using the software may be prepared, but only for 662292SN/A * Non-Commercial Uses. Derivatives of the software may be shared with 672292SN/A * others provided: (i) the others agree to abide by the list of 682907Sktlim@umich.edu * conditions herein which includes the Non-Commercial Use restrictions; 692292SN/A * and (ii) such Derivatives of the software include the above copyright 702292SN/A * notice to acknowledge the contribution from this software where 712292SN/A * applicable, this list of conditions and the disclaimer below. 722292SN/A * 732292SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 742292SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 752292SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 762907Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 772292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 782292SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 792292SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 802292SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 812292SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 822727Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 832727Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 842727Sktlim@umich.edu * 852292SN/A * Authors: Gabe Black 862733Sktlim@umich.edu */ 872292SN/A 882292SN/A#include "arch/x86/decoder.hh" 892292SN/A#include "arch/x86/faults.hh" 902292SN/A#include "base/trace.hh" 912292SN/A#include "config/full_system.hh" 922907Sktlim@umich.edu#include "cpu/thread_context.hh" 932907Sktlim@umich.edu#if !FULL_SYSTEM 942907Sktlim@umich.edu#include "arch/x86/isa_traits.hh" 952907Sktlim@umich.edu#include "mem/page_table.hh" 962348SN/A#include "sim/process.hh" 972307SN/A#else 982307SN/A#include "arch/x86/tlb.hh" 992348SN/A#endif 1002307SN/A 1012307SN/Anamespace X86ISA 1022348SN/A{ 1032307SN/A#if FULL_SYSTEM 1042307SN/A void X86FaultBase::invoke(ThreadContext * tc) 1052292SN/A { 1062292SN/A Addr pc = tc->readPC(); 1072292SN/A DPRINTF(Faults, "RIP %#x: vector %d: %s\n", pc, vector, describe()); 1082292SN/A using namespace X86ISAInst::RomLabels; 1092292SN/A HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); 1102292SN/A MicroPC entry; 1112292SN/A if (m5reg.mode == LongMode) { 1122292SN/A if (isSoft()) { 1132292SN/A entry = extern_label_longModeSoftInterrupt; 1142292SN/A } else { 1152292SN/A entry = extern_label_longModeInterrupt; 1162292SN/A } 1172292SN/A } else { 1182292SN/A entry = extern_label_legacyModeInterrupt; 1192292SN/A } 1202292SN/A tc->setIntReg(INTREG_MICRO(1), vector); 1212292SN/A tc->setIntReg(INTREG_MICRO(7), pc); 1222329SN/A if (errorCode != (uint64_t)(-1)) { 1232292SN/A if (m5reg.mode == LongMode) { 1242292SN/A entry = extern_label_longModeInterruptWithError; 1252292SN/A } else { 1262292SN/A panic("Legacy mode interrupts with error codes " 1272292SN/A "aren't implementde.\n"); 1282292SN/A } 1292292SN/A // Software interrupts shouldn't have error codes. If one does, 1302292SN/A // there would need to be microcode to set it up. 1312292SN/A assert(!isSoft()); 1322292SN/A tc->setIntReg(INTREG_MICRO(15), errorCode); 1332292SN/A } 1342292SN/A tc->setMicroPC(romMicroPC(entry)); 1352292SN/A tc->setNextMicroPC(romMicroPC(entry) + 1); 1362292SN/A } 1372790Sktlim@umich.edu 1382790Sktlim@umich.edu std::string 1392669Sktlim@umich.edu X86FaultBase::describe() const 1402669Sktlim@umich.edu { 1412292SN/A std::stringstream ss; 1422292SN/A ccprintf(ss, "%s", mnemonic()); 1432292SN/A if (errorCode != (uint64_t)(-1)) { 1442292SN/A ccprintf(ss, "(%#x)", errorCode); 1452292SN/A } 1462292SN/A 1472292SN/A return ss.str(); 1482292SN/A } 1492292SN/A 1502292SN/A void X86Trap::invoke(ThreadContext * tc) 1512292SN/A { 1522292SN/A X86FaultBase::invoke(tc); 1532292SN/A // This is the same as a fault, but it happens -after- the instruction. 1542292SN/A tc->setPC(tc->readNextPC()); 1552292SN/A tc->setNextPC(tc->readNextNPC()); 1562292SN/A tc->setNextNPC(tc->readNextNPC() + sizeof(MachInst)); 1572292SN/A } 1582292SN/A 1592292SN/A void X86Abort::invoke(ThreadContext * tc) 1602292SN/A { 1612292SN/A panic("Abort exception!"); 1622292SN/A } 1632292SN/A 1642329SN/A void PageFault::invoke(ThreadContext * tc) 1652292SN/A { 1662292SN/A HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG); 1672292SN/A X86FaultBase::invoke(tc); 1682348SN/A /* 1692292SN/A * If something bad happens while trying to enter the page fault 1702292SN/A * handler, I'm pretty sure that's a double fault and then all bets are 1712292SN/A * off. That means it should be safe to update this state now. 1722348SN/A */ 1732292SN/A if (m5reg.mode == LongMode) { 1742292SN/A tc->setMiscReg(MISCREG_CR2, addr); 1752292SN/A } else { 1762348SN/A tc->setMiscReg(MISCREG_CR2, (uint32_t)addr); 1772292SN/A } 1782292SN/A } 1792292SN/A 1802292SN/A std::string 1812292SN/A PageFault::describe() const 1822292SN/A { 1832292SN/A std::stringstream ss; 1842292SN/A ccprintf(ss, "%s at %#x", X86FaultBase::describe(), addr); 1852292SN/A return ss.str(); 1862292SN/A } 1872292SN/A 1882292SN/A void 1892292SN/A InitInterrupt::invoke(ThreadContext *tc) 1902292SN/A { 1912292SN/A DPRINTF(Faults, "Init interrupt.\n"); 1922292SN/A // The otherwise unmodified integer registers should be set to 0. 1932292SN/A for (int index = 0; index < NUM_INTREGS; index++) { 1942292SN/A tc->setIntReg(index, 0); 1952292SN/A } 1962292SN/A 1972292SN/A CR0 cr0 = tc->readMiscReg(MISCREG_CR0); 1982292SN/A CR0 newCR0 = 1 << 4; 1992292SN/A newCR0.cd = cr0.cd; 2002292SN/A newCR0.nw = cr0.nw; 2012292SN/A tc->setMiscReg(MISCREG_CR0, newCR0); 2022292SN/A tc->setMiscReg(MISCREG_CR2, 0); 2032292SN/A tc->setMiscReg(MISCREG_CR3, 0); 2042292SN/A tc->setMiscReg(MISCREG_CR4, 0); 2052292SN/A 2062292SN/A tc->setMiscReg(MISCREG_RFLAGS, 0x0000000000000002ULL); 2072292SN/A 2082292SN/A tc->setMiscReg(MISCREG_EFER, 0); 2092292SN/A 2102292SN/A SegAttr dataAttr = 0; 2112292SN/A dataAttr.dpl = 0; 2122678Sktlim@umich.edu dataAttr.unusable = 0; 2132678Sktlim@umich.edu dataAttr.defaultSize = 0; 2142292SN/A dataAttr.longMode = 0; 2152907Sktlim@umich.edu dataAttr.avl = 0; 2162907Sktlim@umich.edu dataAttr.granularity = 0; 2172907Sktlim@umich.edu dataAttr.present = 1; 2182292SN/A dataAttr.type = 3; 2192698Sktlim@umich.edu dataAttr.writable = 1; 2202678Sktlim@umich.edu dataAttr.readable = 1; 2212678Sktlim@umich.edu dataAttr.expandDown = 0; 2222698Sktlim@umich.edu dataAttr.system = 1; 2233349Sbinkertn@umich.edu 2242693Sktlim@umich.edu for (int seg = 0; seg != NUM_SEGMENTREGS; seg++) { 2252292SN/A tc->setMiscReg(MISCREG_SEG_SEL(seg), 0); 2262292SN/A tc->setMiscReg(MISCREG_SEG_BASE(seg), 0); 2272292SN/A tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), 0); 2282292SN/A tc->setMiscReg(MISCREG_SEG_LIMIT(seg), 0xffff); 2292292SN/A tc->setMiscReg(MISCREG_SEG_ATTR(seg), dataAttr); 2302292SN/A } 2312292SN/A 2322292SN/A SegAttr codeAttr = 0; 2332292SN/A codeAttr.dpl = 0; 2342292SN/A codeAttr.unusable = 0; 2352292SN/A codeAttr.defaultSize = 0; 2362292SN/A codeAttr.longMode = 0; 2372329SN/A codeAttr.avl = 0; 2382329SN/A codeAttr.granularity = 0; 2392329SN/A codeAttr.present = 1; 2402329SN/A codeAttr.type = 10; 2412292SN/A codeAttr.writable = 0; 2422292SN/A codeAttr.readable = 1; 2432733Sktlim@umich.edu codeAttr.expandDown = 0; 2442292SN/A codeAttr.system = 1; 2452292SN/A 2462292SN/A tc->setMiscReg(MISCREG_CS, 0xf000); 2472292SN/A tc->setMiscReg(MISCREG_CS_BASE, 2482907Sktlim@umich.edu 0x00000000ffff0000ULL); 2492907Sktlim@umich.edu tc->setMiscReg(MISCREG_CS_EFF_BASE, 2502669Sktlim@umich.edu 0x00000000ffff0000ULL); 2512907Sktlim@umich.edu // This has the base value pre-added. 2522907Sktlim@umich.edu tc->setMiscReg(MISCREG_CS_LIMIT, 0xffffffff); 2532292SN/A tc->setMiscReg(MISCREG_CS_ATTR, codeAttr); 2542698Sktlim@umich.edu 2552678Sktlim@umich.edu tc->setPC(0x000000000000fff0ULL + 2562678Sktlim@umich.edu tc->readMiscReg(MISCREG_CS_BASE)); 2572678Sktlim@umich.edu tc->setNextPC(tc->readPC() + sizeof(MachInst)); 2582698Sktlim@umich.edu 2592678Sktlim@umich.edu tc->setMiscReg(MISCREG_TSG_BASE, 0); 2602678Sktlim@umich.edu tc->setMiscReg(MISCREG_TSG_LIMIT, 0xffff); 2612678Sktlim@umich.edu 2622678Sktlim@umich.edu tc->setMiscReg(MISCREG_IDTR_BASE, 0); 2632698Sktlim@umich.edu tc->setMiscReg(MISCREG_IDTR_LIMIT, 0xffff); 2642678Sktlim@umich.edu 2652698Sktlim@umich.edu tc->setMiscReg(MISCREG_TSL, 0); 2662678Sktlim@umich.edu tc->setMiscReg(MISCREG_TSL_BASE, 0); 2672698Sktlim@umich.edu tc->setMiscReg(MISCREG_TSL_LIMIT, 0xffff); 2682678Sktlim@umich.edu tc->setMiscReg(MISCREG_TSL_ATTR, 0); 2692698Sktlim@umich.edu 2702678Sktlim@umich.edu tc->setMiscReg(MISCREG_TR, 0); 2712678Sktlim@umich.edu tc->setMiscReg(MISCREG_TR_BASE, 0); 2722678Sktlim@umich.edu tc->setMiscReg(MISCREG_TR_LIMIT, 0xffff); 2732698Sktlim@umich.edu tc->setMiscReg(MISCREG_TR_ATTR, 0); 2742678Sktlim@umich.edu 2752678Sktlim@umich.edu // This value should be the family/model/stepping of the processor. 2762678Sktlim@umich.edu // (page 418). It should be consistent with the value from CPUID, but 2772678Sktlim@umich.edu // the actual value probably doesn't matter much. 2782678Sktlim@umich.edu tc->setIntReg(INTREG_RDX, 0); 2792678Sktlim@umich.edu 2802678Sktlim@umich.edu tc->setMiscReg(MISCREG_DR0, 0); 2812678Sktlim@umich.edu tc->setMiscReg(MISCREG_DR1, 0); 2822678Sktlim@umich.edu tc->setMiscReg(MISCREG_DR2, 0); 2832678Sktlim@umich.edu tc->setMiscReg(MISCREG_DR3, 0); 2842678Sktlim@umich.edu 2852678Sktlim@umich.edu tc->setMiscReg(MISCREG_DR6, 0x00000000ffff0ff0ULL); 2862698Sktlim@umich.edu tc->setMiscReg(MISCREG_DR7, 0x0000000000000400ULL); 2872678Sktlim@umich.edu 2882678Sktlim@umich.edu // Update the handy M5 Reg. 2892698Sktlim@umich.edu tc->setMiscReg(MISCREG_M5_REG, 0); 2902678Sktlim@umich.edu MicroPC entry = X86ISAInst::RomLabels::extern_label_initIntHalt; 2912678Sktlim@umich.edu tc->setMicroPC(romMicroPC(entry)); 2922678Sktlim@umich.edu tc->setNextMicroPC(romMicroPC(entry) + 1); 2932678Sktlim@umich.edu } 2942678Sktlim@umich.edu 2952678Sktlim@umich.edu void 2962292SN/A StartupInterrupt::invoke(ThreadContext *tc) 2972292SN/A { 2982292SN/A DPRINTF(Faults, "Startup interrupt with vector %#x.\n", vector); 2992292SN/A HandyM5Reg m5Reg = tc->readMiscReg(MISCREG_M5_REG); 3002292SN/A if (m5Reg.mode != LegacyMode || m5Reg.submode != RealMode) { 3012292SN/A panic("Startup IPI recived outside of real mode. " 3022292SN/A "Don't know what to do. %d, %d", m5Reg.mode, m5Reg.submode); 3032292SN/A } 3042292SN/A 3052292SN/A tc->setMiscReg(MISCREG_CS, vector << 8); 3062292SN/A tc->setMiscReg(MISCREG_CS_BASE, vector << 12); 3072292SN/A tc->setMiscReg(MISCREG_CS_EFF_BASE, vector << 12); 3082292SN/A // This has the base value pre-added. 3092292SN/A tc->setMiscReg(MISCREG_CS_LIMIT, 0xffff); 3102292SN/A 3112292SN/A tc->setPC(tc->readMiscReg(MISCREG_CS_BASE)); 3122669Sktlim@umich.edu tc->setNextPC(tc->readPC() + sizeof(MachInst)); 3132669Sktlim@umich.edu } 3142292SN/A 3152292SN/A#endif 3162292SN/A} // namespace X86ISA 3172292SN/A 3182292SN/A