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