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