39 40namespace MipsISA 41{ 42 43std::string 44ISA::miscRegNames[NumMiscRegs] = 45{ 46 "Index", "MVPControl", "MVPConf0", "MVPConf1", "", "", "", "", 47 "Random", "VPEControl", "VPEConf0", "VPEConf1", 48 "YQMask", "VPESchedule", "VPEScheFBack", "VPEOpt", 49 "EntryLo0", "TCStatus", "TCBind", "TCRestart", 50 "TCHalt", "TCContext", "TCSchedule", "TCScheFBack", 51 "EntryLo1", "", "", "", "", "", "", "", 52 "Context", "ContextConfig", "", "", "", "", "", "", 53 "PageMask", "PageGrain", "", "", "", "", "", "", 54 "Wired", "SRSConf0", "SRCConf1", "SRSConf2", 55 "SRSConf3", "SRSConf4", "", "", 56 "HWREna", "", "", "", "", "", "", "", 57 "BadVAddr", "", "", "", "", "", "", "", 58 "Count", "", "", "", "", "", "", "", 59 "EntryHi", "", "", "", "", "", "", "", 60 "Compare", "", "", "", "", "", "", "", 61 "Status", "IntCtl", "SRSCtl", "SRSMap", "", "", "", "", 62 "Cause", "", "", "", "", "", "", "", 63 "EPC", "", "", "", "", "", "", "", 64 "PRId", "EBase", "", "", "", "", "", "", 65 "Config", "Config1", "Config2", "Config3", "", "", "", "", 66 "LLAddr", "", "", "", "", "", "", "", 67 "WatchLo0", "WatchLo1", "WatchLo2", "WatchLo3", 68 "WatchLo4", "WatchLo5", "WatchLo6", "WatchLo7", 69 "WatchHi0", "WatchHi1", "WatchHi2", "WatchHi3", 70 "WatchHi4", "WatchHi5", "WatchHi6", "WatchHi7", 71 "XCContext64", "", "", "", "", "", "", "", 72 "", "", "", "", "", "", "", "", 73 "", "", "", "", "", "", "", "", 74 "Debug", "TraceControl1", "TraceControl2", "UserTraceData", 75 "TraceBPC", "", "", "", 76 "DEPC", "", "", "", "", "", "", "", 77 "PerfCnt0", "PerfCnt1", "PerfCnt2", "PerfCnt3", 78 "PerfCnt4", "PerfCnt5", "PerfCnt6", "PerfCnt7", 79 "ErrCtl", "", "", "", "", "", "", "", 80 "CacheErr0", "CacheErr1", "CacheErr2", "CacheErr3", "", "", "", "", 81 "TagLo0", "DataLo1", "TagLo2", "DataLo3", 82 "TagLo4", "DataLo5", "TagLo6", "DataLo7", 83 "TagHi0", "DataHi1", "TagHi2", "DataHi3", 84 "TagHi4", "DataHi5", "TagHi6", "DataHi7", 85 "ErrorEPC", "", "", "", "", "", "", "", 86 "DESAVE", "", "", "", "", "", "", "", 87 "LLFlag" 88}; 89
| 40 41namespace MipsISA 42{ 43 44std::string 45ISA::miscRegNames[NumMiscRegs] = 46{ 47 "Index", "MVPControl", "MVPConf0", "MVPConf1", "", "", "", "", 48 "Random", "VPEControl", "VPEConf0", "VPEConf1", 49 "YQMask", "VPESchedule", "VPEScheFBack", "VPEOpt", 50 "EntryLo0", "TCStatus", "TCBind", "TCRestart", 51 "TCHalt", "TCContext", "TCSchedule", "TCScheFBack", 52 "EntryLo1", "", "", "", "", "", "", "", 53 "Context", "ContextConfig", "", "", "", "", "", "", 54 "PageMask", "PageGrain", "", "", "", "", "", "", 55 "Wired", "SRSConf0", "SRCConf1", "SRSConf2", 56 "SRSConf3", "SRSConf4", "", "", 57 "HWREna", "", "", "", "", "", "", "", 58 "BadVAddr", "", "", "", "", "", "", "", 59 "Count", "", "", "", "", "", "", "", 60 "EntryHi", "", "", "", "", "", "", "", 61 "Compare", "", "", "", "", "", "", "", 62 "Status", "IntCtl", "SRSCtl", "SRSMap", "", "", "", "", 63 "Cause", "", "", "", "", "", "", "", 64 "EPC", "", "", "", "", "", "", "", 65 "PRId", "EBase", "", "", "", "", "", "", 66 "Config", "Config1", "Config2", "Config3", "", "", "", "", 67 "LLAddr", "", "", "", "", "", "", "", 68 "WatchLo0", "WatchLo1", "WatchLo2", "WatchLo3", 69 "WatchLo4", "WatchLo5", "WatchLo6", "WatchLo7", 70 "WatchHi0", "WatchHi1", "WatchHi2", "WatchHi3", 71 "WatchHi4", "WatchHi5", "WatchHi6", "WatchHi7", 72 "XCContext64", "", "", "", "", "", "", "", 73 "", "", "", "", "", "", "", "", 74 "", "", "", "", "", "", "", "", 75 "Debug", "TraceControl1", "TraceControl2", "UserTraceData", 76 "TraceBPC", "", "", "", 77 "DEPC", "", "", "", "", "", "", "", 78 "PerfCnt0", "PerfCnt1", "PerfCnt2", "PerfCnt3", 79 "PerfCnt4", "PerfCnt5", "PerfCnt6", "PerfCnt7", 80 "ErrCtl", "", "", "", "", "", "", "", 81 "CacheErr0", "CacheErr1", "CacheErr2", "CacheErr3", "", "", "", "", 82 "TagLo0", "DataLo1", "TagLo2", "DataLo3", 83 "TagLo4", "DataLo5", "TagLo6", "DataLo7", 84 "TagHi0", "DataHi1", "TagHi2", "DataHi3", 85 "TagHi4", "DataHi5", "TagHi6", "DataHi7", 86 "ErrorEPC", "", "", "", "", "", "", "", 87 "DESAVE", "", "", "", "", "", "", "", 88 "LLFlag" 89}; 90
|
145void 146ISA::clear() 147{ 148 for(int i = 0; i < NumMiscRegs; i++) { 149 for (int j = 0; j < miscRegFile[i].size(); j++) 150 miscRegFile[i][j] = 0; 151 152 for (int k = 0; k < miscRegFile_WriteMask[i].size(); k++) 153 miscRegFile_WriteMask[i][k] = (long unsigned int)(-1); 154 } 155} 156 157 158void 159ISA::configCP() 160{ 161 DPRINTF(MipsPRA, "Resetting CP0 State with %i TCs and %i VPEs\n", 162 numThreads, numVpes); 163 164 CoreSpecific cp; 165 panic("CP state must be set before the following code is used"); 166 167 // Do Default CP0 initialization HERE 168 169 // Do Initialization for MT cores here (eventually use 170 // core_name parameter to toggle this initialization) 171 // =================================================== 172 DPRINTF(MipsPRA, "Initializing CP0 State.... "); 173 174 PRIdReg procId = readMiscRegNoEffect(MISCREG_PRID); 175 procId.coOp = cp.CP0_PRId_CompanyOptions; 176 procId.coId = cp.CP0_PRId_CompanyID; 177 procId.procId = cp.CP0_PRId_ProcessorID; 178 procId.rev = cp.CP0_PRId_Revision; 179 setMiscRegNoEffect(MISCREG_PRID, procId); 180 181 // Now, create Write Mask for ProcID register 182 MiscReg procIDMask = 0; // Read-Only register 183 replaceBits(procIDMask, 0, 32, 0); 184 setRegMask(MISCREG_PRID, procIDMask); 185 186 // Config 187 ConfigReg cfg = readMiscRegNoEffect(MISCREG_CONFIG); 188 cfg.be = cp.CP0_Config_BE; 189 cfg.at = cp.CP0_Config_AT; 190 cfg.ar = cp.CP0_Config_AR; 191 cfg.mt = cp.CP0_Config_MT; 192 cfg.vi = cp.CP0_Config_VI; 193 cfg.m = 1; 194 setMiscRegNoEffect(MISCREG_CONFIG, cfg); 195 // Now, create Write Mask for Config register 196 MiscReg cfg_Mask = 0x7FFF0007; 197 replaceBits(cfg_Mask, 0, 32, 0); 198 setRegMask(MISCREG_CONFIG, cfg_Mask); 199 200 // Config1 201 Config1Reg cfg1 = readMiscRegNoEffect(MISCREG_CONFIG1); 202 cfg1.mmuSize = cp.CP0_Config1_MMU; 203 cfg1.is = cp.CP0_Config1_IS; 204 cfg1.il = cp.CP0_Config1_IL; 205 cfg1.ia = cp.CP0_Config1_IA; 206 cfg1.ds = cp.CP0_Config1_DS; 207 cfg1.dl = cp.CP0_Config1_DL; 208 cfg1.da = cp.CP0_Config1_DA; 209 cfg1.fp = cp.CP0_Config1_FP; 210 cfg1.ep = cp.CP0_Config1_EP; 211 cfg1.wr = cp.CP0_Config1_WR; 212 cfg1.md = cp.CP0_Config1_MD; 213 cfg1.c2 = cp.CP0_Config1_C2; 214 cfg1.pc = cp.CP0_Config1_PC; 215 cfg1.m = cp.CP0_Config1_M; 216 setMiscRegNoEffect(MISCREG_CONFIG1, cfg1); 217 // Now, create Write Mask for Config register 218 MiscReg cfg1_Mask = 0; // Read Only Register 219 replaceBits(cfg1_Mask, 0, 32, 0); 220 setRegMask(MISCREG_CONFIG1, cfg1_Mask); 221 222 // Config2 223 Config2Reg cfg2 = readMiscRegNoEffect(MISCREG_CONFIG2); 224 cfg2.tu = cp.CP0_Config2_TU; 225 cfg2.ts = cp.CP0_Config2_TS; 226 cfg2.tl = cp.CP0_Config2_TL; 227 cfg2.ta = cp.CP0_Config2_TA; 228 cfg2.su = cp.CP0_Config2_SU; 229 cfg2.ss = cp.CP0_Config2_SS; 230 cfg2.sl = cp.CP0_Config2_SL; 231 cfg2.sa = cp.CP0_Config2_SA; 232 cfg2.m = cp.CP0_Config2_M; 233 setMiscRegNoEffect(MISCREG_CONFIG2, cfg2); 234 // Now, create Write Mask for Config register 235 MiscReg cfg2_Mask = 0x7000F000; // Read Only Register 236 replaceBits(cfg2_Mask, 0, 32, 0); 237 setRegMask(MISCREG_CONFIG2, cfg2_Mask); 238 239 // Config3 240 Config3Reg cfg3 = readMiscRegNoEffect(MISCREG_CONFIG3); 241 cfg3.dspp = cp.CP0_Config3_DSPP; 242 cfg3.lpa = cp.CP0_Config3_LPA; 243 cfg3.veic = cp.CP0_Config3_VEIC; 244 cfg3.vint = cp.CP0_Config3_VInt; 245 cfg3.sp = cp.CP0_Config3_SP; 246 cfg3.mt = cp.CP0_Config3_MT; 247 cfg3.sm = cp.CP0_Config3_SM; 248 cfg3.tl = cp.CP0_Config3_TL; 249 setMiscRegNoEffect(MISCREG_CONFIG3, cfg3); 250 // Now, create Write Mask for Config register 251 MiscReg cfg3_Mask = 0; // Read Only Register 252 replaceBits(cfg3_Mask, 0, 32, 0); 253 setRegMask(MISCREG_CONFIG3, cfg3_Mask); 254 255 // EBase - CPUNum 256 EBaseReg eBase = readMiscRegNoEffect(MISCREG_EBASE); 257 eBase.cpuNum = cp.CP0_EBase_CPUNum; 258 replaceBits(eBase, 31, 31, 1); 259 setMiscRegNoEffect(MISCREG_EBASE, eBase); 260 // Now, create Write Mask for Config register 261 MiscReg EB_Mask = 0x3FFFF000;// Except Exception Base, the 262 // entire register is read only 263 replaceBits(EB_Mask, 0, 32, 0); 264 setRegMask(MISCREG_EBASE, EB_Mask); 265 266 // SRS Control - HSS (Highest Shadow Set) 267 SRSCtlReg scsCtl = readMiscRegNoEffect(MISCREG_SRSCTL); 268 scsCtl.hss = cp.CP0_SrsCtl_HSS; 269 setMiscRegNoEffect(MISCREG_SRSCTL, scsCtl); 270 // Now, create Write Mask for the SRS Ctl register 271 MiscReg SC_Mask = 0x0000F3C0; 272 replaceBits(SC_Mask, 0, 32, 0); 273 setRegMask(MISCREG_SRSCTL, SC_Mask); 274 275 // IntCtl - IPTI, IPPCI 276 IntCtlReg intCtl = readMiscRegNoEffect(MISCREG_INTCTL); 277 intCtl.ipti = cp.CP0_IntCtl_IPTI; 278 intCtl.ippci = cp.CP0_IntCtl_IPPCI; 279 setMiscRegNoEffect(MISCREG_INTCTL, intCtl); 280 // Now, create Write Mask for the IntCtl register 281 MiscReg IC_Mask = 0x000003E0; 282 replaceBits(IC_Mask, 0, 32, 0); 283 setRegMask(MISCREG_INTCTL, IC_Mask); 284 285 // Watch Hi - M - FIXME (More than 1 Watch register) 286 WatchHiReg watchHi = readMiscRegNoEffect(MISCREG_WATCHHI0); 287 watchHi.m = cp.CP0_WatchHi_M; 288 setMiscRegNoEffect(MISCREG_WATCHHI0, watchHi); 289 // Now, create Write Mask for the IntCtl register 290 MiscReg wh_Mask = 0x7FFF0FFF; 291 replaceBits(wh_Mask, 0, 32, 0); 292 setRegMask(MISCREG_WATCHHI0, wh_Mask); 293 294 // Perf Ctr - M - FIXME (More than 1 PerfCnt Pair) 295 PerfCntCtlReg perfCntCtl = readMiscRegNoEffect(MISCREG_PERFCNT0); 296 perfCntCtl.m = cp.CP0_PerfCtr_M; 297 perfCntCtl.w = cp.CP0_PerfCtr_W; 298 setMiscRegNoEffect(MISCREG_PERFCNT0, perfCntCtl); 299 // Now, create Write Mask for the IntCtl register 300 MiscReg pc_Mask = 0x00007FF; 301 replaceBits(pc_Mask, 0, 32, 0); 302 setRegMask(MISCREG_PERFCNT0, pc_Mask); 303 304 // Random 305 setMiscRegNoEffect(MISCREG_CP0_RANDOM, 63); 306 // Now, create Write Mask for the IntCtl register 307 MiscReg random_Mask = 0; 308 replaceBits(random_Mask, 0, 32, 0); 309 setRegMask(MISCREG_CP0_RANDOM, random_Mask); 310 311 // PageGrain 312 PageGrainReg pageGrain = readMiscRegNoEffect(MISCREG_PAGEGRAIN); 313 pageGrain.esp = cp.CP0_Config3_SP; 314 setMiscRegNoEffect(MISCREG_PAGEGRAIN, pageGrain); 315 // Now, create Write Mask for the IntCtl register 316 MiscReg pg_Mask = 0x10000000; 317 replaceBits(pg_Mask, 0, 32, 0); 318 setRegMask(MISCREG_PAGEGRAIN, pg_Mask); 319 320 // Status 321 StatusReg status = readMiscRegNoEffect(MISCREG_STATUS); 322 // Only CU0 and IE are modified on a reset - everything else needs 323 // to be controlled on a per CPU model basis 324 325 // Enable CP0 on reset 326 // status.cu0 = 1; 327 328 // Enable ERL bit on a reset 329 status.erl = 1; 330 // Enable BEV bit on a reset 331 status.bev = 1; 332 333 setMiscRegNoEffect(MISCREG_STATUS, status); 334 // Now, create Write Mask for the Status register 335 MiscReg stat_Mask = 0xFF78FF17; 336 replaceBits(stat_Mask, 0, 32, 0); 337 setRegMask(MISCREG_STATUS, stat_Mask); 338 339 340 // MVPConf0 341 MVPConf0Reg mvpConf0 = readMiscRegNoEffect(MISCREG_MVP_CONF0); 342 mvpConf0.tca = 1; 343 mvpConf0.pvpe = numVpes - 1; 344 mvpConf0.ptc = numThreads - 1; 345 setMiscRegNoEffect(MISCREG_MVP_CONF0, mvpConf0); 346 347 // VPEConf0 348 VPEConf0Reg vpeConf0 = readMiscRegNoEffect(MISCREG_VPE_CONF0); 349 vpeConf0.mvp = 1; 350 setMiscRegNoEffect(MISCREG_VPE_CONF0, vpeConf0); 351 352 // TCBind 353 for (ThreadID tid = 0; tid < numThreads; tid++) { 354 TCBindReg tcBind = readMiscRegNoEffect(MISCREG_TC_BIND, tid); 355 tcBind.curTC = tid; 356 setMiscRegNoEffect(MISCREG_TC_BIND, tcBind, tid); 357 } 358 // TCHalt 359 TCHaltReg tcHalt = readMiscRegNoEffect(MISCREG_TC_HALT); 360 tcHalt.h = 0; 361 setMiscRegNoEffect(MISCREG_TC_HALT, tcHalt); 362 363 // TCStatus 364 // Set TCStatus Activated to 1 for the initial thread that is running 365 TCStatusReg tcStatus = readMiscRegNoEffect(MISCREG_TC_STATUS); 366 tcStatus.a = 1; 367 setMiscRegNoEffect(MISCREG_TC_STATUS, tcStatus); 368 369 // Set Dynamically Allocatable bit to 1 for all other threads 370 for (ThreadID tid = 1; tid < numThreads; tid++) { 371 tcStatus = readMiscRegNoEffect(MISCREG_TC_STATUS, tid); 372 tcStatus.da = 1; 373 setMiscRegNoEffect(MISCREG_TC_STATUS, tcStatus, tid); 374 } 375 376 377 MiscReg mask = 0x7FFFFFFF; 378 379 // Now, create Write Mask for the Index register 380 replaceBits(mask, 0, 32, 0); 381 setRegMask(MISCREG_INDEX, mask); 382 383 mask = 0x3FFFFFFF; 384 replaceBits(mask, 0, 32, 0); 385 setRegMask(MISCREG_ENTRYLO0, mask); 386 setRegMask(MISCREG_ENTRYLO1, mask); 387 388 mask = 0xFF800000; 389 replaceBits(mask, 0, 32, 0); 390 setRegMask(MISCREG_CONTEXT, mask); 391 392 mask = 0x1FFFF800; 393 replaceBits(mask, 0, 32, 0); 394 setRegMask(MISCREG_PAGEMASK, mask); 395 396 mask = 0x0; 397 replaceBits(mask, 0, 32, 0); 398 setRegMask(MISCREG_BADVADDR, mask); 399 setRegMask(MISCREG_LLADDR, mask); 400 401 mask = 0x08C00300; 402 replaceBits(mask, 0, 32, 0); 403 setRegMask(MISCREG_CAUSE, mask); 404 405} 406 407inline unsigned 408ISA::getVPENum(ThreadID tid) 409{ 410 TCBindReg tcBind = miscRegFile[MISCREG_TC_BIND][tid]; 411 return tcBind.curVPE; 412} 413 414MiscReg 415ISA::readMiscRegNoEffect(int misc_reg, ThreadID tid) 416{ 417 unsigned reg_sel = (bankType[misc_reg] == perThreadContext) 418 ? tid : getVPENum(tid); 419 DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) (%lx).\n", 420 misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], 421 miscRegFile[misc_reg][reg_sel]); 422 return miscRegFile[misc_reg][reg_sel]; 423} 424 425//@TODO: MIPS MT's register view automatically connects 426// Status to TCStatus depending on current thread 427//template <class TC> 428MiscReg 429ISA::readMiscReg(int misc_reg, ThreadContext *tc, ThreadID tid) 430{ 431 unsigned reg_sel = (bankType[misc_reg] == perThreadContext) 432 ? tid : getVPENum(tid); 433 DPRINTF(MipsPRA, 434 "Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n", 435 misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], 436 miscRegFile[misc_reg][reg_sel]); 437 438 return miscRegFile[misc_reg][reg_sel]; 439} 440 441void 442ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val, ThreadID tid) 443{ 444 unsigned reg_sel = (bankType[misc_reg] == perThreadContext) 445 ? tid : getVPENum(tid); 446 DPRINTF(MipsPRA, 447 "[tid:%i]: Setting (direct set) CP0 Register:%u " 448 "Select:%u (%s) to %#x.\n", 449 tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val); 450 451 miscRegFile[misc_reg][reg_sel] = val; 452} 453 454void 455ISA::setRegMask(int misc_reg, const MiscReg &val, ThreadID tid) 456{ 457 unsigned reg_sel = (bankType[misc_reg] == perThreadContext) 458 ? tid : getVPENum(tid); 459 DPRINTF(MipsPRA, 460 "[tid:%i]: Setting CP0 Register: %u Select: %u (%s) to %#x\n", 461 tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val); 462 miscRegFile_WriteMask[misc_reg][reg_sel] = val; 463} 464 465// PROGRAMMER'S NOTES: 466// (1) Some CP0 Registers have fields that cannot 467// be overwritten. Make sure to handle those particular registers 468// with care! 469void 470ISA::setMiscReg(int misc_reg, const MiscReg &val, 471 ThreadContext *tc, ThreadID tid) 472{ 473 int reg_sel = (bankType[misc_reg] == perThreadContext) 474 ? tid : getVPENum(tid); 475 476 DPRINTF(MipsPRA, 477 "[tid:%i]: Setting CP0 Register:%u " 478 "Select:%u (%s) to %#x, with effect.\n", 479 tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val); 480 481 MiscReg cp0_val = filterCP0Write(misc_reg, reg_sel, val); 482 483 miscRegFile[misc_reg][reg_sel] = cp0_val; 484 485 scheduleCP0Update(tc->getCpuPtr(), Cycles(1)); 486} 487 488/** 489 * This method doesn't need to adjust the Control Register Offset 490 * since it has already been done in the calling method 491 * (setRegWithEffect) 492*/ 493MiscReg 494ISA::filterCP0Write(int misc_reg, int reg_sel, const MiscReg &val) 495{ 496 MiscReg retVal = val; 497 498 // Mask off read-only regions 499 retVal &= miscRegFile_WriteMask[misc_reg][reg_sel]; 500 MiscReg curVal = miscRegFile[misc_reg][reg_sel]; 501 // Mask off current alue with inverse mask (clear writeable bits) 502 curVal &= (~miscRegFile_WriteMask[misc_reg][reg_sel]); 503 retVal |= curVal; // Combine the two 504 DPRINTF(MipsPRA, 505 "filterCP0Write: Mask: %lx, Inverse Mask: %lx, write Val: %x, " 506 "current val: %lx, written val: %x\n", 507 miscRegFile_WriteMask[misc_reg][reg_sel], 508 ~miscRegFile_WriteMask[misc_reg][reg_sel], 509 val, miscRegFile[misc_reg][reg_sel], retVal); 510 return retVal; 511} 512 513void 514ISA::scheduleCP0Update(BaseCPU *cpu, Cycles delay) 515{ 516 if (!cp0Updated) { 517 cp0Updated = true; 518 519 //schedule UPDATE 520 CP0Event *cp0_event = new CP0Event(this, cpu, UpdateCP0); 521 cpu->schedule(cp0_event, cpu->clockEdge(delay)); 522 } 523} 524 525void 526ISA::updateCPU(BaseCPU *cpu) 527{ 528 /////////////////////////////////////////////////////////////////// 529 // 530 // EVALUATE CP0 STATE FOR MIPS MT 531 // 532 /////////////////////////////////////////////////////////////////// 533 MVPConf0Reg mvpConf0 = readMiscRegNoEffect(MISCREG_MVP_CONF0); 534 ThreadID num_threads = mvpConf0.ptc + 1; 535 536 for (ThreadID tid = 0; tid < num_threads; tid++) { 537 TCStatusReg tcStatus = readMiscRegNoEffect(MISCREG_TC_STATUS, tid); 538 TCHaltReg tcHalt = readMiscRegNoEffect(MISCREG_TC_HALT, tid); 539 540 //@todo: add vpe/mt check here thru mvpcontrol & vpecontrol regs 541 if (tcHalt.h == 1 || tcStatus.a == 0) { 542 haltThread(cpu->getContext(tid)); 543 } else if (tcHalt.h == 0 && tcStatus.a == 1) { 544 restoreThread(cpu->getContext(tid)); 545 } 546 } 547 548 num_threads = mvpConf0.ptc + 1; 549 550 // Toggle update flag after we finished updating 551 cp0Updated = false; 552} 553 554ISA::CP0Event::CP0Event(CP0 *_cp0, BaseCPU *_cpu, CP0EventType e_type) 555 : Event(CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), cp0EventType(e_type) 556{ } 557 558void 559ISA::CP0Event::process() 560{ 561 switch (cp0EventType) 562 { 563 case UpdateCP0: 564 cp0->updateCPU(cpu); 565 break; 566 } 567} 568 569const char * 570ISA::CP0Event::description() const 571{ 572 return "Coprocessor-0 event"; 573} 574 575void 576ISA::CP0Event::scheduleEvent(Cycles delay) 577{ 578 cpu->reschedule(this, cpu->clockEdge(delay), true); 579} 580 581void 582ISA::CP0Event::unscheduleEvent() 583{ 584 if (scheduled()) 585 squash(); 586} 587 588}
| 151void 152ISA::clear() 153{ 154 for(int i = 0; i < NumMiscRegs; i++) { 155 for (int j = 0; j < miscRegFile[i].size(); j++) 156 miscRegFile[i][j] = 0; 157 158 for (int k = 0; k < miscRegFile_WriteMask[i].size(); k++) 159 miscRegFile_WriteMask[i][k] = (long unsigned int)(-1); 160 } 161} 162 163 164void 165ISA::configCP() 166{ 167 DPRINTF(MipsPRA, "Resetting CP0 State with %i TCs and %i VPEs\n", 168 numThreads, numVpes); 169 170 CoreSpecific cp; 171 panic("CP state must be set before the following code is used"); 172 173 // Do Default CP0 initialization HERE 174 175 // Do Initialization for MT cores here (eventually use 176 // core_name parameter to toggle this initialization) 177 // =================================================== 178 DPRINTF(MipsPRA, "Initializing CP0 State.... "); 179 180 PRIdReg procId = readMiscRegNoEffect(MISCREG_PRID); 181 procId.coOp = cp.CP0_PRId_CompanyOptions; 182 procId.coId = cp.CP0_PRId_CompanyID; 183 procId.procId = cp.CP0_PRId_ProcessorID; 184 procId.rev = cp.CP0_PRId_Revision; 185 setMiscRegNoEffect(MISCREG_PRID, procId); 186 187 // Now, create Write Mask for ProcID register 188 MiscReg procIDMask = 0; // Read-Only register 189 replaceBits(procIDMask, 0, 32, 0); 190 setRegMask(MISCREG_PRID, procIDMask); 191 192 // Config 193 ConfigReg cfg = readMiscRegNoEffect(MISCREG_CONFIG); 194 cfg.be = cp.CP0_Config_BE; 195 cfg.at = cp.CP0_Config_AT; 196 cfg.ar = cp.CP0_Config_AR; 197 cfg.mt = cp.CP0_Config_MT; 198 cfg.vi = cp.CP0_Config_VI; 199 cfg.m = 1; 200 setMiscRegNoEffect(MISCREG_CONFIG, cfg); 201 // Now, create Write Mask for Config register 202 MiscReg cfg_Mask = 0x7FFF0007; 203 replaceBits(cfg_Mask, 0, 32, 0); 204 setRegMask(MISCREG_CONFIG, cfg_Mask); 205 206 // Config1 207 Config1Reg cfg1 = readMiscRegNoEffect(MISCREG_CONFIG1); 208 cfg1.mmuSize = cp.CP0_Config1_MMU; 209 cfg1.is = cp.CP0_Config1_IS; 210 cfg1.il = cp.CP0_Config1_IL; 211 cfg1.ia = cp.CP0_Config1_IA; 212 cfg1.ds = cp.CP0_Config1_DS; 213 cfg1.dl = cp.CP0_Config1_DL; 214 cfg1.da = cp.CP0_Config1_DA; 215 cfg1.fp = cp.CP0_Config1_FP; 216 cfg1.ep = cp.CP0_Config1_EP; 217 cfg1.wr = cp.CP0_Config1_WR; 218 cfg1.md = cp.CP0_Config1_MD; 219 cfg1.c2 = cp.CP0_Config1_C2; 220 cfg1.pc = cp.CP0_Config1_PC; 221 cfg1.m = cp.CP0_Config1_M; 222 setMiscRegNoEffect(MISCREG_CONFIG1, cfg1); 223 // Now, create Write Mask for Config register 224 MiscReg cfg1_Mask = 0; // Read Only Register 225 replaceBits(cfg1_Mask, 0, 32, 0); 226 setRegMask(MISCREG_CONFIG1, cfg1_Mask); 227 228 // Config2 229 Config2Reg cfg2 = readMiscRegNoEffect(MISCREG_CONFIG2); 230 cfg2.tu = cp.CP0_Config2_TU; 231 cfg2.ts = cp.CP0_Config2_TS; 232 cfg2.tl = cp.CP0_Config2_TL; 233 cfg2.ta = cp.CP0_Config2_TA; 234 cfg2.su = cp.CP0_Config2_SU; 235 cfg2.ss = cp.CP0_Config2_SS; 236 cfg2.sl = cp.CP0_Config2_SL; 237 cfg2.sa = cp.CP0_Config2_SA; 238 cfg2.m = cp.CP0_Config2_M; 239 setMiscRegNoEffect(MISCREG_CONFIG2, cfg2); 240 // Now, create Write Mask for Config register 241 MiscReg cfg2_Mask = 0x7000F000; // Read Only Register 242 replaceBits(cfg2_Mask, 0, 32, 0); 243 setRegMask(MISCREG_CONFIG2, cfg2_Mask); 244 245 // Config3 246 Config3Reg cfg3 = readMiscRegNoEffect(MISCREG_CONFIG3); 247 cfg3.dspp = cp.CP0_Config3_DSPP; 248 cfg3.lpa = cp.CP0_Config3_LPA; 249 cfg3.veic = cp.CP0_Config3_VEIC; 250 cfg3.vint = cp.CP0_Config3_VInt; 251 cfg3.sp = cp.CP0_Config3_SP; 252 cfg3.mt = cp.CP0_Config3_MT; 253 cfg3.sm = cp.CP0_Config3_SM; 254 cfg3.tl = cp.CP0_Config3_TL; 255 setMiscRegNoEffect(MISCREG_CONFIG3, cfg3); 256 // Now, create Write Mask for Config register 257 MiscReg cfg3_Mask = 0; // Read Only Register 258 replaceBits(cfg3_Mask, 0, 32, 0); 259 setRegMask(MISCREG_CONFIG3, cfg3_Mask); 260 261 // EBase - CPUNum 262 EBaseReg eBase = readMiscRegNoEffect(MISCREG_EBASE); 263 eBase.cpuNum = cp.CP0_EBase_CPUNum; 264 replaceBits(eBase, 31, 31, 1); 265 setMiscRegNoEffect(MISCREG_EBASE, eBase); 266 // Now, create Write Mask for Config register 267 MiscReg EB_Mask = 0x3FFFF000;// Except Exception Base, the 268 // entire register is read only 269 replaceBits(EB_Mask, 0, 32, 0); 270 setRegMask(MISCREG_EBASE, EB_Mask); 271 272 // SRS Control - HSS (Highest Shadow Set) 273 SRSCtlReg scsCtl = readMiscRegNoEffect(MISCREG_SRSCTL); 274 scsCtl.hss = cp.CP0_SrsCtl_HSS; 275 setMiscRegNoEffect(MISCREG_SRSCTL, scsCtl); 276 // Now, create Write Mask for the SRS Ctl register 277 MiscReg SC_Mask = 0x0000F3C0; 278 replaceBits(SC_Mask, 0, 32, 0); 279 setRegMask(MISCREG_SRSCTL, SC_Mask); 280 281 // IntCtl - IPTI, IPPCI 282 IntCtlReg intCtl = readMiscRegNoEffect(MISCREG_INTCTL); 283 intCtl.ipti = cp.CP0_IntCtl_IPTI; 284 intCtl.ippci = cp.CP0_IntCtl_IPPCI; 285 setMiscRegNoEffect(MISCREG_INTCTL, intCtl); 286 // Now, create Write Mask for the IntCtl register 287 MiscReg IC_Mask = 0x000003E0; 288 replaceBits(IC_Mask, 0, 32, 0); 289 setRegMask(MISCREG_INTCTL, IC_Mask); 290 291 // Watch Hi - M - FIXME (More than 1 Watch register) 292 WatchHiReg watchHi = readMiscRegNoEffect(MISCREG_WATCHHI0); 293 watchHi.m = cp.CP0_WatchHi_M; 294 setMiscRegNoEffect(MISCREG_WATCHHI0, watchHi); 295 // Now, create Write Mask for the IntCtl register 296 MiscReg wh_Mask = 0x7FFF0FFF; 297 replaceBits(wh_Mask, 0, 32, 0); 298 setRegMask(MISCREG_WATCHHI0, wh_Mask); 299 300 // Perf Ctr - M - FIXME (More than 1 PerfCnt Pair) 301 PerfCntCtlReg perfCntCtl = readMiscRegNoEffect(MISCREG_PERFCNT0); 302 perfCntCtl.m = cp.CP0_PerfCtr_M; 303 perfCntCtl.w = cp.CP0_PerfCtr_W; 304 setMiscRegNoEffect(MISCREG_PERFCNT0, perfCntCtl); 305 // Now, create Write Mask for the IntCtl register 306 MiscReg pc_Mask = 0x00007FF; 307 replaceBits(pc_Mask, 0, 32, 0); 308 setRegMask(MISCREG_PERFCNT0, pc_Mask); 309 310 // Random 311 setMiscRegNoEffect(MISCREG_CP0_RANDOM, 63); 312 // Now, create Write Mask for the IntCtl register 313 MiscReg random_Mask = 0; 314 replaceBits(random_Mask, 0, 32, 0); 315 setRegMask(MISCREG_CP0_RANDOM, random_Mask); 316 317 // PageGrain 318 PageGrainReg pageGrain = readMiscRegNoEffect(MISCREG_PAGEGRAIN); 319 pageGrain.esp = cp.CP0_Config3_SP; 320 setMiscRegNoEffect(MISCREG_PAGEGRAIN, pageGrain); 321 // Now, create Write Mask for the IntCtl register 322 MiscReg pg_Mask = 0x10000000; 323 replaceBits(pg_Mask, 0, 32, 0); 324 setRegMask(MISCREG_PAGEGRAIN, pg_Mask); 325 326 // Status 327 StatusReg status = readMiscRegNoEffect(MISCREG_STATUS); 328 // Only CU0 and IE are modified on a reset - everything else needs 329 // to be controlled on a per CPU model basis 330 331 // Enable CP0 on reset 332 // status.cu0 = 1; 333 334 // Enable ERL bit on a reset 335 status.erl = 1; 336 // Enable BEV bit on a reset 337 status.bev = 1; 338 339 setMiscRegNoEffect(MISCREG_STATUS, status); 340 // Now, create Write Mask for the Status register 341 MiscReg stat_Mask = 0xFF78FF17; 342 replaceBits(stat_Mask, 0, 32, 0); 343 setRegMask(MISCREG_STATUS, stat_Mask); 344 345 346 // MVPConf0 347 MVPConf0Reg mvpConf0 = readMiscRegNoEffect(MISCREG_MVP_CONF0); 348 mvpConf0.tca = 1; 349 mvpConf0.pvpe = numVpes - 1; 350 mvpConf0.ptc = numThreads - 1; 351 setMiscRegNoEffect(MISCREG_MVP_CONF0, mvpConf0); 352 353 // VPEConf0 354 VPEConf0Reg vpeConf0 = readMiscRegNoEffect(MISCREG_VPE_CONF0); 355 vpeConf0.mvp = 1; 356 setMiscRegNoEffect(MISCREG_VPE_CONF0, vpeConf0); 357 358 // TCBind 359 for (ThreadID tid = 0; tid < numThreads; tid++) { 360 TCBindReg tcBind = readMiscRegNoEffect(MISCREG_TC_BIND, tid); 361 tcBind.curTC = tid; 362 setMiscRegNoEffect(MISCREG_TC_BIND, tcBind, tid); 363 } 364 // TCHalt 365 TCHaltReg tcHalt = readMiscRegNoEffect(MISCREG_TC_HALT); 366 tcHalt.h = 0; 367 setMiscRegNoEffect(MISCREG_TC_HALT, tcHalt); 368 369 // TCStatus 370 // Set TCStatus Activated to 1 for the initial thread that is running 371 TCStatusReg tcStatus = readMiscRegNoEffect(MISCREG_TC_STATUS); 372 tcStatus.a = 1; 373 setMiscRegNoEffect(MISCREG_TC_STATUS, tcStatus); 374 375 // Set Dynamically Allocatable bit to 1 for all other threads 376 for (ThreadID tid = 1; tid < numThreads; tid++) { 377 tcStatus = readMiscRegNoEffect(MISCREG_TC_STATUS, tid); 378 tcStatus.da = 1; 379 setMiscRegNoEffect(MISCREG_TC_STATUS, tcStatus, tid); 380 } 381 382 383 MiscReg mask = 0x7FFFFFFF; 384 385 // Now, create Write Mask for the Index register 386 replaceBits(mask, 0, 32, 0); 387 setRegMask(MISCREG_INDEX, mask); 388 389 mask = 0x3FFFFFFF; 390 replaceBits(mask, 0, 32, 0); 391 setRegMask(MISCREG_ENTRYLO0, mask); 392 setRegMask(MISCREG_ENTRYLO1, mask); 393 394 mask = 0xFF800000; 395 replaceBits(mask, 0, 32, 0); 396 setRegMask(MISCREG_CONTEXT, mask); 397 398 mask = 0x1FFFF800; 399 replaceBits(mask, 0, 32, 0); 400 setRegMask(MISCREG_PAGEMASK, mask); 401 402 mask = 0x0; 403 replaceBits(mask, 0, 32, 0); 404 setRegMask(MISCREG_BADVADDR, mask); 405 setRegMask(MISCREG_LLADDR, mask); 406 407 mask = 0x08C00300; 408 replaceBits(mask, 0, 32, 0); 409 setRegMask(MISCREG_CAUSE, mask); 410 411} 412 413inline unsigned 414ISA::getVPENum(ThreadID tid) 415{ 416 TCBindReg tcBind = miscRegFile[MISCREG_TC_BIND][tid]; 417 return tcBind.curVPE; 418} 419 420MiscReg 421ISA::readMiscRegNoEffect(int misc_reg, ThreadID tid) 422{ 423 unsigned reg_sel = (bankType[misc_reg] == perThreadContext) 424 ? tid : getVPENum(tid); 425 DPRINTF(MipsPRA, "Reading CP0 Register:%u Select:%u (%s) (%lx).\n", 426 misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], 427 miscRegFile[misc_reg][reg_sel]); 428 return miscRegFile[misc_reg][reg_sel]; 429} 430 431//@TODO: MIPS MT's register view automatically connects 432// Status to TCStatus depending on current thread 433//template <class TC> 434MiscReg 435ISA::readMiscReg(int misc_reg, ThreadContext *tc, ThreadID tid) 436{ 437 unsigned reg_sel = (bankType[misc_reg] == perThreadContext) 438 ? tid : getVPENum(tid); 439 DPRINTF(MipsPRA, 440 "Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n", 441 misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], 442 miscRegFile[misc_reg][reg_sel]); 443 444 return miscRegFile[misc_reg][reg_sel]; 445} 446 447void 448ISA::setMiscRegNoEffect(int misc_reg, const MiscReg &val, ThreadID tid) 449{ 450 unsigned reg_sel = (bankType[misc_reg] == perThreadContext) 451 ? tid : getVPENum(tid); 452 DPRINTF(MipsPRA, 453 "[tid:%i]: Setting (direct set) CP0 Register:%u " 454 "Select:%u (%s) to %#x.\n", 455 tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val); 456 457 miscRegFile[misc_reg][reg_sel] = val; 458} 459 460void 461ISA::setRegMask(int misc_reg, const MiscReg &val, ThreadID tid) 462{ 463 unsigned reg_sel = (bankType[misc_reg] == perThreadContext) 464 ? tid : getVPENum(tid); 465 DPRINTF(MipsPRA, 466 "[tid:%i]: Setting CP0 Register: %u Select: %u (%s) to %#x\n", 467 tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val); 468 miscRegFile_WriteMask[misc_reg][reg_sel] = val; 469} 470 471// PROGRAMMER'S NOTES: 472// (1) Some CP0 Registers have fields that cannot 473// be overwritten. Make sure to handle those particular registers 474// with care! 475void 476ISA::setMiscReg(int misc_reg, const MiscReg &val, 477 ThreadContext *tc, ThreadID tid) 478{ 479 int reg_sel = (bankType[misc_reg] == perThreadContext) 480 ? tid : getVPENum(tid); 481 482 DPRINTF(MipsPRA, 483 "[tid:%i]: Setting CP0 Register:%u " 484 "Select:%u (%s) to %#x, with effect.\n", 485 tid, misc_reg / 8, misc_reg % 8, miscRegNames[misc_reg], val); 486 487 MiscReg cp0_val = filterCP0Write(misc_reg, reg_sel, val); 488 489 miscRegFile[misc_reg][reg_sel] = cp0_val; 490 491 scheduleCP0Update(tc->getCpuPtr(), Cycles(1)); 492} 493 494/** 495 * This method doesn't need to adjust the Control Register Offset 496 * since it has already been done in the calling method 497 * (setRegWithEffect) 498*/ 499MiscReg 500ISA::filterCP0Write(int misc_reg, int reg_sel, const MiscReg &val) 501{ 502 MiscReg retVal = val; 503 504 // Mask off read-only regions 505 retVal &= miscRegFile_WriteMask[misc_reg][reg_sel]; 506 MiscReg curVal = miscRegFile[misc_reg][reg_sel]; 507 // Mask off current alue with inverse mask (clear writeable bits) 508 curVal &= (~miscRegFile_WriteMask[misc_reg][reg_sel]); 509 retVal |= curVal; // Combine the two 510 DPRINTF(MipsPRA, 511 "filterCP0Write: Mask: %lx, Inverse Mask: %lx, write Val: %x, " 512 "current val: %lx, written val: %x\n", 513 miscRegFile_WriteMask[misc_reg][reg_sel], 514 ~miscRegFile_WriteMask[misc_reg][reg_sel], 515 val, miscRegFile[misc_reg][reg_sel], retVal); 516 return retVal; 517} 518 519void 520ISA::scheduleCP0Update(BaseCPU *cpu, Cycles delay) 521{ 522 if (!cp0Updated) { 523 cp0Updated = true; 524 525 //schedule UPDATE 526 CP0Event *cp0_event = new CP0Event(this, cpu, UpdateCP0); 527 cpu->schedule(cp0_event, cpu->clockEdge(delay)); 528 } 529} 530 531void 532ISA::updateCPU(BaseCPU *cpu) 533{ 534 /////////////////////////////////////////////////////////////////// 535 // 536 // EVALUATE CP0 STATE FOR MIPS MT 537 // 538 /////////////////////////////////////////////////////////////////// 539 MVPConf0Reg mvpConf0 = readMiscRegNoEffect(MISCREG_MVP_CONF0); 540 ThreadID num_threads = mvpConf0.ptc + 1; 541 542 for (ThreadID tid = 0; tid < num_threads; tid++) { 543 TCStatusReg tcStatus = readMiscRegNoEffect(MISCREG_TC_STATUS, tid); 544 TCHaltReg tcHalt = readMiscRegNoEffect(MISCREG_TC_HALT, tid); 545 546 //@todo: add vpe/mt check here thru mvpcontrol & vpecontrol regs 547 if (tcHalt.h == 1 || tcStatus.a == 0) { 548 haltThread(cpu->getContext(tid)); 549 } else if (tcHalt.h == 0 && tcStatus.a == 1) { 550 restoreThread(cpu->getContext(tid)); 551 } 552 } 553 554 num_threads = mvpConf0.ptc + 1; 555 556 // Toggle update flag after we finished updating 557 cp0Updated = false; 558} 559 560ISA::CP0Event::CP0Event(CP0 *_cp0, BaseCPU *_cpu, CP0EventType e_type) 561 : Event(CPU_Tick_Pri), cp0(_cp0), cpu(_cpu), cp0EventType(e_type) 562{ } 563 564void 565ISA::CP0Event::process() 566{ 567 switch (cp0EventType) 568 { 569 case UpdateCP0: 570 cp0->updateCPU(cpu); 571 break; 572 } 573} 574 575const char * 576ISA::CP0Event::description() const 577{ 578 return "Coprocessor-0 event"; 579} 580 581void 582ISA::CP0Event::scheduleEvent(Cycles delay) 583{ 584 cpu->reschedule(this, cpu->clockEdge(delay), true); 585} 586 587void 588ISA::CP0Event::unscheduleEvent() 589{ 590 if (scheduled()) 591 squash(); 592} 593 594}
|