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