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