misc_regfile.cc

来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· CC 代码 · 共 638 行 · 第 1/2 页

CC
638
字号
    replaceBits(SC_Mask,0,32,0);    setRegMask(SRSCtl,SC_Mask);    // IntCtl - IPTI, IPPCI    MiscReg IC = readRegNoEffect(IntCtl);    replaceBits(IC, IntCtl_IPTI_HI,IntCtl_IPTI_LO,p->coreParams.CP0_IntCtl_IPTI);    replaceBits(IC, IntCtl_IPPCI_HI,IntCtl_IPPCI_LO,p->coreParams.CP0_IntCtl_IPPCI);    setRegNoEffect(IntCtl, IC);    // Now, create Write Mask for the IntCtl register    MiscReg IC_Mask = 0x000003E0;    replaceBits(IC_Mask,0,32,0);    setRegMask(IntCtl,IC_Mask);    // Watch Hi - M - FIXME (More than 1 Watch register)    MiscReg WHi = readRegNoEffect(WatchHi0);    replaceBits(WHi, WatchHi_M, p->coreParams.CP0_WatchHi_M);    setRegNoEffect(WatchHi0, WHi);    // Now, create Write Mask for the IntCtl register    MiscReg wh_Mask = 0x7FFF0FFF;    replaceBits(wh_Mask,0,32,0);    setRegMask(WatchHi0,wh_Mask);    // Perf Ctr - M - FIXME (More than 1 PerfCnt Pair)    MiscReg PCtr = readRegNoEffect(PerfCnt0);    replaceBits(PCtr, PerfCntCtl_M, p->coreParams.CP0_PerfCtr_M);    replaceBits(PCtr, PerfCntCtl_W, p->coreParams.CP0_PerfCtr_W);    setRegNoEffect(PerfCnt0, PCtr);    // Now, create Write Mask for the IntCtl register    MiscReg pc_Mask = 0x00007FF;    replaceBits(pc_Mask,0,32,0);    setRegMask(PerfCnt0,pc_Mask);    // Random    MiscReg random = readRegNoEffect(CP0_Random);    random = 63;    setRegNoEffect(CP0_Random, random);    // Now, create Write Mask for the IntCtl register    MiscReg random_Mask = 0;    replaceBits(random_Mask,0,32,0);    setRegMask(CP0_Random,random_Mask);    // PageGrain    MiscReg pagegrain = readRegNoEffect(PageGrain);    replaceBits(pagegrain,PageGrain_ESP,p->coreParams.CP0_Config3_SP);    setRegNoEffect(PageGrain, pagegrain);    // Now, create Write Mask for the IntCtl register    MiscReg pg_Mask = 0x10000000;    replaceBits(pg_Mask,0,32,0);    setRegMask(PageGrain,pg_Mask);    // Status    MiscReg stat = readRegNoEffect(Status);    // Only CU0 and IE are modified on a reset - everything else needs to be controlled       // on a per CPU model basis    //    replaceBits(stat, Status_CU0_HI,Status_CU0_LO, 1); // Enable CP0 on reset    replaceBits(stat, Status_ERL_HI, Status_ERL_LO, 1); // Enable ERL bit on a reset    replaceBits(stat, Status_BEV_HI, Status_BEV_LO, 1); // Enable BEV bit on a reset    setRegNoEffect(Status, stat);    // Now, create Write Mask for the Status register    MiscReg stat_Mask = 0xFF78FF17;    replaceBits(stat_Mask,0,32,0);    setRegMask(Status,stat_Mask);    // MVPConf0    MiscReg mvp_conf0 = readRegNoEffect(MVPConf0);    replaceBits(mvp_conf0, MVPC0_TCA, 1);    replaceBits(mvp_conf0, MVPC0_PVPE_HI, MVPC0_PVPE_LO, num_vpes - 1);    replaceBits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO, num_threads - 1);    setRegNoEffect(MVPConf0, mvp_conf0);    // VPEConf0    MiscReg vpe_conf0 = readRegNoEffect(VPEConf0);    replaceBits(vpe_conf0, VPEC0_MVP, 1);    setRegNoEffect(VPEConf0, vpe_conf0);    // TCBind    for (int tid = 0; tid < num_threads; tid++) {        MiscReg tc_bind = readRegNoEffect(TCBind, tid);        replaceBits(tc_bind, TCB_CUR_TC_HI, TCB_CUR_TC_LO, tid);        setRegNoEffect(TCBind, tc_bind, tid);    }    // TCHalt    MiscReg tc_halt = readRegNoEffect(TCHalt);    replaceBits(tc_halt, TCH_H, 0);    setRegNoEffect(TCHalt, tc_halt);    /*for (int tid = 1; tid < num_threads; tid++) {        // Set TCHalt Halt bit to 1 for all other threads        tc_halt = readRegNoEffect(TCHalt, tid);        replaceBits(tc_halt, TCH_H, 1);        setReg(TCHalt, tc_halt, tid);        }*/    // TCStatus    // Set TCStatus Activated to 1 for the initial thread that is running    MiscReg tc_status = readRegNoEffect(TCStatus);    replaceBits(tc_status, TCS_A, 1);    setRegNoEffect(TCStatus, tc_status);    // Set Dynamically Allocatable bit to 1 for all other threads    for (int tid = 1; tid < num_threads; tid++) {        tc_status = readRegNoEffect(TCStatus, tid);        replaceBits(tc_status, TCSTATUS_DA, 1);        setRegNoEffect(TCStatus, tc_status, tid);    }    MiscReg Mask = 0x7FFFFFFF;    // Now, create Write Mask for the Index register    replaceBits(Mask,0,32,0);    setRegMask(Index,Mask);    Mask = 0x3FFFFFFF;    replaceBits(Mask,0,32,0);    setRegMask(EntryLo0,Mask);    setRegMask(EntryLo1,Mask);    Mask = 0xFF800000;    replaceBits(Mask,0,32,0);    setRegMask(Context,Mask);    Mask = 0x1FFFF800;    replaceBits(Mask,0,32,0);    setRegMask(PageMask,Mask);    Mask = 0x0;    replaceBits(Mask,0,32,0);    setRegMask(BadVAddr,Mask);    setRegMask(LLAddr,Mask);    Mask = 0x08C00300;    replaceBits(Mask,0,32,0);    setRegMask(Cause,Mask);}inline std::stringMipsISA::getMiscRegName(unsigned reg_idx){    return MiscRegFile::miscRegNames[reg_idx];}inline unsignedMiscRegFile::getVPENum(unsigned tid){    unsigned tc_bind = miscRegFile[TCBind - Ctrl_Base_DepTag][tid];    return bits(tc_bind, TCB_CUR_VPE_HI, TCB_CUR_VPE_LO);}MiscRegMiscRegFile::readRegNoEffect(int reg_idx, unsigned tid){    int misc_reg = reg_idx - Ctrl_Base_DepTag;    unsigned reg_sel = (bankType[misc_reg] == perThreadContext)        ? tid : getVPENum(tid);    DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) (%lx).\n",            misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg),miscRegFile[misc_reg][reg_sel]);    return miscRegFile[misc_reg][reg_sel];}//@TODO: MIPS MT's register view automatically connects//       Status to TCStatus depending on current thread//template <class TC>MiscRegMiscRegFile::readReg(int reg_idx,                               ThreadContext *tc,  unsigned tid){    int misc_reg = reg_idx - Ctrl_Base_DepTag;    unsigned reg_sel = (bankType[misc_reg] == perThreadContext)        ? tid : getVPENum(tid);    DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n",            misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg),miscRegFile[misc_reg][reg_sel]);    switch (misc_reg)    {      default:        return miscRegFile[misc_reg][reg_sel];    }}voidMiscRegFile::setRegNoEffect(int reg_idx, const MiscReg &val, unsigned tid){    int misc_reg = reg_idx - Ctrl_Base_DepTag;    unsigned reg_sel = (bankType[misc_reg] == perThreadContext)        ? tid : getVPENum(tid);    DPRINTF(MipsPRA, "[tid:%i]: Setting (direct set) CP0 Register:%u Select:%u (%s) to %#x.\n",            tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val);    miscRegFile[misc_reg][reg_sel] = val;}voidMiscRegFile::setRegMask(int reg_idx, const MiscReg &val, unsigned tid){  //  return;  int misc_reg = reg_idx - Ctrl_Base_DepTag;    unsigned reg_sel = (bankType[misc_reg] == perThreadContext)        ? tid : getVPENum(tid);    DPRINTF(MipsPRA,"[tid:%i]: Setting CP0 Register: %u Select: %u (%s) to %#x\n",tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val);    miscRegFile_WriteMask[misc_reg][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!//template <class TC>voidMiscRegFile::setReg(int reg_idx, const MiscReg &val,                              ThreadContext *tc, unsigned tid){    int misc_reg = reg_idx - Ctrl_Base_DepTag;    int reg_sel = (bankType[misc_reg] == perThreadContext)        ? tid : getVPENum(tid);    DPRINTF(MipsPRA, "[tid:%i]: Setting CP0 Register:%u Select:%u (%s) to %#x, with effect.\n",            tid, misc_reg / 8, misc_reg % 8, getMiscRegName(misc_reg), val);    MiscReg cp0_val = filterCP0Write(misc_reg, reg_sel, val);    miscRegFile[misc_reg][reg_sel] = cp0_val;    scheduleCP0Update(1);}/** This method doesn't need to adjust the Control Register Offset since    it has already been done in the calling method (setRegWithEffect) */MiscReg MiscRegFile::filterCP0Write(int misc_reg, int reg_sel, const MiscReg &val){  MiscReg retVal = val;  retVal &= miscRegFile_WriteMask[misc_reg][reg_sel]; // Mask off read-only regions  MiscReg curVal = miscRegFile[misc_reg][reg_sel];  curVal &= (~miscRegFile_WriteMask[misc_reg][reg_sel]); // Mask off current alue with inverse mask (clear writeable bits)  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[misc_reg][reg_sel],~miscRegFile_WriteMask[misc_reg][reg_sel],val,miscRegFile[misc_reg][reg_sel],retVal);  return retVal;}voidMiscRegFile::scheduleCP0Update(int delay){    if (!cp0Updated) {        cp0Updated = true;        //schedule UPDATE        CP0Event *cp0_event = new CP0Event(this, cpu, UpdateCP0);        cp0_event->schedule(curTick + cpu->ticks(delay));    }}voidMiscRegFile::updateCPU(){    ///////////////////////////////////////////////////////////////////    //    // EVALUATE CP0 STATE FOR MIPS MT    //    ///////////////////////////////////////////////////////////////////    unsigned mvp_conf0 = readRegNoEffect(MVPConf0);    unsigned num_threads = bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;    for (int tid = 0; tid < num_threads; tid++) {        MiscReg tc_status = readRegNoEffect(TCStatus, tid);        MiscReg tc_halt = readRegNoEffect(TCHalt, tid);        //@todo: add vpe/mt check here thru mvpcontrol & vpecontrol regs        if (bits(tc_halt, TCH_H) == 1 || bits(tc_status, TCS_A) == 0)  {            haltThread(cpu->getContext(tid));        } else if (bits(tc_halt, TCH_H) == 0 && bits(tc_status, TCS_A) == 1) {            restoreThread(cpu->getContext(tid));        }    }    num_threads = bits(mvp_conf0, MVPC0_PTC_HI, MVPC0_PTC_LO) + 1;    // Toggle update flag after we finished updating    cp0Updated = false;}MiscRegFile::CP0Event::CP0Event(CP0 *_cp0, BaseCPU *_cpu, CP0EventType e_type)    : Event(&mainEventQueue, CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), cp0EventType(e_type){  }voidMiscRegFile::CP0Event::process(){    switch (cp0EventType)    {      case UpdateCP0:        cp0->updateCPU();        break;    }    //cp0EventRemoveList.push(this);}const char *MiscRegFile::CP0Event::description() const{    return "Coprocessor-0 event";}voidMiscRegFile::CP0Event::scheduleEvent(int delay){    if (squashed())        reschedule(curTick + cpu->ticks(delay));    else if (!scheduled())        schedule(curTick + cpu->ticks(delay));}voidMiscRegFile::CP0Event::unscheduleEvent(){    if (scheduled())        squash();}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?