/*
 * Copyright (c) 2003-2007 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.  Redistributions
 * in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.  Neither the name of
 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include "arch/x86/decoder.hh"
#include "arch/x86/faults.hh"
#include "base/trace.hh"
#include "config/full_system.hh"
#include "cpu/thread_context.hh"
#if !FULL_SYSTEM
#include "arch/x86/isa_traits.hh"
#include "mem/page_table.hh"
#include "sim/process.hh"
#else
#include "arch/x86/tlb.hh"
#endif

namespace X86ISA
{
#if FULL_SYSTEM
    void X86FaultBase::invoke(ThreadContext * tc)
    {
        Addr pc = tc->readPC();
        DPRINTF(Faults, "RIP %#x: vector %d: %s\n", pc, vector, describe());
        using namespace X86ISAInst::RomLabels;
        HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
        MicroPC entry;
        if (m5reg.mode == LongMode) {
            if (isSoft()) {
                entry = extern_label_longModeSoftInterrupt;
            } else {
                entry = extern_label_longModeInterrupt;
            }
        } else {
            entry = extern_label_legacyModeInterrupt;
        }
        tc->setIntReg(INTREG_MICRO(1), vector);
        tc->setIntReg(INTREG_MICRO(7), pc);
        if (errorCode != (uint64_t)(-1)) {
            if (m5reg.mode == LongMode) {
                entry = extern_label_longModeInterruptWithError;
            } else {
                panic("Legacy mode interrupts with error codes "
                        "aren't implementde.\n");
            }
            // Software interrupts shouldn't have error codes. If one does,
            // there would need to be microcode to set it up.
            assert(!isSoft());
            tc->setIntReg(INTREG_MICRO(15), errorCode);
        }
        tc->setMicroPC(romMicroPC(entry));
        tc->setNextMicroPC(romMicroPC(entry) + 1);
    }

    std::string
    X86FaultBase::describe() const
    {
        std::stringstream ss;
        ccprintf(ss, "%s", mnemonic());
        if (errorCode != (uint64_t)(-1)) {
            ccprintf(ss, "(%#x)", errorCode);
        }

        return ss.str();
    }
    
    void X86Trap::invoke(ThreadContext * tc)
    {
        X86FaultBase::invoke(tc);
        // This is the same as a fault, but it happens -after- the instruction.
        tc->setPC(tc->readNextPC());
        tc->setNextPC(tc->readNextNPC());
        tc->setNextNPC(tc->readNextNPC() + sizeof(MachInst));
    }

    void X86Abort::invoke(ThreadContext * tc)
    {
        panic("Abort exception!");
    }

    void PageFault::invoke(ThreadContext * tc)
    {
        HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
        X86FaultBase::invoke(tc);
        /*
         * If something bad happens while trying to enter the page fault
         * handler, I'm pretty sure that's a double fault and then all bets are
         * off. That means it should be safe to update this state now.
         */
        if (m5reg.mode == LongMode) {
            tc->setMiscReg(MISCREG_CR2, addr);
        } else {
            tc->setMiscReg(MISCREG_CR2, (uint32_t)addr);
        }
    }

    std::string
    PageFault::describe() const
    {
        std::stringstream ss;
        ccprintf(ss, "%s at %#x", X86FaultBase::describe(), addr);
        return ss.str();
    }

    void
    InitInterrupt::invoke(ThreadContext *tc)
    {
        DPRINTF(Faults, "Init interrupt.\n");
        // The otherwise unmodified integer registers should be set to 0.
        for (int index = 0; index < NUM_INTREGS; index++) {
            tc->setIntReg(index, 0);
        }

        CR0 cr0 = tc->readMiscReg(MISCREG_CR0);
        CR0 newCR0 = 1 << 4;
        newCR0.cd = cr0.cd;
        newCR0.nw = cr0.nw;
        tc->setMiscReg(MISCREG_CR0, newCR0);
        tc->setMiscReg(MISCREG_CR2, 0);
        tc->setMiscReg(MISCREG_CR3, 0);
        tc->setMiscReg(MISCREG_CR4, 0);

        tc->setMiscReg(MISCREG_RFLAGS, 0x0000000000000002ULL);

        tc->setMiscReg(MISCREG_EFER, 0);

        SegAttr dataAttr = 0;
        dataAttr.dpl = 0;
        dataAttr.unusable = 0;
        dataAttr.defaultSize = 0;
        dataAttr.longMode = 0;
        dataAttr.avl = 0;
        dataAttr.granularity = 0;
        dataAttr.present = 1;
        dataAttr.type = 3;
        dataAttr.writable = 1;
        dataAttr.readable = 1;
        dataAttr.expandDown = 0;
        dataAttr.system = 1;

        for (int seg = 0; seg != NUM_SEGMENTREGS; seg++) {
            tc->setMiscReg(MISCREG_SEG_SEL(seg), 0);
            tc->setMiscReg(MISCREG_SEG_BASE(seg), 0);
            tc->setMiscReg(MISCREG_SEG_EFF_BASE(seg), 0);
            tc->setMiscReg(MISCREG_SEG_LIMIT(seg), 0xffff);
            tc->setMiscReg(MISCREG_SEG_ATTR(seg), dataAttr);
        }

        SegAttr codeAttr = 0;
        codeAttr.dpl = 0;
        codeAttr.unusable = 0;
        codeAttr.defaultSize = 0;
        codeAttr.longMode = 0;
        codeAttr.avl = 0;
        codeAttr.granularity = 0;
        codeAttr.present = 1;
        codeAttr.type = 10;
        codeAttr.writable = 0;
        codeAttr.readable = 1;
        codeAttr.expandDown = 0;
        codeAttr.system = 1;

        tc->setMiscReg(MISCREG_CS, 0xf000);
        tc->setMiscReg(MISCREG_CS_BASE,
                0x00000000ffff0000ULL);
        tc->setMiscReg(MISCREG_CS_EFF_BASE,
                0x00000000ffff0000ULL);
        // This has the base value pre-added.
        tc->setMiscReg(MISCREG_CS_LIMIT, 0xffffffff);
        tc->setMiscReg(MISCREG_CS_ATTR, codeAttr);

        tc->setPC(0x000000000000fff0ULL +
                tc->readMiscReg(MISCREG_CS_BASE));
        tc->setNextPC(tc->readPC() + sizeof(MachInst));

        tc->setMiscReg(MISCREG_TSG_BASE, 0);
        tc->setMiscReg(MISCREG_TSG_LIMIT, 0xffff);

        tc->setMiscReg(MISCREG_IDTR_BASE, 0);
        tc->setMiscReg(MISCREG_IDTR_LIMIT, 0xffff);

        tc->setMiscReg(MISCREG_TSL, 0);
        tc->setMiscReg(MISCREG_TSL_BASE, 0);
        tc->setMiscReg(MISCREG_TSL_LIMIT, 0xffff);
        tc->setMiscReg(MISCREG_TSL_ATTR, 0);

        tc->setMiscReg(MISCREG_TR, 0);
        tc->setMiscReg(MISCREG_TR_BASE, 0);
        tc->setMiscReg(MISCREG_TR_LIMIT, 0xffff);
        tc->setMiscReg(MISCREG_TR_ATTR, 0);

        // This value should be the family/model/stepping of the processor.
        // (page 418). It should be consistent with the value from CPUID, but
        // the actual value probably doesn't matter much.
        tc->setIntReg(INTREG_RDX, 0);

        tc->setMiscReg(MISCREG_DR0, 0);
        tc->setMiscReg(MISCREG_DR1, 0);
        tc->setMiscReg(MISCREG_DR2, 0);
        tc->setMiscReg(MISCREG_DR3, 0);

        tc->setMiscReg(MISCREG_DR6, 0x00000000ffff0ff0ULL);
        tc->setMiscReg(MISCREG_DR7, 0x0000000000000400ULL);

        // Update the handy M5 Reg.
        tc->setMiscReg(MISCREG_M5_REG, 0);
        MicroPC entry = X86ISAInst::RomLabels::extern_label_initIntHalt;
        tc->setMicroPC(romMicroPC(entry));
        tc->setNextMicroPC(romMicroPC(entry) + 1);
    }

    void
    StartupInterrupt::invoke(ThreadContext *tc)
    {
        DPRINTF(Faults, "Startup interrupt with vector %#x.\n", vector);
        HandyM5Reg m5Reg = tc->readMiscReg(MISCREG_M5_REG);
        if (m5Reg.mode != LegacyMode || m5Reg.submode != RealMode) {
            panic("Startup IPI recived outside of real mode. "
                    "Don't know what to do. %d, %d", m5Reg.mode, m5Reg.submode);
        }

        tc->setMiscReg(MISCREG_CS, vector << 8);
        tc->setMiscReg(MISCREG_CS_BASE, vector << 12);
        tc->setMiscReg(MISCREG_CS_EFF_BASE, vector << 12);
        // This has the base value pre-added.
        tc->setMiscReg(MISCREG_CS_LIMIT, 0xffff);

        tc->setPC(tc->readMiscReg(MISCREG_CS_BASE));
        tc->setNextPC(tc->readPC() + sizeof(MachInst));
    }

#endif
} // namespace X86ISA

