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