isa.cc revision 8794:e2ac2b7164dd
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
40namespace SparcISA
41{
42
43enum RegMask
44{
45    PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
46};
47
48void
49ISA::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
62void
63ISA::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
72void
73ISA::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
82void
83ISA::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
144MiscReg
145ISA::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
304MiscReg
305ISA::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
352void
353ISA::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
532void
533ISA::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
603void
604ISA::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
679void
680ISA::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}
755