/*
 * Copyright (c) 2009 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/mips/isa.hh"

#include "arch/mips/mt.hh"
#include "arch/mips/mt_constants.hh"
#include "arch/mips/pra_constants.hh"
#include "arch/mips/regs/float.hh"
#include "arch/mips/regs/int.hh"
#include "arch/mips/regs/misc.hh"
#include "base/bitfield.hh"
#include "cpu/base.hh"
#include "cpu/reg_class.hh"
#include "cpu/thread_context.hh"
#include "debug/MatRegs.hh"
#include "debug/MipsPRA.hh"
#include "params/MipsISA.hh"

namespace gem5
{

namespace MipsISA
{

std::string
ISA::miscRegNames[misc_reg::NumRegs] =
{
    "Index", "MVPControl", "MVPConf0", "MVPConf1", "", "", "", "",
    "Random", "VPEControl", "VPEConf0", "VPEConf1",
        "YQMask", "VPESchedule", "VPEScheFBack", "VPEOpt",
    "EntryLo0", "TCStatus", "TCBind", "TCRestart",
        "TCHalt", "TCContext", "TCSchedule", "TCScheFBack",
    "EntryLo1", "", "", "", "", "", "", "",
    "Context", "ContextConfig", "", "", "", "", "", "",
    "PageMask", "PageGrain", "", "", "", "", "", "",
    "Wired", "SRSConf0", "SRCConf1", "SRSConf2",
        "SRSConf3", "SRSConf4", "", "",
    "HWREna", "", "", "", "", "", "", "",
    "BadVAddr", "", "", "", "", "", "", "",
    "Count", "", "", "", "", "", "", "",
    "EntryHi", "", "", "", "", "", "", "",
    "Compare", "", "", "", "", "", "", "",
    "Status", "IntCtl", "SRSCtl", "SRSMap", "", "", "", "",
    "Cause", "", "", "", "", "", "", "",
    "EPC", "", "", "", "", "", "", "",
    "PRId", "EBase", "", "", "", "", "", "",
    "Config", "Config1", "Config2", "Config3", "", "", "", "",
    "LLAddr", "", "", "", "", "", "", "",
    "WatchLo0", "WatchLo1", "WatchLo2", "WatchLo3",
        "WatchLo4", "WatchLo5", "WatchLo6", "WatchLo7",
    "WatchHi0", "WatchHi1", "WatchHi2", "WatchHi3",
        "WatchHi4", "WatchHi5", "WatchHi6", "WatchHi7",
    "XCContext64", "", "", "", "", "", "", "",
    "", "", "", "", "", "", "", "",
    "", "", "", "", "", "", "", "",
    "Debug", "TraceControl1", "TraceControl2", "UserTraceData",
        "TraceBPC", "", "", "",
    "DEPC", "", "", "", "", "", "", "",
    "PerfCnt0", "PerfCnt1", "PerfCnt2", "PerfCnt3",
        "PerfCnt4", "PerfCnt5", "PerfCnt6", "PerfCnt7",
    "ErrCtl", "", "", "", "", "", "", "",
    "CacheErr0", "CacheErr1", "CacheErr2", "CacheErr3", "", "", "", "",
    "TagLo0", "DataLo1", "TagLo2", "DataLo3",
        "TagLo4", "DataLo5", "TagLo6", "DataLo7",
    "TagHi0", "DataHi1", "TagHi2", "DataHi3",
        "TagHi4", "DataHi5", "TagHi6", "DataHi7",
    "ErrorEPC", "", "", "", "", "", "", "",
    "DESAVE", "", "", "", "", "", "", "",
    "LLFlag"
};

namespace
{

/* Not applicable to MIPS. */
constexpr RegClass vecRegClass(VecRegClass, VecRegClassName, 1,
        debug::IntRegs);
constexpr RegClass vecElemClass(VecElemClass, VecElemClassName, 2,
        debug::IntRegs);
constexpr RegClass vecPredRegClass(VecPredRegClass, VecPredRegClassName, 1,
        debug::IntRegs);
constexpr RegClass matRegClass(MatRegClass, MatRegClassName, 1, debug::MatRegs);
constexpr RegClass ccRegClass(CCRegClass, CCRegClassName, 0, debug::IntRegs);

} // anonymous namespace

ISA::ISA(const Params &p) : BaseISA(p), numThreads(p.num_threads),
    numVpes(p.num_vpes)
{
    _regClasses.push_back(&intRegClass);
    _regClasses.push_back(&floatRegClass);
    _regClasses.push_back(&vecRegClass);
    _regClasses.push_back(&vecElemClass);
    _regClasses.push_back(&vecPredRegClass);
    _regClasses.push_back(&matRegClass);
    _regClasses.push_back(&ccRegClass);
    _regClasses.push_back(&miscRegClass);

    miscRegFile.resize(misc_reg::NumRegs);
    bankType.resize(misc_reg::NumRegs);

    for (int i = 0; i < misc_reg::NumRegs; i++) {
        miscRegFile[i].resize(1);
        bankType[i] = perProcessor;
    }

    miscRegFile_WriteMask.resize(misc_reg::NumRegs);

    for (int i = 0; i < misc_reg::NumRegs; i++) {
        miscRegFile_WriteMask[i].push_back(0);
    }

    // Initialize all Per-VPE regs
    uint32_t per_vpe_regs[] = { misc_reg::VpeControl,
                                misc_reg::VpeConf0, misc_reg::VpeConf1,
                                misc_reg::Yqmask,
                                misc_reg::VpeSchedule, misc_reg::VpeSchefback,
                                misc_reg::VpeOpt, misc_reg::SrsConf0,
                                misc_reg::SrsConf1, misc_reg::SrsConf2,
                                misc_reg::SrsConf3, misc_reg::SrsConf4,
                                misc_reg::Ebase
                              };
    uint32_t num_vpe_regs = sizeof(per_vpe_regs) / 4;
    for (int i = 0; i < num_vpe_regs; i++) {
        if (numVpes > 1) {
            miscRegFile[per_vpe_regs[i]].resize(numVpes);
        }
        bankType[per_vpe_regs[i]] = perVirtProcessor;
    }

    // Initialize all Per-TC regs
    uint32_t per_tc_regs[] = { misc_reg::Status,
                               misc_reg::TcStatus, misc_reg::TcBind,
                               misc_reg::TcRestart, misc_reg::TcHalt,
                               misc_reg::TcContext, misc_reg::TcSchedule,
                               misc_reg::TcSchefback,
                               misc_reg::Debug, misc_reg::Lladdr
                             };
    uint32_t num_tc_regs = sizeof(per_tc_regs) /  4;

    for (int i = 0; i < num_tc_regs; i++) {
        miscRegFile[per_tc_regs[i]].resize(numThreads);
        bankType[per_tc_regs[i]] = perThreadContext;
    }

    clear();
}

void
ISA::clear()
{
    for (int i = 0; i < misc_reg::NumRegs; i++) {
        for (int j = 0; j < miscRegFile[i].size(); j++)
            miscRegFile[i][j] = 0;

        for (int k = 0; k < miscRegFile_WriteMask[i].size(); k++)
            miscRegFile_WriteMask[i][k] = (long unsigned int)(-1);
    }
}

void
ISA::copyRegsFrom(ThreadContext *src)
{
    // First loop through the integer registers.
    for (auto &id: intRegClass)
        tc->setReg(id, src->getReg(id));

    // Then loop through the floating point registers.
    for (auto &id: floatRegClass)
        tc->setReg(id, src->getReg(id));

    // Copy misc. registers
    for (int i = 0; i < misc_reg::NumRegs; i++)
        tc->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));

    // Copy over the PC State
    tc->pcState(src->pcState());
}


void
ISA::configCP()
{
    DPRINTF(MipsPRA, "Resetting CP0 State with %i TCs and %i VPEs\n",
            numThreads, numVpes);

    CoreSpecific cp;
    panic("CP state must be set before the following code is used");

    // Do Default CP0 initialization HERE

    // Do Initialization for MT cores here (eventually use
    // core_name parameter to toggle this initialization)
    // ===================================================
    DPRINTF(MipsPRA, "Initializing CP0 State.... ");

    PRIdReg procId = readMiscRegNoEffect(misc_reg::Prid);
    procId.coOp = cp.CP0_PRId_CompanyOptions;
    procId.coId = cp.CP0_PRId_CompanyID;
    procId.procId = cp.CP0_PRId_ProcessorID;
    procId.rev = cp.CP0_PRId_Revision;
    setMiscRegNoEffect(misc_reg::Prid, procId);

    // Now, create Write Mask for ProcID register
    RegVal procIDMask = 0; // Read-Only register
    replaceBits(procIDMask, 32, 0, 0);
    setRegMask(misc_reg::Prid, procIDMask);

    // Config
    ConfigReg cfg = readMiscRegNoEffect(misc_reg::Config);
    cfg.be = cp.CP0_Config_BE;
    cfg.at = cp.CP0_Config_AT;
    cfg.ar = cp.CP0_Config_AR;
    cfg.mt = cp.CP0_Config_MT;
    cfg.vi = cp.CP0_Config_VI;
    cfg.m = 1;
    setMiscRegNoEffect(misc_reg::Config, cfg);
    // Now, create Write Mask for Config register
    RegVal cfg_Mask = 0x7FFF0007;
    replaceBits(cfg_Mask, 32, 0, 0);
    setRegMask(misc_reg::Config, cfg_Mask);

    // Config1
    Config1Reg cfg1 = readMiscRegNoEffect(misc_reg::Config1);
    cfg1.mmuSize = cp.CP0_Config1_MMU;
    cfg1.is = cp.CP0_Config1_IS;
    cfg1.il = cp.CP0_Config1_IL;
    cfg1.ia = cp.CP0_Config1_IA;
    cfg1.ds = cp.CP0_Config1_DS;
    cfg1.dl = cp.CP0_Config1_DL;
    cfg1.da = cp.CP0_Config1_DA;
    cfg1.fp = cp.CP0_Config1_FP;
    cfg1.ep = cp.CP0_Config1_EP;
    cfg1.wr = cp.CP0_Config1_WR;
    cfg1.md = cp.CP0_Config1_MD;
    cfg1.c2 = cp.CP0_Config1_C2;
    cfg1.pc = cp.CP0_Config1_PC;
    cfg1.m = cp.CP0_Config1_M;
    setMiscRegNoEffect(misc_reg::Config1, cfg1);
    // Now, create Write Mask for Config register
    RegVal cfg1_Mask = 0; // Read Only Register
    replaceBits(cfg1_Mask, 32,0 , 0);
    setRegMask(misc_reg::Config1, cfg1_Mask);

    // Config2
    Config2Reg cfg2 = readMiscRegNoEffect(misc_reg::Config2);
    cfg2.tu = cp.CP0_Config2_TU;
    cfg2.ts = cp.CP0_Config2_TS;
    cfg2.tl = cp.CP0_Config2_TL;
    cfg2.ta = cp.CP0_Config2_TA;
    cfg2.su = cp.CP0_Config2_SU;
    cfg2.ss = cp.CP0_Config2_SS;
    cfg2.sl = cp.CP0_Config2_SL;
    cfg2.sa = cp.CP0_Config2_SA;
    cfg2.m = cp.CP0_Config2_M;
    setMiscRegNoEffect(misc_reg::Config2, cfg2);
    // Now, create Write Mask for Config register
    RegVal cfg2_Mask = 0x7000F000; // Read Only Register
    replaceBits(cfg2_Mask, 32, 0, 0);
    setRegMask(misc_reg::Config2, cfg2_Mask);

    // Config3
    Config3Reg cfg3 = readMiscRegNoEffect(misc_reg::Config3);
    cfg3.dspp = cp.CP0_Config3_DSPP;
    cfg3.lpa = cp.CP0_Config3_LPA;
    cfg3.veic = cp.CP0_Config3_VEIC;
    cfg3.vint = cp.CP0_Config3_VInt;
    cfg3.sp = cp.CP0_Config3_SP;
    cfg3.mt = cp.CP0_Config3_MT;
    cfg3.sm = cp.CP0_Config3_SM;
    cfg3.tl = cp.CP0_Config3_TL;
    setMiscRegNoEffect(misc_reg::Config3, cfg3);
    // Now, create Write Mask for Config register
    RegVal cfg3_Mask = 0; // Read Only Register
    replaceBits(cfg3_Mask, 32,0 , 0);
    setRegMask(misc_reg::Config3, cfg3_Mask);

    // EBase - CPUNum
    EBaseReg eBase = readMiscRegNoEffect(misc_reg::Ebase);
    eBase.cpuNum = cp.CP0_EBase_CPUNum;
    replaceBits(eBase, 31, 31, 1);
    setMiscRegNoEffect(misc_reg::Ebase, eBase);
    // Now, create Write Mask for Config register
    RegVal EB_Mask = 0x3FFFF000;// Except Exception Base, the
                                 // entire register is read only
    replaceBits(EB_Mask, 32, 0, 0);
    setRegMask(misc_reg::Ebase, EB_Mask);

    // SRS Control - HSS (Highest Shadow Set)
    SRSCtlReg scsCtl = readMiscRegNoEffect(misc_reg::Srsctl);
    scsCtl.hss = cp.CP0_SrsCtl_HSS;
    setMiscRegNoEffect(misc_reg::Srsctl, scsCtl);
    // Now, create Write Mask for the SRS Ctl register
    RegVal SC_Mask = 0x0000F3C0;
    replaceBits(SC_Mask, 32, 0, 0);
    setRegMask(misc_reg::Srsctl, SC_Mask);

    // IntCtl - IPTI, IPPCI
    IntCtlReg intCtl = readMiscRegNoEffect(misc_reg::Intctl);
    intCtl.ipti = cp.CP0_IntCtl_IPTI;
    intCtl.ippci = cp.CP0_IntCtl_IPPCI;
    setMiscRegNoEffect(misc_reg::Intctl, intCtl);
    // Now, create Write Mask for the IntCtl register
    RegVal IC_Mask = 0x000003E0;
    replaceBits(IC_Mask, 32, 0, 0);
    setRegMask(misc_reg::Intctl, IC_Mask);

    // Watch Hi - M - FIXME (More than 1 Watch register)
    WatchHiReg watchHi = readMiscRegNoEffect(misc_reg::Watchhi0);
    watchHi.m = cp.CP0_WatchHi_M;
    setMiscRegNoEffect(misc_reg::Watchhi0, watchHi);
    // Now, create Write Mask for the IntCtl register
    RegVal wh_Mask = 0x7FFF0FFF;
    replaceBits(wh_Mask, 32, 0, 0);
    setRegMask(misc_reg::Watchhi0, wh_Mask);

    // Perf Ctr - M - FIXME (More than 1 PerfCnt Pair)
    PerfCntCtlReg perfCntCtl = readMiscRegNoEffect(misc_reg::Perfcnt0);
    perfCntCtl.m = cp.CP0_PerfCtr_M;
    perfCntCtl.w = cp.CP0_PerfCtr_W;
    setMiscRegNoEffect(misc_reg::Perfcnt0, perfCntCtl);
    // Now, create Write Mask for the IntCtl register
    RegVal pc_Mask = 0x00007FF;
    replaceBits(pc_Mask, 32, 0, 0);
    setRegMask(misc_reg::Perfcnt0, pc_Mask);

    // Random
    setMiscRegNoEffect(misc_reg::Cp0Random, 63);
    // Now, create Write Mask for the IntCtl register
    RegVal random_Mask = 0;
    replaceBits(random_Mask, 32, 0, 0);
    setRegMask(misc_reg::Cp0Random, random_Mask);

    // PageGrain
    PageGrainReg pageGrain = readMiscRegNoEffect(misc_reg::Pagegrain);
    pageGrain.esp = cp.CP0_Config3_SP;
    setMiscRegNoEffect(misc_reg::Pagegrain, pageGrain);
    // Now, create Write Mask for the IntCtl register
    RegVal pg_Mask = 0x10000000;
    replaceBits(pg_Mask, 32, 0, 0);
    setRegMask(misc_reg::Pagegrain, pg_Mask);

    // Status
    StatusReg status = readMiscRegNoEffect(misc_reg::Status);
    // Only CU0 and IE are modified on a reset - everything else needs
    // to be controlled on a per CPU model basis

    // Enable CP0 on reset
    // status.cu0 = 1;

    // Enable ERL bit on a reset
    status.erl = 1;
    // Enable BEV bit on a reset
    status.bev = 1;

    setMiscRegNoEffect(misc_reg::Status, status);
    // Now, create Write Mask for the Status register
    RegVal stat_Mask = 0xFF78FF17;
    replaceBits(stat_Mask, 32, 0, 0);
    setRegMask(misc_reg::Status, stat_Mask);


    // MVPConf0
    MVPConf0Reg mvpConf0 = readMiscRegNoEffect(misc_reg::MvpConf0);
    mvpConf0.tca = 1;
    mvpConf0.pvpe = numVpes - 1;
    mvpConf0.ptc = numThreads - 1;
    setMiscRegNoEffect(misc_reg::MvpConf0, mvpConf0);

    // VPEConf0
    VPEConf0Reg vpeConf0 = readMiscRegNoEffect(misc_reg::VpeConf0);
    vpeConf0.mvp = 1;
    setMiscRegNoEffect(misc_reg::VpeConf0, vpeConf0);

    // TCBind
    for (ThreadID tid = 0; tid < numThreads; tid++) {
        TCBindReg tcBind = readMiscRegNoEffect(misc_reg::TcBind, tid);
        tcBind.curTC = tid;
        setMiscRegNoEffect(misc_reg::TcBind, tcBind, tid);
    }
    // TCHalt
    TCHaltReg tcHalt = readMiscRegNoEffect(misc_reg::TcHalt);
    tcHalt.h = 0;
    setMiscRegNoEffect(misc_reg::TcHalt, tcHalt);

    // TCStatus
    // Set TCStatus Activated to 1 for the initial thread that is running
    TCStatusReg tcStatus = readMiscRegNoEffect(misc_reg::TcStatus);
    tcStatus.a = 1;
    setMiscRegNoEffect(misc_reg::TcStatus, tcStatus);

    // Set Dynamically Allocatable bit to 1 for all other threads
    for (ThreadID tid = 1; tid < numThreads; tid++) {
        tcStatus = readMiscRegNoEffect(misc_reg::TcStatus, tid);
        tcStatus.da = 1;
        setMiscRegNoEffect(misc_reg::TcStatus, tcStatus, tid);
    }


    RegVal mask = 0x7FFFFFFF;

    // Now, create Write Mask for the Index register
    replaceBits(mask, 32, 0, 0);
    setRegMask(misc_reg::Index, mask);

    mask = 0x3FFFFFFF;
    replaceBits(mask, 32, 0, 0);
    setRegMask(misc_reg::Entrylo0, mask);
    setRegMask(misc_reg::Entrylo1, mask);

    mask = 0xFF800000;
    replaceBits(mask, 32, 0, 0);
    setRegMask(misc_reg::Context, mask);

    mask = 0x1FFFF800;
    replaceBits(mask, 32, 0, 0);
    setRegMask(misc_reg::Pagemask, mask);

    mask = 0x0;
    replaceBits(mask, 32, 0, 0);
    setRegMask(misc_reg::Badvaddr, mask);
    setRegMask(misc_reg::Lladdr, mask);

    mask = 0x08C00300;
    replaceBits(mask, 32, 0, 0);
    setRegMask(misc_reg::Cause, mask);

}

inline unsigned
ISA::getVPENum(ThreadID tid) const
{
    TCBindReg tcBind = miscRegFile[misc_reg::TcBind][tid];
    return tcBind.curVPE;
}

RegVal
ISA::readMiscRegNoEffect(RegIndex idx, ThreadID tid) const
{
    unsigned reg_sel = (bankType[idx] == perThreadContext)
        ? tid : getVPENum(tid);
    DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) (%lx).\n",
            idx / 8, idx % 8, miscRegNames[idx], miscRegFile[idx][reg_sel]);
    return miscRegFile[idx][reg_sel];
}

//@TODO: MIPS MT's register view automatically connects
//       Status to TCStatus depending on current thread
//template <class TC>
RegVal
ISA::readMiscReg(RegIndex idx, ThreadID tid)
{
    unsigned reg_sel = (bankType[idx] == perThreadContext)
        ? tid : getVPENum(tid);
    DPRINTF(MipsPRA,
            "Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n",
            idx / 8, idx % 8, miscRegNames[idx], miscRegFile[idx][reg_sel]);

    return miscRegFile[idx][reg_sel];
}

void
ISA::setMiscRegNoEffect(RegIndex idx, RegVal val, ThreadID tid)
{
    unsigned reg_sel = (bankType[idx] == perThreadContext)
        ? tid : getVPENum(tid);
    DPRINTF(MipsPRA,
            "[tid:%i] Setting (direct set) CP0 Register:%u "
            "Select:%u (%s) to %#x.\n",
            tid, idx / 8, idx % 8, miscRegNames[idx], val);

    miscRegFile[idx][reg_sel] = val;
}

void
ISA::setRegMask(RegIndex idx, RegVal val, ThreadID tid)
{
    unsigned reg_sel = (bankType[idx] == perThreadContext)
        ? tid : getVPENum(tid);
    DPRINTF(MipsPRA,
            "[tid:%i] Setting CP0 Register: %u Select: %u (%s) to %#x\n",
            tid, idx / 8, idx % 8, miscRegNames[idx], val);
    miscRegFile_WriteMask[idx][reg_sel] = val;
}

// PROGRAMMER'S NOTES:
// (1) Some CP0 Registers have fields that cannot
// be overwritten. Make sure to handle those particular registers
// with care!
void
ISA::setMiscReg(RegIndex idx, RegVal val, ThreadID tid)
{
    int reg_sel = (bankType[idx] == perThreadContext)
        ? tid : getVPENum(tid);

    DPRINTF(MipsPRA,
            "[tid:%i] Setting CP0 Register:%u "
            "Select:%u (%s) to %#x, with effect.\n",
            tid, idx / 8, idx % 8, miscRegNames[idx], val);

    RegVal cp0_val = filterCP0Write(idx, reg_sel, val);

    miscRegFile[idx][reg_sel] = cp0_val;

    scheduleCP0Update(tc->getCpuPtr(), Cycles(1));
}

/**
 * This method doesn't need to adjust the Control Register Offset
 * since it has already been done in the calling method
 * (setRegWithEffect)
*/
RegVal
ISA::filterCP0Write(RegIndex idx, int reg_sel, RegVal val)
{
    RegVal retVal = val;

    // Mask off read-only regions
    retVal &= miscRegFile_WriteMask[idx][reg_sel];
    RegVal curVal = miscRegFile[idx][reg_sel];
    // Mask off current alue with inverse mask (clear writeable bits)
    curVal &= (~miscRegFile_WriteMask[idx][reg_sel]);
    retVal |= curVal; // Combine the two
    DPRINTF(MipsPRA,
            "filterCP0Write: Mask: %lx, Inverse Mask: %lx, write Val: %x, "
            "current val: %lx, written val: %x\n",
            miscRegFile_WriteMask[idx][reg_sel],
            ~miscRegFile_WriteMask[idx][reg_sel],
            val, miscRegFile[idx][reg_sel], retVal);
    return retVal;
}

void
ISA::scheduleCP0Update(BaseCPU *cpu, Cycles delay)
{
    if (!cp0Updated) {
        cp0Updated = true;

        //schedule UPDATE
        auto cp0_event = new EventFunctionWrapper(
            [this, cpu]{ processCP0Event(cpu, UpdateCP0); },
            "Coprocessor-0 event", true, Event::CPU_Tick_Pri);
        cpu->schedule(cp0_event, cpu->clockEdge(delay));
    }
}

void
ISA::updateCPU(BaseCPU *cpu)
{
    ///////////////////////////////////////////////////////////////////
    //
    // EVALUATE CP0 STATE FOR MIPS MT
    //
    ///////////////////////////////////////////////////////////////////
    MVPConf0Reg mvpConf0 = readMiscRegNoEffect(misc_reg::MvpConf0);
    ThreadID num_threads = mvpConf0.ptc + 1;

    for (ThreadID tid = 0; tid < num_threads; tid++) {
        TCStatusReg tcStatus = readMiscRegNoEffect(misc_reg::TcStatus, tid);
        TCHaltReg tcHalt = readMiscRegNoEffect(misc_reg::TcHalt, tid);

        //@todo: add vpe/mt check here thru mvpcontrol & vpecontrol regs
        if (tcHalt.h == 1 || tcStatus.a == 0)  {
            haltThread(cpu->getContext(tid));
        } else if (tcHalt.h == 0 && tcStatus.a == 1) {
            restoreThread(cpu->getContext(tid));
        }
    }

    num_threads = mvpConf0.ptc + 1;

    // Toggle update flag after we finished updating
    cp0Updated = false;
}

void
ISA::processCP0Event(BaseCPU *cpu, CP0EventType cp0EventType)
{
    switch (cp0EventType)
    {
      case UpdateCP0:
        updateCPU(cpu);
        break;
    }
}

} // namespace MipsISA
} // namespace gem5
