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