Deleted Added
sdiff udiff text old ( 6335:a08470cb53e5 ) new ( 6337:cac56cd6b015 )
full compact
1/*
2 * Copyright (c) 2009 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 */
30
31#include "arch/sparc/asi.hh"
32#include "arch/sparc/isa.hh"
33#include "base/bitfield.hh"
34#include "base/trace.hh"
35#include "config/full_system.hh"
36#include "cpu/base.hh"
37#include "cpu/thread_context.hh"
38
39namespace SparcISA
40{
41
42enum RegMask
43{
44 PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
45};
46
47void
48ISA::clear()
49{
50 //y = 0;
51 //ccr = 0;
52 asi = 0;
53 tick = ULL(1) << 63;
54 fprs = 0;
55 gsr = 0;
56 softint = 0;
57 tick_cmpr = 0;
58 stick = 0;
59 stick_cmpr = 0;
60 memset(tpc, 0, sizeof(tpc));
61 memset(tnpc, 0, sizeof(tnpc));
62 memset(tstate, 0, sizeof(tstate));
63 memset(tt, 0, sizeof(tt));
64 pstate = 0;
65 tl = 0;
66 pil = 0;
67 cwp = 0;
68 //cansave = 0;
69 //canrestore = 0;
70 //cleanwin = 0;
71 //otherwin = 0;
72 //wstate = 0;
73 gl = 0;
74 //In a T1, bit 11 is apparently always 1
75 hpstate = (1 << 11);
76 memset(htstate, 0, sizeof(htstate));
77 hintp = 0;
78 htba = 0;
79 hstick_cmpr = 0;
80 //This is set this way in Legion for some reason
81 strandStatusReg = 0x50000;
82 fsr = 0;
83
84 priContext = 0;
85 secContext = 0;
86 partId = 0;
87 lsuCtrlReg = 0;
88
89 memset(scratchPad, 0, sizeof(scratchPad));
90#if FULL_SYSTEM
91 tickCompare = NULL;
92 sTickCompare = NULL;
93 hSTickCompare = NULL;
94#endif
95}
96
97MiscReg
98ISA::readMiscRegNoEffect(int miscReg)
99{
100
101 // The three miscRegs are moved up from the switch statement
102 // due to more frequent calls.
103
104 if (miscReg == MISCREG_GL)
105 return gl;
106 if (miscReg == MISCREG_CWP)
107 return cwp;
108 if (miscReg == MISCREG_TLB_DATA) {
109 /* Package up all the data for the tlb:
110 * 6666555555555544444444443333333333222222222211111111110000000000
111 * 3210987654321098765432109876543210987654321098765432109876543210
112 * secContext | priContext | |tl|partid| |||||^hpriv
113 * ||||^red
114 * |||^priv
115 * ||^am
116 * |^lsuim
117 * ^lsudm
118 */
119 return bits((uint64_t)hpstate,2,2) |
120 bits((uint64_t)hpstate,5,5) << 1 |
121 bits((uint64_t)pstate,3,2) << 2 |
122 bits((uint64_t)lsuCtrlReg,3,2) << 4 |
123 bits((uint64_t)partId,7,0) << 8 |
124 bits((uint64_t)tl,2,0) << 16 |
125 (uint64_t)priContext << 32 |
126 (uint64_t)secContext << 48;
127 }
128
129 switch (miscReg) {
130 //case MISCREG_TLB_DATA:
131 // [original contents see above]
132 //case MISCREG_Y:
133 // return y;
134 //case MISCREG_CCR:
135 // return ccr;
136 case MISCREG_ASI:
137 return asi;
138 case MISCREG_FPRS:
139 return fprs;
140 case MISCREG_TICK:
141 return tick;
142 case MISCREG_PCR:
143 panic("PCR not implemented\n");
144 case MISCREG_PIC:
145 panic("PIC not implemented\n");
146 case MISCREG_GSR:
147 return gsr;
148 case MISCREG_SOFTINT:
149 return softint;
150 case MISCREG_TICK_CMPR:
151 return tick_cmpr;
152 case MISCREG_STICK:
153 return stick;
154 case MISCREG_STICK_CMPR:
155 return stick_cmpr;
156
157 /** Privilged Registers */
158 case MISCREG_TPC:
159 return tpc[tl-1];
160 case MISCREG_TNPC:
161 return tnpc[tl-1];
162 case MISCREG_TSTATE:
163 return tstate[tl-1];
164 case MISCREG_TT:
165 return tt[tl-1];
166 case MISCREG_PRIVTICK:
167 panic("Priviliged access to tick registers not implemented\n");
168 case MISCREG_TBA:
169 return tba;
170 case MISCREG_PSTATE:
171 return pstate;
172 case MISCREG_TL:
173 return tl;
174 case MISCREG_PIL:
175 return pil;
176 //CWP, GL moved
177 //case MISCREG_CWP:
178 // return cwp;
179 //case MISCREG_CANSAVE:
180 // return cansave;
181 //case MISCREG_CANRESTORE:
182 // return canrestore;
183 //case MISCREG_CLEANWIN:
184 // return cleanwin;
185 //case MISCREG_OTHERWIN:
186 // return otherwin;
187 //case MISCREG_WSTATE:
188 // return wstate;
189 //case MISCREG_GL:
190 // return gl;
191
192 /** Hyper privileged registers */
193 case MISCREG_HPSTATE:
194 return hpstate;
195 case MISCREG_HTSTATE:
196 return htstate[tl-1];
197 case MISCREG_HINTP:
198 return hintp;
199 case MISCREG_HTBA:
200 return htba;
201 case MISCREG_STRAND_STS_REG:
202 return strandStatusReg;
203 case MISCREG_HSTICK_CMPR:
204 return hstick_cmpr;
205
206 /** Floating Point Status Register */
207 case MISCREG_FSR:
208 DPRINTF(MiscRegs, "FSR read as: %#x\n", fsr);
209 return fsr;
210
211 case MISCREG_MMU_P_CONTEXT:
212 return priContext;
213 case MISCREG_MMU_S_CONTEXT:
214 return secContext;
215 case MISCREG_MMU_PART_ID:
216 return partId;
217 case MISCREG_MMU_LSU_CTRL:
218 return lsuCtrlReg;
219
220 case MISCREG_SCRATCHPAD_R0:
221 return scratchPad[0];
222 case MISCREG_SCRATCHPAD_R1:
223 return scratchPad[1];
224 case MISCREG_SCRATCHPAD_R2:
225 return scratchPad[2];
226 case MISCREG_SCRATCHPAD_R3:
227 return scratchPad[3];
228 case MISCREG_SCRATCHPAD_R4:
229 return scratchPad[4];
230 case MISCREG_SCRATCHPAD_R5:
231 return scratchPad[5];
232 case MISCREG_SCRATCHPAD_R6:
233 return scratchPad[6];
234 case MISCREG_SCRATCHPAD_R7:
235 return scratchPad[7];
236 case MISCREG_QUEUE_CPU_MONDO_HEAD:
237 return cpu_mondo_head;
238 case MISCREG_QUEUE_CPU_MONDO_TAIL:
239 return cpu_mondo_tail;
240 case MISCREG_QUEUE_DEV_MONDO_HEAD:
241 return dev_mondo_head;
242 case MISCREG_QUEUE_DEV_MONDO_TAIL:
243 return dev_mondo_tail;
244 case MISCREG_QUEUE_RES_ERROR_HEAD:
245 return res_error_head;
246 case MISCREG_QUEUE_RES_ERROR_TAIL:
247 return res_error_tail;
248 case MISCREG_QUEUE_NRES_ERROR_HEAD:
249 return nres_error_head;
250 case MISCREG_QUEUE_NRES_ERROR_TAIL:
251 return nres_error_tail;
252 default:
253 panic("Miscellaneous register %d not implemented\n", miscReg);
254 }
255}
256
257MiscReg
258ISA::readMiscReg(int miscReg, ThreadContext * tc)
259{
260 switch (miscReg) {
261 // tick and stick are aliased to each other in niagra
262 // well store the tick data in stick and the interrupt bit in tick
263 case MISCREG_STICK:
264 case MISCREG_TICK:
265 case MISCREG_PRIVTICK:
266 // I'm not sure why legion ignores the lowest two bits, but we'll go
267 // with it
268 // change from curCycle() to instCount() until we're done with legion
269 DPRINTF(Timer, "Instruction Count when TICK read: %#X stick=%#X\n",
270 tc->getCpuPtr()->instCount(), stick);
271 return mbits(tc->getCpuPtr()->instCount() + (int64_t)stick,62,2) |
272 mbits(tick,63,63);
273 case MISCREG_FPRS:
274 // in legion if fp is enabled du and dl are set
275 return fprs | 0x3;
276 case MISCREG_PCR:
277 case MISCREG_PIC:
278 panic("Performance Instrumentation not impl\n");
279 case MISCREG_SOFTINT_CLR:
280 case MISCREG_SOFTINT_SET:
281 panic("Can read from softint clr/set\n");
282 case MISCREG_SOFTINT:
283 case MISCREG_TICK_CMPR:
284 case MISCREG_STICK_CMPR:
285 case MISCREG_HINTP:
286 case MISCREG_HTSTATE:
287 case MISCREG_HTBA:
288 case MISCREG_HVER:
289 case MISCREG_STRAND_STS_REG:
290 case MISCREG_HSTICK_CMPR:
291 case MISCREG_QUEUE_CPU_MONDO_HEAD:
292 case MISCREG_QUEUE_CPU_MONDO_TAIL:
293 case MISCREG_QUEUE_DEV_MONDO_HEAD:
294 case MISCREG_QUEUE_DEV_MONDO_TAIL:
295 case MISCREG_QUEUE_RES_ERROR_HEAD:
296 case MISCREG_QUEUE_RES_ERROR_TAIL:
297 case MISCREG_QUEUE_NRES_ERROR_HEAD:
298 case MISCREG_QUEUE_NRES_ERROR_TAIL:
299#if FULL_SYSTEM
300 case MISCREG_HPSTATE:
301 return readFSReg(miscReg, tc);
302#else
303 case MISCREG_HPSTATE:
304 //HPSTATE is special because because sometimes in privilege
305 //checks for instructions it will read HPSTATE to make sure
306 //the priv. level is ok So, we'll just have to tell it it
307 //isn't, instead of panicing.
308 return 0;
309
310 panic("Accessing Fullsystem register %d in SE mode\n", miscReg);
311#endif
312
313 }
314 return readMiscRegNoEffect(miscReg);
315}
316
317void
318ISA::setMiscRegNoEffect(int miscReg, MiscReg val)
319{
320 switch (miscReg) {
321// case MISCREG_Y:
322// y = val;
323// break;
324// case MISCREG_CCR:
325// ccr = val;
326// break;
327 case MISCREG_ASI:
328 asi = val;
329 break;
330 case MISCREG_FPRS:
331 fprs = val;
332 break;
333 case MISCREG_TICK:
334 tick = val;
335 break;
336 case MISCREG_PCR:
337 panic("PCR not implemented\n");
338 case MISCREG_PIC:
339 panic("PIC not implemented\n");
340 case MISCREG_GSR:
341 gsr = val;
342 break;
343 case MISCREG_SOFTINT:
344 softint = val;
345 break;
346 case MISCREG_TICK_CMPR:
347 tick_cmpr = val;
348 break;
349 case MISCREG_STICK:
350 stick = val;
351 break;
352 case MISCREG_STICK_CMPR:
353 stick_cmpr = val;
354 break;
355
356 /** Privilged Registers */
357 case MISCREG_TPC:
358 tpc[tl-1] = val;
359 break;
360 case MISCREG_TNPC:
361 tnpc[tl-1] = val;
362 break;
363 case MISCREG_TSTATE:
364 tstate[tl-1] = val;
365 break;
366 case MISCREG_TT:
367 tt[tl-1] = val;
368 break;
369 case MISCREG_PRIVTICK:
370 panic("Priviliged access to tick regesiters not implemented\n");
371 case MISCREG_TBA:
372 // clear lower 7 bits on writes.
373 tba = val & ULL(~0x7FFF);
374 break;
375 case MISCREG_PSTATE:
376 pstate = (val & PSTATE_MASK);
377 break;
378 case MISCREG_TL:
379 tl = val;
380 break;
381 case MISCREG_PIL:
382 pil = val;
383 break;
384 case MISCREG_CWP:
385 cwp = val;
386 break;
387// case MISCREG_CANSAVE:
388// cansave = val;
389// break;
390// case MISCREG_CANRESTORE:
391// canrestore = val;
392// break;
393// case MISCREG_CLEANWIN:
394// cleanwin = val;
395// break;
396// case MISCREG_OTHERWIN:
397// otherwin = val;
398// break;
399// case MISCREG_WSTATE:
400// wstate = val;
401// break;
402 case MISCREG_GL:
403 gl = val;
404 break;
405
406 /** Hyper privileged registers */
407 case MISCREG_HPSTATE:
408 hpstate = val;
409 break;
410 case MISCREG_HTSTATE:
411 htstate[tl-1] = val;
412 break;
413 case MISCREG_HINTP:
414 hintp = val;
415 case MISCREG_HTBA:
416 htba = val;
417 break;
418 case MISCREG_STRAND_STS_REG:
419 strandStatusReg = val;
420 break;
421 case MISCREG_HSTICK_CMPR:
422 hstick_cmpr = val;
423 break;
424
425 /** Floating Point Status Register */
426 case MISCREG_FSR:
427 fsr = val;
428 DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr);
429 break;
430
431 case MISCREG_MMU_P_CONTEXT:
432 priContext = val;
433 break;
434 case MISCREG_MMU_S_CONTEXT:
435 secContext = val;
436 break;
437 case MISCREG_MMU_PART_ID:
438 partId = val;
439 break;
440 case MISCREG_MMU_LSU_CTRL:
441 lsuCtrlReg = val;
442 break;
443
444 case MISCREG_SCRATCHPAD_R0:
445 scratchPad[0] = val;
446 break;
447 case MISCREG_SCRATCHPAD_R1:
448 scratchPad[1] = val;
449 break;
450 case MISCREG_SCRATCHPAD_R2:
451 scratchPad[2] = val;
452 break;
453 case MISCREG_SCRATCHPAD_R3:
454 scratchPad[3] = val;
455 break;
456 case MISCREG_SCRATCHPAD_R4:
457 scratchPad[4] = val;
458 break;
459 case MISCREG_SCRATCHPAD_R5:
460 scratchPad[5] = val;
461 break;
462 case MISCREG_SCRATCHPAD_R6:
463 scratchPad[6] = val;
464 break;
465 case MISCREG_SCRATCHPAD_R7:
466 scratchPad[7] = val;
467 break;
468 case MISCREG_QUEUE_CPU_MONDO_HEAD:
469 cpu_mondo_head = val;
470 break;
471 case MISCREG_QUEUE_CPU_MONDO_TAIL:
472 cpu_mondo_tail = val;
473 break;
474 case MISCREG_QUEUE_DEV_MONDO_HEAD:
475 dev_mondo_head = val;
476 break;
477 case MISCREG_QUEUE_DEV_MONDO_TAIL:
478 dev_mondo_tail = val;
479 break;
480 case MISCREG_QUEUE_RES_ERROR_HEAD:
481 res_error_head = val;
482 break;
483 case MISCREG_QUEUE_RES_ERROR_TAIL:
484 res_error_tail = val;
485 break;
486 case MISCREG_QUEUE_NRES_ERROR_HEAD:
487 nres_error_head = val;
488 break;
489 case MISCREG_QUEUE_NRES_ERROR_TAIL:
490 nres_error_tail = val;
491 break;
492 default:
493 panic("Miscellaneous register %d not implemented\n", miscReg);
494 }
495}
496
497void
498ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc)
499{
500 MiscReg new_val = val;
501
502 switch (miscReg) {
503 case MISCREG_STICK:
504 case MISCREG_TICK:
505 // stick and tick are same thing on niagra
506 // use stick for offset and tick for holding intrrupt bit
507 stick = mbits(val,62,0) - tc->getCpuPtr()->instCount();
508 tick = mbits(val,63,63);
509 DPRINTF(Timer, "Writing TICK=%#X\n", val);
510 break;
511 case MISCREG_FPRS:
512 //Configure the fpu based on the fprs
513 break;
514 case MISCREG_PCR:
515 //Set up performance counting based on pcr value
516 break;
517 case MISCREG_PSTATE:
518 pstate = val & PSTATE_MASK;
519 return;
520 case MISCREG_TL:
521 tl = val;
522#if FULL_SYSTEM
523 if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
524 tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
525 else
526 tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
527#endif
528 return;
529 case MISCREG_CWP:
530 new_val = val >= NWindows ? NWindows - 1 : val;
531 if (val >= NWindows)
532 new_val = NWindows - 1;
533 break;
534 case MISCREG_GL:
535 break;
536 case MISCREG_PIL:
537 case MISCREG_SOFTINT:
538 case MISCREG_SOFTINT_SET:
539 case MISCREG_SOFTINT_CLR:
540 case MISCREG_TICK_CMPR:
541 case MISCREG_STICK_CMPR:
542 case MISCREG_HINTP:
543 case MISCREG_HTSTATE:
544 case MISCREG_HTBA:
545 case MISCREG_HVER:
546 case MISCREG_STRAND_STS_REG:
547 case MISCREG_HSTICK_CMPR:
548 case MISCREG_QUEUE_CPU_MONDO_HEAD:
549 case MISCREG_QUEUE_CPU_MONDO_TAIL:
550 case MISCREG_QUEUE_DEV_MONDO_HEAD:
551 case MISCREG_QUEUE_DEV_MONDO_TAIL:
552 case MISCREG_QUEUE_RES_ERROR_HEAD:
553 case MISCREG_QUEUE_RES_ERROR_TAIL:
554 case MISCREG_QUEUE_NRES_ERROR_HEAD:
555 case MISCREG_QUEUE_NRES_ERROR_TAIL:
556#if FULL_SYSTEM
557 case MISCREG_HPSTATE:
558 setFSReg(miscReg, val, tc);
559 return;
560#else
561 case MISCREG_HPSTATE:
562 //HPSTATE is special because normal trap processing saves HPSTATE when
563 //it goes into a trap, and restores it when it returns.
564 return;
565 panic("Accessing Fullsystem register %d to %#x in SE mode\n",
566 miscReg, val);
567#endif
568 }
569 setMiscRegNoEffect(miscReg, new_val);
570}
571
572void
573ISA::serialize(EventManager *em, std::ostream &os)
574{
575 SERIALIZE_SCALAR(asi);
576 SERIALIZE_SCALAR(tick);
577 SERIALIZE_SCALAR(fprs);
578 SERIALIZE_SCALAR(gsr);
579 SERIALIZE_SCALAR(softint);
580 SERIALIZE_SCALAR(tick_cmpr);
581 SERIALIZE_SCALAR(stick);
582 SERIALIZE_SCALAR(stick_cmpr);
583 SERIALIZE_ARRAY(tpc,MaxTL);
584 SERIALIZE_ARRAY(tnpc,MaxTL);
585 SERIALIZE_ARRAY(tstate,MaxTL);
586 SERIALIZE_ARRAY(tt,MaxTL);
587 SERIALIZE_SCALAR(tba);
588 SERIALIZE_SCALAR(pstate);
589 SERIALIZE_SCALAR(tl);
590 SERIALIZE_SCALAR(pil);
591 SERIALIZE_SCALAR(cwp);
592 SERIALIZE_SCALAR(gl);
593 SERIALIZE_SCALAR(hpstate);
594 SERIALIZE_ARRAY(htstate,MaxTL);
595 SERIALIZE_SCALAR(hintp);
596 SERIALIZE_SCALAR(htba);
597 SERIALIZE_SCALAR(hstick_cmpr);
598 SERIALIZE_SCALAR(strandStatusReg);
599 SERIALIZE_SCALAR(fsr);
600 SERIALIZE_SCALAR(priContext);
601 SERIALIZE_SCALAR(secContext);
602 SERIALIZE_SCALAR(partId);
603 SERIALIZE_SCALAR(lsuCtrlReg);
604 SERIALIZE_ARRAY(scratchPad,8);
605 SERIALIZE_SCALAR(cpu_mondo_head);
606 SERIALIZE_SCALAR(cpu_mondo_tail);
607 SERIALIZE_SCALAR(dev_mondo_head);
608 SERIALIZE_SCALAR(dev_mondo_tail);
609 SERIALIZE_SCALAR(res_error_head);
610 SERIALIZE_SCALAR(res_error_tail);
611 SERIALIZE_SCALAR(nres_error_head);
612 SERIALIZE_SCALAR(nres_error_tail);
613#if FULL_SYSTEM
614 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
615 ThreadContext *tc = NULL;
616 BaseCPU *cpu = NULL;
617 int tc_num = 0;
618 bool tick_intr_sched = true;
619
620 if (tickCompare)
621 tc = tickCompare->getTC();
622 else if (sTickCompare)
623 tc = sTickCompare->getTC();
624 else if (hSTickCompare)
625 tc = hSTickCompare->getTC();
626 else
627 tick_intr_sched = false;
628
629 SERIALIZE_SCALAR(tick_intr_sched);
630
631 if (tc) {
632 cpu = tc->getCpuPtr();
633 tc_num = cpu->findContext(tc);
634 if (tickCompare && tickCompare->scheduled())
635 tick_cmp = tickCompare->when();
636 if (sTickCompare && sTickCompare->scheduled())
637 stick_cmp = sTickCompare->when();
638 if (hSTickCompare && hSTickCompare->scheduled())
639 hstick_cmp = hSTickCompare->when();
640
641 SERIALIZE_OBJPTR(cpu);
642 SERIALIZE_SCALAR(tc_num);
643 SERIALIZE_SCALAR(tick_cmp);
644 SERIALIZE_SCALAR(stick_cmp);
645 SERIALIZE_SCALAR(hstick_cmp);
646 }
647#endif
648}
649
650void
651ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
652{
653 UNSERIALIZE_SCALAR(asi);
654 UNSERIALIZE_SCALAR(tick);
655 UNSERIALIZE_SCALAR(fprs);
656 UNSERIALIZE_SCALAR(gsr);
657 UNSERIALIZE_SCALAR(softint);
658 UNSERIALIZE_SCALAR(tick_cmpr);
659 UNSERIALIZE_SCALAR(stick);
660 UNSERIALIZE_SCALAR(stick_cmpr);
661 UNSERIALIZE_ARRAY(tpc,MaxTL);
662 UNSERIALIZE_ARRAY(tnpc,MaxTL);
663 UNSERIALIZE_ARRAY(tstate,MaxTL);
664 UNSERIALIZE_ARRAY(tt,MaxTL);
665 UNSERIALIZE_SCALAR(tba);
666 UNSERIALIZE_SCALAR(pstate);
667 UNSERIALIZE_SCALAR(tl);
668 UNSERIALIZE_SCALAR(pil);
669 UNSERIALIZE_SCALAR(cwp);
670 UNSERIALIZE_SCALAR(gl);
671 UNSERIALIZE_SCALAR(hpstate);
672 UNSERIALIZE_ARRAY(htstate,MaxTL);
673 UNSERIALIZE_SCALAR(hintp);
674 UNSERIALIZE_SCALAR(htba);
675 UNSERIALIZE_SCALAR(hstick_cmpr);
676 UNSERIALIZE_SCALAR(strandStatusReg);
677 UNSERIALIZE_SCALAR(fsr);
678 UNSERIALIZE_SCALAR(priContext);
679 UNSERIALIZE_SCALAR(secContext);
680 UNSERIALIZE_SCALAR(partId);
681 UNSERIALIZE_SCALAR(lsuCtrlReg);
682 UNSERIALIZE_ARRAY(scratchPad,8);
683 UNSERIALIZE_SCALAR(cpu_mondo_head);
684 UNSERIALIZE_SCALAR(cpu_mondo_tail);
685 UNSERIALIZE_SCALAR(dev_mondo_head);
686 UNSERIALIZE_SCALAR(dev_mondo_tail);
687 UNSERIALIZE_SCALAR(res_error_head);
688 UNSERIALIZE_SCALAR(res_error_tail);
689 UNSERIALIZE_SCALAR(nres_error_head);
690 UNSERIALIZE_SCALAR(nres_error_tail);
691
692#if FULL_SYSTEM
693 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
694 ThreadContext *tc = NULL;
695 BaseCPU *cpu = NULL;
696 int tc_num;
697 bool tick_intr_sched;
698 UNSERIALIZE_SCALAR(tick_intr_sched);
699 if (tick_intr_sched) {
700 UNSERIALIZE_OBJPTR(cpu);
701 if (cpu) {
702 UNSERIALIZE_SCALAR(tc_num);
703 UNSERIALIZE_SCALAR(tick_cmp);
704 UNSERIALIZE_SCALAR(stick_cmp);
705 UNSERIALIZE_SCALAR(hstick_cmp);
706 tc = cpu->getContext(tc_num);
707
708 if (tick_cmp) {
709 tickCompare = new TickCompareEvent(this, tc);
710 em->schedule(tickCompare, tick_cmp);
711 }
712 if (stick_cmp) {
713 sTickCompare = new STickCompareEvent(this, tc);
714 em->schedule(sTickCompare, stick_cmp);
715 }
716 if (hstick_cmp) {
717 hSTickCompare = new HSTickCompareEvent(this, tc);
718 em->schedule(hSTickCompare, hstick_cmp);
719 }
720 }
721 }
722
723 #endif
724}
725
726int
727ISA::flattenIntIndex(int reg)
728{
729 int gl = readMiscRegNoEffect(MISCREG_GL);
730 int cwp = readMiscRegNoEffect(MISCREG_CWP);
731 //DPRINTF(RegisterWindows, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp);
732 int newReg;
733 //The total number of global registers
734 int numGlobals = (MaxGL + 1) * 8;
735 if(reg < 8)
736 {
737 //Global register
738 //Put it in the appropriate set of globals
739 newReg = reg + gl * 8;
740 }
741 else if(reg < NumIntArchRegs)
742 {
743 //Regular windowed register
744 //Put it in the window pointed to by cwp
745 newReg = numGlobals +
746 ((reg - 8 - cwp * 16 + NWindows * 16) % (NWindows * 16));
747 }
748 else if(reg < NumIntArchRegs + NumMicroIntRegs)
749 {
750 //Microcode register
751 //Displace from the end of the regular registers
752 newReg = reg - NumIntArchRegs + numGlobals + NWindows * 16;
753 }
754 else if(reg < 2 * NumIntArchRegs + NumMicroIntRegs)
755 {
756 reg -= (NumIntArchRegs + NumMicroIntRegs);
757 if(reg < 8)
758 {
759 //Global register from the next window
760 //Put it in the appropriate set of globals
761 newReg = reg + gl * 8;
762 }
763 else
764 {
765 //Windowed register from the previous window
766 //Put it in the window before the one pointed to by cwp
767 newReg = numGlobals +
768 ((reg - 8 - (cwp - 1) * 16 + NWindows * 16) % (NWindows * 16));
769 }
770 }
771 else if(reg < 3 * NumIntArchRegs + NumMicroIntRegs)
772 {
773 reg -= (2 * NumIntArchRegs + NumMicroIntRegs);
774 if(reg < 8)
775 {
776 //Global register from the previous window
777 //Put it in the appropriate set of globals
778 newReg = reg + gl * 8;
779 }
780 else
781 {
782 //Windowed register from the next window
783 //Put it in the window after the one pointed to by cwp
784 newReg = numGlobals +
785 ((reg - 8 - (cwp + 1) * 16 + NWindows * 16) % (NWindows * 16));
786 }
787 }
788 else
789 panic("Tried to flatten invalid register index %d!\n", reg);
790 DPRINTF(RegisterWindows, "Flattened register %d to %d.\n", reg, newReg);
791 return newReg;
792}
793
794}