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 + -
显示快捷键?