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_constants.hh"
33 #include "arch/mips/mt.hh"
34 #include "arch/mips/pra_constants.hh"
35 #include "base/bitfield.hh"
36 #include "cpu/base.hh"
37 #include "cpu/thread_context.hh"
43 ISA::miscRegNames
[NumMiscRegs
] =
45 "Index", "MVPControl", "MVPConf0", "MVPConf1", "", "", "", "",
46 "Random", "VPEControl", "VPEConf0", "VPEConf1",
47 "YQMask", "VPESchedule", "VPEScheFBack", "VPEOpt",
48 "EntryLo0", "TCStatus", "TCBind", "TCRestart",
49 "TCHalt", "TCContext", "TCSchedule", "TCScheFBack",
50 "EntryLo1", "", "", "", "", "", "", "",
51 "Context", "ContextConfig", "", "", "", "", "", "",
52 "PageMask", "PageGrain", "", "", "", "", "", "",
53 "Wired", "SRSConf0", "SRCConf1", "SRSConf2",
54 "SRSConf3", "SRSConf4", "", "",
55 "HWREna", "", "", "", "", "", "", "",
56 "BadVAddr", "", "", "", "", "", "", "",
57 "Count", "", "", "", "", "", "", "",
58 "EntryHi", "", "", "", "", "", "", "",
59 "Compare", "", "", "", "", "", "", "",
60 "Status", "IntCtl", "SRSCtl", "SRSMap", "", "", "", "",
61 "Cause", "", "", "", "", "", "", "",
62 "EPC", "", "", "", "", "", "", "",
63 "PRId", "EBase", "", "", "", "", "", "",
64 "Config", "Config1", "Config2", "Config3", "", "", "", "",
65 "LLAddr", "", "", "", "", "", "", "",
66 "WatchLo0", "WatchLo1", "WatchLo2", "WatchLo3",
67 "WatchLo4", "WatchLo5", "WatchLo6", "WatchLo7",
68 "WatchHi0", "WatchHi1", "WatchHi2", "WatchHi3",
69 "WatchHi4", "WatchHi5", "WatchHi6", "WatchHi7",
70 "XCContext64", "", "", "", "", "", "", "",
71 "", "", "", "", "", "", "", "",
72 "", "", "", "", "", "", "", "",
73 "Debug", "TraceControl1", "TraceControl2", "UserTraceData",
74 "TraceBPC", "", "", "",
75 "DEPC", "", "", "", "", "", "", "",
76 "PerfCnt0", "PerfCnt1", "PerfCnt2", "PerfCnt3",
77 "PerfCnt4", "PerfCnt5", "PerfCnt6", "PerfCnt7",
78 "ErrCtl", "", "", "", "", "", "", "",
79 "CacheErr0", "CacheErr1", "CacheErr2", "CacheErr3", "", "", "", "",
80 "TagLo0", "DataLo1", "TagLo2", "DataLo3",
81 "TagLo4", "DataLo5", "TagLo6", "DataLo7",
82 "TagHi0", "DataHi1", "TagHi2", "DataHi3",
83 "TagHi4", "DataHi5", "TagHi6", "DataHi7",
84 "ErrorEPC", "", "", "", "", "", "", "",
85 "DESAVE", "", "", "", "", "", "", "",
94 ISA::ISA(BaseCPU
*_cpu
)
103 miscRegFile
.resize(NumMiscRegs
);
104 bankType
.resize(NumMiscRegs
);
106 for (int i
=0; i
< NumMiscRegs
; i
++) {
107 miscRegFile
[i
].resize(1);
108 bankType
[i
] = perProcessor
;
111 miscRegFile_WriteMask
.resize(NumMiscRegs
);
113 for (int i
=0; i
< NumMiscRegs
; i
++) {
114 miscRegFile_WriteMask
[i
].push_back(0);
120 ISA::clear(unsigned tid_or_vpn
)
122 for(int i
= 0; i
< NumMiscRegs
; i
++) {
123 miscRegFile
[i
][tid_or_vpn
] = 0;
124 miscRegFile_WriteMask
[i
][tid_or_vpn
] = (long unsigned int)(-1);
129 ISA::expandForMultithreading(ThreadID num_threads
, unsigned num_vpes
)
131 // Initialize all Per-VPE regs
132 uint32_t per_vpe_regs
[] = { VPEControl
, VPEConf0
, VPEConf1
, YQMask
,
133 VPESchedule
, VPEScheFBack
, VPEOpt
, SRSConf0
,
134 SRSConf1
, SRSConf2
, SRSConf3
, SRSConf4
,
137 uint32_t num_vpe_regs
= sizeof(per_vpe_regs
) / 4;
138 for (int i
= 0; i
< num_vpe_regs
; i
++) {
140 miscRegFile
[per_vpe_regs
[i
]].resize(num_vpes
);
142 bankType
[per_vpe_regs
[i
]] = perVirtProcessor
;
145 // Initialize all Per-TC regs
146 uint32_t per_tc_regs
[] = { Status
, TCStatus
, TCBind
, TCRestart
, TCHalt
,
147 TCContext
, TCSchedule
, TCScheFBack
, Debug
,
150 uint32_t num_tc_regs
= sizeof(per_tc_regs
) / 4;
152 for (int i
= 0; i
< num_tc_regs
; i
++) {
153 miscRegFile
[per_tc_regs
[i
]].resize(num_threads
);
154 bankType
[per_tc_regs
[i
]] = perThreadContext
;
159 for (int i
=1; i
< num_vpes
; i
++) {
166 //@TODO: Use MIPS STYLE CONSTANTS (e.g. TCHALT_H instead of TCH_H)
168 ISA::reset(std::string core_name
, ThreadID num_threads
,
169 unsigned num_vpes
, BaseCPU
*_cpu
)
171 DPRINTF(MipsPRA
, "Resetting CP0 State with %i TCs and %i VPEs\n",
172 num_threads
, num_vpes
);
175 MipsISA::CoreSpecific
&cp
= cpu
->coreParams
;
177 // Do Default CP0 initialization HERE
179 // Do Initialization for MT cores here (eventually use
180 // core_name parameter to toggle this initialization)
181 // ===================================================
182 DPRINTF(MipsPRA
, "Initializing CP0 State.... ");
184 MiscReg ProcID
= readMiscRegNoEffect(PRId
);
185 replaceBits(ProcID
,PRIdCoOp_HI
,PRIdCoOp_LO
,cp
.CP0_PRId_CompanyOptions
);
186 replaceBits(ProcID
,PRIdCoID_HI
,PRIdCoID_LO
,cp
.CP0_PRId_CompanyID
);
187 replaceBits(ProcID
,PRIdProc_ID_HI
,PRIdProc_ID_LO
,cp
.CP0_PRId_ProcessorID
);
188 replaceBits(ProcID
,PRIdRev_HI
,PRIdRev_LO
,cp
.CP0_PRId_Revision
);
189 setMiscRegNoEffect(PRId
,ProcID
);
190 // Now, create Write Mask for ProcID register
191 MiscReg ProcID_Mask
= 0; // Read-Only register
192 replaceBits(ProcID_Mask
,0,32,0);
193 setRegMask(PRId
,ProcID_Mask
);
196 MiscReg cfg
= readMiscRegNoEffect(Config
);
197 replaceBits(cfg
, Config_BE_HI
, Config_BE_LO
, cp
.CP0_Config_BE
);
198 replaceBits(cfg
, Config_AT_HI
, Config_AT_LO
, cp
.CP0_Config_AT
);
199 replaceBits(cfg
, Config_AR_HI
, Config_AR_LO
, cp
.CP0_Config_AR
);
200 replaceBits(cfg
, Config_MT_HI
, Config_MT_LO
, cp
.CP0_Config_MT
);
201 replaceBits(cfg
, Config_VI_HI
, Config_VI_LO
, cp
.CP0_Config_VI
);
202 replaceBits(cfg
, Config_M
, 1);
203 setMiscRegNoEffect(Config
, cfg
);
204 // Now, create Write Mask for Config register
205 MiscReg cfg_Mask
= 0x7FFF0007;
206 replaceBits(cfg_Mask
,0,32,0);
207 setRegMask(Config
,cfg_Mask
);
210 MiscReg cfg1
= readMiscRegNoEffect(Config1
);
211 replaceBits(cfg1
, Config1_MMUSize_HI
, Config1_MMUSize_LO
,
213 replaceBits(cfg1
, Config1_IS_HI
, Config1_IS_LO
, cp
.CP0_Config1_IS
);
214 replaceBits(cfg1
, Config1_IL_HI
, Config1_IL_LO
, cp
.CP0_Config1_IL
);
215 replaceBits(cfg1
, Config1_IA_HI
, Config1_IA_LO
, cp
.CP0_Config1_IA
);
216 replaceBits(cfg1
, Config1_DS_HI
, Config1_DS_LO
, cp
.CP0_Config1_DS
);
217 replaceBits(cfg1
, Config1_DL_HI
, Config1_DL_LO
, cp
.CP0_Config1_DL
);
218 replaceBits(cfg1
, Config1_DA_HI
, Config1_DA_LO
, cp
.CP0_Config1_DA
);
219 replaceBits(cfg1
, Config1_FP_HI
, Config1_FP_LO
, cp
.CP0_Config1_FP
);
220 replaceBits(cfg1
, Config1_EP_HI
, Config1_EP_LO
, cp
.CP0_Config1_EP
);
221 replaceBits(cfg1
, Config1_WR_HI
, Config1_WR_LO
, cp
.CP0_Config1_WR
);
222 replaceBits(cfg1
, Config1_MD_HI
, Config1_MD_LO
, cp
.CP0_Config1_MD
);
223 replaceBits(cfg1
, Config1_C2_HI
, Config1_C2_LO
, cp
.CP0_Config1_C2
);
224 replaceBits(cfg1
, Config1_PC_HI
, Config1_PC_LO
, cp
.CP0_Config1_PC
);
225 replaceBits(cfg1
, Config1_M
, cp
.CP0_Config1_M
);
226 setMiscRegNoEffect(Config1
, cfg1
);
227 // Now, create Write Mask for Config register
228 MiscReg cfg1_Mask
= 0; // Read Only Register
229 replaceBits(cfg1_Mask
,0,32,0);
230 setRegMask(Config1
,cfg1_Mask
);
233 MiscReg cfg2
= readMiscRegNoEffect(Config2
);
234 replaceBits(cfg2
, Config2_TU_HI
, Config2_TU_LO
, cp
.CP0_Config2_TU
);
235 replaceBits(cfg2
, Config2_TS_HI
, Config2_TS_LO
, cp
.CP0_Config2_TS
);
236 replaceBits(cfg2
, Config2_TL_HI
, Config2_TL_LO
, cp
.CP0_Config2_TL
);
237 replaceBits(cfg2
, Config2_TA_HI
, Config2_TA_LO
, cp
.CP0_Config2_TA
);
238 replaceBits(cfg2
, Config2_SU_HI
, Config2_SU_LO
, cp
.CP0_Config2_SU
);
239 replaceBits(cfg2
, Config2_SS_HI
, Config2_SS_LO
, cp
.CP0_Config2_SS
);
240 replaceBits(cfg2
, Config2_SL_HI
, Config2_SL_LO
, cp
.CP0_Config2_SL
);
241 replaceBits(cfg2
, Config2_SA_HI
, Config2_SA_LO
, cp
.CP0_Config2_SA
);
242 replaceBits(cfg2
, Config2_M
, cp
.CP0_Config2_M
);
243 setMiscRegNoEffect(Config2
, cfg2
);
244 // Now, create Write Mask for Config register
245 MiscReg cfg2_Mask
= 0x7000F000; // Read Only Register
246 replaceBits(cfg2_Mask
,0,32,0);
247 setRegMask(Config2
,cfg2_Mask
);
250 MiscReg cfg3
= readMiscRegNoEffect(Config3
);
251 replaceBits(cfg3
, Config3_DSPP_HI
, Config3_DSPP_LO
, cp
.CP0_Config3_DSPP
);
252 replaceBits(cfg3
, Config3_LPA_HI
, Config3_LPA_LO
, cp
.CP0_Config3_LPA
);
253 replaceBits(cfg3
, Config3_VEIC_HI
, Config3_VEIC_LO
, cp
.CP0_Config3_VEIC
);
254 replaceBits(cfg3
, Config3_VINT_HI
, Config3_VINT_LO
, cp
.CP0_Config3_VInt
);
255 replaceBits(cfg3
, Config3_SP_HI
, Config3_SP_LO
, cp
.CP0_Config3_SP
);
256 replaceBits(cfg3
, Config3_MT_HI
, Config3_MT_LO
, cp
.CP0_Config3_MT
);
257 replaceBits(cfg3
, Config3_SM_HI
, Config3_SM_LO
, cp
.CP0_Config3_SM
);
258 replaceBits(cfg3
, Config3_TL_HI
, Config3_TL_LO
, cp
.CP0_Config3_TL
);
259 setMiscRegNoEffect(Config3
, cfg3
);
260 // Now, create Write Mask for Config register
261 MiscReg cfg3_Mask
= 0; // Read Only Register
262 replaceBits(cfg3_Mask
,0,32,0);
263 setRegMask(Config3
,cfg3_Mask
);
266 MiscReg EB
= readMiscRegNoEffect(EBase
);
267 replaceBits(EB
, EBase_CPUNum_HI
, EBase_CPUNum_LO
, cp
.CP0_EBase_CPUNum
);
268 replaceBits(EB
, 31, 31, 1);
269 setMiscRegNoEffect(EBase
, EB
);
270 // Now, create Write Mask for Config register
271 MiscReg EB_Mask
= 0x3FFFF000;// Except Exception Base, the
272 // entire register is read only
273 replaceBits(EB_Mask
,0,32,0);
274 setRegMask(EBase
,EB_Mask
);
276 // SRS Control - HSS (Highest Shadow Set)
277 MiscReg SC
= readMiscRegNoEffect(SRSCtl
);
278 replaceBits(SC
, SRSCtl_HSS_HI
,SRSCtl_HSS_LO
,cp
.CP0_SrsCtl_HSS
);
279 setMiscRegNoEffect(SRSCtl
, SC
);
280 // Now, create Write Mask for the SRS Ctl register
281 MiscReg SC_Mask
= 0x0000F3C0;
282 replaceBits(SC_Mask
,0,32,0);
283 setRegMask(SRSCtl
,SC_Mask
);
285 // IntCtl - IPTI, IPPCI
286 MiscReg IC
= readMiscRegNoEffect(IntCtl
);
287 replaceBits(IC
, IntCtl_IPTI_HI
,IntCtl_IPTI_LO
,cp
.CP0_IntCtl_IPTI
);
288 replaceBits(IC
, IntCtl_IPPCI_HI
,IntCtl_IPPCI_LO
,cp
.CP0_IntCtl_IPPCI
);
289 setMiscRegNoEffect(IntCtl
, IC
);
290 // Now, create Write Mask for the IntCtl register
291 MiscReg IC_Mask
= 0x000003E0;
292 replaceBits(IC_Mask
,0,32,0);
293 setRegMask(IntCtl
,IC_Mask
);
295 // Watch Hi - M - FIXME (More than 1 Watch register)
296 MiscReg WHi
= readMiscRegNoEffect(WatchHi0
);
297 replaceBits(WHi
, WatchHi_M
, cp
.CP0_WatchHi_M
);
298 setMiscRegNoEffect(WatchHi0
, WHi
);
299 // Now, create Write Mask for the IntCtl register
300 MiscReg wh_Mask
= 0x7FFF0FFF;
301 replaceBits(wh_Mask
,0,32,0);
302 setRegMask(WatchHi0
,wh_Mask
);
304 // Perf Ctr - M - FIXME (More than 1 PerfCnt Pair)
305 MiscReg PCtr
= readMiscRegNoEffect(PerfCnt0
);
306 replaceBits(PCtr
, PerfCntCtl_M
, cp
.CP0_PerfCtr_M
);
307 replaceBits(PCtr
, PerfCntCtl_W
, cp
.CP0_PerfCtr_W
);
308 setMiscRegNoEffect(PerfCnt0
, PCtr
);
309 // Now, create Write Mask for the IntCtl register
310 MiscReg pc_Mask
= 0x00007FF;
311 replaceBits(pc_Mask
,0,32,0);
312 setRegMask(PerfCnt0
,pc_Mask
);
315 MiscReg random
= readMiscRegNoEffect(CP0_Random
);
317 setMiscRegNoEffect(CP0_Random
, random
);
318 // Now, create Write Mask for the IntCtl register
319 MiscReg random_Mask
= 0;
320 replaceBits(random_Mask
,0,32,0);
321 setRegMask(CP0_Random
,random_Mask
);
324 MiscReg pagegrain
= readMiscRegNoEffect(PageGrain
);
325 replaceBits(pagegrain
,PageGrain_ESP
,cp
.CP0_Config3_SP
);
326 setMiscRegNoEffect(PageGrain
, pagegrain
);
327 // Now, create Write Mask for the IntCtl register
328 MiscReg pg_Mask
= 0x10000000;
329 replaceBits(pg_Mask
,0,32,0);
330 setRegMask(PageGrain
,pg_Mask
);
333 MiscReg stat
= readMiscRegNoEffect(Status
);
334 // Only CU0 and IE are modified on a reset - everything else needs
335 // to be controlled on a per CPU model basis
337 // Enable CP0 on reset
338 // replaceBits(stat, Status_CU0_HI,Status_CU0_LO, 1);
340 // Enable ERL bit on a reset
341 replaceBits(stat
, Status_ERL_HI
, Status_ERL_LO
, 1);
343 // Enable BEV bit on a reset
344 replaceBits(stat
, Status_BEV_HI
, Status_BEV_LO
, 1);
346 setMiscRegNoEffect(Status
, stat
);
347 // Now, create Write Mask for the Status register
348 MiscReg stat_Mask
= 0xFF78FF17;
349 replaceBits(stat_Mask
,0,32,0);
350 setRegMask(Status
,stat_Mask
);
354 MiscReg mvp_conf0
= readMiscRegNoEffect(MVPConf0
);
355 replaceBits(mvp_conf0
, MVPC0_TCA
, 1);
356 replaceBits(mvp_conf0
, MVPC0_PVPE_HI
, MVPC0_PVPE_LO
, num_vpes
- 1);
357 replaceBits(mvp_conf0
, MVPC0_PTC_HI
, MVPC0_PTC_LO
, num_threads
- 1);
358 setMiscRegNoEffect(MVPConf0
, mvp_conf0
);
361 MiscReg vpe_conf0
= readMiscRegNoEffect(VPEConf0
);
362 replaceBits(vpe_conf0
, VPEC0_MVP
, 1);
363 setMiscRegNoEffect(VPEConf0
, vpe_conf0
);
366 for (ThreadID tid
= 0; tid
< num_threads
; tid
++) {
367 MiscReg tc_bind
= readMiscRegNoEffect(TCBind
, tid
);
368 replaceBits(tc_bind
, TCB_CUR_TC_HI
, TCB_CUR_TC_LO
, tid
);
369 setMiscRegNoEffect(TCBind
, tc_bind
, tid
);
372 MiscReg tc_halt
= readMiscRegNoEffect(TCHalt
);
373 replaceBits(tc_halt
, TCH_H
, 0);
374 setMiscRegNoEffect(TCHalt
, tc_halt
);
375 /*for (ThreadID tid = 1; tid < num_threads; tid++) {
376 // Set TCHalt Halt bit to 1 for all other threads
377 tc_halt = readMiscRegNoEffect(TCHalt, tid);
378 replaceBits(tc_halt, TCH_H, 1);
379 setReg(TCHalt, tc_halt, tid);
383 // Set TCStatus Activated to 1 for the initial thread that is running
384 MiscReg tc_status
= readMiscRegNoEffect(TCStatus
);
385 replaceBits(tc_status
, TCS_A
, 1);
386 setMiscRegNoEffect(TCStatus
, tc_status
);
388 // Set Dynamically Allocatable bit to 1 for all other threads
389 for (ThreadID tid
= 1; tid
< num_threads
; tid
++) {
390 tc_status
= readMiscRegNoEffect(TCStatus
, tid
);
391 replaceBits(tc_status
, TCSTATUS_DA
, 1);
392 setMiscRegNoEffect(TCStatus
, tc_status
, tid
);
396 MiscReg Mask
= 0x7FFFFFFF;
398 // Now, create Write Mask for the Index register
399 replaceBits(Mask
,0,32,0);
400 setRegMask(Index
,Mask
);
403 replaceBits(Mask
,0,32,0);
404 setRegMask(EntryLo0
,Mask
);
405 setRegMask(EntryLo1
,Mask
);
408 replaceBits(Mask
,0,32,0);
409 setRegMask(Context
,Mask
);
412 replaceBits(Mask
,0,32,0);
413 setRegMask(PageMask
,Mask
);
416 replaceBits(Mask
,0,32,0);
417 setRegMask(BadVAddr
,Mask
);
418 setRegMask(LLAddr
,Mask
);
421 replaceBits(Mask
,0,32,0);
422 setRegMask(Cause
,Mask
);
427 ISA::getVPENum(ThreadID tid
)
429 unsigned tc_bind
= miscRegFile
[TCBind
- Ctrl_Base_DepTag
][tid
];
430 return bits(tc_bind
, TCB_CUR_VPE_HI
, TCB_CUR_VPE_LO
);
434 ISA::readMiscRegNoEffect(int reg_idx
, ThreadID tid
)
436 int misc_reg
= reg_idx
- Ctrl_Base_DepTag
;
437 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
438 ? tid
: getVPENum(tid
);
439 DPRINTF(MipsPRA
, "Reading CP0 Register:%u Select:%u (%s) (%lx).\n",
440 misc_reg
/ 8, misc_reg
% 8, miscRegNames
[misc_reg
],
441 miscRegFile
[misc_reg
][reg_sel
]);
442 return miscRegFile
[misc_reg
][reg_sel
];
445 //@TODO: MIPS MT's register view automatically connects
446 // Status to TCStatus depending on current thread
447 //template <class TC>
449 ISA::readMiscReg(int reg_idx
, ThreadContext
*tc
, ThreadID tid
)
451 int misc_reg
= reg_idx
- Ctrl_Base_DepTag
;
452 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
453 ? tid
: getVPENum(tid
);
455 "Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n",
456 misc_reg
/ 8, misc_reg
% 8, miscRegNames
[misc_reg
],
457 miscRegFile
[misc_reg
][reg_sel
]);
463 return miscRegFile
[misc_reg
][reg_sel
];
468 ISA::setMiscRegNoEffect(int reg_idx
, const MiscReg
&val
, ThreadID tid
)
470 int misc_reg
= reg_idx
- Ctrl_Base_DepTag
;
471 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
472 ? tid
: getVPENum(tid
);
474 "[tid:%i]: Setting (direct set) CP0 Register:%u "
475 "Select:%u (%s) to %#x.\n",
476 tid
, misc_reg
/ 8, misc_reg
% 8, miscRegNames
[misc_reg
], val
);
478 miscRegFile
[misc_reg
][reg_sel
] = val
;
482 ISA::setRegMask(int reg_idx
, const MiscReg
&val
, ThreadID tid
)
485 int misc_reg
= reg_idx
- Ctrl_Base_DepTag
;
486 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
487 ? tid
: getVPENum(tid
);
489 "[tid:%i]: Setting CP0 Register: %u Select: %u (%s) to %#x\n",
490 tid
, misc_reg
/ 8, misc_reg
% 8, miscRegNames
[misc_reg
], val
);
491 miscRegFile_WriteMask
[misc_reg
][reg_sel
] = val
;
494 // PROGRAMMER'S NOTES:
495 // (1) Some CP0 Registers have fields that cannot
496 // be overwritten. Make sure to handle those particular registers
498 //template <class TC>
500 ISA::setMiscReg(int reg_idx
, const MiscReg
&val
,
501 ThreadContext
*tc
, ThreadID tid
)
503 int misc_reg
= reg_idx
- Ctrl_Base_DepTag
;
504 int reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
505 ? tid
: getVPENum(tid
);
508 "[tid:%i]: Setting CP0 Register:%u "
509 "Select:%u (%s) to %#x, with effect.\n",
510 tid
, misc_reg
/ 8, misc_reg
% 8, miscRegNames
[misc_reg
], val
);
512 MiscReg cp0_val
= filterCP0Write(misc_reg
, reg_sel
, val
);
514 miscRegFile
[misc_reg
][reg_sel
] = cp0_val
;
516 scheduleCP0Update(1);
520 * This method doesn't need to adjust the Control Register Offset
521 * since it has already been done in the calling method
525 ISA::filterCP0Write(int misc_reg
, int reg_sel
, const MiscReg
&val
)
527 MiscReg retVal
= val
;
529 // Mask off read-only regions
530 retVal
&= miscRegFile_WriteMask
[misc_reg
][reg_sel
];
531 MiscReg curVal
= miscRegFile
[misc_reg
][reg_sel
];
532 // Mask off current alue with inverse mask (clear writeable bits)
533 curVal
&= (~miscRegFile_WriteMask
[misc_reg
][reg_sel
]);
534 retVal
|= curVal
; // Combine the two
536 "filterCP0Write: Mask: %lx, Inverse Mask: %lx, write Val: %x, "
537 "current val: %lx, written val: %x\n",
538 miscRegFile_WriteMask
[misc_reg
][reg_sel
],
539 ~miscRegFile_WriteMask
[misc_reg
][reg_sel
],
540 val
, miscRegFile
[misc_reg
][reg_sel
], retVal
);
545 ISA::scheduleCP0Update(int delay
)
551 CP0Event
*cp0_event
= new CP0Event(this, cpu
, UpdateCP0
);
552 cpu
->schedule(cp0_event
, curTick
+ cpu
->ticks(delay
));
559 ///////////////////////////////////////////////////////////////////
561 // EVALUATE CP0 STATE FOR MIPS MT
563 ///////////////////////////////////////////////////////////////////
564 unsigned mvp_conf0
= readMiscRegNoEffect(MVPConf0
);
565 ThreadID num_threads
= bits(mvp_conf0
, MVPC0_PTC_HI
, MVPC0_PTC_LO
) + 1;
567 for (ThreadID tid
= 0; tid
< num_threads
; tid
++) {
568 MiscReg tc_status
= readMiscRegNoEffect(TCStatus
, tid
);
569 MiscReg tc_halt
= readMiscRegNoEffect(TCHalt
, tid
);
571 //@todo: add vpe/mt check here thru mvpcontrol & vpecontrol regs
572 if (bits(tc_halt
, TCH_H
) == 1 || bits(tc_status
, TCS_A
) == 0) {
573 haltThread(cpu
->getContext(tid
));
574 } else if (bits(tc_halt
, TCH_H
) == 0 && bits(tc_status
, TCS_A
) == 1) {
575 restoreThread(cpu
->getContext(tid
));
579 num_threads
= bits(mvp_conf0
, MVPC0_PTC_HI
, MVPC0_PTC_LO
) + 1;
581 // Toggle update flag after we finished updating
585 ISA::CP0Event::CP0Event(CP0
*_cp0
, BaseCPU
*_cpu
, CP0EventType e_type
)
586 : Event(CPU_Tick_Pri
), cp0(_cp0
), cpu(_cpu
), cp0EventType(e_type
)
590 ISA::CP0Event::process()
592 switch (cp0EventType
)
599 //cp0EventRemoveList.push(this);
603 ISA::CP0Event::description() const
605 return "Coprocessor-0 event";
609 ISA::CP0Event::scheduleEvent(int delay
)
611 cpu
->reschedule(this, curTick
+ cpu
->ticks(delay
), true);
615 ISA::CP0Event::unscheduleEvent()