acb6f9c213d1674c2aae3da1ebee208b55ec9380
2 * Copyright (c) 2006 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.
28 * Authors: Korey Sewell
32 #include "base/bitfield.hh"
34 #include "arch/mips/regfile/misc_regfile.hh"
35 #include "arch/mips/mt_constants.hh"
36 #include "arch/mips/pra_constants.hh"
38 #include "cpu/thread_context.hh"
39 #include "cpu/base.hh"
40 #include "cpu/exetrace.hh"
44 std::string
MiscRegFile::miscRegNames
[NumMiscRegs
] =
45 {"Index", "MVPControl", "MVPConf0", "MVPConf1", "", "", "", "",
46 "Random", "VPEControl", "VPEConf0", "VPEConf1", "YQMask", "VPESchedule", "VPEScheFBack", "VPEOpt",
47 "EntryLo0", "TCStatus", "TCBind", "TCRestart", "TCHalt", "TCContext", "TCSchedule", "TCScheFBack",
48 "EntryLo1", "", "", "", "", "", "", "",
49 "Context", "ContextConfig", "", "", "", "", "", "",
50 "PageMask", "PageGrain", "", "", "", "", "", "",
51 "Wired", "SRSConf0", "SRCConf1", "SRSConf2", "SRSConf3", "SRSConf4", "", "",
52 "HWREna", "", "", "", "", "", "", "",
53 "BadVAddr", "", "", "", "", "", "", "",
54 "Count", "", "", "", "", "", "", "",
55 "EntryHi", "", "", "", "", "", "", "",
56 "Compare", "", "", "", "", "", "", "",
57 "Status", "IntCtl", "SRSCtl", "SRSMap", "", "", "", "",
58 "Cause", "", "", "", "", "", "", "",
59 "EPC", "", "", "", "", "", "", "",
60 "PRId", "EBase", "", "", "", "", "", "",
61 "Config", "Config1", "Config2", "Config3", "", "", "", "",
62 "LLAddr", "", "", "", "", "", "", "",
63 "WatchLo0", "WatchLo1", "WatchLo2", "WatchLo3", "WatchLo4", "WatchLo5", "WatchLo6", "WatchLo7",
64 "WatchHi0", "WatchHi1", "WatchHi2", "WatchHi3", "WatchHi4", "WatchHi5", "WatchHi6", "WatchHi7",
65 "XCContext64", "", "", "", "", "", "", "",
66 "", "", "", "", "", "", "", "",
67 "", "", "", "", "", "", "", "",
68 "Debug", "TraceControl1", "TraceControl2", "UserTraceData", "TraceBPC", "", "", "",
69 "DEPC", "", "", "", "", "", "", "",
70 "PerfCnt0", "PerfCnt1", "PerfCnt2", "PerfCnt3", "PerfCnt4", "PerfCnt5", "PerfCnt6", "PerfCnt7",
71 "ErrCtl", "", "", "", "", "", "", "",
72 "CacheErr0", "CacheErr1", "CacheErr2", "CacheErr3", "", "", "", "",
73 "TagLo0", "DataLo1", "TagLo2", "DataLo3", "TagLo4", "DataLo5", "TagLo6", "DataLo7",
74 "TagHi0", "DataHi1", "TagHi2", "DataHi3", "TagHi4", "DataHi5", "TagHi6", "DataHi7",
75 "ErrorEPC", "", "", "", "", "", "", "",
76 "DESAVE", "", "", "", "", "", "", "",
80 MiscRegFile::MiscRegFile()
85 MiscRegFile::MiscRegFile(BaseCPU
*_cpu
)
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);
111 MiscRegFile::clear(unsigned tid_or_vpn
)
113 for(int i
= 0; i
< NumMiscRegs
; i
++) {
114 miscRegFile
[i
][tid_or_vpn
] = 0;
115 miscRegFile_WriteMask
[i
][tid_or_vpn
] = (long unsigned int)(-1);
120 MiscRegFile::expandForMultithreading(unsigned num_threads
, unsigned num_vpes
)
122 // Initialize all Per-VPE regs
123 uint32_t per_vpe_regs
[] = { VPEControl
, VPEConf0
, VPEConf1
, YQMask
,
124 VPESchedule
, VPEScheFBack
, VPEOpt
, SRSConf0
,
125 SRSConf1
, SRSConf2
, SRSConf3
, SRSConf4
,
128 uint32_t num_vpe_regs
= sizeof(per_vpe_regs
) / 4;
129 for (int i
= 0; i
< num_vpe_regs
; i
++) {
131 miscRegFile
[per_vpe_regs
[i
]].resize(num_vpes
);
133 bankType
[per_vpe_regs
[i
]] = perVirtProcessor
;
136 // Initialize all Per-TC regs
137 uint32_t per_tc_regs
[] = { Status
, TCStatus
, TCBind
, TCRestart
, TCHalt
,
138 TCContext
, TCSchedule
, TCScheFBack
, Debug
,
141 uint32_t num_tc_regs
= sizeof(per_tc_regs
) / 4;
143 for (int i
= 0; i
< num_tc_regs
; i
++) {
144 miscRegFile
[per_tc_regs
[i
]].resize(num_threads
);
145 bankType
[per_tc_regs
[i
]] = perThreadContext
;
150 for (int i
=1; i
< num_vpes
; i
++) {
156 int MiscRegFile::getInstAsid()
158 MiscReg Entry_Hi
= readRegNoEffect(EntryHi
);
159 return bits(Entry_Hi
,EntryHi_ASID_HI
,EntryHi_ASID_LO
);
162 int MiscRegFile:: getDataAsid()
164 MiscReg EHi
= readRegNoEffect(EntryHi
);
165 return bits(EHi
,EntryHi_ASID_HI
,EntryHi_ASID_LO
);
167 //@TODO: Use MIPS STYLE CONSTANTS (e.g. TCHALT_H instead of TCH_H)
169 MiscRegFile::reset(std::string core_name
, unsigned num_threads
,
170 unsigned num_vpes
, BaseCPU
*_cpu
)
173 DPRINTF(MipsPRA
, "Resetting CP0 State with %i TCs and %i VPEs\n",
174 num_threads
, num_vpes
);
176 const BaseCPU::Params
*p
= _cpu
->params
;
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
= readRegNoEffect(PRId
);
185 replaceBits(ProcID
,PRIdCoOp_HI
,PRIdCoOp_LO
,p
->coreParams
.CP0_PRId_CompanyOptions
);
186 replaceBits(ProcID
,PRIdCoID_HI
,PRIdCoID_LO
,p
->coreParams
.CP0_PRId_CompanyID
);
187 replaceBits(ProcID
,PRIdProc_ID_HI
,PRIdProc_ID_LO
,p
->coreParams
.CP0_PRId_ProcessorID
);
188 replaceBits(ProcID
,PRIdRev_HI
,PRIdRev_LO
,p
->coreParams
.CP0_PRId_Revision
);
189 setRegNoEffect(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
= readRegNoEffect(Config
);
197 replaceBits(cfg
, Config_BE_HI
, Config_BE_LO
, p
->coreParams
.CP0_Config_BE
);
198 replaceBits(cfg
, Config_AT_HI
, Config_AT_LO
, p
->coreParams
.CP0_Config_AT
);
199 replaceBits(cfg
, Config_AR_HI
, Config_AR_LO
, p
->coreParams
.CP0_Config_AR
);
200 replaceBits(cfg
, Config_MT_HI
, Config_MT_LO
, p
->coreParams
.CP0_Config_MT
);
201 replaceBits(cfg
, Config_VI_HI
, Config_VI_LO
, p
->coreParams
.CP0_Config_VI
);
202 replaceBits(cfg
, Config_M
, 1);
203 setRegNoEffect(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
= readRegNoEffect(Config1
);
211 replaceBits(cfg1
, Config1_MMUSize_HI
, Config1_MMUSize_LO
, p
->coreParams
.CP0_Config1_MMU
);
212 replaceBits(cfg1
, Config1_IS_HI
, Config1_IS_LO
, p
->coreParams
.CP0_Config1_IS
);
213 replaceBits(cfg1
, Config1_IL_HI
, Config1_IL_LO
, p
->coreParams
.CP0_Config1_IL
);
214 replaceBits(cfg1
, Config1_IA_HI
, Config1_IA_LO
, p
->coreParams
.CP0_Config1_IA
);
215 replaceBits(cfg1
, Config1_DS_HI
, Config1_DS_LO
, p
->coreParams
.CP0_Config1_DS
);
216 replaceBits(cfg1
, Config1_DL_HI
, Config1_DL_LO
, p
->coreParams
.CP0_Config1_DL
);
217 replaceBits(cfg1
, Config1_DA_HI
, Config1_DA_LO
, p
->coreParams
.CP0_Config1_DA
);
218 replaceBits(cfg1
, Config1_FP_HI
, Config1_FP_LO
, p
->coreParams
.CP0_Config1_FP
);
219 replaceBits(cfg1
, Config1_EP_HI
, Config1_EP_LO
, p
->coreParams
.CP0_Config1_EP
);
220 replaceBits(cfg1
, Config1_WR_HI
, Config1_WR_LO
, p
->coreParams
.CP0_Config1_WR
);
221 replaceBits(cfg1
, Config1_MD_HI
, Config1_MD_LO
, p
->coreParams
.CP0_Config1_MD
);
222 replaceBits(cfg1
, Config1_C2_HI
, Config1_C2_LO
, p
->coreParams
.CP0_Config1_C2
);
223 replaceBits(cfg1
, Config1_PC_HI
, Config1_PC_LO
, p
->coreParams
.CP0_Config1_PC
);
224 replaceBits(cfg1
, Config1_M
, p
->coreParams
.CP0_Config1_M
);
225 setRegNoEffect(Config1
, cfg1
);
226 // Now, create Write Mask for Config register
227 MiscReg cfg1_Mask
= 0; // Read Only Register
228 replaceBits(cfg1_Mask
,0,32,0);
229 setRegMask(Config1
,cfg1_Mask
);
232 MiscReg cfg2
= readRegNoEffect(Config2
);
233 replaceBits(cfg2
, Config2_TU_HI
, Config2_TU_LO
, p
->coreParams
.CP0_Config2_TU
);
234 replaceBits(cfg2
, Config2_TS_HI
, Config2_TS_LO
, p
->coreParams
.CP0_Config2_TS
);
235 replaceBits(cfg2
, Config2_TL_HI
, Config2_TL_LO
, p
->coreParams
.CP0_Config2_TL
);
236 replaceBits(cfg2
, Config2_TA_HI
, Config2_TA_LO
, p
->coreParams
.CP0_Config2_TA
);
237 replaceBits(cfg2
, Config2_SU_HI
, Config2_SU_LO
, p
->coreParams
.CP0_Config2_SU
);
238 replaceBits(cfg2
, Config2_SS_HI
, Config2_SS_LO
, p
->coreParams
.CP0_Config2_SS
);
239 replaceBits(cfg2
, Config2_SL_HI
, Config2_SL_LO
, p
->coreParams
.CP0_Config2_SL
);
240 replaceBits(cfg2
, Config2_SA_HI
, Config2_SA_LO
, p
->coreParams
.CP0_Config2_SA
);
241 replaceBits(cfg2
, Config2_M
, p
->coreParams
.CP0_Config2_M
);
242 setRegNoEffect(Config2
, cfg2
);
243 // Now, create Write Mask for Config register
244 MiscReg cfg2_Mask
= 0x7000F000; // Read Only Register
245 replaceBits(cfg2_Mask
,0,32,0);
246 setRegMask(Config2
,cfg2_Mask
);
249 MiscReg cfg3
= readRegNoEffect(Config3
);
250 replaceBits(cfg3
, Config3_DSPP_HI
, Config3_DSPP_LO
, p
->coreParams
.CP0_Config3_DSPP
);
251 replaceBits(cfg3
, Config3_LPA_HI
, Config3_LPA_LO
, p
->coreParams
.CP0_Config3_LPA
);
252 replaceBits(cfg3
, Config3_VEIC_HI
, Config3_VEIC_LO
, p
->coreParams
.CP0_Config3_VEIC
);
253 replaceBits(cfg3
, Config3_VINT_HI
, Config3_VINT_LO
, p
->coreParams
.CP0_Config3_VInt
);
254 replaceBits(cfg3
, Config3_SP_HI
, Config3_SP_LO
, p
->coreParams
.CP0_Config3_SP
);
255 replaceBits(cfg3
, Config3_MT_HI
, Config3_MT_LO
, p
->coreParams
.CP0_Config3_MT
);
256 replaceBits(cfg3
, Config3_SM_HI
, Config3_SM_LO
, p
->coreParams
.CP0_Config3_SM
);
257 replaceBits(cfg3
, Config3_TL_HI
, Config3_TL_LO
, p
->coreParams
.CP0_Config3_TL
);
258 setRegNoEffect(Config3
, cfg3
);
259 // Now, create Write Mask for Config register
260 MiscReg cfg3_Mask
= 0; // Read Only Register
261 replaceBits(cfg3_Mask
,0,32,0);
262 setRegMask(Config3
,cfg3_Mask
);
265 MiscReg EB
= readRegNoEffect(EBase
);
266 replaceBits(EB
, EBase_CPUNum_HI
, EBase_CPUNum_LO
, p
->coreParams
.CP0_EBase_CPUNum
);
267 replaceBits(EB
, 31, 31, 1);
268 setRegNoEffect(EBase
, EB
);
269 // Now, create Write Mask for Config register
270 MiscReg EB_Mask
= 0x3FFFF000;// Except Exception Base, the
271 // entire register is read only
272 replaceBits(EB_Mask
,0,32,0);
273 setRegMask(EBase
,EB_Mask
);
275 // SRS Control - HSS (Highest Shadow Set)
276 MiscReg SC
= readRegNoEffect(SRSCtl
);
277 replaceBits(SC
, SRSCtl_HSS_HI
,SRSCtl_HSS_LO
,p
->coreParams
.CP0_SrsCtl_HSS
);
278 setRegNoEffect(SRSCtl
, SC
);
279 // Now, create Write Mask for the SRS Ctl register
280 MiscReg SC_Mask
= 0x0000F3C0;
281 replaceBits(SC_Mask
,0,32,0);
282 setRegMask(SRSCtl
,SC_Mask
);
284 // IntCtl - IPTI, IPPCI
285 MiscReg IC
= readRegNoEffect(IntCtl
);
286 replaceBits(IC
, IntCtl_IPTI_HI
,IntCtl_IPTI_LO
,p
->coreParams
.CP0_IntCtl_IPTI
);
287 replaceBits(IC
, IntCtl_IPPCI_HI
,IntCtl_IPPCI_LO
,p
->coreParams
.CP0_IntCtl_IPPCI
);
288 setRegNoEffect(IntCtl
, IC
);
289 // Now, create Write Mask for the IntCtl register
290 MiscReg IC_Mask
= 0x000003E0;
291 replaceBits(IC_Mask
,0,32,0);
292 setRegMask(IntCtl
,IC_Mask
);
294 // Watch Hi - M - FIXME (More than 1 Watch register)
295 MiscReg WHi
= readRegNoEffect(WatchHi0
);
296 replaceBits(WHi
, WatchHi_M
, p
->coreParams
.CP0_WatchHi_M
);
297 setRegNoEffect(WatchHi0
, WHi
);
298 // Now, create Write Mask for the IntCtl register
299 MiscReg wh_Mask
= 0x7FFF0FFF;
300 replaceBits(wh_Mask
,0,32,0);
301 setRegMask(WatchHi0
,wh_Mask
);
303 // Perf Ctr - M - FIXME (More than 1 PerfCnt Pair)
304 MiscReg PCtr
= readRegNoEffect(PerfCnt0
);
305 replaceBits(PCtr
, PerfCntCtl_M
, p
->coreParams
.CP0_PerfCtr_M
);
306 replaceBits(PCtr
, PerfCntCtl_W
, p
->coreParams
.CP0_PerfCtr_W
);
307 setRegNoEffect(PerfCnt0
, PCtr
);
308 // Now, create Write Mask for the IntCtl register
309 MiscReg pc_Mask
= 0x00007FF;
310 replaceBits(pc_Mask
,0,32,0);
311 setRegMask(PerfCnt0
,pc_Mask
);
314 MiscReg random
= readRegNoEffect(CP0_Random
);
316 setRegNoEffect(CP0_Random
, random
);
317 // Now, create Write Mask for the IntCtl register
318 MiscReg random_Mask
= 0;
319 replaceBits(random_Mask
,0,32,0);
320 setRegMask(CP0_Random
,random_Mask
);
323 MiscReg pagegrain
= readRegNoEffect(PageGrain
);
324 replaceBits(pagegrain
,PageGrain_ESP
,p
->coreParams
.CP0_Config3_SP
);
325 setRegNoEffect(PageGrain
, pagegrain
);
326 // Now, create Write Mask for the IntCtl register
327 MiscReg pg_Mask
= 0x10000000;
328 replaceBits(pg_Mask
,0,32,0);
329 setRegMask(PageGrain
,pg_Mask
);
332 MiscReg stat
= readRegNoEffect(Status
);
333 // Only CU0 and IE are modified on a reset - everything else needs to be controlled
334 // on a per CPU model basis
335 // replaceBits(stat, Status_CU0_HI,Status_CU0_LO, 1); // Enable CP0 on reset
337 replaceBits(stat
, Status_ERL_HI
, Status_ERL_LO
, 1); // Enable ERL bit on a reset
338 replaceBits(stat
, Status_BEV_HI
, Status_BEV_LO
, 1); // Enable BEV bit on a reset
339 setRegNoEffect(Status
, stat
);
340 // Now, create Write Mask for the Status register
341 MiscReg stat_Mask
= 0xFF78FF17;
342 replaceBits(stat_Mask
,0,32,0);
343 setRegMask(Status
,stat_Mask
);
347 MiscReg mvp_conf0
= readRegNoEffect(MVPConf0
);
348 replaceBits(mvp_conf0
, MVPC0_TCA
, 1);
349 replaceBits(mvp_conf0
, MVPC0_PVPE_HI
, MVPC0_PVPE_LO
, num_vpes
- 1);
350 replaceBits(mvp_conf0
, MVPC0_PTC_HI
, MVPC0_PTC_LO
, num_threads
- 1);
351 setRegNoEffect(MVPConf0
, mvp_conf0
);
354 MiscReg vpe_conf0
= readRegNoEffect(VPEConf0
);
355 replaceBits(vpe_conf0
, VPEC0_MVP
, 1);
356 setRegNoEffect(VPEConf0
, vpe_conf0
);
359 for (int tid
= 0; tid
< num_threads
; tid
++) {
360 MiscReg tc_bind
= readRegNoEffect(TCBind
, tid
);
361 replaceBits(tc_bind
, TCB_CUR_TC_HI
, TCB_CUR_TC_LO
, tid
);
362 setRegNoEffect(TCBind
, tc_bind
, tid
);
365 MiscReg tc_halt
= readRegNoEffect(TCHalt
);
366 replaceBits(tc_halt
, TCH_H
, 0);
367 setRegNoEffect(TCHalt
, tc_halt
);
368 /*for (int tid = 1; tid < num_threads; tid++) {
369 // Set TCHalt Halt bit to 1 for all other threads
370 tc_halt = readRegNoEffect(TCHalt, tid);
371 replaceBits(tc_halt, TCH_H, 1);
372 setReg(TCHalt, tc_halt, tid);
376 // Set TCStatus Activated to 1 for the initial thread that is running
377 MiscReg tc_status
= readRegNoEffect(TCStatus
);
378 replaceBits(tc_status
, TCS_A
, 1);
379 setRegNoEffect(TCStatus
, tc_status
);
381 // Set Dynamically Allocatable bit to 1 for all other threads
382 for (int tid
= 1; tid
< num_threads
; tid
++) {
383 tc_status
= readRegNoEffect(TCStatus
, tid
);
384 replaceBits(tc_status
, TCSTATUS_DA
, 1);
385 setRegNoEffect(TCStatus
, tc_status
, tid
);
389 MiscReg Mask
= 0x7FFFFFFF;
391 // Now, create Write Mask for the Index register
392 replaceBits(Mask
,0,32,0);
393 setRegMask(Index
,Mask
);
396 replaceBits(Mask
,0,32,0);
397 setRegMask(EntryLo0
,Mask
);
398 setRegMask(EntryLo1
,Mask
);
401 replaceBits(Mask
,0,32,0);
402 setRegMask(Context
,Mask
);
405 replaceBits(Mask
,0,32,0);
406 setRegMask(PageMask
,Mask
);
409 replaceBits(Mask
,0,32,0);
410 setRegMask(BadVAddr
,Mask
);
411 setRegMask(LLAddr
,Mask
);
414 replaceBits(Mask
,0,32,0);
415 setRegMask(Cause
,Mask
);
420 MipsISA::getMiscRegName(unsigned reg_idx
)
422 return MiscRegFile::miscRegNames
[reg_idx
];
426 MiscRegFile::getVPENum(unsigned tid
)
428 unsigned tc_bind
= miscRegFile
[TCBind
- Ctrl_Base_DepTag
][tid
];
429 return bits(tc_bind
, TCB_CUR_VPE_HI
, TCB_CUR_VPE_LO
);
433 MiscRegFile::readRegNoEffect(int reg_idx
, unsigned tid
)
435 int misc_reg
= reg_idx
- Ctrl_Base_DepTag
;
436 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
437 ? tid
: getVPENum(tid
);
438 DPRINTF(MipsPRA
, "Reading CP0 Register:%u Select:%u (%s) (%lx).\n",
439 misc_reg
/ 8, misc_reg
% 8, getMiscRegName(misc_reg
),miscRegFile
[misc_reg
][reg_sel
]);
440 return miscRegFile
[misc_reg
][reg_sel
];
443 //@TODO: MIPS MT's register view automatically connects
444 // Status to TCStatus depending on current thread
445 //template <class TC>
447 MiscRegFile::readReg(int reg_idx
,
448 ThreadContext
*tc
, unsigned tid
)
450 int misc_reg
= reg_idx
- Ctrl_Base_DepTag
;
451 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
452 ? tid
: getVPENum(tid
);
453 DPRINTF(MipsPRA
, "Reading CP0 Register:%u Select:%u (%s) with effect (%lx).\n",
454 misc_reg
/ 8, misc_reg
% 8, getMiscRegName(misc_reg
),miscRegFile
[misc_reg
][reg_sel
]);
460 return miscRegFile
[misc_reg
][reg_sel
];
465 MiscRegFile::setRegNoEffect(int reg_idx
, const MiscReg
&val
, unsigned tid
)
467 int misc_reg
= reg_idx
- Ctrl_Base_DepTag
;
468 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
469 ? tid
: getVPENum(tid
);
470 DPRINTF(MipsPRA
, "[tid:%i]: Setting (direct set) CP0 Register:%u Select:%u (%s) to %#x.\n",
471 tid
, misc_reg
/ 8, misc_reg
% 8, getMiscRegName(misc_reg
), val
);
473 miscRegFile
[misc_reg
][reg_sel
] = val
;
476 MiscRegFile::setRegMask(int reg_idx
, const MiscReg
&val
, unsigned tid
)
479 int misc_reg
= reg_idx
- Ctrl_Base_DepTag
;
480 unsigned reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
481 ? tid
: getVPENum(tid
);
482 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
);
483 miscRegFile_WriteMask
[misc_reg
][reg_sel
] = val
;
486 // PROGRAMMER'S NOTES:
487 // (1) Some CP0 Registers have fields that cannot
488 // be overwritten. Make sure to handle those particular registers
490 //template <class TC>
492 MiscRegFile::setReg(int reg_idx
, const MiscReg
&val
,
493 ThreadContext
*tc
, unsigned tid
)
495 int misc_reg
= reg_idx
- Ctrl_Base_DepTag
;
496 int reg_sel
= (bankType
[misc_reg
] == perThreadContext
)
497 ? tid
: getVPENum(tid
);
499 DPRINTF(MipsPRA
, "[tid:%i]: Setting CP0 Register:%u Select:%u (%s) to %#x, with effect.\n",
500 tid
, misc_reg
/ 8, misc_reg
% 8, getMiscRegName(misc_reg
), val
);
502 MiscReg cp0_val
= filterCP0Write(misc_reg
, reg_sel
, val
);
504 miscRegFile
[misc_reg
][reg_sel
] = cp0_val
;
506 scheduleCP0Update(1);
508 /** This method doesn't need to adjust the Control Register Offset since
509 it has already been done in the calling method (setRegWithEffect) */
510 MiscReg
MiscRegFile::filterCP0Write(int misc_reg
, int reg_sel
, const MiscReg
&val
)
512 MiscReg retVal
= val
;
513 retVal
&= miscRegFile_WriteMask
[misc_reg
][reg_sel
]; // Mask off read-only regions
514 MiscReg curVal
= miscRegFile
[misc_reg
][reg_sel
];
515 curVal
&= (~miscRegFile_WriteMask
[misc_reg
][reg_sel
]); // Mask off current alue with inverse mask (clear writeable bits)
516 retVal
|= curVal
; // Combine the two
517 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
);
521 MiscRegFile::scheduleCP0Update(int delay
)
527 CP0Event
*cp0_event
= new CP0Event(this, cpu
, UpdateCP0
);
528 cp0_event
->schedule(curTick
+ cpu
->ticks(delay
));
533 MiscRegFile::updateCPU()
535 ///////////////////////////////////////////////////////////////////
537 // EVALUATE CP0 STATE FOR MIPS MT
539 ///////////////////////////////////////////////////////////////////
540 unsigned mvp_conf0
= readRegNoEffect(MVPConf0
);
541 unsigned num_threads
= bits(mvp_conf0
, MVPC0_PTC_HI
, MVPC0_PTC_LO
) + 1;
543 for (int tid
= 0; tid
< num_threads
; tid
++) {
544 MiscReg tc_status
= readRegNoEffect(TCStatus
, tid
);
545 MiscReg tc_halt
= readRegNoEffect(TCHalt
, tid
);
547 //@todo: add vpe/mt check here thru mvpcontrol & vpecontrol regs
548 if (bits(tc_halt
, TCH_H
) == 1 || bits(tc_status
, TCS_A
) == 0) {
549 haltThread(cpu
->getContext(tid
));
550 } else if (bits(tc_halt
, TCH_H
) == 0 && bits(tc_status
, TCS_A
) == 1) {
551 restoreThread(cpu
->getContext(tid
));
555 num_threads
= bits(mvp_conf0
, MVPC0_PTC_HI
, MVPC0_PTC_LO
) + 1;
557 // Toggle update flag after we finished updating
561 MiscRegFile::CP0Event::CP0Event(CP0
*_cp0
, BaseCPU
*_cpu
, CP0EventType e_type
)
562 : Event(&mainEventQueue
, CPU_Tick_Pri
), cp0(_cp0
), cpu(_cpu
), cp0EventType(e_type
)
566 MiscRegFile::CP0Event::process()
568 switch (cp0EventType
)
575 //cp0EventRemoveList.push(this);
579 MiscRegFile::CP0Event::description()
581 return "Coprocessor-0 event";
585 MiscRegFile::CP0Event::scheduleEvent(int delay
)
588 reschedule(curTick
+ cpu
->ticks(delay
));
589 else if (!scheduled())
590 schedule(curTick
+ cpu
->ticks(delay
));
594 MiscRegFile::CP0Event::unscheduleEvent()