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"
44 ISA::miscRegNames
[NumMiscRegs
] =
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", "", "", "", "", "", "", "",
90 ISA::ISA(uint8_t num_threads
, uint8_t num_vpes
)
92 numThreads
= num_threads
;
95 miscRegFile
.resize(NumMiscRegs
);
96 bankType
.resize(NumMiscRegs
);
98 for (int i
=0; i
< NumMiscRegs
; i
++) {
99 miscRegFile
[i
].resize(1);
100 bankType
[i
] = perProcessor
;
103 miscRegFile_WriteMask
.resize(NumMiscRegs
);
105 for (int i
= 0; i
< NumMiscRegs
; i
++) {
106 miscRegFile_WriteMask
[i
].push_back(0);
109 // Initialize all Per-VPE regs
110 uint32_t per_vpe_regs
[] = { MISCREG_VPE_CONTROL
,
111 MISCREG_VPE_CONF0
, MISCREG_VPE_CONF1
,
113 MISCREG_VPE_SCHEDULE
, MISCREG_VPE_SCHEFBACK
,
114 MISCREG_VPE_OPT
, MISCREG_SRS_CONF0
,
115 MISCREG_SRS_CONF1
, MISCREG_SRS_CONF2
,
116 MISCREG_SRS_CONF3
, MISCREG_SRS_CONF4
,
119 uint32_t num_vpe_regs
= sizeof(per_vpe_regs
) / 4;
120 for (int i
= 0; i
< num_vpe_regs
; i
++) {
122 miscRegFile
[per_vpe_regs
[i
]].resize(numVpes
);
124 bankType
[per_vpe_regs
[i
]] = perVirtProcessor
;
127 // Initialize all Per-TC regs
128 uint32_t per_tc_regs
[] = { MISCREG_STATUS
,
129 MISCREG_TC_STATUS
, MISCREG_TC_BIND
,
130 MISCREG_TC_RESTART
, MISCREG_TC_HALT
,
131 MISCREG_TC_CONTEXT
, MISCREG_TC_SCHEDULE
,
132 MISCREG_TC_SCHEFBACK
,
133 MISCREG_DEBUG
, MISCREG_LLADDR
135 uint32_t num_tc_regs
= sizeof(per_tc_regs
) / 4;
137 for (int i
= 0; i
< num_tc_regs
; i
++) {
138 miscRegFile
[per_tc_regs
[i
]].resize(numThreads
);
139 bankType
[per_tc_regs
[i
]] = perThreadContext
;
148 for(int i
= 0; i
< NumMiscRegs
; i
++) {
149 for (int j
= 0; j
< miscRegFile
[i
].size(); j
++)
150 miscRegFile
[i
][j
] = 0;
152 for (int k
= 0; k
< miscRegFile_WriteMask
[i
].size(); k
++)
153 miscRegFile_WriteMask
[i
][k
] = (long unsigned int)(-1);
161 DPRINTF(MipsPRA
, "Resetting CP0 State with %i TCs and %i VPEs\n",
162 numThreads
, numVpes
);
165 panic("CP state must be set before the following code is used");
167 // Do Default CP0 initialization HERE
169 // Do Initialization for MT cores here (eventually use
170 // core_name parameter to toggle this initialization)
171 // ===================================================
172 DPRINTF(MipsPRA
, "Initializing CP0 State.... ");
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
);
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
);
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
;
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
325 // Enable CP0 on reset
328 // Enable ERL bit on a reset
330 // Enable BEV bit on a reset
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
);
341 MVPConf0Reg mvpConf0
= readMiscRegNoEffect(MISCREG_MVP_CONF0
);
343 mvpConf0
.pvpe
= numVpes
- 1;
344 mvpConf0
.ptc
= numThreads
- 1;
345 setMiscRegNoEffect(MISCREG_MVP_CONF0
, mvpConf0
);
348 VPEConf0Reg vpeConf0
= readMiscRegNoEffect(MISCREG_VPE_CONF0
);
350 setMiscRegNoEffect(MISCREG_VPE_CONF0
, vpeConf0
);
353 for (ThreadID tid
= 0; tid
< numThreads
; tid
++) {
354 TCBindReg tcBind
= readMiscRegNoEffect(MISCREG_TC_BIND
, tid
);
356 setMiscRegNoEffect(MISCREG_TC_BIND
, tcBind
, tid
);
359 TCHaltReg tcHalt
= readMiscRegNoEffect(MISCREG_TC_HALT
);
361 setMiscRegNoEffect(MISCREG_TC_HALT
, tcHalt
);
364 // Set TCStatus Activated to 1 for the initial thread that is running
365 TCStatusReg tcStatus
= readMiscRegNoEffect(MISCREG_TC_STATUS
);
367 setMiscRegNoEffect(MISCREG_TC_STATUS
, tcStatus
);
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
);
373 setMiscRegNoEffect(MISCREG_TC_STATUS
, tcStatus
, tid
);
377 MiscReg mask
= 0x7FFFFFFF;
379 // Now, create Write Mask for the Index register
380 replaceBits(mask
, 0, 32, 0);
381 setRegMask(MISCREG_INDEX
, mask
);
384 replaceBits(mask
, 0, 32, 0);
385 setRegMask(MISCREG_ENTRYLO0
, mask
);
386 setRegMask(MISCREG_ENTRYLO1
, mask
);
389 replaceBits(mask
, 0, 32, 0);
390 setRegMask(MISCREG_CONTEXT
, mask
);
393 replaceBits(mask
, 0, 32, 0);
394 setRegMask(MISCREG_PAGEMASK
, mask
);
397 replaceBits(mask
, 0, 32, 0);
398 setRegMask(MISCREG_BADVADDR
, mask
);
399 setRegMask(MISCREG_LLADDR
, mask
);
402 replaceBits(mask
, 0, 32, 0);
403 setRegMask(MISCREG_CAUSE
, mask
);
408 ISA::getVPENum(ThreadID tid
)
410 TCBindReg tcBind
= miscRegFile
[MISCREG_TC_BIND
][tid
];
411 return tcBind
.curVPE
;
415 ISA::readMiscRegNoEffect(int misc_reg
, ThreadID tid
)
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
];
425 //@TODO: MIPS MT's register view automatically connects
426 // Status to TCStatus depending on current thread
427 //template <class TC>
429 ISA::readMiscReg(int misc_reg
, ThreadContext
*tc
, ThreadID tid
)
431 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
432 ? tid
: getVPENum(tid
);
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
]);
438 return miscRegFile
[misc_reg
][reg_sel
];
442 ISA::setMiscRegNoEffect(int misc_reg
, const MiscReg
&val
, ThreadID tid
)
444 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
445 ? tid
: getVPENum(tid
);
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
);
451 miscRegFile
[misc_reg
][reg_sel
] = val
;
455 ISA::setRegMask(int misc_reg
, const MiscReg
&val
, ThreadID tid
)
457 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
458 ? tid
: getVPENum(tid
);
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
;
465 // PROGRAMMER'S NOTES:
466 // (1) Some CP0 Registers have fields that cannot
467 // be overwritten. Make sure to handle those particular registers
470 ISA::setMiscReg(int misc_reg
, const MiscReg
&val
,
471 ThreadContext
*tc
, ThreadID tid
)
473 int reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
474 ? tid
: getVPENum(tid
);
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
);
481 MiscReg cp0_val
= filterCP0Write(misc_reg
, reg_sel
, val
);
483 miscRegFile
[misc_reg
][reg_sel
] = cp0_val
;
485 scheduleCP0Update(tc
->getCpuPtr(), Cycles(1));
489 * This method doesn't need to adjust the Control Register Offset
490 * since it has already been done in the calling method
494 ISA::filterCP0Write(int misc_reg
, int reg_sel
, const MiscReg
&val
)
496 MiscReg retVal
= val
;
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
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
);
514 ISA::scheduleCP0Update(BaseCPU
*cpu
, Cycles delay
)
520 CP0Event
*cp0_event
= new CP0Event(this, cpu
, UpdateCP0
);
521 cpu
->schedule(cp0_event
, cpu
->clockEdge(delay
));
526 ISA::updateCPU(BaseCPU
*cpu
)
528 ///////////////////////////////////////////////////////////////////
530 // EVALUATE CP0 STATE FOR MIPS MT
532 ///////////////////////////////////////////////////////////////////
533 MVPConf0Reg mvpConf0
= readMiscRegNoEffect(MISCREG_MVP_CONF0
);
534 ThreadID num_threads
= mvpConf0
.ptc
+ 1;
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
);
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
));
548 num_threads
= mvpConf0
.ptc
+ 1;
550 // Toggle update flag after we finished updating
554 ISA::CP0Event::CP0Event(CP0
*_cp0
, BaseCPU
*_cpu
, CP0EventType e_type
)
555 : Event(CPU_Tick_Pri
), cp0(_cp0
), cpu(_cpu
), cp0EventType(e_type
)
559 ISA::CP0Event::process()
561 switch (cp0EventType
)
570 ISA::CP0Event::description() const
572 return "Coprocessor-0 event";
576 ISA::CP0Event::scheduleEvent(Cycles delay
)
578 cpu
->reschedule(this, cpu
->clockEdge(delay
), true);
582 ISA::CP0Event::unscheduleEvent()