/*
 * 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/insts/static_inst.hh"
#include "arch/x86/mmu.hh"
#include "arch/x86/regs/int.hh"
#include "arch/x86/regs/misc.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 gem5
{

namespace X86ISA
{

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

    PCState pc = tc->pcState().as<PCState>();
    DPRINTF(Faults, "RIP %#x: vector %d: %s\n", pc.pc(), vector, describe());
    using namespace X86ISAInst::rom_labels;
    HandyM5Reg m5reg = tc->readMiscRegNoEffect(misc_reg::M5Reg);
    MicroPC entry;
    if (m5reg.mode == LongMode) {
        entry = extern_label_longModeInterrupt;
    } else {
        if (m5reg.submode == RealMode)
            entry = extern_label_realModeInterrupt;
        else
            entry = extern_label_legacyModeInterrupt;
    }
    tc->setReg(intRegMicro(1), vector);
    Addr cs_base = tc->readMiscRegNoEffect(misc_reg::CsEffBase);
    tc->setReg(intRegMicro(7), pc.pc() - cs_base);
    if (errorCode != (uint64_t)(-1)) {
        if (m5reg.mode == LongMode) {
            entry = extern_label_longModeInterruptWithError;
        } else {
            panic("Legacy mode interrupts with error codes "
                    "aren't implemented.");
        }
        tc->setReg(intRegMicro(15), errorCode);
    }
    pc.upc(romMicroPC(entry));
    pc.nupc(romMicroPC(entry) + 1);
    tc->pcState(pc);
}

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)
{
    // This is the same as a fault, but it happens -after- the
    // instruction.
    X86FaultBase::invoke(tc);
}

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 {
        auto *xsi = static_cast<X86StaticInst *>(inst.get());
        panic("Unrecognized/invalid instruction executed:\n %s",
                xsi->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(misc_reg::M5Reg);
        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(misc_reg::Cr2, addr);
        else
            tc->setMiscReg(misc_reg::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(),
                  inst->disassemble(tc->pcState().instAddr(),
                      &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 < int_reg::NumArchRegs; index++) {
        tc->setReg(intRegClass[index], (RegVal)0);
    }

    CR0 cr0 = tc->readMiscReg(misc_reg::Cr0);
    CR0 newCR0 = 1 << 4;
    newCR0.cd = cr0.cd;
    newCR0.nw = cr0.nw;
    tc->setMiscReg(misc_reg::Cr0, newCR0);
    tc->setMiscReg(misc_reg::Cr2, 0);
    tc->setMiscReg(misc_reg::Cr3, 0);
    tc->setMiscReg(misc_reg::Cr4, 0);

    tc->setMiscReg(misc_reg::Rflags, 0x0000000000000002ULL);

    tc->setMiscReg(misc_reg::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 != segment_idx::NumIdxs; seg++) {
        tc->setMiscReg(misc_reg::segSel(seg), 0);
        tc->setMiscReg(misc_reg::segBase(seg), 0);
        tc->setMiscReg(misc_reg::segEffBase(seg), 0);
        tc->setMiscReg(misc_reg::segLimit(seg), 0xffff);
        tc->setMiscReg(misc_reg::segAttr(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(misc_reg::Cs, 0xf000);
    tc->setMiscReg(misc_reg::CsBase, 0x00000000ffff0000ULL);
    tc->setMiscReg(misc_reg::CsEffBase, 0x00000000ffff0000ULL);
    // This has the base value pre-added.
    tc->setMiscReg(misc_reg::CsLimit, 0xffffffff);
    tc->setMiscReg(misc_reg::CsAttr, codeAttr);

    PCState pc(0x000000000000fff0ULL + tc->readMiscReg(misc_reg::CsBase));
    tc->pcState(pc);

    tc->setMiscReg(misc_reg::TsgBase, 0);
    tc->setMiscReg(misc_reg::TsgLimit, 0xffff);

    tc->setMiscReg(misc_reg::IdtrBase, 0);
    tc->setMiscReg(misc_reg::IdtrLimit, 0xffff);

    SegAttr tslAttr = 0;
    tslAttr.unusable = 1;
    tslAttr.present = 1;
    tslAttr.type = 2; // LDT
    tc->setMiscReg(misc_reg::Tsl, 0);
    tc->setMiscReg(misc_reg::TslBase, 0);
    tc->setMiscReg(misc_reg::TslLimit, 0xffff);
    tc->setMiscReg(misc_reg::TslAttr, tslAttr);

    SegAttr trAttr = 0;
    trAttr.unusable = 0;
    trAttr.present = 1;
    trAttr.type = 3; // Busy 16-bit TSS
    tc->setMiscReg(misc_reg::Tr, 0);
    tc->setMiscReg(misc_reg::TrBase, 0);
    tc->setMiscReg(misc_reg::TrLimit, 0xffff);
    tc->setMiscReg(misc_reg::TrAttr, 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->setReg(int_reg::Rdx, (RegVal)0);

    tc->setMiscReg(misc_reg::Dr0, 0);
    tc->setMiscReg(misc_reg::Dr1, 0);
    tc->setMiscReg(misc_reg::Dr2, 0);
    tc->setMiscReg(misc_reg::Dr3, 0);

    tc->setMiscReg(misc_reg::Dr6, 0x00000000ffff0ff0ULL);
    tc->setMiscReg(misc_reg::Dr7, 0x0000000000000400ULL);

    tc->setMiscReg(misc_reg::Mxcsr, 0x1f80);

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

    // Update the handy M5 Reg.
    tc->setMiscReg(misc_reg::M5Reg, 0);
    MicroPC entry = X86ISAInst::rom_labels::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(misc_reg::M5Reg);
    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(misc_reg::Cs, vector << 8);
    tc->setMiscReg(misc_reg::CsBase, vector << 12);
    tc->setMiscReg(misc_reg::CsEffBase, vector << 12);
    // This has the base value pre-added.
    tc->setMiscReg(misc_reg::CsLimit, 0xffff);

    tc->pcState(tc->readMiscReg(misc_reg::CsBase));
}

} // namespace X86ISA
} // namespace gem5
