/*
 * 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/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}, FaultStat()};

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

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

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

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

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

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

//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}, FaultStat()};

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

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

//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}, FaultStat()};

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

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

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

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

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

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

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

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

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

//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}, FaultStat()};

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

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

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

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

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

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

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

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

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

//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}, FaultStat()};

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**
 * 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)
{
    MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL);
    MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
    PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
    HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
    MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
    MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
    MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
    MiscReg CANSAVE = tc->readMiscRegNoEffect(NumIntArchRegs + 3);
    MiscReg 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)
{
    MiscReg TL = tc->readMiscRegNoEffect(MISCREG_TL);
    MiscReg TSTATE = tc->readMiscRegNoEffect(MISCREG_TSTATE);
    PSTATE pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE);
    HPSTATE hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE);
    MiscReg CCR = tc->readIntReg(NumIntArchRegs + 2);
    MiscReg ASI = tc->readMiscRegNoEffect(MISCREG_ASI);
    MiscReg CWP = tc->readMiscRegNoEffect(MISCREG_CWP);
    MiscReg CANSAVE = tc->readIntReg(NumIntArchRegs + 3);
    MiscReg 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(MiscReg 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, MiscReg 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, MiscReg TT, MiscReg 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.
    MiscReg tl = tc->readMiscRegNoEffect(MISCREG_TL);
    MiscReg 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();
    TlbEntry entry;
    bool success = p->pTable->lookup(vaddr, entry);
    if (!success) {
        panic("Tried to execute unmapped address %#x.\n", vaddr);
    } else {
        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;

        // 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.
        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();
    TlbEntry entry;
    bool success = p->pTable->lookup(vaddr, entry);
    if (!success) {
        if (p->fixupStackFault(vaddr))
            success = p->pTable->lookup(vaddr, entry);
    }
    if (!success) {
        panic("Tried to access unmapped address %#x.\n", vaddr);
    } else {
        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.
        MiscReg 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;

        // 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.
        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

