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