isa.cc revision 8059
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::reloadRegMap()
49{
50    installGlobals(gl, CurrentGlobalsOffset);
51    installWindow(cwp, CurrentWindowOffset);
52    // Microcode registers.
53    for (int i = 0; i < NumMicroIntRegs; i++)
54        intRegMap[MicroIntOffset + i] = i + TotalGlobals + NWindows * 16;
55    installGlobals(gl, NextGlobalsOffset);
56    installWindow(cwp - 1, NextWindowOffset);
57    installGlobals(gl, PreviousGlobalsOffset);
58    installWindow(cwp + 1, PreviousWindowOffset);
59}
60
61void
62ISA::installWindow(int cwp, int offset)
63{
64    assert(offset >= 0 && offset + NumWindowedRegs <= NumIntRegs);
65    RegIndex *mapChunk = intRegMap + offset;
66    for (int i = 0; i < NumWindowedRegs; i++)
67        mapChunk[i] = TotalGlobals +
68            ((i - cwp * RegsPerWindow + TotalWindowed) % (TotalWindowed));
69}
70
71void
72ISA::installGlobals(int gl, int offset)
73{
74    assert(offset >= 0 && offset + NumGlobalRegs <= NumIntRegs);
75    RegIndex *mapChunk = intRegMap + offset;
76    mapChunk[0] = 0;
77    for (int i = 1; i < NumGlobalRegs; i++)
78        mapChunk[i] = i + gl * NumGlobalRegs;
79}
80
81void
82ISA::clear()
83{
84    cwp = 0;
85    gl = 0;
86    reloadRegMap();
87
88    // y = 0;
89    // ccr = 0;
90    asi = 0;
91    tick = ULL(1) << 63;
92    fprs = 0;
93    gsr = 0;
94    softint = 0;
95    tick_cmpr = 0;
96    stick = 0;
97    stick_cmpr = 0;
98    memset(tpc, 0, sizeof(tpc));
99    memset(tnpc, 0, sizeof(tnpc));
100    memset(tstate, 0, sizeof(tstate));
101    memset(tt, 0, sizeof(tt));
102    tba = 0;
103    pstate = 0;
104    tl = 0;
105    pil = 0;
106    // cansave = 0;
107    // canrestore = 0;
108    // cleanwin = 0;
109    // otherwin = 0;
110    // wstate = 0;
111    // In a T1, bit 11 is apparently always 1
112    hpstate = (1 << 11);
113    memset(htstate, 0, sizeof(htstate));
114    hintp = 0;
115    htba = 0;
116    hstick_cmpr = 0;
117    // This is set this way in Legion for some reason
118    strandStatusReg = 0x50000;
119    fsr = 0;
120
121    priContext = 0;
122    secContext = 0;
123    partId = 0;
124    lsuCtrlReg = 0;
125
126    memset(scratchPad, 0, sizeof(scratchPad));
127
128    cpu_mondo_head = 0;
129    cpu_mondo_tail = 0;
130    dev_mondo_head = 0;
131    dev_mondo_tail = 0;
132    res_error_head = 0;
133    res_error_tail = 0;
134    nres_error_head = 0;
135    nres_error_tail = 0;
136
137#if FULL_SYSTEM
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#endif
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#if FULL_SYSTEM
348      case MISCREG_HPSTATE:
349        return readFSReg(miscReg, tc);
350#else
351      case MISCREG_HPSTATE:
352        // HPSTATE is special because because sometimes in privilege
353        // checks for instructions it will read HPSTATE to make sure
354        // the priv. level is ok So, we'll just have to tell it it
355        // isn't, instead of panicing.
356        return 0;
357
358      panic("Accessing Fullsystem register %d in SE mode\n", miscReg);
359#endif
360
361    }
362    return readMiscRegNoEffect(miscReg);
363}
364
365void
366ISA::setMiscRegNoEffect(int miscReg, MiscReg val)
367{
368    switch (miscReg) {
369//      case MISCREG_Y:
370//        y = val;
371//        break;
372//      case MISCREG_CCR:
373//        ccr = val;
374//        break;
375      case MISCREG_ASI:
376        asi = val;
377        break;
378      case MISCREG_FPRS:
379        fprs = val;
380        break;
381      case MISCREG_TICK:
382        tick = val;
383        break;
384      case MISCREG_PCR:
385        panic("PCR not implemented\n");
386      case MISCREG_PIC:
387        panic("PIC not implemented\n");
388      case MISCREG_GSR:
389        gsr = val;
390        break;
391      case MISCREG_SOFTINT:
392        softint = val;
393        break;
394      case MISCREG_TICK_CMPR:
395        tick_cmpr = val;
396        break;
397      case MISCREG_STICK:
398        stick = val;
399        break;
400      case MISCREG_STICK_CMPR:
401        stick_cmpr = val;
402        break;
403
404        /** Privilged Registers */
405      case MISCREG_TPC:
406        tpc[tl-1] = val;
407        break;
408      case MISCREG_TNPC:
409        tnpc[tl-1] = val;
410        break;
411      case MISCREG_TSTATE:
412        tstate[tl-1] = val;
413        break;
414      case MISCREG_TT:
415        tt[tl-1] = val;
416        break;
417      case MISCREG_PRIVTICK:
418        panic("Priviliged access to tick regesiters not implemented\n");
419      case MISCREG_TBA:
420        // clear lower 7 bits on writes.
421        tba = val & ULL(~0x7FFF);
422        break;
423      case MISCREG_PSTATE:
424        pstate = (val & PSTATE_MASK);
425        break;
426      case MISCREG_TL:
427        tl = val;
428        break;
429      case MISCREG_PIL:
430        pil = val;
431        break;
432      case MISCREG_CWP:
433        cwp = val;
434        break;
435//      case MISCREG_CANSAVE:
436//        cansave = val;
437//        break;
438//      case MISCREG_CANRESTORE:
439//        canrestore = val;
440//        break;
441//      case MISCREG_CLEANWIN:
442//        cleanwin = val;
443//        break;
444//      case MISCREG_OTHERWIN:
445//        otherwin = val;
446//        break;
447//      case MISCREG_WSTATE:
448//        wstate = val;
449//        break;
450      case MISCREG_GL:
451        gl = val;
452        break;
453
454        /** Hyper privileged registers */
455      case MISCREG_HPSTATE:
456        hpstate = val;
457        break;
458      case MISCREG_HTSTATE:
459        htstate[tl-1] = val;
460        break;
461      case MISCREG_HINTP:
462        hintp = val;
463      case MISCREG_HTBA:
464        htba = val;
465        break;
466      case MISCREG_STRAND_STS_REG:
467        strandStatusReg = val;
468        break;
469      case MISCREG_HSTICK_CMPR:
470        hstick_cmpr = val;
471        break;
472
473        /** Floating Point Status Register */
474      case MISCREG_FSR:
475        fsr = val;
476        DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr);
477        break;
478
479      case MISCREG_MMU_P_CONTEXT:
480        priContext = val;
481        break;
482      case MISCREG_MMU_S_CONTEXT:
483        secContext = val;
484        break;
485      case MISCREG_MMU_PART_ID:
486        partId = val;
487        break;
488      case MISCREG_MMU_LSU_CTRL:
489        lsuCtrlReg = val;
490        break;
491
492      case MISCREG_SCRATCHPAD_R0:
493        scratchPad[0] = val;
494        break;
495      case MISCREG_SCRATCHPAD_R1:
496        scratchPad[1] = val;
497        break;
498      case MISCREG_SCRATCHPAD_R2:
499        scratchPad[2] = val;
500        break;
501      case MISCREG_SCRATCHPAD_R3:
502        scratchPad[3] = val;
503        break;
504      case MISCREG_SCRATCHPAD_R4:
505        scratchPad[4] = val;
506        break;
507      case MISCREG_SCRATCHPAD_R5:
508        scratchPad[5] = val;
509        break;
510      case MISCREG_SCRATCHPAD_R6:
511        scratchPad[6] = val;
512        break;
513      case MISCREG_SCRATCHPAD_R7:
514        scratchPad[7] = val;
515        break;
516      case MISCREG_QUEUE_CPU_MONDO_HEAD:
517        cpu_mondo_head = val;
518        break;
519      case MISCREG_QUEUE_CPU_MONDO_TAIL:
520        cpu_mondo_tail = val;
521        break;
522      case MISCREG_QUEUE_DEV_MONDO_HEAD:
523        dev_mondo_head = val;
524        break;
525      case MISCREG_QUEUE_DEV_MONDO_TAIL:
526        dev_mondo_tail = val;
527        break;
528      case MISCREG_QUEUE_RES_ERROR_HEAD:
529        res_error_head = val;
530        break;
531      case MISCREG_QUEUE_RES_ERROR_TAIL:
532        res_error_tail = val;
533        break;
534      case MISCREG_QUEUE_NRES_ERROR_HEAD:
535        nres_error_head = val;
536        break;
537      case MISCREG_QUEUE_NRES_ERROR_TAIL:
538        nres_error_tail = val;
539        break;
540      default:
541        panic("Miscellaneous register %d not implemented\n", miscReg);
542    }
543}
544
545void
546ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc)
547{
548    MiscReg new_val = val;
549
550    switch (miscReg) {
551      case MISCREG_STICK:
552      case MISCREG_TICK:
553        // stick and tick are same thing on niagra
554        // use stick for offset and tick for holding intrrupt bit
555        stick = mbits(val,62,0) - tc->getCpuPtr()->instCount();
556        tick = mbits(val,63,63);
557        DPRINTF(Timer, "Writing TICK=%#X\n", val);
558        break;
559      case MISCREG_FPRS:
560        // Configure the fpu based on the fprs
561        break;
562      case MISCREG_PCR:
563        // Set up performance counting based on pcr value
564        break;
565      case MISCREG_PSTATE:
566        pstate = val & PSTATE_MASK;
567        return;
568      case MISCREG_TL:
569        tl = val;
570#if FULL_SYSTEM
571        if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
572            tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
573        else
574            tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
575#endif
576        return;
577      case MISCREG_CWP:
578        new_val = val >= NWindows ? NWindows - 1 : val;
579        if (val >= NWindows)
580            new_val = NWindows - 1;
581
582        installWindow(new_val, CurrentWindowOffset);
583        installWindow(new_val - 1, NextWindowOffset);
584        installWindow(new_val + 1, PreviousWindowOffset);
585        break;
586      case MISCREG_GL:
587        installGlobals(val, CurrentGlobalsOffset);
588        installGlobals(val, NextGlobalsOffset);
589        installGlobals(val, PreviousGlobalsOffset);
590        break;
591      case MISCREG_PIL:
592      case MISCREG_SOFTINT:
593      case MISCREG_SOFTINT_SET:
594      case MISCREG_SOFTINT_CLR:
595      case MISCREG_TICK_CMPR:
596      case MISCREG_STICK_CMPR:
597      case MISCREG_HINTP:
598      case MISCREG_HTSTATE:
599      case MISCREG_HTBA:
600      case MISCREG_HVER:
601      case MISCREG_STRAND_STS_REG:
602      case MISCREG_HSTICK_CMPR:
603      case MISCREG_QUEUE_CPU_MONDO_HEAD:
604      case MISCREG_QUEUE_CPU_MONDO_TAIL:
605      case MISCREG_QUEUE_DEV_MONDO_HEAD:
606      case MISCREG_QUEUE_DEV_MONDO_TAIL:
607      case MISCREG_QUEUE_RES_ERROR_HEAD:
608      case MISCREG_QUEUE_RES_ERROR_TAIL:
609      case MISCREG_QUEUE_NRES_ERROR_HEAD:
610      case MISCREG_QUEUE_NRES_ERROR_TAIL:
611#if FULL_SYSTEM
612      case MISCREG_HPSTATE:
613        setFSReg(miscReg, val, tc);
614        return;
615#else
616      case MISCREG_HPSTATE:
617        // HPSTATE is special because normal trap processing saves HPSTATE when
618        // it goes into a trap, and restores it when it returns.
619        return;
620      panic("Accessing Fullsystem register %d to %#x in SE mode\n",
621              miscReg, val);
622#endif
623    }
624    setMiscRegNoEffect(miscReg, new_val);
625}
626
627void
628ISA::serialize(EventManager *em, std::ostream &os)
629{
630    SERIALIZE_SCALAR(asi);
631    SERIALIZE_SCALAR(tick);
632    SERIALIZE_SCALAR(fprs);
633    SERIALIZE_SCALAR(gsr);
634    SERIALIZE_SCALAR(softint);
635    SERIALIZE_SCALAR(tick_cmpr);
636    SERIALIZE_SCALAR(stick);
637    SERIALIZE_SCALAR(stick_cmpr);
638    SERIALIZE_ARRAY(tpc,MaxTL);
639    SERIALIZE_ARRAY(tnpc,MaxTL);
640    SERIALIZE_ARRAY(tstate,MaxTL);
641    SERIALIZE_ARRAY(tt,MaxTL);
642    SERIALIZE_SCALAR(tba);
643    SERIALIZE_SCALAR(pstate);
644    SERIALIZE_SCALAR(tl);
645    SERIALIZE_SCALAR(pil);
646    SERIALIZE_SCALAR(cwp);
647    SERIALIZE_SCALAR(gl);
648    SERIALIZE_SCALAR(hpstate);
649    SERIALIZE_ARRAY(htstate,MaxTL);
650    SERIALIZE_SCALAR(hintp);
651    SERIALIZE_SCALAR(htba);
652    SERIALIZE_SCALAR(hstick_cmpr);
653    SERIALIZE_SCALAR(strandStatusReg);
654    SERIALIZE_SCALAR(fsr);
655    SERIALIZE_SCALAR(priContext);
656    SERIALIZE_SCALAR(secContext);
657    SERIALIZE_SCALAR(partId);
658    SERIALIZE_SCALAR(lsuCtrlReg);
659    SERIALIZE_ARRAY(scratchPad,8);
660    SERIALIZE_SCALAR(cpu_mondo_head);
661    SERIALIZE_SCALAR(cpu_mondo_tail);
662    SERIALIZE_SCALAR(dev_mondo_head);
663    SERIALIZE_SCALAR(dev_mondo_tail);
664    SERIALIZE_SCALAR(res_error_head);
665    SERIALIZE_SCALAR(res_error_tail);
666    SERIALIZE_SCALAR(nres_error_head);
667    SERIALIZE_SCALAR(nres_error_tail);
668#if FULL_SYSTEM
669    Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
670    ThreadContext *tc = NULL;
671    BaseCPU *cpu = NULL;
672    int tc_num = 0;
673    bool tick_intr_sched = true;
674
675    if (tickCompare)
676        tc = tickCompare->getTC();
677    else if (sTickCompare)
678        tc = sTickCompare->getTC();
679    else if (hSTickCompare)
680        tc = hSTickCompare->getTC();
681    else
682        tick_intr_sched = false;
683
684    SERIALIZE_SCALAR(tick_intr_sched);
685
686    if (tc) {
687        cpu = tc->getCpuPtr();
688        tc_num = cpu->findContext(tc);
689        if (tickCompare && tickCompare->scheduled())
690            tick_cmp = tickCompare->when();
691        if (sTickCompare && sTickCompare->scheduled())
692            stick_cmp = sTickCompare->when();
693        if (hSTickCompare && hSTickCompare->scheduled())
694            hstick_cmp = hSTickCompare->when();
695
696        SERIALIZE_OBJPTR(cpu);
697        SERIALIZE_SCALAR(tc_num);
698        SERIALIZE_SCALAR(tick_cmp);
699        SERIALIZE_SCALAR(stick_cmp);
700        SERIALIZE_SCALAR(hstick_cmp);
701    }
702#endif
703}
704
705void
706ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
707{
708    UNSERIALIZE_SCALAR(asi);
709    UNSERIALIZE_SCALAR(tick);
710    UNSERIALIZE_SCALAR(fprs);
711    UNSERIALIZE_SCALAR(gsr);
712    UNSERIALIZE_SCALAR(softint);
713    UNSERIALIZE_SCALAR(tick_cmpr);
714    UNSERIALIZE_SCALAR(stick);
715    UNSERIALIZE_SCALAR(stick_cmpr);
716    UNSERIALIZE_ARRAY(tpc,MaxTL);
717    UNSERIALIZE_ARRAY(tnpc,MaxTL);
718    UNSERIALIZE_ARRAY(tstate,MaxTL);
719    UNSERIALIZE_ARRAY(tt,MaxTL);
720    UNSERIALIZE_SCALAR(tba);
721    UNSERIALIZE_SCALAR(pstate);
722    UNSERIALIZE_SCALAR(tl);
723    UNSERIALIZE_SCALAR(pil);
724    UNSERIALIZE_SCALAR(cwp);
725    UNSERIALIZE_SCALAR(gl);
726    reloadRegMap();
727    UNSERIALIZE_SCALAR(hpstate);
728    UNSERIALIZE_ARRAY(htstate,MaxTL);
729    UNSERIALIZE_SCALAR(hintp);
730    UNSERIALIZE_SCALAR(htba);
731    UNSERIALIZE_SCALAR(hstick_cmpr);
732    UNSERIALIZE_SCALAR(strandStatusReg);
733    UNSERIALIZE_SCALAR(fsr);
734    UNSERIALIZE_SCALAR(priContext);
735    UNSERIALIZE_SCALAR(secContext);
736    UNSERIALIZE_SCALAR(partId);
737    UNSERIALIZE_SCALAR(lsuCtrlReg);
738    UNSERIALIZE_ARRAY(scratchPad,8);
739    UNSERIALIZE_SCALAR(cpu_mondo_head);
740    UNSERIALIZE_SCALAR(cpu_mondo_tail);
741    UNSERIALIZE_SCALAR(dev_mondo_head);
742    UNSERIALIZE_SCALAR(dev_mondo_tail);
743    UNSERIALIZE_SCALAR(res_error_head);
744    UNSERIALIZE_SCALAR(res_error_tail);
745    UNSERIALIZE_SCALAR(nres_error_head);
746    UNSERIALIZE_SCALAR(nres_error_tail);
747
748#if FULL_SYSTEM
749    Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
750    ThreadContext *tc = NULL;
751    BaseCPU *cpu = NULL;
752    int tc_num;
753    bool tick_intr_sched;
754    UNSERIALIZE_SCALAR(tick_intr_sched);
755    if (tick_intr_sched) {
756        UNSERIALIZE_OBJPTR(cpu);
757        if (cpu) {
758            UNSERIALIZE_SCALAR(tc_num);
759            UNSERIALIZE_SCALAR(tick_cmp);
760            UNSERIALIZE_SCALAR(stick_cmp);
761            UNSERIALIZE_SCALAR(hstick_cmp);
762            tc = cpu->getContext(tc_num);
763
764            if (tick_cmp) {
765                tickCompare = new TickCompareEvent(this, tc);
766                em->schedule(tickCompare, tick_cmp);
767            }
768            if (stick_cmp)  {
769                sTickCompare = new STickCompareEvent(this, tc);
770                em->schedule(sTickCompare, stick_cmp);
771            }
772            if (hstick_cmp)  {
773                hSTickCompare = new HSTickCompareEvent(this, tc);
774                em->schedule(hSTickCompare, hstick_cmp);
775            }
776        }
777    }
778
779 #endif
780}
781
782}
783