I missed a couple of WithEffects, this should do it
[gem5.git] / src / arch / sparc / miscregfile.cc
1 /*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
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.
15 *
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.
27 *
28 * Authors: Gabe Black
29 * Ali Saidi
30 */
31
32 #include "arch/sparc/asi.hh"
33 #include "arch/sparc/miscregfile.hh"
34 #include "base/bitfield.hh"
35 #include "base/trace.hh"
36 #include "config/full_system.hh"
37 #include "cpu/base.hh"
38 #include "cpu/thread_context.hh"
39
40 using namespace SparcISA;
41 using namespace std;
42
43 class Checkpoint;
44
45 //These functions map register indices to names
46 string SparcISA::getMiscRegName(RegIndex index)
47 {
48 static::string miscRegName[NumMiscRegs] =
49 {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic",
50 "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
51 "stick", "stick_cmpr",
52 "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
53 "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin",
54 "wstate",*/ "gl",
55 "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
56 "hstick_cmpr",
57 "fsr", "prictx", "secctx", "partId", "lsuCtrlReg", "itbTsbC0Ps0",
58 "itbTsbC0Ps1", "iTlbC0Cnfg", "itbTsbCXPs0", "itbTsbCXPs1",
59 "iTlbCXCnfg","iTlbSfsr", "iTlbTagAcs", "dtbTsbC0Ps0",
60 "dtbTsbC0Ps1", "dTlbC0Cnfg", "dtbTsbCXPs0", "dtbTsbCXPs1",
61 "dTlbCXCnfg","dTlbSfsr", "dTlbSfar", "dTlbTagAcs",
62 "scratch0", "scratch1", "scratch2", "scratch3", "scratch4",
63 "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail",
64 "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail",
65 "nresErrorHead", "nresErrorTail", "TlbData" };
66
67 return miscRegName[index];
68 }
69
70 enum RegMask
71 {
72 PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
73 };
74
75 void MiscRegFile::clear()
76 {
77 //y = 0;
78 //ccr = 0;
79 asi = 0;
80 tick = ULL(1) << 63;
81 fprs = 0;
82 gsr = 0;
83 softint = 0;
84 tick_cmpr = 0;
85 stick = 0;
86 stick_cmpr = 0;
87 memset(tpc, 0, sizeof(tpc));
88 memset(tnpc, 0, sizeof(tnpc));
89 memset(tstate, 0, sizeof(tstate));
90 memset(tt, 0, sizeof(tt));
91 pstate = 0;
92 tl = 0;
93 pil = 0;
94 cwp = 0;
95 //cansave = 0;
96 //canrestore = 0;
97 //cleanwin = 0;
98 //otherwin = 0;
99 //wstate = 0;
100 gl = 0;
101 //In a T1, bit 11 is apparently always 1
102 hpstate = (1 << 11);
103 memset(htstate, 0, sizeof(htstate));
104 hintp = 0;
105 htba = 0;
106 hstick_cmpr = 0;
107 //This is set this way in Legion for some reason
108 strandStatusReg = 0x50000;
109 fsr = 0;
110
111 priContext = 0;
112 secContext = 0;
113 partId = 0;
114 lsuCtrlReg = 0;
115
116 iTlbC0TsbPs0 = 0;
117 iTlbC0TsbPs1 = 0;
118 iTlbC0Config = 0;
119 iTlbCXTsbPs0 = 0;
120 iTlbCXTsbPs1 = 0;
121 iTlbCXConfig = 0;
122 iTlbSfsr = 0;
123 iTlbTagAccess = 0;
124
125 dTlbC0TsbPs0 = 0;
126 dTlbC0TsbPs1 = 0;
127 dTlbC0Config = 0;
128 dTlbCXTsbPs0 = 0;
129 dTlbCXTsbPs1 = 0;
130 dTlbCXConfig = 0;
131 dTlbSfsr = 0;
132 dTlbSfar = 0;
133 dTlbTagAccess = 0;
134
135 memset(scratchPad, 0, sizeof(scratchPad));
136 #if FULL_SYSTEM
137 tickCompare = NULL;
138 sTickCompare = NULL;
139 hSTickCompare = NULL;
140 #endif
141 }
142
143 MiscReg MiscRegFile::readRegNoEffect(int miscReg)
144 {
145 switch (miscReg) {
146 case MISCREG_TLB_DATA:
147 /* Package up all the data for the tlb:
148 * 6666555555555544444444443333333333222222222211111111110000000000
149 * 3210987654321098765432109876543210987654321098765432109876543210
150 * secContext | priContext | |tl|partid| |||||^hpriv
151 * ||||^red
152 * |||^priv
153 * ||^am
154 * |^lsuim
155 * ^lsudm
156 */
157 return bits((uint64_t)hpstate,2,2) |
158 bits((uint64_t)hpstate,5,5) << 1 |
159 bits((uint64_t)pstate,3,2) << 2 |
160 bits((uint64_t)lsuCtrlReg,3,2) << 4 |
161 bits((uint64_t)partId,7,0) << 8 |
162 bits((uint64_t)tl,2,0) << 16 |
163 (uint64_t)priContext << 32 |
164 (uint64_t)secContext << 48;
165
166 //case MISCREG_Y:
167 // return y;
168 //case MISCREG_CCR:
169 // return ccr;
170 case MISCREG_ASI:
171 return asi;
172 case MISCREG_FPRS:
173 return fprs;
174 case MISCREG_TICK:
175 return tick;
176 case MISCREG_PCR:
177 panic("PCR not implemented\n");
178 case MISCREG_PIC:
179 panic("PIC not implemented\n");
180 case MISCREG_GSR:
181 return gsr;
182 case MISCREG_SOFTINT:
183 return softint;
184 case MISCREG_TICK_CMPR:
185 return tick_cmpr;
186 case MISCREG_STICK:
187 return stick;
188 case MISCREG_STICK_CMPR:
189 return stick_cmpr;
190
191 /** Privilged Registers */
192 case MISCREG_TPC:
193 return tpc[tl-1];
194 case MISCREG_TNPC:
195 return tnpc[tl-1];
196 case MISCREG_TSTATE:
197 return tstate[tl-1];
198 case MISCREG_TT:
199 return tt[tl-1];
200 case MISCREG_PRIVTICK:
201 panic("Priviliged access to tick registers not implemented\n");
202 case MISCREG_TBA:
203 return tba;
204 case MISCREG_PSTATE:
205 return pstate;
206 case MISCREG_TL:
207 return tl;
208 case MISCREG_PIL:
209 return pil;
210 case MISCREG_CWP:
211 return cwp;
212 //case MISCREG_CANSAVE:
213 // return cansave;
214 //case MISCREG_CANRESTORE:
215 // return canrestore;
216 //case MISCREG_CLEANWIN:
217 // return cleanwin;
218 //case MISCREG_OTHERWIN:
219 // return otherwin;
220 //case MISCREG_WSTATE:
221 // return wstate;
222 case MISCREG_GL:
223 return gl;
224
225 /** Hyper privileged registers */
226 case MISCREG_HPSTATE:
227 return hpstate;
228 case MISCREG_HTSTATE:
229 return htstate[tl-1];
230 case MISCREG_HINTP:
231 return hintp;
232 case MISCREG_HTBA:
233 return htba;
234 case MISCREG_HVER:
235 // XXX set to match Legion
236 return ULL(0x3e) << 48 |
237 ULL(0x23) << 32 |
238 ULL(0x20) << 24 |
239 //MaxGL << 16 | XXX For some reason legion doesn't set GL
240 MaxTL << 8 |
241 (NWindows -1) << 0;
242 case MISCREG_STRAND_STS_REG:
243 return strandStatusReg;
244 case MISCREG_HSTICK_CMPR:
245 return hstick_cmpr;
246
247 /** Floating Point Status Register */
248 case MISCREG_FSR:
249 DPRINTF(Sparc, "FSR read as: %#x\n", fsr);
250 return fsr;
251
252 case MISCREG_MMU_P_CONTEXT:
253 return priContext;
254 case MISCREG_MMU_S_CONTEXT:
255 return secContext;
256 case MISCREG_MMU_PART_ID:
257 return partId;
258 case MISCREG_MMU_LSU_CTRL:
259 return lsuCtrlReg;
260
261 case MISCREG_MMU_ITLB_C0_TSB_PS0:
262 return iTlbC0TsbPs0;
263 case MISCREG_MMU_ITLB_C0_TSB_PS1:
264 return iTlbC0TsbPs1;
265 case MISCREG_MMU_ITLB_C0_CONFIG:
266 return iTlbC0Config;
267 case MISCREG_MMU_ITLB_CX_TSB_PS0:
268 return iTlbCXTsbPs0;
269 case MISCREG_MMU_ITLB_CX_TSB_PS1:
270 return iTlbCXTsbPs1;
271 case MISCREG_MMU_ITLB_CX_CONFIG:
272 return iTlbCXConfig;
273 case MISCREG_MMU_ITLB_SFSR:
274 return iTlbSfsr;
275 case MISCREG_MMU_ITLB_TAG_ACCESS:
276 return iTlbTagAccess;
277
278 case MISCREG_MMU_DTLB_C0_TSB_PS0:
279 return dTlbC0TsbPs0;
280 case MISCREG_MMU_DTLB_C0_TSB_PS1:
281 return dTlbC0TsbPs1;
282 case MISCREG_MMU_DTLB_C0_CONFIG:
283 return dTlbC0Config;
284 case MISCREG_MMU_DTLB_CX_TSB_PS0:
285 return dTlbCXTsbPs0;
286 case MISCREG_MMU_DTLB_CX_TSB_PS1:
287 return dTlbCXTsbPs1;
288 case MISCREG_MMU_DTLB_CX_CONFIG:
289 return dTlbCXConfig;
290 case MISCREG_MMU_DTLB_SFSR:
291 return dTlbSfsr;
292 case MISCREG_MMU_DTLB_SFAR:
293 return dTlbSfar;
294 case MISCREG_MMU_DTLB_TAG_ACCESS:
295 return dTlbTagAccess;
296
297 case MISCREG_SCRATCHPAD_R0:
298 return scratchPad[0];
299 case MISCREG_SCRATCHPAD_R1:
300 return scratchPad[1];
301 case MISCREG_SCRATCHPAD_R2:
302 return scratchPad[2];
303 case MISCREG_SCRATCHPAD_R3:
304 return scratchPad[3];
305 case MISCREG_SCRATCHPAD_R4:
306 return scratchPad[4];
307 case MISCREG_SCRATCHPAD_R5:
308 return scratchPad[5];
309 case MISCREG_SCRATCHPAD_R6:
310 return scratchPad[6];
311 case MISCREG_SCRATCHPAD_R7:
312 return scratchPad[7];
313 case MISCREG_QUEUE_CPU_MONDO_HEAD:
314 return cpu_mondo_head;
315 case MISCREG_QUEUE_CPU_MONDO_TAIL:
316 return cpu_mondo_tail;
317 case MISCREG_QUEUE_DEV_MONDO_HEAD:
318 return dev_mondo_head;
319 case MISCREG_QUEUE_DEV_MONDO_TAIL:
320 return dev_mondo_tail;
321 case MISCREG_QUEUE_RES_ERROR_HEAD:
322 return res_error_head;
323 case MISCREG_QUEUE_RES_ERROR_TAIL:
324 return res_error_tail;
325 case MISCREG_QUEUE_NRES_ERROR_HEAD:
326 return nres_error_head;
327 case MISCREG_QUEUE_NRES_ERROR_TAIL:
328 return nres_error_tail;
329 default:
330 panic("Miscellaneous register %d not implemented\n", miscReg);
331 }
332 }
333
334 MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc)
335 {
336 switch (miscReg) {
337 // tick and stick are aliased to each other in niagra
338 // well store the tick data in stick and the interrupt bit in tick
339 case MISCREG_STICK:
340 case MISCREG_TICK:
341 case MISCREG_PRIVTICK:
342 // I'm not sure why legion ignores the lowest two bits, but we'll go
343 // with it
344 // change from curCycle() to instCount() until we're done with legion
345 DPRINTF(Timer, "Instruction Count when TICK read: %#X stick=%#X\n",
346 tc->getCpuPtr()->instCount(), stick);
347 return mbits(tc->getCpuPtr()->instCount() + (int64_t)stick,62,2) |
348 mbits(tick,63,63);
349 case MISCREG_FPRS:
350 // in legion if fp is enabled du and dl are set
351 return fprs | 0x3;
352 case MISCREG_PCR:
353 case MISCREG_PIC:
354 panic("Performance Instrumentation not impl\n");
355 case MISCREG_SOFTINT_CLR:
356 case MISCREG_SOFTINT_SET:
357 panic("Can read from softint clr/set\n");
358 case MISCREG_SOFTINT:
359 case MISCREG_TICK_CMPR:
360 case MISCREG_STICK_CMPR:
361 case MISCREG_HINTP:
362 case MISCREG_HTSTATE:
363 case MISCREG_HTBA:
364 case MISCREG_HVER:
365 case MISCREG_STRAND_STS_REG:
366 case MISCREG_HSTICK_CMPR:
367 case MISCREG_QUEUE_CPU_MONDO_HEAD:
368 case MISCREG_QUEUE_CPU_MONDO_TAIL:
369 case MISCREG_QUEUE_DEV_MONDO_HEAD:
370 case MISCREG_QUEUE_DEV_MONDO_TAIL:
371 case MISCREG_QUEUE_RES_ERROR_HEAD:
372 case MISCREG_QUEUE_RES_ERROR_TAIL:
373 case MISCREG_QUEUE_NRES_ERROR_HEAD:
374 case MISCREG_QUEUE_NRES_ERROR_TAIL:
375 #if FULL_SYSTEM
376 case MISCREG_HPSTATE:
377 return readFSReg(miscReg, tc);
378 #else
379 case MISCREG_HPSTATE:
380 //HPSTATE is special because because sometimes in privilege checks for instructions
381 //it will read HPSTATE to make sure the priv. level is ok
382 //So, we'll just have to tell it it isn't, instead of panicing.
383 return 0;
384
385 panic("Accessing Fullsystem register %s in SE mode\n",getMiscRegName(miscReg));
386 #endif
387
388 }
389 return readRegNoEffect(miscReg);
390 }
391
392 void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val)
393 {
394 switch (miscReg) {
395 // case MISCREG_Y:
396 // y = val;
397 // break;
398 // case MISCREG_CCR:
399 // ccr = val;
400 // break;
401 case MISCREG_ASI:
402 asi = val;
403 break;
404 case MISCREG_FPRS:
405 fprs = val;
406 break;
407 case MISCREG_TICK:
408 tick = val;
409 break;
410 case MISCREG_PCR:
411 panic("PCR not implemented\n");
412 case MISCREG_PIC:
413 panic("PIC not implemented\n");
414 case MISCREG_GSR:
415 gsr = val;
416 break;
417 case MISCREG_SOFTINT:
418 softint = val;
419 break;
420 case MISCREG_TICK_CMPR:
421 tick_cmpr = val;
422 break;
423 case MISCREG_STICK:
424 stick = val;
425 break;
426 case MISCREG_STICK_CMPR:
427 stick_cmpr = val;
428 break;
429
430 /** Privilged Registers */
431 case MISCREG_TPC:
432 tpc[tl-1] = val;
433 break;
434 case MISCREG_TNPC:
435 tnpc[tl-1] = val;
436 break;
437 case MISCREG_TSTATE:
438 tstate[tl-1] = val;
439 break;
440 case MISCREG_TT:
441 tt[tl-1] = val;
442 break;
443 case MISCREG_PRIVTICK:
444 panic("Priviliged access to tick regesiters not implemented\n");
445 case MISCREG_TBA:
446 // clear lower 7 bits on writes.
447 tba = val & ULL(~0x7FFF);
448 break;
449 case MISCREG_PSTATE:
450 pstate = (val & PSTATE_MASK);
451 break;
452 case MISCREG_TL:
453 tl = val;
454 break;
455 case MISCREG_PIL:
456 pil = val;
457 break;
458 case MISCREG_CWP:
459 cwp = val;
460 break;
461 // case MISCREG_CANSAVE:
462 // cansave = val;
463 // break;
464 // case MISCREG_CANRESTORE:
465 // canrestore = val;
466 // break;
467 // case MISCREG_CLEANWIN:
468 // cleanwin = val;
469 // break;
470 // case MISCREG_OTHERWIN:
471 // otherwin = val;
472 // break;
473 // case MISCREG_WSTATE:
474 // wstate = val;
475 // break;
476 case MISCREG_GL:
477 gl = val;
478 break;
479
480 /** Hyper privileged registers */
481 case MISCREG_HPSTATE:
482 hpstate = val;
483 break;
484 case MISCREG_HTSTATE:
485 htstate[tl-1] = val;
486 break;
487 case MISCREG_HINTP:
488 hintp = val;
489 case MISCREG_HTBA:
490 htba = val;
491 break;
492 case MISCREG_STRAND_STS_REG:
493 strandStatusReg = val;
494 break;
495 case MISCREG_HSTICK_CMPR:
496 hstick_cmpr = val;
497 break;
498
499 /** Floating Point Status Register */
500 case MISCREG_FSR:
501 fsr = val;
502 DPRINTF(Sparc, "FSR written with: %#x\n", fsr);
503 break;
504
505 case MISCREG_MMU_P_CONTEXT:
506 priContext = val;
507 break;
508 case MISCREG_MMU_S_CONTEXT:
509 secContext = val;
510 break;
511 case MISCREG_MMU_PART_ID:
512 partId = val;
513 break;
514 case MISCREG_MMU_LSU_CTRL:
515 lsuCtrlReg = val;
516 break;
517
518 case MISCREG_MMU_ITLB_C0_TSB_PS0:
519 iTlbC0TsbPs0 = val;
520 break;
521 case MISCREG_MMU_ITLB_C0_TSB_PS1:
522 iTlbC0TsbPs1 = val;
523 break;
524 case MISCREG_MMU_ITLB_C0_CONFIG:
525 iTlbC0Config = val;
526 break;
527 case MISCREG_MMU_ITLB_CX_TSB_PS0:
528 iTlbCXTsbPs0 = val;
529 break;
530 case MISCREG_MMU_ITLB_CX_TSB_PS1:
531 iTlbCXTsbPs1 = val;
532 break;
533 case MISCREG_MMU_ITLB_CX_CONFIG:
534 iTlbCXConfig = val;
535 break;
536 case MISCREG_MMU_ITLB_SFSR:
537 iTlbSfsr = val;
538 break;
539 case MISCREG_MMU_ITLB_TAG_ACCESS:
540 iTlbTagAccess = val;
541 break;
542
543 case MISCREG_MMU_DTLB_C0_TSB_PS0:
544 dTlbC0TsbPs0 = val;
545 break;
546 case MISCREG_MMU_DTLB_C0_TSB_PS1:
547 dTlbC0TsbPs1 = val;
548 break;
549 case MISCREG_MMU_DTLB_C0_CONFIG:
550 dTlbC0Config = val;
551 break;
552 case MISCREG_MMU_DTLB_CX_TSB_PS0:
553 dTlbCXTsbPs0 = val;
554 break;
555 case MISCREG_MMU_DTLB_CX_TSB_PS1:
556 dTlbCXTsbPs1 = val;
557 break;
558 case MISCREG_MMU_DTLB_CX_CONFIG:
559 dTlbCXConfig = val;
560 break;
561 case MISCREG_MMU_DTLB_SFSR:
562 dTlbSfsr = val;
563 break;
564 case MISCREG_MMU_DTLB_SFAR:
565 dTlbSfar = val;
566 break;
567 case MISCREG_MMU_DTLB_TAG_ACCESS:
568 dTlbTagAccess = val;
569 break;
570
571 case MISCREG_SCRATCHPAD_R0:
572 scratchPad[0] = val;
573 break;
574 case MISCREG_SCRATCHPAD_R1:
575 scratchPad[1] = val;
576 break;
577 case MISCREG_SCRATCHPAD_R2:
578 scratchPad[2] = val;
579 break;
580 case MISCREG_SCRATCHPAD_R3:
581 scratchPad[3] = val;
582 break;
583 case MISCREG_SCRATCHPAD_R4:
584 scratchPad[4] = val;
585 break;
586 case MISCREG_SCRATCHPAD_R5:
587 scratchPad[5] = val;
588 break;
589 case MISCREG_SCRATCHPAD_R6:
590 scratchPad[6] = val;
591 break;
592 case MISCREG_SCRATCHPAD_R7:
593 scratchPad[7] = val;
594 break;
595 case MISCREG_QUEUE_CPU_MONDO_HEAD:
596 cpu_mondo_head = val;
597 break;
598 case MISCREG_QUEUE_CPU_MONDO_TAIL:
599 cpu_mondo_tail = val;
600 break;
601 case MISCREG_QUEUE_DEV_MONDO_HEAD:
602 dev_mondo_head = val;
603 break;
604 case MISCREG_QUEUE_DEV_MONDO_TAIL:
605 dev_mondo_tail = val;
606 break;
607 case MISCREG_QUEUE_RES_ERROR_HEAD:
608 res_error_head = val;
609 break;
610 case MISCREG_QUEUE_RES_ERROR_TAIL:
611 res_error_tail = val;
612 break;
613 case MISCREG_QUEUE_NRES_ERROR_HEAD:
614 nres_error_head = val;
615 break;
616 case MISCREG_QUEUE_NRES_ERROR_TAIL:
617 nres_error_tail = val;
618 break;
619 default:
620 panic("Miscellaneous register %d not implemented\n", miscReg);
621 }
622 }
623
624 void MiscRegFile::setReg(int miscReg,
625 const MiscReg &val, ThreadContext * tc)
626 {
627 MiscReg new_val = val;
628
629 switch (miscReg) {
630 case MISCREG_STICK:
631 case MISCREG_TICK:
632 // stick and tick are same thing on niagra
633 // use stick for offset and tick for holding intrrupt bit
634 stick = mbits(val,62,0) - tc->getCpuPtr()->instCount();
635 tick = mbits(val,63,63);
636 DPRINTF(Timer, "Writing TICK=%#X\n", val);
637 break;
638 case MISCREG_FPRS:
639 //Configure the fpu based on the fprs
640 break;
641 case MISCREG_PCR:
642 //Set up performance counting based on pcr value
643 break;
644 case MISCREG_PSTATE:
645 pstate = val & PSTATE_MASK;
646 return;
647 case MISCREG_TL:
648 tl = val;
649 #if FULL_SYSTEM
650 if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
651 tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0);
652 else
653 tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0);
654 #endif
655 return;
656 case MISCREG_CWP:
657 new_val = val > NWindows ? NWindows - 1 : val;
658 tc->changeRegFileContext(CONTEXT_CWP, new_val);
659 break;
660 case MISCREG_GL:
661 tc->changeRegFileContext(CONTEXT_GLOBALS, val);
662 break;
663 case MISCREG_PIL:
664 case MISCREG_SOFTINT:
665 case MISCREG_SOFTINT_SET:
666 case MISCREG_SOFTINT_CLR:
667 case MISCREG_TICK_CMPR:
668 case MISCREG_STICK_CMPR:
669 case MISCREG_HINTP:
670 case MISCREG_HTSTATE:
671 case MISCREG_HTBA:
672 case MISCREG_HVER:
673 case MISCREG_STRAND_STS_REG:
674 case MISCREG_HSTICK_CMPR:
675 case MISCREG_QUEUE_CPU_MONDO_HEAD:
676 case MISCREG_QUEUE_CPU_MONDO_TAIL:
677 case MISCREG_QUEUE_DEV_MONDO_HEAD:
678 case MISCREG_QUEUE_DEV_MONDO_TAIL:
679 case MISCREG_QUEUE_RES_ERROR_HEAD:
680 case MISCREG_QUEUE_RES_ERROR_TAIL:
681 case MISCREG_QUEUE_NRES_ERROR_HEAD:
682 case MISCREG_QUEUE_NRES_ERROR_TAIL:
683 #if FULL_SYSTEM
684 case MISCREG_HPSTATE:
685 setFSReg(miscReg, val, tc);
686 return;
687 #else
688 case MISCREG_HPSTATE:
689 //HPSTATE is special because normal trap processing saves HPSTATE when
690 //it goes into a trap, and restores it when it returns.
691 return;
692 panic("Accessing Fullsystem register %s to %#x in SE mode\n", getMiscRegName(miscReg), val);
693 #endif
694 }
695 setRegNoEffect(miscReg, new_val);
696 }
697
698 void MiscRegFile::serialize(std::ostream & os)
699 {
700 SERIALIZE_SCALAR(asi);
701 SERIALIZE_SCALAR(tick);
702 SERIALIZE_SCALAR(fprs);
703 SERIALIZE_SCALAR(gsr);
704 SERIALIZE_SCALAR(softint);
705 SERIALIZE_SCALAR(tick_cmpr);
706 SERIALIZE_SCALAR(stick);
707 SERIALIZE_SCALAR(stick_cmpr);
708 SERIALIZE_ARRAY(tpc,MaxTL);
709 SERIALIZE_ARRAY(tnpc,MaxTL);
710 SERIALIZE_ARRAY(tstate,MaxTL);
711 SERIALIZE_ARRAY(tt,MaxTL);
712 SERIALIZE_SCALAR(tba);
713 SERIALIZE_SCALAR(pstate);
714 SERIALIZE_SCALAR(tl);
715 SERIALIZE_SCALAR(pil);
716 SERIALIZE_SCALAR(cwp);
717 SERIALIZE_SCALAR(gl);
718 SERIALIZE_SCALAR(hpstate);
719 SERIALIZE_ARRAY(htstate,MaxTL);
720 SERIALIZE_SCALAR(hintp);
721 SERIALIZE_SCALAR(htba);
722 SERIALIZE_SCALAR(hstick_cmpr);
723 SERIALIZE_SCALAR(strandStatusReg);
724 SERIALIZE_SCALAR(fsr);
725 SERIALIZE_SCALAR(priContext);
726 SERIALIZE_SCALAR(secContext);
727 SERIALIZE_SCALAR(partId);
728 SERIALIZE_SCALAR(lsuCtrlReg);
729 SERIALIZE_SCALAR(iTlbC0TsbPs0);
730 SERIALIZE_SCALAR(iTlbC0TsbPs1);
731 SERIALIZE_SCALAR(iTlbC0Config);
732 SERIALIZE_SCALAR(iTlbCXTsbPs0);
733 SERIALIZE_SCALAR(iTlbCXTsbPs1);
734 SERIALIZE_SCALAR(iTlbCXConfig);
735 SERIALIZE_SCALAR(iTlbSfsr);
736 SERIALIZE_SCALAR(iTlbTagAccess);
737 SERIALIZE_SCALAR(dTlbC0TsbPs0);
738 SERIALIZE_SCALAR(dTlbC0TsbPs1);
739 SERIALIZE_SCALAR(dTlbC0Config);
740 SERIALIZE_SCALAR(dTlbCXTsbPs0);
741 SERIALIZE_SCALAR(dTlbCXTsbPs1);
742 SERIALIZE_SCALAR(dTlbCXConfig);
743 SERIALIZE_SCALAR(dTlbSfsr);
744 SERIALIZE_SCALAR(dTlbSfar);
745 SERIALIZE_SCALAR(dTlbTagAccess);
746 SERIALIZE_ARRAY(scratchPad,8);
747 SERIALIZE_SCALAR(cpu_mondo_head);
748 SERIALIZE_SCALAR(cpu_mondo_tail);
749 SERIALIZE_SCALAR(dev_mondo_head);
750 SERIALIZE_SCALAR(dev_mondo_tail);
751 SERIALIZE_SCALAR(res_error_head);
752 SERIALIZE_SCALAR(res_error_tail);
753 SERIALIZE_SCALAR(nres_error_head);
754 SERIALIZE_SCALAR(nres_error_tail);
755 #if FULL_SYSTEM
756 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
757 ThreadContext *tc = NULL;
758 BaseCPU *cpu = NULL;
759 int tc_num = 0;
760 bool tick_intr_sched = true;
761
762 if (tickCompare)
763 tc = tickCompare->getTC();
764 else if (sTickCompare)
765 tc = sTickCompare->getTC();
766 else if (hSTickCompare)
767 tc = hSTickCompare->getTC();
768 else
769 tick_intr_sched = false;
770
771 SERIALIZE_SCALAR(tick_intr_sched);
772
773 if (tc) {
774 cpu = tc->getCpuPtr();
775 tc_num = cpu->findContext(tc);
776 if (tickCompare && tickCompare->scheduled())
777 tick_cmp = tickCompare->when();
778 if (sTickCompare && sTickCompare->scheduled())
779 stick_cmp = sTickCompare->when();
780 if (hSTickCompare && hSTickCompare->scheduled())
781 hstick_cmp = hSTickCompare->when();
782
783 SERIALIZE_OBJPTR(cpu);
784 SERIALIZE_SCALAR(tc_num);
785 SERIALIZE_SCALAR(tick_cmp);
786 SERIALIZE_SCALAR(stick_cmp);
787 SERIALIZE_SCALAR(hstick_cmp);
788 }
789 #endif
790 }
791
792 void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
793 {
794 UNSERIALIZE_SCALAR(asi);
795 UNSERIALIZE_SCALAR(tick);
796 UNSERIALIZE_SCALAR(fprs);
797 UNSERIALIZE_SCALAR(gsr);
798 UNSERIALIZE_SCALAR(softint);
799 UNSERIALIZE_SCALAR(tick_cmpr);
800 UNSERIALIZE_SCALAR(stick);
801 UNSERIALIZE_SCALAR(stick_cmpr);
802 UNSERIALIZE_ARRAY(tpc,MaxTL);
803 UNSERIALIZE_ARRAY(tnpc,MaxTL);
804 UNSERIALIZE_ARRAY(tstate,MaxTL);
805 UNSERIALIZE_ARRAY(tt,MaxTL);
806 UNSERIALIZE_SCALAR(tba);
807 UNSERIALIZE_SCALAR(pstate);
808 UNSERIALIZE_SCALAR(tl);
809 UNSERIALIZE_SCALAR(pil);
810 UNSERIALIZE_SCALAR(cwp);
811 UNSERIALIZE_SCALAR(gl);
812 UNSERIALIZE_SCALAR(hpstate);
813 UNSERIALIZE_ARRAY(htstate,MaxTL);
814 UNSERIALIZE_SCALAR(hintp);
815 UNSERIALIZE_SCALAR(htba);
816 UNSERIALIZE_SCALAR(hstick_cmpr);
817 UNSERIALIZE_SCALAR(strandStatusReg);
818 UNSERIALIZE_SCALAR(fsr);
819 UNSERIALIZE_SCALAR(priContext);
820 UNSERIALIZE_SCALAR(secContext);
821 UNSERIALIZE_SCALAR(partId);
822 UNSERIALIZE_SCALAR(lsuCtrlReg);
823 UNSERIALIZE_SCALAR(iTlbC0TsbPs0);
824 UNSERIALIZE_SCALAR(iTlbC0TsbPs1);
825 UNSERIALIZE_SCALAR(iTlbC0Config);
826 UNSERIALIZE_SCALAR(iTlbCXTsbPs0);
827 UNSERIALIZE_SCALAR(iTlbCXTsbPs1);
828 UNSERIALIZE_SCALAR(iTlbCXConfig);
829 UNSERIALIZE_SCALAR(iTlbSfsr);
830 UNSERIALIZE_SCALAR(iTlbTagAccess);
831 UNSERIALIZE_SCALAR(dTlbC0TsbPs0);
832 UNSERIALIZE_SCALAR(dTlbC0TsbPs1);
833 UNSERIALIZE_SCALAR(dTlbC0Config);
834 UNSERIALIZE_SCALAR(dTlbCXTsbPs0);
835 UNSERIALIZE_SCALAR(dTlbCXTsbPs1);
836 UNSERIALIZE_SCALAR(dTlbCXConfig);
837 UNSERIALIZE_SCALAR(dTlbSfsr);
838 UNSERIALIZE_SCALAR(dTlbSfar);
839 UNSERIALIZE_SCALAR(dTlbTagAccess);
840 UNSERIALIZE_ARRAY(scratchPad,8);
841 UNSERIALIZE_SCALAR(cpu_mondo_head);
842 UNSERIALIZE_SCALAR(cpu_mondo_tail);
843 UNSERIALIZE_SCALAR(dev_mondo_head);
844 UNSERIALIZE_SCALAR(dev_mondo_tail);
845 UNSERIALIZE_SCALAR(res_error_head);
846 UNSERIALIZE_SCALAR(res_error_tail);
847 UNSERIALIZE_SCALAR(nres_error_head);
848 UNSERIALIZE_SCALAR(nres_error_tail);
849
850 #if FULL_SYSTEM
851 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
852 ThreadContext *tc = NULL;
853 BaseCPU *cpu = NULL;
854 int tc_num;
855 bool tick_intr_sched;
856 UNSERIALIZE_SCALAR(tick_intr_sched);
857 if (tick_intr_sched) {
858 UNSERIALIZE_OBJPTR(cpu);
859 if (cpu) {
860 UNSERIALIZE_SCALAR(tc_num);
861 UNSERIALIZE_SCALAR(tick_cmp);
862 UNSERIALIZE_SCALAR(stick_cmp);
863 UNSERIALIZE_SCALAR(hstick_cmp);
864 tc = cpu->getContext(tc_num);
865
866 if (tick_cmp) {
867 tickCompare = new TickCompareEvent(this, tc);
868 tickCompare->schedule(tick_cmp);
869 }
870 if (stick_cmp) {
871 sTickCompare = new STickCompareEvent(this, tc);
872 sTickCompare->schedule(stick_cmp);
873 }
874 if (hstick_cmp) {
875 hSTickCompare = new HSTickCompareEvent(this, tc);
876 hSTickCompare->schedule(hstick_cmp);
877 }
878 }
879 }
880
881 #endif
882 }