/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * 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.
 */

#include "arch/x86/faults.hh"

#include "arch/x86/generated/decoder.hh"
#include "arch/x86/isa_traits.hh"
#include "arch/x86/mmu.hh"
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "cpu/thread_context.hh"
#include "debug/Faults.hh"
#include "sim/full_system.hh"
#include "sim/process.hh"

namespace X86ISA
{

void
X86FaultBase::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    if (!FullSystem) {
        FaultBase::invoke(tc, inst);
        return;
    }

    PCState pcState = tc->pcState();
    Addr pc = pcState.pc();
    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) {
        entry = isSoft() ? extern_label_longModeSoftInterrupt :
                           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 implemented.");
        }
        // 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);
    }
    pcState.upc(romMicroPC(entry));
    pcState.nupc(romMicroPC(entry) + 1);
    tc->pcState(pcState);
}

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, const StaticInstPtr &inst)
{
    X86FaultBase::invoke(tc);
    if (!FullSystem)
        return;

    // This is the same as a fault, but it happens -after- the
    // instruction.
    PCState pc = tc->pcState();
    pc.uEnd();
}

void
X86Abort::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    panic("Abort exception!");
}

void
InvalidOpcode::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    if (FullSystem) {
        X86Fault::invoke(tc, inst);
    } else {
        panic("Unrecognized/invalid instruction executed:\n %s",
                inst->machInst);
    }
}

void
PageFault::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    if (FullSystem) {
        // Invalidate any matching TLB entries before handling the page fault.
        tc->getMMUPtr()->demapPage(addr, 0);
        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);
    } else if (!tc->getProcessPtr()->fixupFault(addr)) {
        PageFaultErrorCode code = errorCode;
        const char *modeStr = "";
        if (code.fetch)
            modeStr = "execute";
        else if (code.write)
            modeStr = "write";
        else
            modeStr = "read";

        // print information about what we are panic'ing on
        if (!inst) {
            panic("Tried to %s unmapped address %#x.", modeStr, addr);
        } else {
            panic("Tried to %s unmapped address %#x.\nPC: %#x, Instr: %s",
                  modeStr, addr, tc->pcState().pc(),
                  inst->disassemble(tc->pcState().pc(),
                      &Loader::debugSymbolTable));
        }
    }
}

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

void
InitInterrupt::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    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);

    PCState pc(0x000000000000fff0ULL + tc->readMiscReg(MISCREG_CS_BASE));
    tc->pcState(pc);

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

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

    SegAttr tslAttr = 0;
    tslAttr.present = 1;
    tslAttr.type = 2; // LDT
    tc->setMiscReg(MISCREG_TSL, 0);
    tc->setMiscReg(MISCREG_TSL_BASE, 0);
    tc->setMiscReg(MISCREG_TSL_LIMIT, 0xffff);
    tc->setMiscReg(MISCREG_TSL_ATTR, tslAttr);

    SegAttr trAttr = 0;
    trAttr.present = 1;
    trAttr.type = 3; // Busy 16-bit TSS
    tc->setMiscReg(MISCREG_TR, 0);
    tc->setMiscReg(MISCREG_TR_BASE, 0);
    tc->setMiscReg(MISCREG_TR_LIMIT, 0xffff);
    tc->setMiscReg(MISCREG_TR_ATTR, trAttr);

    // 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);

    tc->setMiscReg(MISCREG_MXCSR, 0x1f80);

    // Flag all elements on the x87 stack as empty.
    tc->setMiscReg(MISCREG_FTW, 0xFFFF);

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

void
StartupInterrupt::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    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->pcState(tc->readMiscReg(MISCREG_CS_BASE));
}

} // namespace X86ISA
