2 * Copyright (c) 2009 The Regents of The University of Michigan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "arch/mips/isa.hh"
32 #include "arch/mips/mt.hh"
33 #include "arch/mips/mt_constants.hh"
34 #include "arch/mips/pra_constants.hh"
35 #include "base/bitfield.hh"
36 #include "cpu/base.hh"
37 #include "cpu/thread_context.hh"
38 #include "debug/MipsPRA.hh"
39 #include "params/MipsISA.hh"
45 ISA::miscRegNames
[NumMiscRegs
] =
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", "", "", "", "", "", "", "",
92 : SimObject(p
), numThreads(p
->num_threads
), numVpes(p
->num_vpes
)
94 miscRegFile
.resize(NumMiscRegs
);
95 bankType
.resize(NumMiscRegs
);
97 for (int i
=0; i
< NumMiscRegs
; i
++) {
98 miscRegFile
[i
].resize(1);
99 bankType
[i
] = perProcessor
;
102 miscRegFile_WriteMask
.resize(NumMiscRegs
);
104 for (int i
= 0; i
< NumMiscRegs
; i
++) {
105 miscRegFile_WriteMask
[i
].push_back(0);
108 // Initialize all Per-VPE regs
109 uint32_t per_vpe_regs
[] = { MISCREG_VPE_CONTROL
,
110 MISCREG_VPE_CONF0
, MISCREG_VPE_CONF1
,
112 MISCREG_VPE_SCHEDULE
, MISCREG_VPE_SCHEFBACK
,
113 MISCREG_VPE_OPT
, MISCREG_SRS_CONF0
,
114 MISCREG_SRS_CONF1
, MISCREG_SRS_CONF2
,
115 MISCREG_SRS_CONF3
, MISCREG_SRS_CONF4
,
118 uint32_t num_vpe_regs
= sizeof(per_vpe_regs
) / 4;
119 for (int i
= 0; i
< num_vpe_regs
; i
++) {
121 miscRegFile
[per_vpe_regs
[i
]].resize(numVpes
);
123 bankType
[per_vpe_regs
[i
]] = perVirtProcessor
;
126 // Initialize all Per-TC regs
127 uint32_t per_tc_regs
[] = { MISCREG_STATUS
,
128 MISCREG_TC_STATUS
, MISCREG_TC_BIND
,
129 MISCREG_TC_RESTART
, MISCREG_TC_HALT
,
130 MISCREG_TC_CONTEXT
, MISCREG_TC_SCHEDULE
,
131 MISCREG_TC_SCHEFBACK
,
132 MISCREG_DEBUG
, MISCREG_LLADDR
134 uint32_t num_tc_regs
= sizeof(per_tc_regs
) / 4;
136 for (int i
= 0; i
< num_tc_regs
; i
++) {
137 miscRegFile
[per_tc_regs
[i
]].resize(numThreads
);
138 bankType
[per_tc_regs
[i
]] = perThreadContext
;
144 const MipsISAParams
*
147 return dynamic_cast<const Params
*>(_params
);
153 for (int i
= 0; i
< NumMiscRegs
; i
++) {
154 for (int j
= 0; j
< miscRegFile
[i
].size(); j
++)
155 miscRegFile
[i
][j
] = 0;
157 for (int k
= 0; k
< miscRegFile_WriteMask
[i
].size(); k
++)
158 miscRegFile_WriteMask
[i
][k
] = (long unsigned int)(-1);
166 DPRINTF(MipsPRA
, "Resetting CP0 State with %i TCs and %i VPEs\n",
167 numThreads
, numVpes
);
170 panic("CP state must be set before the following code is used");
172 // Do Default CP0 initialization HERE
174 // Do Initialization for MT cores here (eventually use
175 // core_name parameter to toggle this initialization)
176 // ===================================================
177 DPRINTF(MipsPRA
, "Initializing CP0 State.... ");
179 PRIdReg procId
= readMiscRegNoEffect(MISCREG_PRID
);
180 procId
.coOp
= cp
.CP0_PRId_CompanyOptions
;
181 procId
.coId
= cp
.CP0_PRId_CompanyID
;
182 procId
.procId
= cp
.CP0_PRId_ProcessorID
;
183 procId
.rev
= cp
.CP0_PRId_Revision
;
184 setMiscRegNoEffect(MISCREG_PRID
, procId
);
186 // Now, create Write Mask for ProcID register
187 MiscReg procIDMask
= 0; // Read-Only register
188 replaceBits(procIDMask
, 0, 32, 0);
189 setRegMask(MISCREG_PRID
, procIDMask
);
192 ConfigReg cfg
= readMiscRegNoEffect(MISCREG_CONFIG
);
193 cfg
.be
= cp
.CP0_Config_BE
;
194 cfg
.at
= cp
.CP0_Config_AT
;
195 cfg
.ar
= cp
.CP0_Config_AR
;
196 cfg
.mt
= cp
.CP0_Config_MT
;
197 cfg
.vi
= cp
.CP0_Config_VI
;
199 setMiscRegNoEffect(MISCREG_CONFIG
, cfg
);
200 // Now, create Write Mask for Config register
201 MiscReg cfg_Mask
= 0x7FFF0007;
202 replaceBits(cfg_Mask
, 0, 32, 0);
203 setRegMask(MISCREG_CONFIG
, cfg_Mask
);
206 Config1Reg cfg1
= readMiscRegNoEffect(MISCREG_CONFIG1
);
207 cfg1
.mmuSize
= cp
.CP0_Config1_MMU
;
208 cfg1
.is
= cp
.CP0_Config1_IS
;
209 cfg1
.il
= cp
.CP0_Config1_IL
;
210 cfg1
.ia
= cp
.CP0_Config1_IA
;
211 cfg1
.ds
= cp
.CP0_Config1_DS
;
212 cfg1
.dl
= cp
.CP0_Config1_DL
;
213 cfg1
.da
= cp
.CP0_Config1_DA
;
214 cfg1
.fp
= cp
.CP0_Config1_FP
;
215 cfg1
.ep
= cp
.CP0_Config1_EP
;
216 cfg1
.wr
= cp
.CP0_Config1_WR
;
217 cfg1
.md
= cp
.CP0_Config1_MD
;
218 cfg1
.c2
= cp
.CP0_Config1_C2
;
219 cfg1
.pc
= cp
.CP0_Config1_PC
;
220 cfg1
.m
= cp
.CP0_Config1_M
;
221 setMiscRegNoEffect(MISCREG_CONFIG1
, cfg1
);
222 // Now, create Write Mask for Config register
223 MiscReg cfg1_Mask
= 0; // Read Only Register
224 replaceBits(cfg1_Mask
, 0, 32, 0);
225 setRegMask(MISCREG_CONFIG1
, cfg1_Mask
);
228 Config2Reg cfg2
= readMiscRegNoEffect(MISCREG_CONFIG2
);
229 cfg2
.tu
= cp
.CP0_Config2_TU
;
230 cfg2
.ts
= cp
.CP0_Config2_TS
;
231 cfg2
.tl
= cp
.CP0_Config2_TL
;
232 cfg2
.ta
= cp
.CP0_Config2_TA
;
233 cfg2
.su
= cp
.CP0_Config2_SU
;
234 cfg2
.ss
= cp
.CP0_Config2_SS
;
235 cfg2
.sl
= cp
.CP0_Config2_SL
;
236 cfg2
.sa
= cp
.CP0_Config2_SA
;
237 cfg2
.m
= cp
.CP0_Config2_M
;
238 setMiscRegNoEffect(MISCREG_CONFIG2
, cfg2
);
239 // Now, create Write Mask for Config register
240 MiscReg cfg2_Mask
= 0x7000F000; // Read Only Register
241 replaceBits(cfg2_Mask
, 0, 32, 0);
242 setRegMask(MISCREG_CONFIG2
, cfg2_Mask
);
245 Config3Reg cfg3
= readMiscRegNoEffect(MISCREG_CONFIG3
);
246 cfg3
.dspp
= cp
.CP0_Config3_DSPP
;
247 cfg3
.lpa
= cp
.CP0_Config3_LPA
;
248 cfg3
.veic
= cp
.CP0_Config3_VEIC
;
249 cfg3
.vint
= cp
.CP0_Config3_VInt
;
250 cfg3
.sp
= cp
.CP0_Config3_SP
;
251 cfg3
.mt
= cp
.CP0_Config3_MT
;
252 cfg3
.sm
= cp
.CP0_Config3_SM
;
253 cfg3
.tl
= cp
.CP0_Config3_TL
;
254 setMiscRegNoEffect(MISCREG_CONFIG3
, cfg3
);
255 // Now, create Write Mask for Config register
256 MiscReg cfg3_Mask
= 0; // Read Only Register
257 replaceBits(cfg3_Mask
, 0, 32, 0);
258 setRegMask(MISCREG_CONFIG3
, cfg3_Mask
);
261 EBaseReg eBase
= readMiscRegNoEffect(MISCREG_EBASE
);
262 eBase
.cpuNum
= cp
.CP0_EBase_CPUNum
;
263 replaceBits(eBase
, 31, 31, 1);
264 setMiscRegNoEffect(MISCREG_EBASE
, eBase
);
265 // Now, create Write Mask for Config register
266 MiscReg EB_Mask
= 0x3FFFF000;// Except Exception Base, the
267 // entire register is read only
268 replaceBits(EB_Mask
, 0, 32, 0);
269 setRegMask(MISCREG_EBASE
, EB_Mask
);
271 // SRS Control - HSS (Highest Shadow Set)
272 SRSCtlReg scsCtl
= readMiscRegNoEffect(MISCREG_SRSCTL
);
273 scsCtl
.hss
= cp
.CP0_SrsCtl_HSS
;
274 setMiscRegNoEffect(MISCREG_SRSCTL
, scsCtl
);
275 // Now, create Write Mask for the SRS Ctl register
276 MiscReg SC_Mask
= 0x0000F3C0;
277 replaceBits(SC_Mask
, 0, 32, 0);
278 setRegMask(MISCREG_SRSCTL
, SC_Mask
);
280 // IntCtl - IPTI, IPPCI
281 IntCtlReg intCtl
= readMiscRegNoEffect(MISCREG_INTCTL
);
282 intCtl
.ipti
= cp
.CP0_IntCtl_IPTI
;
283 intCtl
.ippci
= cp
.CP0_IntCtl_IPPCI
;
284 setMiscRegNoEffect(MISCREG_INTCTL
, intCtl
);
285 // Now, create Write Mask for the IntCtl register
286 MiscReg IC_Mask
= 0x000003E0;
287 replaceBits(IC_Mask
, 0, 32, 0);
288 setRegMask(MISCREG_INTCTL
, IC_Mask
);
290 // Watch Hi - M - FIXME (More than 1 Watch register)
291 WatchHiReg watchHi
= readMiscRegNoEffect(MISCREG_WATCHHI0
);
292 watchHi
.m
= cp
.CP0_WatchHi_M
;
293 setMiscRegNoEffect(MISCREG_WATCHHI0
, watchHi
);
294 // Now, create Write Mask for the IntCtl register
295 MiscReg wh_Mask
= 0x7FFF0FFF;
296 replaceBits(wh_Mask
, 0, 32, 0);
297 setRegMask(MISCREG_WATCHHI0
, wh_Mask
);
299 // Perf Ctr - M - FIXME (More than 1 PerfCnt Pair)
300 PerfCntCtlReg perfCntCtl
= readMiscRegNoEffect(MISCREG_PERFCNT0
);
301 perfCntCtl
.m
= cp
.CP0_PerfCtr_M
;
302 perfCntCtl
.w
= cp
.CP0_PerfCtr_W
;
303 setMiscRegNoEffect(MISCREG_PERFCNT0
, perfCntCtl
);
304 // Now, create Write Mask for the IntCtl register
305 MiscReg pc_Mask
= 0x00007FF;
306 replaceBits(pc_Mask
, 0, 32, 0);
307 setRegMask(MISCREG_PERFCNT0
, pc_Mask
);
310 setMiscRegNoEffect(MISCREG_CP0_RANDOM
, 63);
311 // Now, create Write Mask for the IntCtl register
312 MiscReg random_Mask
= 0;
313 replaceBits(random_Mask
, 0, 32, 0);
314 setRegMask(MISCREG_CP0_RANDOM
, random_Mask
);
317 PageGrainReg pageGrain
= readMiscRegNoEffect(MISCREG_PAGEGRAIN
);
318 pageGrain
.esp
= cp
.CP0_Config3_SP
;
319 setMiscRegNoEffect(MISCREG_PAGEGRAIN
, pageGrain
);
320 // Now, create Write Mask for the IntCtl register
321 MiscReg pg_Mask
= 0x10000000;
322 replaceBits(pg_Mask
, 0, 32, 0);
323 setRegMask(MISCREG_PAGEGRAIN
, pg_Mask
);
326 StatusReg status
= readMiscRegNoEffect(MISCREG_STATUS
);
327 // Only CU0 and IE are modified on a reset - everything else needs
328 // to be controlled on a per CPU model basis
330 // Enable CP0 on reset
333 // Enable ERL bit on a reset
335 // Enable BEV bit on a reset
338 setMiscRegNoEffect(MISCREG_STATUS
, status
);
339 // Now, create Write Mask for the Status register
340 MiscReg stat_Mask
= 0xFF78FF17;
341 replaceBits(stat_Mask
, 0, 32, 0);
342 setRegMask(MISCREG_STATUS
, stat_Mask
);
346 MVPConf0Reg mvpConf0
= readMiscRegNoEffect(MISCREG_MVP_CONF0
);
348 mvpConf0
.pvpe
= numVpes
- 1;
349 mvpConf0
.ptc
= numThreads
- 1;
350 setMiscRegNoEffect(MISCREG_MVP_CONF0
, mvpConf0
);
353 VPEConf0Reg vpeConf0
= readMiscRegNoEffect(MISCREG_VPE_CONF0
);
355 setMiscRegNoEffect(MISCREG_VPE_CONF0
, vpeConf0
);
358 for (ThreadID tid
= 0; tid
< numThreads
; tid
++) {
359 TCBindReg tcBind
= readMiscRegNoEffect(MISCREG_TC_BIND
, tid
);
361 setMiscRegNoEffect(MISCREG_TC_BIND
, tcBind
, tid
);
364 TCHaltReg tcHalt
= readMiscRegNoEffect(MISCREG_TC_HALT
);
366 setMiscRegNoEffect(MISCREG_TC_HALT
, tcHalt
);
369 // Set TCStatus Activated to 1 for the initial thread that is running
370 TCStatusReg tcStatus
= readMiscRegNoEffect(MISCREG_TC_STATUS
);
372 setMiscRegNoEffect(MISCREG_TC_STATUS
, tcStatus
);
374 // Set Dynamically Allocatable bit to 1 for all other threads
375 for (ThreadID tid
= 1; tid
< numThreads
; tid
++) {
376 tcStatus
= readMiscRegNoEffect(MISCREG_TC_STATUS
, tid
);
378 setMiscRegNoEffect(MISCREG_TC_STATUS
, tcStatus
, tid
);
382 MiscReg mask
= 0x7FFFFFFF;
384 // Now, create Write Mask for the Index register
385 replaceBits(mask
, 0, 32, 0);
386 setRegMask(MISCREG_INDEX
, mask
);
389 replaceBits(mask
, 0, 32, 0);
390 setRegMask(MISCREG_ENTRYLO0
, mask
);
391 setRegMask(MISCREG_ENTRYLO1
, mask
);
394 replaceBits(mask
, 0, 32, 0);
395 setRegMask(MISCREG_CONTEXT
, mask
);
398 replaceBits(mask
, 0, 32, 0);
399 setRegMask(MISCREG_PAGEMASK
, mask
);
402 replaceBits(mask
, 0, 32, 0);
403 setRegMask(MISCREG_BADVADDR
, mask
);
404 setRegMask(MISCREG_LLADDR
, mask
);
407 replaceBits(mask
, 0, 32, 0);
408 setRegMask(MISCREG_CAUSE
, mask
);
413 ISA::getVPENum(ThreadID tid
) const
415 TCBindReg tcBind
= miscRegFile
[MISCREG_TC_BIND
][tid
];
416 return tcBind
.curVPE
;
420 ISA::readMiscRegNoEffect(int misc_reg
, ThreadID tid
) const
422 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
423 ? tid
: getVPENum(tid
);
424 DPRINTF(MipsPRA
, "Reading CP0 Register:%u Select:%u (%s) (%lx).\n",
425 misc_reg
/ 8, misc_reg
% 8, miscRegNames
[misc_reg
],
426 miscRegFile
[misc_reg
][reg_sel
]);
427 return miscRegFile
[misc_reg
][reg_sel
];
430 //@TODO: MIPS MT's register view automatically connects
431 // Status to TCStatus depending on current thread
432 //template <class TC>
434 ISA::readMiscReg(int misc_reg
, ThreadContext
*tc
, ThreadID tid
)
436 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
437 ? tid
: getVPENum(tid
);
439 "Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n",
440 misc_reg
/ 8, misc_reg
% 8, miscRegNames
[misc_reg
],
441 miscRegFile
[misc_reg
][reg_sel
]);
443 return miscRegFile
[misc_reg
][reg_sel
];
447 ISA::setMiscRegNoEffect(int misc_reg
, const MiscReg
&val
, ThreadID tid
)
449 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
450 ? tid
: getVPENum(tid
);
452 "[tid:%i]: Setting (direct set) CP0 Register:%u "
453 "Select:%u (%s) to %#x.\n",
454 tid
, misc_reg
/ 8, misc_reg
% 8, miscRegNames
[misc_reg
], val
);
456 miscRegFile
[misc_reg
][reg_sel
] = val
;
460 ISA::setRegMask(int misc_reg
, const MiscReg
&val
, ThreadID tid
)
462 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
463 ? tid
: getVPENum(tid
);
465 "[tid:%i]: Setting CP0 Register: %u Select: %u (%s) to %#x\n",
466 tid
, misc_reg
/ 8, misc_reg
% 8, miscRegNames
[misc_reg
], val
);
467 miscRegFile_WriteMask
[misc_reg
][reg_sel
] = val
;
470 // PROGRAMMER'S NOTES:
471 // (1) Some CP0 Registers have fields that cannot
472 // be overwritten. Make sure to handle those particular registers
475 ISA::setMiscReg(int misc_reg
, const MiscReg
&val
,
476 ThreadContext
*tc
, ThreadID tid
)
478 int reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
479 ? tid
: getVPENum(tid
);
482 "[tid:%i]: Setting CP0 Register:%u "
483 "Select:%u (%s) to %#x, with effect.\n",
484 tid
, misc_reg
/ 8, misc_reg
% 8, miscRegNames
[misc_reg
], val
);
486 MiscReg cp0_val
= filterCP0Write(misc_reg
, reg_sel
, val
);
488 miscRegFile
[misc_reg
][reg_sel
] = cp0_val
;
490 scheduleCP0Update(tc
->getCpuPtr(), Cycles(1));
494 * This method doesn't need to adjust the Control Register Offset
495 * since it has already been done in the calling method
499 ISA::filterCP0Write(int misc_reg
, int reg_sel
, const MiscReg
&val
)
501 MiscReg retVal
= val
;
503 // Mask off read-only regions
504 retVal
&= miscRegFile_WriteMask
[misc_reg
][reg_sel
];
505 MiscReg curVal
= miscRegFile
[misc_reg
][reg_sel
];
506 // Mask off current alue with inverse mask (clear writeable bits)
507 curVal
&= (~miscRegFile_WriteMask
[misc_reg
][reg_sel
]);
508 retVal
|= curVal
; // Combine the two
510 "filterCP0Write: Mask: %lx, Inverse Mask: %lx, write Val: %x, "
511 "current val: %lx, written val: %x\n",
512 miscRegFile_WriteMask
[misc_reg
][reg_sel
],
513 ~miscRegFile_WriteMask
[misc_reg
][reg_sel
],
514 val
, miscRegFile
[misc_reg
][reg_sel
], retVal
);
519 ISA::scheduleCP0Update(BaseCPU
*cpu
, Cycles delay
)
525 CP0Event
*cp0_event
= new CP0Event(this, cpu
, UpdateCP0
);
526 cpu
->schedule(cp0_event
, cpu
->clockEdge(delay
));
531 ISA::updateCPU(BaseCPU
*cpu
)
533 ///////////////////////////////////////////////////////////////////
535 // EVALUATE CP0 STATE FOR MIPS MT
537 ///////////////////////////////////////////////////////////////////
538 MVPConf0Reg mvpConf0
= readMiscRegNoEffect(MISCREG_MVP_CONF0
);
539 ThreadID num_threads
= mvpConf0
.ptc
+ 1;
541 for (ThreadID tid
= 0; tid
< num_threads
; tid
++) {
542 TCStatusReg tcStatus
= readMiscRegNoEffect(MISCREG_TC_STATUS
, tid
);
543 TCHaltReg tcHalt
= readMiscRegNoEffect(MISCREG_TC_HALT
, tid
);
545 //@todo: add vpe/mt check here thru mvpcontrol & vpecontrol regs
546 if (tcHalt
.h
== 1 || tcStatus
.a
== 0) {
547 haltThread(cpu
->getContext(tid
));
548 } else if (tcHalt
.h
== 0 && tcStatus
.a
== 1) {
549 restoreThread(cpu
->getContext(tid
));
553 num_threads
= mvpConf0
.ptc
+ 1;
555 // Toggle update flag after we finished updating
559 ISA::CP0Event::CP0Event(CP0
*_cp0
, BaseCPU
*_cpu
, CP0EventType e_type
)
560 : Event(CPU_Tick_Pri
), cp0(_cp0
), cpu(_cpu
), cp0EventType(e_type
)
564 ISA::CP0Event::process()
566 switch (cp0EventType
)
575 ISA::CP0Event::description() const
577 return "Coprocessor-0 event";
581 ISA::CP0Event::scheduleEvent(Cycles delay
)
583 cpu
->reschedule(this, cpu
->clockEdge(delay
), true);
587 ISA::CP0Event::unscheduleEvent()
596 MipsISAParams::create()
598 return new MipsISA::ISA(this);