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
176RegVal
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 (RegVal)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 (RegVal)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
337RegVal
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, RegVal 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        break;
484      case MISCREG_HTBA:
485        htba = val;
486        break;
487      case MISCREG_STRAND_STS_REG:
488        strandStatusReg = val;
489        break;
490      case MISCREG_HSTICK_CMPR:
491        hstick_cmpr = val;
492        break;
493
494        /** Floating Point Status Register */
495      case MISCREG_FSR:
496        fsr = val;
497        DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr);
498        break;
499
500      case MISCREG_MMU_P_CONTEXT:
501        priContext = val;
502        break;
503      case MISCREG_MMU_S_CONTEXT:
504        secContext = val;
505        break;
506      case MISCREG_MMU_PART_ID:
507        partId = val;
508        break;
509      case MISCREG_MMU_LSU_CTRL:
510        lsuCtrlReg = val;
511        break;
512
513      case MISCREG_SCRATCHPAD_R0:
514        scratchPad[0] = val;
515        break;
516      case MISCREG_SCRATCHPAD_R1:
517        scratchPad[1] = val;
518        break;
519      case MISCREG_SCRATCHPAD_R2:
520        scratchPad[2] = val;
521        break;
522      case MISCREG_SCRATCHPAD_R3:
523        scratchPad[3] = val;
524        break;
525      case MISCREG_SCRATCHPAD_R4:
526        scratchPad[4] = val;
527        break;
528      case MISCREG_SCRATCHPAD_R5:
529        scratchPad[5] = val;
530        break;
531      case MISCREG_SCRATCHPAD_R6:
532        scratchPad[6] = val;
533        break;
534      case MISCREG_SCRATCHPAD_R7:
535        scratchPad[7] = val;
536        break;
537      case MISCREG_QUEUE_CPU_MONDO_HEAD:
538        cpu_mondo_head = val;
539        break;
540      case MISCREG_QUEUE_CPU_MONDO_TAIL:
541        cpu_mondo_tail = val;
542        break;
543      case MISCREG_QUEUE_DEV_MONDO_HEAD:
544        dev_mondo_head = val;
545        break;
546      case MISCREG_QUEUE_DEV_MONDO_TAIL:
547        dev_mondo_tail = val;
548        break;
549      case MISCREG_QUEUE_RES_ERROR_HEAD:
550        res_error_head = val;
551        break;
552      case MISCREG_QUEUE_RES_ERROR_TAIL:
553        res_error_tail = val;
554        break;
555      case MISCREG_QUEUE_NRES_ERROR_HEAD:
556        nres_error_head = val;
557        break;
558      case MISCREG_QUEUE_NRES_ERROR_TAIL:
559        nres_error_tail = val;
560        break;
561      default:
562        panic("Miscellaneous register %d not implemented\n", miscReg);
563    }
564}
565
566void
567ISA::setMiscReg(int miscReg, RegVal val, ThreadContext * tc)
568{
569    RegVal new_val = val;
570
571    switch (miscReg) {
572      case MISCREG_ASI:
573        tc->getDecoderPtr()->setContext(val);
574        break;
575      case MISCREG_STICK:
576      case MISCREG_TICK:
577        // stick and tick are same thing on niagra
578        // use stick for offset and tick for holding intrrupt bit
579        stick = mbits(val,62,0) - tc->getCpuPtr()->instCount();
580        tick = mbits(val,63,63);
581        DPRINTF(Timer, "Writing TICK=%#X\n", val);
582        break;
583      case MISCREG_FPRS:
584        // Configure the fpu based on the fprs
585        break;
586      case MISCREG_PCR:
587        // Set up performance counting based on pcr value
588        break;
589      case MISCREG_PSTATE:
590        pstate = val & PstateMask;
591        return;
592      case MISCREG_TL:
593        {
594            tl = val;
595            if (hpstate.tlz && tl == 0 && !hpstate.hpriv)
596                tc->getCpuPtr()->postInterrupt(0, IT_TRAP_LEVEL_ZERO, 0);
597            else
598                tc->getCpuPtr()->clearInterrupt(0, IT_TRAP_LEVEL_ZERO, 0);
599            return;
600        }
601      case MISCREG_CWP:
602        new_val = val >= NWindows ? NWindows - 1 : val;
603        if (val >= NWindows)
604            new_val = NWindows - 1;
605
606        installWindow(new_val, CurrentWindowOffset);
607        installWindow(new_val - 1, NextWindowOffset);
608        installWindow(new_val + 1, PreviousWindowOffset);
609        break;
610      case MISCREG_GL:
611        installGlobals(val, CurrentGlobalsOffset);
612        installGlobals(val, NextGlobalsOffset);
613        installGlobals(val, PreviousGlobalsOffset);
614        break;
615      case MISCREG_PIL:
616      case MISCREG_SOFTINT:
617      case MISCREG_SOFTINT_SET:
618      case MISCREG_SOFTINT_CLR:
619      case MISCREG_TICK_CMPR:
620      case MISCREG_STICK_CMPR:
621      case MISCREG_HINTP:
622      case MISCREG_HTSTATE:
623      case MISCREG_HTBA:
624      case MISCREG_HVER:
625      case MISCREG_STRAND_STS_REG:
626      case MISCREG_HSTICK_CMPR:
627      case MISCREG_QUEUE_CPU_MONDO_HEAD:
628      case MISCREG_QUEUE_CPU_MONDO_TAIL:
629      case MISCREG_QUEUE_DEV_MONDO_HEAD:
630      case MISCREG_QUEUE_DEV_MONDO_TAIL:
631      case MISCREG_QUEUE_RES_ERROR_HEAD:
632      case MISCREG_QUEUE_RES_ERROR_TAIL:
633      case MISCREG_QUEUE_NRES_ERROR_HEAD:
634      case MISCREG_QUEUE_NRES_ERROR_TAIL:
635      case MISCREG_HPSTATE:
636        setFSReg(miscReg, val, tc);
637        return;
638    }
639    setMiscRegNoEffect(miscReg, new_val);
640}
641
642void
643ISA::serialize(CheckpointOut &cp) const
644{
645    SERIALIZE_SCALAR(asi);
646    SERIALIZE_SCALAR(tick);
647    SERIALIZE_SCALAR(fprs);
648    SERIALIZE_SCALAR(gsr);
649    SERIALIZE_SCALAR(softint);
650    SERIALIZE_SCALAR(tick_cmpr);
651    SERIALIZE_SCALAR(stick);
652    SERIALIZE_SCALAR(stick_cmpr);
653    SERIALIZE_ARRAY(tpc,MaxTL);
654    SERIALIZE_ARRAY(tnpc,MaxTL);
655    SERIALIZE_ARRAY(tstate,MaxTL);
656    SERIALIZE_ARRAY(tt,MaxTL);
657    SERIALIZE_SCALAR(tba);
658    SERIALIZE_SCALAR(pstate);
659    SERIALIZE_SCALAR(tl);
660    SERIALIZE_SCALAR(pil);
661    SERIALIZE_SCALAR(cwp);
662    SERIALIZE_SCALAR(gl);
663    SERIALIZE_SCALAR(hpstate);
664    SERIALIZE_ARRAY(htstate,MaxTL);
665    SERIALIZE_SCALAR(hintp);
666    SERIALIZE_SCALAR(htba);
667    SERIALIZE_SCALAR(hstick_cmpr);
668    SERIALIZE_SCALAR(strandStatusReg);
669    SERIALIZE_SCALAR(fsr);
670    SERIALIZE_SCALAR(priContext);
671    SERIALIZE_SCALAR(secContext);
672    SERIALIZE_SCALAR(partId);
673    SERIALIZE_SCALAR(lsuCtrlReg);
674    SERIALIZE_ARRAY(scratchPad,8);
675    SERIALIZE_SCALAR(cpu_mondo_head);
676    SERIALIZE_SCALAR(cpu_mondo_tail);
677    SERIALIZE_SCALAR(dev_mondo_head);
678    SERIALIZE_SCALAR(dev_mondo_tail);
679    SERIALIZE_SCALAR(res_error_head);
680    SERIALIZE_SCALAR(res_error_tail);
681    SERIALIZE_SCALAR(nres_error_head);
682    SERIALIZE_SCALAR(nres_error_tail);
683    Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
684    ThreadContext *tc = NULL;
685    BaseCPU *cpu = NULL;
686    int tc_num = 0;
687    bool tick_intr_sched = true;
688
689    if (tickCompare)
690        tc = tickCompare->getTC();
691    else if (sTickCompare)
692        tc = sTickCompare->getTC();
693    else if (hSTickCompare)
694        tc = hSTickCompare->getTC();
695    else
696        tick_intr_sched = false;
697
698    SERIALIZE_SCALAR(tick_intr_sched);
699
700    if (tc) {
701        cpu = tc->getCpuPtr();
702        tc_num = cpu->findContext(tc);
703        if (tickCompare && tickCompare->scheduled())
704            tick_cmp = tickCompare->when();
705        if (sTickCompare && sTickCompare->scheduled())
706            stick_cmp = sTickCompare->when();
707        if (hSTickCompare && hSTickCompare->scheduled())
708            hstick_cmp = hSTickCompare->when();
709
710        SERIALIZE_OBJPTR(cpu);
711        SERIALIZE_SCALAR(tc_num);
712        SERIALIZE_SCALAR(tick_cmp);
713        SERIALIZE_SCALAR(stick_cmp);
714        SERIALIZE_SCALAR(hstick_cmp);
715    }
716}
717
718void
719ISA::unserialize(CheckpointIn &cp)
720{
721    UNSERIALIZE_SCALAR(asi);
722    UNSERIALIZE_SCALAR(tick);
723    UNSERIALIZE_SCALAR(fprs);
724    UNSERIALIZE_SCALAR(gsr);
725    UNSERIALIZE_SCALAR(softint);
726    UNSERIALIZE_SCALAR(tick_cmpr);
727    UNSERIALIZE_SCALAR(stick);
728    UNSERIALIZE_SCALAR(stick_cmpr);
729    UNSERIALIZE_ARRAY(tpc,MaxTL);
730    UNSERIALIZE_ARRAY(tnpc,MaxTL);
731    UNSERIALIZE_ARRAY(tstate,MaxTL);
732    UNSERIALIZE_ARRAY(tt,MaxTL);
733    UNSERIALIZE_SCALAR(tba);
734    {
735        uint16_t pstate;
736        UNSERIALIZE_SCALAR(pstate);
737        this->pstate = pstate;
738    }
739    UNSERIALIZE_SCALAR(tl);
740    UNSERIALIZE_SCALAR(pil);
741    UNSERIALIZE_SCALAR(cwp);
742    UNSERIALIZE_SCALAR(gl);
743    reloadRegMap();
744    {
745        uint64_t hpstate;
746        UNSERIALIZE_SCALAR(hpstate);
747        this->hpstate = hpstate;
748    }
749    UNSERIALIZE_ARRAY(htstate,MaxTL);
750    UNSERIALIZE_SCALAR(hintp);
751    UNSERIALIZE_SCALAR(htba);
752    UNSERIALIZE_SCALAR(hstick_cmpr);
753    UNSERIALIZE_SCALAR(strandStatusReg);
754    UNSERIALIZE_SCALAR(fsr);
755    UNSERIALIZE_SCALAR(priContext);
756    UNSERIALIZE_SCALAR(secContext);
757    UNSERIALIZE_SCALAR(partId);
758    UNSERIALIZE_SCALAR(lsuCtrlReg);
759    UNSERIALIZE_ARRAY(scratchPad,8);
760    UNSERIALIZE_SCALAR(cpu_mondo_head);
761    UNSERIALIZE_SCALAR(cpu_mondo_tail);
762    UNSERIALIZE_SCALAR(dev_mondo_head);
763    UNSERIALIZE_SCALAR(dev_mondo_tail);
764    UNSERIALIZE_SCALAR(res_error_head);
765    UNSERIALIZE_SCALAR(res_error_tail);
766    UNSERIALIZE_SCALAR(nres_error_head);
767    UNSERIALIZE_SCALAR(nres_error_tail);
768
769    Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
770    ThreadContext *tc = NULL;
771    BaseCPU *cpu = NULL;
772    int tc_num;
773    bool tick_intr_sched;
774    UNSERIALIZE_SCALAR(tick_intr_sched);
775    if (tick_intr_sched) {
776        UNSERIALIZE_OBJPTR(cpu);
777        if (cpu) {
778            UNSERIALIZE_SCALAR(tc_num);
779            UNSERIALIZE_SCALAR(tick_cmp);
780            UNSERIALIZE_SCALAR(stick_cmp);
781            UNSERIALIZE_SCALAR(hstick_cmp);
782            tc = cpu->getContext(tc_num);
783
784            if (tick_cmp) {
785                tickCompare = new TickCompareEvent(this, tc);
786                schedule(tickCompare, tick_cmp);
787            }
788            if (stick_cmp)  {
789                sTickCompare = new STickCompareEvent(this, tc);
790                schedule(sTickCompare, stick_cmp);
791            }
792            if (hstick_cmp)  {
793                hSTickCompare = new HSTickCompareEvent(this, tc);
794                schedule(hSTickCompare, hstick_cmp);
795            }
796        }
797    }
798
799}
800
801}
802
803SparcISA::ISA *
804SparcISAParams::create()
805{
806    return new SparcISA::ISA(this);
807}
808