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