/*
 * Copyright (c) 2003-2005 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
 *          Kevin Lim
 */

#include "arch/sparc/faults.hh"

#include <algorithm>

#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/process.hh"
#include "arch/sparc/tlb.hh"
#include "arch/sparc/types.hh"
#include "base/bitfield.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "mem/page_table.hh"
#include "sim/full_system.hh"
#include "sim/process.hh"

using namespace std;

namespace SparcISA
{

template<> SparcFaultBase::FaultVals
    SparcFault<PowerOnReset>::vals
("power_on_reset", 0x001, 0, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<WatchDogReset>::vals
("watch_dog_reset", 0x002, 120, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<ExternallyInitiatedReset>::vals
("externally_initiated_reset", 0x003, 110, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<SoftwareInitiatedReset>::vals
("software_initiated_reset", 0x004, 130, {{SH, SH, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<REDStateException>::vals
("RED_state_exception", 0x005, 1, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<StoreError>::vals
("store_error", 0x007, 201, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<InstructionAccessException>::vals
("instruction_access_exception", 0x008, 300, {{H, H, H}});

//XXX This trap is apparently dropped from ua2005
/*template<> SparcFaultBase::FaultVals
    SparcFault<InstructionAccessMMUMiss>::vals
    ("inst_mmu", 0x009, 2, {{H, H, H}});*/

template<> SparcFaultBase::FaultVals
    SparcFault<InstructionAccessError>::vals
("instruction_access_error", 0x00A, 400, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<IllegalInstruction>::vals
("illegal_instruction", 0x010, 620, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<PrivilegedOpcode>::vals
("privileged_opcode", 0x011, 700, {{P, SH, SH}});

//XXX This trap is apparently dropped from ua2005
/*template<> SparcFaultBase::FaultVals
    SparcFault<UnimplementedLDD>::vals
    ("unimp_ldd", 0x012, 6, {{H, H, H}});*/

//XXX This trap is apparently dropped from ua2005
/*template<> SparcFaultBase::FaultVals
    SparcFault<UnimplementedSTD>::vals
    ("unimp_std", 0x013, 6, {{H, H, H}});*/

template<> SparcFaultBase::FaultVals
    SparcFault<FpDisabled>::vals
("fp_disabled", 0x020, 800, {{P, P, H}});

/* SPARCv8 and SPARCv9 define just fp_disabled trap. SIMD is not contemplated
 * as a separate part. Therefore, we use the same code and TT */
template<> SparcFaultBase::FaultVals
    SparcFault<VecDisabled>::vals
("fp_disabled", 0x020, 800, {{P, P, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<FpExceptionIEEE754>::vals
("fp_exception_ieee_754", 0x021, 1110, {{P, P, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<FpExceptionOther>::vals
("fp_exception_other", 0x022, 1110, {{P, P, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<TagOverflow>::vals
("tag_overflow", 0x023, 1400, {{P, P, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<CleanWindow>::vals
("clean_window", 0x024, 1010, {{P, P, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<DivisionByZero>::vals
("division_by_zero", 0x028, 1500, {{P, P, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<InternalProcessorError>::vals
("internal_processor_error", 0x029, 4, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<InstructionInvalidTSBEntry>::vals
("instruction_invalid_tsb_entry", 0x02A, 210, {{H, H, SH}});

template<> SparcFaultBase::FaultVals
    SparcFault<DataInvalidTSBEntry>::vals
("data_invalid_tsb_entry", 0x02B, 1203, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<DataAccessException>::vals
("data_access_exception", 0x030, 1201, {{H, H, H}});

//XXX This trap is apparently dropped from ua2005
/*template<> SparcFaultBase::FaultVals
    SparcFault<DataAccessMMUMiss>::vals
    ("data_mmu", 0x031, 12, {{H, H, H}});*/

template<> SparcFaultBase::FaultVals
    SparcFault<DataAccessError>::vals
("data_access_error", 0x032, 1210, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<DataAccessProtection>::vals
("data_access_protection", 0x033, 1207, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<MemAddressNotAligned>::vals
("mem_address_not_aligned", 0x034, 1020, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<LDDFMemAddressNotAligned>::vals
("LDDF_mem_address_not_aligned", 0x035, 1010, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<STDFMemAddressNotAligned>::vals
("STDF_mem_address_not_aligned", 0x036, 1010, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<PrivilegedAction>::vals
("privileged_action", 0x037, 1110, {{H, H, SH}});

template<> SparcFaultBase::FaultVals
    SparcFault<LDQFMemAddressNotAligned>::vals
("LDQF_mem_address_not_aligned", 0x038, 1010, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<STQFMemAddressNotAligned>::vals
("STQF_mem_address_not_aligned", 0x039, 1010, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<InstructionRealTranslationMiss>::vals
("instruction_real_translation_miss", 0x03E, 208, {{H, H, SH}});

template<> SparcFaultBase::FaultVals
    SparcFault<DataRealTranslationMiss>::vals
("data_real_translation_miss", 0x03F, 1203, {{H, H, H}});

//XXX This trap is apparently dropped from ua2005
/*template<> SparcFaultBase::FaultVals
    SparcFault<AsyncDataError>::vals
    ("async_data", 0x040, 2, {{H, H, H}});*/

template<> SparcFaultBase::FaultVals
    SparcFault<InterruptLevelN>::vals
("interrupt_level_n", 0x040, 0, {{P, P, SH}});

template<> SparcFaultBase::FaultVals
    SparcFault<HstickMatch>::vals
("hstick_match", 0x05E, 1601, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<TrapLevelZero>::vals
("trap_level_zero", 0x05F, 202, {{H, H, SH}});

template<> SparcFaultBase::FaultVals
    SparcFault<InterruptVector>::vals
("interrupt_vector", 0x060, 2630, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<PAWatchpoint>::vals
("PA_watchpoint", 0x061, 1209, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<VAWatchpoint>::vals
("VA_watchpoint", 0x062, 1120, {{P, P, SH}});

template<> SparcFaultBase::FaultVals
    SparcFault<FastInstructionAccessMMUMiss>::vals
("fast_instruction_access_MMU_miss", 0x064, 208, {{H, H, SH}});

template<> SparcFaultBase::FaultVals
    SparcFault<FastDataAccessMMUMiss>::vals
("fast_data_access_MMU_miss", 0x068, 1203, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<FastDataAccessProtection>::vals
("fast_data_access_protection", 0x06C, 1207, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<InstructionBreakpoint>::vals
("instruction_break", 0x076, 610, {{H, H, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<CpuMondo>::vals
("cpu_mondo", 0x07C, 1608, {{P, P, SH}});

template<> SparcFaultBase::FaultVals
    SparcFault<DevMondo>::vals
("dev_mondo", 0x07D, 1611, {{P, P, SH}});

template<> SparcFaultBase::FaultVals
    SparcFault<ResumableError>::vals
("resume_error", 0x07E, 3330, {{P, P, SH}});

template<> SparcFaultBase::FaultVals
    SparcFault<SpillNNormal>::vals
("spill_n_normal", 0x080, 900, {{P, P, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<SpillNOther>::vals
("spill_n_other", 0x0A0, 900, {{P, P, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<FillNNormal>::vals
("fill_n_normal", 0x0C0, 900, {{P, P, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<FillNOther>::vals
("fill_n_other", 0x0E0, 900, {{P, P, H}});

template<> SparcFaultBase::FaultVals
    SparcFault<TrapInstruction>::vals
("trap_instruction", 0x100, 1602, {{P, P, H}});

/**
 * This causes the thread context to enter RED state. This causes the side
 * effects which go with entering RED state because of a trap.
 */

void
enterREDState(ThreadContext *tc)
{
    //@todo Disable the mmu?
    //@todo Disable watchpoints?
    HPSTATE hpstate= tc->readMiscRegNoEffect(MISCREG_HPSTATE);
    hpstate.red = 1;
    hpstate.hpriv = 1;
    tc->setMiscReg(MISCREG_HPSTATE, hpstate);
    // PSTATE.priv is set to 1 here. The manual says it should be 0, but
    // Legion sets it to 1.
    PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
    pstate.priv = 1;
    tc->setMiscReg(MISCREG_PSTATE, pstate);
}

/**
 * This sets everything up for a RED state trap except for actually jumping to
 * the handler.
 */

void
doREDFault(ThreadContext *tc, TrapType tt)
{
    RegVal TL = tc->readMiscRegNoEffect(MISCREG_TL);
    RegVal TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
    PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
    HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
    RegVal CCR = tc->readIntReg(NumIntArchRegs + 2);
    RegVal ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
    RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
    RegVal CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3);
    RegVal GL = tc->readMiscRegNoEffect(MISCREG_GL);
    PCState pc = tc->pcState();

    TL++;

    Addr pcMask = pstate.am ? mask(32) : mask(64);

    // set TSTATE.gl to gl
    replaceBits(TSTATE, 42, 40, GL);
    // set TSTATE.ccr to ccr
    replaceBits(TSTATE, 39, 32, CCR);
    // set TSTATE.asi to asi
    replaceBits(TSTATE, 31, 24, ASI);
    // set TSTATE.pstate to pstate
    replaceBits(TSTATE, 20, 8, pstate);
    // set TSTATE.cwp to cwp
    replaceBits(TSTATE, 4, 0, CWP);

    // Write back TSTATE
    tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);

    // set TPC to PC
    tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
    // set TNPC to NPC
    tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);

    // set HTSTATE.hpstate to hpstate
    tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate);

    // TT = trap type;
    tc->setMiscRegNoEffect(MISCREG_TT, tt);

    // Update GL
    tc->setMiscReg(MISCREG_GL, min<int>(GL+1, MaxGL));

    bool priv = pstate.priv; // just save the priv bit
    pstate = 0;
    pstate.priv = priv;
    pstate.pef = 1;
    tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);

    hpstate.red = 1;
    hpstate.hpriv = 1;
    hpstate.ibe = 0;
    hpstate.tlz = 0;
    tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);

    bool changedCWP = true;
    if (tt == 0x24)
        CWP++;
    else if (0x80 <= tt && tt <= 0xbf)
        CWP += (CANSAVE + 2);
    else if (0xc0 <= tt && tt <= 0xff)
        CWP--;
    else
        changedCWP = false;

    if (changedCWP) {
        CWP = (CWP + NWindows) % NWindows;
        tc->setMiscReg(MISCREG_CWP, CWP);
    }
}

/**
 * This sets everything up for a normal trap except for actually jumping to
 * the handler.
 */

void
doNormalFault(ThreadContext *tc, TrapType tt, bool gotoHpriv)
{
    RegVal TL = tc->readMiscRegNoEffect(MISCREG_TL);
    RegVal TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
    PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
    HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
    RegVal CCR = tc->readIntReg(NumIntArchRegs + 2);
    RegVal ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
    RegVal CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
    RegVal CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
    RegVal GL = tc->readMiscRegNoEffect(MISCREG_GL);
    PCState pc = tc->pcState();

    // Increment the trap level
    TL++;
    tc->setMiscRegNoEffect(MISCREG_TL, TL);

    Addr pcMask = pstate.am ? mask(32) : mask(64);

    // Save off state

    // set TSTATE.gl to gl
    replaceBits(TSTATE, 42, 40, GL);
    // set TSTATE.ccr to ccr
    replaceBits(TSTATE, 39, 32, CCR);
    // set TSTATE.asi to asi
    replaceBits(TSTATE, 31, 24, ASI);
    // set TSTATE.pstate to pstate
    replaceBits(TSTATE, 20, 8, pstate);
    // set TSTATE.cwp to cwp
    replaceBits(TSTATE, 4, 0, CWP);

    // Write back TSTATE
    tc->setMiscRegNoEffect(MISCREG_TSTATE, TSTATE);

    // set TPC to PC
    tc->setMiscRegNoEffect(MISCREG_TPC, pc.pc() & pcMask);
    // set TNPC to NPC
    tc->setMiscRegNoEffect(MISCREG_TNPC, pc.npc() & pcMask);

    // set HTSTATE.hpstate to hpstate
    tc->setMiscRegNoEffect(MISCREG_HTSTATE, hpstate);

    // TT = trap type;
    tc->setMiscRegNoEffect(MISCREG_TT, tt);

    // Update the global register level
    if (!gotoHpriv)
        tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxPGL));
    else
        tc->setMiscReg(MISCREG_GL, min<int>(GL + 1, MaxGL));

    // pstate.mm is unchanged
    pstate.pef = 1; // PSTATE.pef = whether or not an fpu is present
    pstate.am = 0;
    pstate.ie = 0;
    // pstate.tle is unchanged
    // pstate.tct = 0

    if (gotoHpriv) {
        pstate.cle = 0;
        // The manual says PSTATE.priv should be 0, but Legion leaves it alone
        hpstate.red = 0;
        hpstate.hpriv = 1;
        hpstate.ibe = 0;
        // hpstate.tlz is unchanged
        tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);
    } else { // we are going to priv
        pstate.priv = 1;
        pstate.cle = pstate.tle;
    }
    tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);


    bool changedCWP = true;
    if (tt == 0x24)
        CWP++;
    else if (0x80 <= tt && tt <= 0xbf)
        CWP += (CANSAVE + 2);
    else if (0xc0 <= tt && tt <= 0xff)
        CWP--;
    else
        changedCWP = false;

    if (changedCWP) {
        CWP = (CWP + NWindows) % NWindows;
        tc->setMiscReg(MISCREG_CWP, CWP);
    }
}

void
getREDVector(RegVal TT, Addr &PC, Addr &NPC)
{
    //XXX The following constant might belong in a header file.
    const Addr RSTVAddr = 0xFFF0000000ULL;
    PC = RSTVAddr | ((TT << 5) & 0xFF);
    NPC = PC + sizeof(MachInst);
}

void
getHyperVector(ThreadContext * tc, Addr &PC, Addr &NPC, RegVal TT)
{
    Addr HTBA = tc->readMiscRegNoEffect(MISCREG_HTBA);
    PC = (HTBA & ~mask(14)) | ((TT << 5) & mask(14));
    NPC = PC + sizeof(MachInst);
}

void
getPrivVector(ThreadContext *tc, Addr &PC, Addr &NPC, RegVal TT, RegVal TL)
{
    Addr TBA = tc->readMiscRegNoEffect(MISCREG_TBA);
    PC = (TBA & ~mask(15)) |
        (TL > 1 ? (1 << 14) : 0) |
        ((TT << 5) & mask(14));
    NPC = PC + sizeof(MachInst);
}

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

    countStat()++;

    // We can refer to this to see what the trap level -was-, but something
    // in the middle could change it in the regfile out from under us.
    RegVal tl = tc->readMiscRegNoEffect(MISCREG_TL);
    RegVal tt = tc->readMiscRegNoEffect(MISCREG_TT);
    PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
    HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);

    Addr PC, NPC;

    PrivilegeLevel current;
    if (hpstate.hpriv)
        current = Hyperprivileged;
    else if (pstate.priv)
        current = Privileged;
    else
        current = User;

    PrivilegeLevel level = getNextLevel(current);

    if (hpstate.red || (tl == MaxTL - 1)) {
        getREDVector(5, PC, NPC);
        doREDFault(tc, tt);
        // This changes the hpstate and pstate, so we need to make sure we
        // save the old version on the trap stack in doREDFault.
        enterREDState(tc);
    } else if (tl == MaxTL) {
        panic("Should go to error state here.. crap\n");
        // Do error_state somehow?
        // Probably inject a WDR fault using the interrupt mechanism.
        // What should the PC and NPC be set to?
    } else if (tl > MaxPTL && level == Privileged) {
        // guest_watchdog fault
        doNormalFault(tc, trapType(), true);
        getHyperVector(tc, PC, NPC, 2);
    } else if (level == Hyperprivileged ||
               (level == Privileged && trapType() >= 384)) {
        doNormalFault(tc, trapType(), true);
        getHyperVector(tc, PC, NPC, trapType());
    } else {
        doNormalFault(tc, trapType(), false);
        getPrivVector(tc, PC, NPC, trapType(), tl + 1);
    }

    PCState pc;
    pc.pc(PC);
    pc.npc(NPC);
    pc.nnpc(NPC + sizeof(MachInst));
    pc.upc(0);
    pc.nupc(1);
    tc->pcState(pc);
}

void
PowerOnReset::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    // For SPARC, when a system is first started, there is a power
    // on reset Trap which sets the processor into the following state.
    // Bits that aren't set aren't defined on startup.

    tc->setMiscRegNoEffect(MISCREG_TL, MaxTL);
    tc->setMiscRegNoEffect(MISCREG_TT, trapType());
    tc->setMiscReg(MISCREG_GL, MaxGL);

    PSTATE pstate = 0;
    pstate.pef = 1;
    pstate.priv = 1;
    tc->setMiscRegNoEffect(MISCREG_PSTATE, pstate);

    // Turn on red and hpriv, set everything else to 0
    HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
    hpstate.red = 1;
    hpstate.hpriv = 1;
    hpstate.ibe = 0;
    hpstate.tlz = 0;
    tc->setMiscRegNoEffect(MISCREG_HPSTATE, hpstate);

    // The tick register is unreadable by nonprivileged software
    tc->setMiscRegNoEffect(MISCREG_TICK, 1ULL << 63);

    // Enter RED state. We do this last so that the actual state preserved in
    // the trap stack is the state from before this fault.
    enterREDState(tc);

    Addr PC, NPC;
    getREDVector(trapType(), PC, NPC);

    PCState pc;
    pc.pc(PC);
    pc.npc(NPC);
    pc.nnpc(NPC + sizeof(MachInst));
    pc.upc(0);
    pc.nupc(1);
    tc->pcState(pc);

    // These registers are specified as "undefined" after a POR, and they
    // should have reasonable values after the miscregfile is reset
    /*
    // Clear all the soft interrupt bits
    softint = 0;
    // disable timer compare interrupts, reset tick_cmpr
    tc->setMiscRegNoEffect(MISCREG_
    tick_cmprFields.int_dis = 1;
    tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
    stickFields.npt = 1; // The TICK register is unreadable by by !priv
    stick_cmprFields.int_dis = 1; // disable timer compare interrupts
    stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing

    tt[tl] = _trapType;

    hintp = 0; // no interrupts pending
    hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
    hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
    */
}

void
FastInstructionAccessMMUMiss::invoke(ThreadContext *tc,
                                     const StaticInstPtr &inst)
{
    if (FullSystem) {
        SparcFaultBase::invoke(tc, inst);
        return;
    }

    Process *p = tc->getProcessPtr();
    const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr);
    panic_if(!pte, "Tried to execute unmapped address %#x.\n", vaddr);

    Addr alignedvaddr = p->pTable->pageAlign(vaddr);

    // Grab fields used during instruction translation to figure out
    // which context to use.
    uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);

    // Inside a VM, a real address is the address that guest OS would
    // interpret to be a physical address. To map to the physical address,
    // it still needs to undergo a translation. The instruction
    // translation code in the SPARC ITLB code assumes that the context is
    // zero (kernel-level) if real addressing is being used.
    bool is_real_address = !bits(tlbdata, 4);

    // The SPARC ITLB code assumes that traps are executed in context
    // zero so we carry that assumption through here.
    bool trapped = bits(tlbdata, 18, 16) > 0;

    // The primary context acts as a PASID. It allows the MMU to
    // distinguish between virtual addresses that would alias to the
    // same physical address (if two or more processes shared the same
    // virtual address mapping).
    int primary_context = bits(tlbdata, 47, 32);

    // The partition id distinguishes between virtualized environments.
    int const partition_id = 0;

    // Given the assumptions in the translateInst code in the SPARC ITLB,
    // the logic works out to the following for the context.
    int context_id = (is_real_address || trapped) ? 0 : primary_context;

    TlbEntry entry(p->pTable->pid(), alignedvaddr, pte->paddr,
                   pte->flags & EmulationPageTable::Uncacheable,
                   pte->flags & EmulationPageTable::ReadOnly);

    // Insert the TLB entry.
    // The entry specifying whether the address is "real" is set to
    // false for syscall emulation mode regardless of whether the
    // address is real in preceding code. Not sure sure that this is
    // correct, but also not sure if it matters at all.
    dynamic_cast<TLB *>(tc->getITBPtr())->
        insert(alignedvaddr, partition_id, context_id, false, entry.pte);
}

void
FastDataAccessMMUMiss::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    if (FullSystem) {
        SparcFaultBase::invoke(tc, inst);
        return;
    }

    Process *p = tc->getProcessPtr();
    const EmulationPageTable::Entry *pte = p->pTable->lookup(vaddr);
    if (!pte && p->fixupStackFault(vaddr))
        pte = p->pTable->lookup(vaddr);
    panic_if(!pte, "Tried to access unmapped address %#x.\n", vaddr);

    Addr alignedvaddr = p->pTable->pageAlign(vaddr);

    // Grab fields used during data translation to figure out
    // which context to use.
    uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA);

    // The primary context acts as a PASID. It allows the MMU to
    // distinguish between virtual addresses that would alias to the
    // same physical address (if two or more processes shared the same
    // virtual address mapping). There's a secondary context used in the
    // DTLB translation code, but it should __probably__ be zero for
    // syscall emulation code. (The secondary context is used by Solaris
    // to allow kernel privilege code to access user space code:
    // [ISBN 0-13-022496-0]:PG199.)
    int primary_context = bits(tlbdata, 47, 32);

    // "Hyper-Privileged Mode" is in use. There are three main modes of
    // operation for Sparc: Hyper-Privileged Mode, Privileged Mode, and
    // User Mode.
    int hpriv = bits(tlbdata, 0);

    // Reset, Error and Debug state is in use. Something horrible has
    // happened or the system is operating in Reset Mode.
    int red = bits(tlbdata, 1);

    // Inside a VM, a real address is the address that guest OS would
    // interpret to be a physical address. To map to the physical address,
    // it still needs to undergo a translation. The instruction
    // translation code in the SPARC ITLB code assumes that the context is
    // zero (kernel-level) if real addressing is being used.
    int is_real_address = !bits(tlbdata, 5);

    // Grab the address space identifier register from the thread context.
    // XXX: Inspecting how setMiscReg and setMiscRegNoEffect behave for
    // MISCREG_ASI causes me to think that the ASI register implementation
    // might be bugged. The NoEffect variant changes the ASI register
    // value in the architectural state while the normal variant changes
    // the context field in the thread context's currently decoded request
    // but does not directly affect the ASI register value in the
    // architectural state. The ASI values and the context field in the
    // request packet seem to have completely different uses.
    RegVal reg_asi = tc->readMiscRegNoEffect(MISCREG_ASI);
    ASI asi = static_cast<ASI>(reg_asi);

    // The SPARC DTLB code assumes that traps are executed in context
    // zero if the asi value is ASI_IMPLICIT (which is 0x0). There's also
    // an assumption that the nucleus address space is being used, but
    // the context is the relevant issue since we need to pass it to TLB.
    bool trapped = bits(tlbdata, 18, 16) > 0;

    // Given the assumptions in the translateData code in the SPARC DTLB,
    // the logic works out to the following for the context.
    int context_id = ((!hpriv && !red && is_real_address) ||
                      asiIsReal(asi) ||
                      (trapped && asi == ASI_IMPLICIT))
                     ? 0 : primary_context;

    // The partition id distinguishes between virtualized environments.
    int const partition_id = 0;

    TlbEntry entry(p->pTable->pid(), alignedvaddr, pte->paddr,
                   pte->flags & EmulationPageTable::Uncacheable,
                   pte->flags & EmulationPageTable::ReadOnly);

    // Insert the TLB entry.
    // The entry specifying whether the address is "real" is set to
    // false for syscall emulation mode regardless of whether the
    // address is real in preceding code. Not sure sure that this is
    // correct, but also not sure if it matters at all.
    dynamic_cast<TLB *>(tc->getDTBPtr())->
        insert(alignedvaddr, partition_id, context_id, false, entry.pte);
}

void
SpillNNormal::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    if (FullSystem) {
        SparcFaultBase::invoke(tc, inst);
        return;
    }

    doNormalFault(tc, trapType(), false);

    Process *p = tc->getProcessPtr();

    SparcProcess *sp = dynamic_cast<SparcProcess *>(p);
    assert(sp);

    // Then adjust the PC and NPC
    tc->pcState(sp->readSpillStart());
}

void
FillNNormal::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    if (FullSystem) {
        SparcFaultBase::invoke(tc, inst);
        return;
    }

    doNormalFault(tc, trapType(), false);

    Process *p = tc->getProcessPtr();

    SparcProcess *sp = dynamic_cast<SparcProcess *>(p);
    assert(sp);

    // Then adjust the PC and NPC
    tc->pcState(sp->readFillStart());
}

void
TrapInstruction::invoke(ThreadContext *tc, const StaticInstPtr &inst)
{
    if (FullSystem) {
        SparcFaultBase::invoke(tc, inst);
        return;
    }

    // In SE, this mechanism is how the process requests a service from
    // the operating system. We'll get the process object from the thread
    // context and let it service the request.

    Process *p = tc->getProcessPtr();

    SparcProcess *sp = dynamic_cast<SparcProcess *>(p);
    assert(sp);

    Fault fault;
    sp->handleTrap(_n, tc, &fault);

    // We need to explicitly advance the pc, since that's not done for us
    // on a faulting instruction
    PCState pc = tc->pcState();
    pc.advance();
    tc->pcState(pc);
}

} // namespace SparcISA

