isa.cc revision 6337:cac56cd6b015
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    pstate = 0;
103    tl = 0;
104    pil = 0;
105    //cansave = 0;
106    //canrestore = 0;
107    //cleanwin = 0;
108    //otherwin = 0;
109    //wstate = 0;
110    //In a T1, bit 11 is apparently always 1
111    hpstate = (1 << 11);
112    memset(htstate, 0, sizeof(htstate));
113    hintp = 0;
114    htba = 0;
115    hstick_cmpr = 0;
116    //This is set this way in Legion for some reason
117    strandStatusReg = 0x50000;
118    fsr = 0;
119
120    priContext = 0;
121    secContext = 0;
122    partId = 0;
123    lsuCtrlReg = 0;
124
125    memset(scratchPad, 0, sizeof(scratchPad));
126#if FULL_SYSTEM
127    tickCompare = NULL;
128    sTickCompare = NULL;
129    hSTickCompare = NULL;
130#endif
131}
132
133MiscReg
134ISA::readMiscRegNoEffect(int miscReg)
135{
136
137  // The three miscRegs are moved up from the switch statement
138  // due to more frequent calls.
139
140  if (miscReg == MISCREG_GL)
141    return gl;
142  if (miscReg == MISCREG_CWP)
143    return cwp;
144  if (miscReg == MISCREG_TLB_DATA) {
145    /* Package up all the data for the tlb:
146     * 6666555555555544444444443333333333222222222211111111110000000000
147     * 3210987654321098765432109876543210987654321098765432109876543210
148     *   secContext   | priContext    |             |tl|partid|  |||||^hpriv
149     *                                                           ||||^red
150     *                                                           |||^priv
151     *                                                           ||^am
152     *                                                           |^lsuim
153     *                                                           ^lsudm
154     */
155    return bits((uint64_t)hpstate,2,2) |
156           bits((uint64_t)hpstate,5,5) << 1 |
157           bits((uint64_t)pstate,3,2) << 2 |
158           bits((uint64_t)lsuCtrlReg,3,2) << 4 |
159           bits((uint64_t)partId,7,0) << 8 |
160           bits((uint64_t)tl,2,0) << 16 |
161                (uint64_t)priContext << 32 |
162                (uint64_t)secContext << 48;
163  }
164
165    switch (miscReg) {
166      //case MISCREG_TLB_DATA:
167      //  [original contents see above]
168      //case MISCREG_Y:
169      //  return y;
170      //case MISCREG_CCR:
171      //  return ccr;
172      case MISCREG_ASI:
173        return asi;
174      case MISCREG_FPRS:
175        return fprs;
176      case MISCREG_TICK:
177        return tick;
178      case MISCREG_PCR:
179        panic("PCR not implemented\n");
180      case MISCREG_PIC:
181        panic("PIC not implemented\n");
182      case MISCREG_GSR:
183        return gsr;
184      case MISCREG_SOFTINT:
185        return softint;
186      case MISCREG_TICK_CMPR:
187        return tick_cmpr;
188      case MISCREG_STICK:
189        return stick;
190      case MISCREG_STICK_CMPR:
191        return stick_cmpr;
192
193        /** Privilged Registers */
194      case MISCREG_TPC:
195        return tpc[tl-1];
196      case MISCREG_TNPC:
197        return tnpc[tl-1];
198      case MISCREG_TSTATE:
199        return tstate[tl-1];
200      case MISCREG_TT:
201        return tt[tl-1];
202      case MISCREG_PRIVTICK:
203        panic("Priviliged access to tick registers not implemented\n");
204      case MISCREG_TBA:
205        return tba;
206      case MISCREG_PSTATE:
207        return pstate;
208      case MISCREG_TL:
209        return tl;
210      case MISCREG_PIL:
211        return pil;
212      //CWP, GL moved
213      //case MISCREG_CWP:
214      //  return cwp;
215      //case MISCREG_CANSAVE:
216      //  return cansave;
217      //case MISCREG_CANRESTORE:
218      //  return canrestore;
219      //case MISCREG_CLEANWIN:
220      //  return cleanwin;
221      //case MISCREG_OTHERWIN:
222      //  return otherwin;
223      //case MISCREG_WSTATE:
224      //  return wstate;
225      //case MISCREG_GL:
226      //  return gl;
227
228        /** Hyper privileged registers */
229      case MISCREG_HPSTATE:
230        return hpstate;
231      case MISCREG_HTSTATE:
232        return htstate[tl-1];
233      case MISCREG_HINTP:
234        return hintp;
235      case MISCREG_HTBA:
236        return htba;
237      case MISCREG_STRAND_STS_REG:
238        return strandStatusReg;
239      case MISCREG_HSTICK_CMPR:
240        return hstick_cmpr;
241
242        /** Floating Point Status Register */
243      case MISCREG_FSR:
244        DPRINTF(MiscRegs, "FSR read as: %#x\n", fsr);
245        return fsr;
246
247      case MISCREG_MMU_P_CONTEXT:
248        return priContext;
249      case MISCREG_MMU_S_CONTEXT:
250        return secContext;
251      case MISCREG_MMU_PART_ID:
252        return partId;
253      case MISCREG_MMU_LSU_CTRL:
254        return lsuCtrlReg;
255
256      case MISCREG_SCRATCHPAD_R0:
257        return scratchPad[0];
258      case MISCREG_SCRATCHPAD_R1:
259        return scratchPad[1];
260      case MISCREG_SCRATCHPAD_R2:
261        return scratchPad[2];
262      case MISCREG_SCRATCHPAD_R3:
263        return scratchPad[3];
264      case MISCREG_SCRATCHPAD_R4:
265        return scratchPad[4];
266      case MISCREG_SCRATCHPAD_R5:
267        return scratchPad[5];
268      case MISCREG_SCRATCHPAD_R6:
269        return scratchPad[6];
270      case MISCREG_SCRATCHPAD_R7:
271        return scratchPad[7];
272      case MISCREG_QUEUE_CPU_MONDO_HEAD:
273        return cpu_mondo_head;
274      case MISCREG_QUEUE_CPU_MONDO_TAIL:
275        return cpu_mondo_tail;
276      case MISCREG_QUEUE_DEV_MONDO_HEAD:
277        return dev_mondo_head;
278      case MISCREG_QUEUE_DEV_MONDO_TAIL:
279        return dev_mondo_tail;
280      case MISCREG_QUEUE_RES_ERROR_HEAD:
281        return res_error_head;
282      case MISCREG_QUEUE_RES_ERROR_TAIL:
283        return res_error_tail;
284      case MISCREG_QUEUE_NRES_ERROR_HEAD:
285        return nres_error_head;
286      case MISCREG_QUEUE_NRES_ERROR_TAIL:
287        return nres_error_tail;
288      default:
289        panic("Miscellaneous register %d not implemented\n", miscReg);
290    }
291}
292
293MiscReg
294ISA::readMiscReg(int miscReg, ThreadContext * tc)
295{
296    switch (miscReg) {
297        // tick and stick are aliased to each other in niagra
298        // well store the tick data in stick and the interrupt bit in tick
299      case MISCREG_STICK:
300      case MISCREG_TICK:
301      case MISCREG_PRIVTICK:
302        // I'm not sure why legion ignores the lowest two bits, but we'll go
303        // with it
304        // change from curCycle() to instCount() until we're done with legion
305        DPRINTF(Timer, "Instruction Count when TICK read: %#X stick=%#X\n",
306                tc->getCpuPtr()->instCount(), stick);
307        return mbits(tc->getCpuPtr()->instCount() + (int64_t)stick,62,2) |
308               mbits(tick,63,63);
309      case MISCREG_FPRS:
310        // in legion if fp is enabled du and dl are set
311        return fprs | 0x3;
312      case MISCREG_PCR:
313      case MISCREG_PIC:
314        panic("Performance Instrumentation not impl\n");
315      case MISCREG_SOFTINT_CLR:
316      case MISCREG_SOFTINT_SET:
317        panic("Can read from softint clr/set\n");
318      case MISCREG_SOFTINT:
319      case MISCREG_TICK_CMPR:
320      case MISCREG_STICK_CMPR:
321      case MISCREG_HINTP:
322      case MISCREG_HTSTATE:
323      case MISCREG_HTBA:
324      case MISCREG_HVER:
325      case MISCREG_STRAND_STS_REG:
326      case MISCREG_HSTICK_CMPR:
327      case MISCREG_QUEUE_CPU_MONDO_HEAD:
328      case MISCREG_QUEUE_CPU_MONDO_TAIL:
329      case MISCREG_QUEUE_DEV_MONDO_HEAD:
330      case MISCREG_QUEUE_DEV_MONDO_TAIL:
331      case MISCREG_QUEUE_RES_ERROR_HEAD:
332      case MISCREG_QUEUE_RES_ERROR_TAIL:
333      case MISCREG_QUEUE_NRES_ERROR_HEAD:
334      case MISCREG_QUEUE_NRES_ERROR_TAIL:
335#if FULL_SYSTEM
336      case MISCREG_HPSTATE:
337        return readFSReg(miscReg, tc);
338#else
339      case MISCREG_HPSTATE:
340        //HPSTATE is special because because sometimes in privilege
341        //checks for instructions it will read HPSTATE to make sure
342        //the priv. level is ok So, we'll just have to tell it it
343        //isn't, instead of panicing.
344        return 0;
345
346      panic("Accessing Fullsystem register %d in SE mode\n", miscReg);
347#endif
348
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 FULL_SYSTEM
559        if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
560            tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
561        else
562            tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
563#endif
564        return;
565      case MISCREG_CWP:
566        new_val = val >= NWindows ? NWindows - 1 : val;
567        if (val >= NWindows)
568            new_val = NWindows - 1;
569
570        installWindow(new_val, CurrentWindowOffset);
571        installWindow(new_val - 1, NextWindowOffset);
572        installWindow(new_val + 1, PreviousWindowOffset);
573        break;
574      case MISCREG_GL:
575        installGlobals(val, CurrentGlobalsOffset);
576        installGlobals(val, NextGlobalsOffset);
577        installGlobals(val, PreviousGlobalsOffset);
578        break;
579      case MISCREG_PIL:
580      case MISCREG_SOFTINT:
581      case MISCREG_SOFTINT_SET:
582      case MISCREG_SOFTINT_CLR:
583      case MISCREG_TICK_CMPR:
584      case MISCREG_STICK_CMPR:
585      case MISCREG_HINTP:
586      case MISCREG_HTSTATE:
587      case MISCREG_HTBA:
588      case MISCREG_HVER:
589      case MISCREG_STRAND_STS_REG:
590      case MISCREG_HSTICK_CMPR:
591      case MISCREG_QUEUE_CPU_MONDO_HEAD:
592      case MISCREG_QUEUE_CPU_MONDO_TAIL:
593      case MISCREG_QUEUE_DEV_MONDO_HEAD:
594      case MISCREG_QUEUE_DEV_MONDO_TAIL:
595      case MISCREG_QUEUE_RES_ERROR_HEAD:
596      case MISCREG_QUEUE_RES_ERROR_TAIL:
597      case MISCREG_QUEUE_NRES_ERROR_HEAD:
598      case MISCREG_QUEUE_NRES_ERROR_TAIL:
599#if FULL_SYSTEM
600      case MISCREG_HPSTATE:
601        setFSReg(miscReg, val, tc);
602        return;
603#else
604      case MISCREG_HPSTATE:
605        //HPSTATE is special because normal trap processing saves HPSTATE when
606        //it goes into a trap, and restores it when it returns.
607        return;
608      panic("Accessing Fullsystem register %d to %#x in SE mode\n",
609              miscReg, val);
610#endif
611    }
612    setMiscRegNoEffect(miscReg, new_val);
613}
614
615void
616ISA::serialize(EventManager *em, std::ostream &os)
617{
618    SERIALIZE_SCALAR(asi);
619    SERIALIZE_SCALAR(tick);
620    SERIALIZE_SCALAR(fprs);
621    SERIALIZE_SCALAR(gsr);
622    SERIALIZE_SCALAR(softint);
623    SERIALIZE_SCALAR(tick_cmpr);
624    SERIALIZE_SCALAR(stick);
625    SERIALIZE_SCALAR(stick_cmpr);
626    SERIALIZE_ARRAY(tpc,MaxTL);
627    SERIALIZE_ARRAY(tnpc,MaxTL);
628    SERIALIZE_ARRAY(tstate,MaxTL);
629    SERIALIZE_ARRAY(tt,MaxTL);
630    SERIALIZE_SCALAR(tba);
631    SERIALIZE_SCALAR(pstate);
632    SERIALIZE_SCALAR(tl);
633    SERIALIZE_SCALAR(pil);
634    SERIALIZE_SCALAR(cwp);
635    SERIALIZE_SCALAR(gl);
636    SERIALIZE_SCALAR(hpstate);
637    SERIALIZE_ARRAY(htstate,MaxTL);
638    SERIALIZE_SCALAR(hintp);
639    SERIALIZE_SCALAR(htba);
640    SERIALIZE_SCALAR(hstick_cmpr);
641    SERIALIZE_SCALAR(strandStatusReg);
642    SERIALIZE_SCALAR(fsr);
643    SERIALIZE_SCALAR(priContext);
644    SERIALIZE_SCALAR(secContext);
645    SERIALIZE_SCALAR(partId);
646    SERIALIZE_SCALAR(lsuCtrlReg);
647    SERIALIZE_ARRAY(scratchPad,8);
648    SERIALIZE_SCALAR(cpu_mondo_head);
649    SERIALIZE_SCALAR(cpu_mondo_tail);
650    SERIALIZE_SCALAR(dev_mondo_head);
651    SERIALIZE_SCALAR(dev_mondo_tail);
652    SERIALIZE_SCALAR(res_error_head);
653    SERIALIZE_SCALAR(res_error_tail);
654    SERIALIZE_SCALAR(nres_error_head);
655    SERIALIZE_SCALAR(nres_error_tail);
656#if FULL_SYSTEM
657    Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
658    ThreadContext *tc = NULL;
659    BaseCPU *cpu = NULL;
660    int tc_num = 0;
661    bool tick_intr_sched = true;
662
663    if (tickCompare)
664        tc = tickCompare->getTC();
665    else if (sTickCompare)
666        tc = sTickCompare->getTC();
667    else if (hSTickCompare)
668        tc = hSTickCompare->getTC();
669    else
670        tick_intr_sched = false;
671
672    SERIALIZE_SCALAR(tick_intr_sched);
673
674    if (tc) {
675        cpu = tc->getCpuPtr();
676        tc_num = cpu->findContext(tc);
677        if (tickCompare && tickCompare->scheduled())
678            tick_cmp = tickCompare->when();
679        if (sTickCompare && sTickCompare->scheduled())
680            stick_cmp = sTickCompare->when();
681        if (hSTickCompare && hSTickCompare->scheduled())
682            hstick_cmp = hSTickCompare->when();
683
684        SERIALIZE_OBJPTR(cpu);
685        SERIALIZE_SCALAR(tc_num);
686        SERIALIZE_SCALAR(tick_cmp);
687        SERIALIZE_SCALAR(stick_cmp);
688        SERIALIZE_SCALAR(hstick_cmp);
689    }
690#endif
691}
692
693void
694ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
695{
696    UNSERIALIZE_SCALAR(asi);
697    UNSERIALIZE_SCALAR(tick);
698    UNSERIALIZE_SCALAR(fprs);
699    UNSERIALIZE_SCALAR(gsr);
700    UNSERIALIZE_SCALAR(softint);
701    UNSERIALIZE_SCALAR(tick_cmpr);
702    UNSERIALIZE_SCALAR(stick);
703    UNSERIALIZE_SCALAR(stick_cmpr);
704    UNSERIALIZE_ARRAY(tpc,MaxTL);
705    UNSERIALIZE_ARRAY(tnpc,MaxTL);
706    UNSERIALIZE_ARRAY(tstate,MaxTL);
707    UNSERIALIZE_ARRAY(tt,MaxTL);
708    UNSERIALIZE_SCALAR(tba);
709    UNSERIALIZE_SCALAR(pstate);
710    UNSERIALIZE_SCALAR(tl);
711    UNSERIALIZE_SCALAR(pil);
712    UNSERIALIZE_SCALAR(cwp);
713    UNSERIALIZE_SCALAR(gl);
714    reloadRegMap();
715    UNSERIALIZE_SCALAR(hpstate);
716    UNSERIALIZE_ARRAY(htstate,MaxTL);
717    UNSERIALIZE_SCALAR(hintp);
718    UNSERIALIZE_SCALAR(htba);
719    UNSERIALIZE_SCALAR(hstick_cmpr);
720    UNSERIALIZE_SCALAR(strandStatusReg);
721    UNSERIALIZE_SCALAR(fsr);
722    UNSERIALIZE_SCALAR(priContext);
723    UNSERIALIZE_SCALAR(secContext);
724    UNSERIALIZE_SCALAR(partId);
725    UNSERIALIZE_SCALAR(lsuCtrlReg);
726    UNSERIALIZE_ARRAY(scratchPad,8);
727    UNSERIALIZE_SCALAR(cpu_mondo_head);
728    UNSERIALIZE_SCALAR(cpu_mondo_tail);
729    UNSERIALIZE_SCALAR(dev_mondo_head);
730    UNSERIALIZE_SCALAR(dev_mondo_tail);
731    UNSERIALIZE_SCALAR(res_error_head);
732    UNSERIALIZE_SCALAR(res_error_tail);
733    UNSERIALIZE_SCALAR(nres_error_head);
734    UNSERIALIZE_SCALAR(nres_error_tail);
735
736#if FULL_SYSTEM
737    Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
738    ThreadContext *tc = NULL;
739    BaseCPU *cpu = NULL;
740    int tc_num;
741    bool tick_intr_sched;
742    UNSERIALIZE_SCALAR(tick_intr_sched);
743    if (tick_intr_sched) {
744        UNSERIALIZE_OBJPTR(cpu);
745        if (cpu) {
746            UNSERIALIZE_SCALAR(tc_num);
747            UNSERIALIZE_SCALAR(tick_cmp);
748            UNSERIALIZE_SCALAR(stick_cmp);
749            UNSERIALIZE_SCALAR(hstick_cmp);
750            tc = cpu->getContext(tc_num);
751
752            if (tick_cmp) {
753                tickCompare = new TickCompareEvent(this, tc);
754                em->schedule(tickCompare, tick_cmp);
755            }
756            if (stick_cmp)  {
757                sTickCompare = new STickCompareEvent(this, tc);
758                em->schedule(sTickCompare, stick_cmp);
759            }
760            if (hstick_cmp)  {
761                hSTickCompare = new HSTickCompareEvent(this, tc);
762                em->schedule(hSTickCompare, hstick_cmp);
763            }
764        }
765    }
766
767 #endif
768}
769
770}
771