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