2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
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.
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.
32 #include "arch/sparc/asi.hh"
33 #include "arch/sparc/miscregfile.hh"
34 #include "base/bitfield.hh"
35 #include "base/trace.hh"
36 #include "config/full_system.hh"
37 #include "cpu/base.hh"
38 #include "cpu/thread_context.hh"
40 using namespace SparcISA
;
45 //These functions map register indices to names
46 string
SparcISA::getMiscRegName(RegIndex index
)
48 static::string miscRegName
[NumMiscRegs
] =
49 {/*"y", "ccr",*/ "asi", "tick", "fprs", "pcr", "pic",
50 "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
51 "stick", "stick_cmpr",
52 "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
53 "pil", "cwp", /*"cansave", "canrestore", "cleanwin", "otherwin",
55 "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
59 return miscRegName
[index
];
64 PSTATE_MASK
= (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
67 void MiscRegFile::clear()
79 memset(tpc
, 0, sizeof(tpc
));
80 memset(tnpc
, 0, sizeof(tnpc
));
81 memset(tstate
, 0, sizeof(tstate
));
82 memset(tt
, 0, sizeof(tt
));
93 //In a T1, bit 11 is apparently always 1
95 memset(htstate
, 0, sizeof(htstate
));
99 //This is set this way in Legion for some reason
100 strandStatusReg
= 0x50000;
127 memset(scratchPad
, 0, sizeof(scratchPad
));
130 MiscReg
MiscRegFile::readReg(int miscReg
)
133 case MISCREG_TLB_DATA
:
134 /* Package up all the data for the tlb:
135 * 6666555555555544444444443333333333222222222211111111110000000000
136 * 3210987654321098765432109876543210987654321098765432109876543210
137 * secContext | priContext | |tl|partid| |||||^hpriv
144 return bits((uint64_t)hpstate
,2,2) |
145 bits((uint64_t)hpstate
,5,5) << 1 |
146 bits((uint64_t)pstate
,3,2) << 2 |
147 bits((uint64_t)lsuCtrlReg
,3,2) << 4 |
148 bits((uint64_t)partId
,7,0) << 8 |
149 bits((uint64_t)tl
,2,0) << 16 |
150 (uint64_t)priContext
<< 32 |
151 (uint64_t)secContext
<< 48;
164 panic("PCR not implemented\n");
166 panic("PIC not implemented\n");
169 case MISCREG_SOFTINT
:
171 case MISCREG_TICK_CMPR
:
175 case MISCREG_STICK_CMPR
:
178 /** Privilged Registers */
187 case MISCREG_PRIVTICK
:
188 panic("Priviliged access to tick registers not implemented\n");
199 //case MISCREG_CANSAVE:
201 //case MISCREG_CANRESTORE:
202 // return canrestore;
203 //case MISCREG_CLEANWIN:
205 //case MISCREG_OTHERWIN:
207 //case MISCREG_WSTATE:
212 /** Hyper privileged registers */
213 case MISCREG_HPSTATE
:
215 case MISCREG_HTSTATE
:
216 return htstate
[tl
-1];
222 return NWindows
| MaxTL
<< 8 | MaxGL
<< 16;
223 case MISCREG_STRAND_STS_REG
:
224 return strandStatusReg
;
225 case MISCREG_HSTICK_CMPR
:
228 /** Floating Point Status Register */
232 case MISCREG_MMU_P_CONTEXT
:
234 case MISCREG_MMU_S_CONTEXT
:
236 case MISCREG_MMU_PART_ID
:
238 case MISCREG_MMU_LSU_CTRL
:
241 case MISCREG_MMU_ITLB_C0_TSB_PS0
:
243 case MISCREG_MMU_ITLB_C0_TSB_PS1
:
245 case MISCREG_MMU_ITLB_C0_CONFIG
:
247 case MISCREG_MMU_ITLB_CX_TSB_PS0
:
249 case MISCREG_MMU_ITLB_CX_TSB_PS1
:
251 case MISCREG_MMU_ITLB_CX_CONFIG
:
253 case MISCREG_MMU_ITLB_SFSR
:
255 case MISCREG_MMU_ITLB_TAG_ACCESS
:
256 return iTlbTagAccess
;
258 case MISCREG_MMU_DTLB_C0_TSB_PS0
:
260 case MISCREG_MMU_DTLB_C0_TSB_PS1
:
262 case MISCREG_MMU_DTLB_C0_CONFIG
:
264 case MISCREG_MMU_DTLB_CX_TSB_PS0
:
266 case MISCREG_MMU_DTLB_CX_TSB_PS1
:
268 case MISCREG_MMU_DTLB_CX_CONFIG
:
270 case MISCREG_MMU_DTLB_SFSR
:
272 case MISCREG_MMU_DTLB_SFAR
:
274 case MISCREG_MMU_DTLB_TAG_ACCESS
:
275 return dTlbTagAccess
;
277 case MISCREG_SCRATCHPAD_R0
:
278 return scratchPad
[0];
279 case MISCREG_SCRATCHPAD_R1
:
280 return scratchPad
[1];
281 case MISCREG_SCRATCHPAD_R2
:
282 return scratchPad
[2];
283 case MISCREG_SCRATCHPAD_R3
:
284 return scratchPad
[3];
285 case MISCREG_SCRATCHPAD_R4
:
286 return scratchPad
[4];
287 case MISCREG_SCRATCHPAD_R5
:
288 return scratchPad
[5];
289 case MISCREG_SCRATCHPAD_R6
:
290 return scratchPad
[6];
291 case MISCREG_SCRATCHPAD_R7
:
292 return scratchPad
[7];
293 case MISCREG_QUEUE_CPU_MONDO_HEAD
:
294 return cpu_mondo_head
;
295 case MISCREG_QUEUE_CPU_MONDO_TAIL
:
296 return cpu_mondo_tail
;
297 case MISCREG_QUEUE_DEV_MONDO_HEAD
:
298 return dev_mondo_head
;
299 case MISCREG_QUEUE_DEV_MONDO_TAIL
:
300 return dev_mondo_tail
;
301 case MISCREG_QUEUE_RES_ERROR_HEAD
:
302 return res_error_head
;
303 case MISCREG_QUEUE_RES_ERROR_TAIL
:
304 return res_error_tail
;
305 case MISCREG_QUEUE_NRES_ERROR_HEAD
:
306 return nres_error_head
;
307 case MISCREG_QUEUE_NRES_ERROR_TAIL
:
308 return nres_error_tail
;
310 panic("Miscellaneous register %d not implemented\n", miscReg
);
314 MiscReg
MiscRegFile::readRegWithEffect(int miscReg
, ThreadContext
* tc
)
317 // tick and stick are aliased to each other in niagra
318 // well store the tick data in stick and the interrupt bit in tick
321 case MISCREG_PRIVTICK
:
322 // I'm not sure why legion ignores the lowest two bits, but we'll go
324 // change from curCycle() to instCount() until we're done with legion
325 DPRINTF(Timer
, "Instruction Count when TICK read: %#X stick=%#X\n",
326 tc
->getCpuPtr()->instCount(), stick
);
327 return mbits(tc
->getCpuPtr()->instCount() + (int64_t)stick
,62,2) |
330 // in legion if fp is enabled du and dl are set
334 panic("Performance Instrumentation not impl\n");
335 /** Floating Point Status Register */
337 warn("Reading FSR Floating Point not implemented\n");
339 case MISCREG_SOFTINT_CLR
:
340 case MISCREG_SOFTINT_SET
:
341 panic("Can read from softint clr/set\n");
342 case MISCREG_SOFTINT
:
343 case MISCREG_TICK_CMPR
:
344 case MISCREG_STICK_CMPR
:
346 case MISCREG_HTSTATE
:
349 case MISCREG_STRAND_STS_REG
:
350 case MISCREG_HSTICK_CMPR
:
351 case MISCREG_QUEUE_CPU_MONDO_HEAD
:
352 case MISCREG_QUEUE_CPU_MONDO_TAIL
:
353 case MISCREG_QUEUE_DEV_MONDO_HEAD
:
354 case MISCREG_QUEUE_DEV_MONDO_TAIL
:
355 case MISCREG_QUEUE_RES_ERROR_HEAD
:
356 case MISCREG_QUEUE_RES_ERROR_TAIL
:
357 case MISCREG_QUEUE_NRES_ERROR_HEAD
:
358 case MISCREG_QUEUE_NRES_ERROR_TAIL
:
360 case MISCREG_HPSTATE
:
361 return readFSRegWithEffect(miscReg
, tc
);
363 case MISCREG_HPSTATE
:
364 //HPSTATE is special because because sometimes in privilege checks for instructions
365 //it will read HPSTATE to make sure the priv. level is ok
366 //So, we'll just have to tell it it isn't, instead of panicing.
369 panic("Accessing Fullsystem register %s in SE mode\n",getMiscRegName(miscReg
));
373 return readReg(miscReg
);
376 void MiscRegFile::setReg(int miscReg
, const MiscReg
&val
)
395 panic("PCR not implemented\n");
397 panic("PIC not implemented\n");
401 case MISCREG_SOFTINT
:
404 case MISCREG_TICK_CMPR
:
410 case MISCREG_STICK_CMPR
:
414 /** Privilged Registers */
427 case MISCREG_PRIVTICK
:
428 panic("Priviliged access to tick regesiters not implemented\n");
430 // clear lower 7 bits on writes.
431 tba
= val
& ULL(~0x7FFF);
434 pstate
= (val
& PSTATE_MASK
);
445 // case MISCREG_CANSAVE:
448 // case MISCREG_CANRESTORE:
451 // case MISCREG_CLEANWIN:
454 // case MISCREG_OTHERWIN:
457 // case MISCREG_WSTATE:
464 /** Hyper privileged registers */
465 case MISCREG_HPSTATE
:
468 case MISCREG_HTSTATE
:
476 case MISCREG_STRAND_STS_REG
:
477 strandStatusReg
= val
;
479 case MISCREG_HSTICK_CMPR
:
483 /** Floating Point Status Register */
488 case MISCREG_MMU_P_CONTEXT
:
491 case MISCREG_MMU_S_CONTEXT
:
494 case MISCREG_MMU_PART_ID
:
497 case MISCREG_MMU_LSU_CTRL
:
501 case MISCREG_MMU_ITLB_C0_TSB_PS0
:
504 case MISCREG_MMU_ITLB_C0_TSB_PS1
:
507 case MISCREG_MMU_ITLB_C0_CONFIG
:
510 case MISCREG_MMU_ITLB_CX_TSB_PS0
:
513 case MISCREG_MMU_ITLB_CX_TSB_PS1
:
516 case MISCREG_MMU_ITLB_CX_CONFIG
:
519 case MISCREG_MMU_ITLB_SFSR
:
522 case MISCREG_MMU_ITLB_TAG_ACCESS
:
526 case MISCREG_MMU_DTLB_C0_TSB_PS0
:
529 case MISCREG_MMU_DTLB_C0_TSB_PS1
:
532 case MISCREG_MMU_DTLB_C0_CONFIG
:
535 case MISCREG_MMU_DTLB_CX_TSB_PS0
:
538 case MISCREG_MMU_DTLB_CX_TSB_PS1
:
541 case MISCREG_MMU_DTLB_CX_CONFIG
:
544 case MISCREG_MMU_DTLB_SFSR
:
547 case MISCREG_MMU_DTLB_SFAR
:
550 case MISCREG_MMU_DTLB_TAG_ACCESS
:
554 case MISCREG_SCRATCHPAD_R0
:
557 case MISCREG_SCRATCHPAD_R1
:
560 case MISCREG_SCRATCHPAD_R2
:
563 case MISCREG_SCRATCHPAD_R3
:
566 case MISCREG_SCRATCHPAD_R4
:
569 case MISCREG_SCRATCHPAD_R5
:
572 case MISCREG_SCRATCHPAD_R6
:
575 case MISCREG_SCRATCHPAD_R7
:
578 case MISCREG_QUEUE_CPU_MONDO_HEAD
:
579 cpu_mondo_head
= val
;
581 case MISCREG_QUEUE_CPU_MONDO_TAIL
:
582 cpu_mondo_tail
= val
;
584 case MISCREG_QUEUE_DEV_MONDO_HEAD
:
585 dev_mondo_head
= val
;
587 case MISCREG_QUEUE_DEV_MONDO_TAIL
:
588 dev_mondo_tail
= val
;
590 case MISCREG_QUEUE_RES_ERROR_HEAD
:
591 res_error_head
= val
;
593 case MISCREG_QUEUE_RES_ERROR_TAIL
:
594 res_error_tail
= val
;
596 case MISCREG_QUEUE_NRES_ERROR_HEAD
:
597 nres_error_head
= val
;
599 case MISCREG_QUEUE_NRES_ERROR_TAIL
:
600 nres_error_tail
= val
;
604 panic("Miscellaneous register %d not implemented\n", miscReg
);
608 void MiscRegFile::setRegWithEffect(int miscReg
,
609 const MiscReg
&val
, ThreadContext
* tc
)
611 MiscReg new_val
= val
;
616 // stick and tick are same thing on niagra
617 // use stick for offset and tick for holding intrrupt bit
618 stick
= mbits(val
,62,0) - tc
->getCpuPtr()->instCount();
619 tick
= mbits(val
,63,63);
620 DPRINTF(Timer
, "Writing TICK=%#X\n", val
);
623 //Configure the fpu based on the fprs
626 //Set up performance counting based on pcr value
629 pstate
= val
& PSTATE_MASK
;
635 new_val
= val
> NWindows
? NWindows
- 1 : val
;
636 tc
->changeRegFileContext(CONTEXT_CWP
, new_val
);
639 tc
->changeRegFileContext(CONTEXT_GLOBALS
, val
);
642 case MISCREG_SOFTINT
:
643 case MISCREG_SOFTINT_SET
:
644 case MISCREG_SOFTINT_CLR
:
645 case MISCREG_TICK_CMPR
:
646 case MISCREG_STICK_CMPR
:
648 case MISCREG_HTSTATE
:
651 case MISCREG_STRAND_STS_REG
:
652 case MISCREG_HSTICK_CMPR
:
653 case MISCREG_QUEUE_CPU_MONDO_HEAD
:
654 case MISCREG_QUEUE_CPU_MONDO_TAIL
:
655 case MISCREG_QUEUE_DEV_MONDO_HEAD
:
656 case MISCREG_QUEUE_DEV_MONDO_TAIL
:
657 case MISCREG_QUEUE_RES_ERROR_HEAD
:
658 case MISCREG_QUEUE_RES_ERROR_TAIL
:
659 case MISCREG_QUEUE_NRES_ERROR_HEAD
:
660 case MISCREG_QUEUE_NRES_ERROR_TAIL
:
662 case MISCREG_HPSTATE
:
663 setFSRegWithEffect(miscReg
, val
, tc
);
666 case MISCREG_HPSTATE
:
667 //HPSTATE is special because normal trap processing saves HPSTATE when
668 //it goes into a trap, and restores it when it returns.
670 panic("Accessing Fullsystem register %s to %#x in SE mode\n", getMiscRegName(miscReg
), val
);
673 setReg(miscReg
, new_val
);
676 void MiscRegFile::serialize(std::ostream
& os
)
678 SERIALIZE_SCALAR(pstate
);
679 SERIALIZE_SCALAR(tba
);
680 // SERIALIZE_SCALAR(y);
681 SERIALIZE_SCALAR(pil
);
682 SERIALIZE_SCALAR(gl
);
683 SERIALIZE_SCALAR(cwp
);
684 SERIALIZE_ARRAY(tt
, MaxTL
);
685 // SERIALIZE_SCALAR(ccr);
686 SERIALIZE_SCALAR(asi
);
687 SERIALIZE_SCALAR(tl
);
688 SERIALIZE_ARRAY(tpc
, MaxTL
);
689 SERIALIZE_ARRAY(tnpc
, MaxTL
);
690 SERIALIZE_ARRAY(tstate
, MaxTL
);
691 SERIALIZE_SCALAR(tick
);
692 // SERIALIZE_SCALAR(cansave);
693 // SERIALIZE_SCALAR(canrestore);
694 // SERIALIZE_SCALAR(otherwin);
695 // SERIALIZE_SCALAR(cleanwin);
696 // SERIALIZE_SCALAR(wstate);
697 SERIALIZE_SCALAR(fsr
);
698 SERIALIZE_SCALAR(fprs
);
699 SERIALIZE_SCALAR(hpstate
);
700 SERIALIZE_ARRAY(htstate
, MaxTL
);
701 SERIALIZE_SCALAR(htba
);
702 SERIALIZE_SCALAR(hstick_cmpr
);
703 SERIALIZE_SCALAR(strandStatusReg
);
704 SERIALIZE_SCALAR(priContext
);
705 SERIALIZE_SCALAR(secContext
);
706 SERIALIZE_SCALAR(partId
);
707 SERIALIZE_SCALAR(lsuCtrlReg
);
708 SERIALIZE_SCALAR(iTlbC0TsbPs0
);
709 SERIALIZE_SCALAR(iTlbC0TsbPs1
);
710 SERIALIZE_SCALAR(iTlbC0Config
);
711 SERIALIZE_SCALAR(iTlbCXTsbPs0
);
712 SERIALIZE_SCALAR(iTlbCXTsbPs1
);
713 SERIALIZE_SCALAR(iTlbCXConfig
);
714 SERIALIZE_SCALAR(iTlbSfsr
);
715 SERIALIZE_SCALAR(iTlbTagAccess
);
716 SERIALIZE_SCALAR(dTlbC0TsbPs0
);
717 SERIALIZE_SCALAR(dTlbC0TsbPs1
);
718 SERIALIZE_SCALAR(dTlbC0Config
);
719 SERIALIZE_SCALAR(dTlbCXTsbPs0
);
720 SERIALIZE_SCALAR(dTlbCXTsbPs1
);
721 SERIALIZE_SCALAR(dTlbSfsr
);
722 SERIALIZE_SCALAR(dTlbSfar
);
723 SERIALIZE_SCALAR(dTlbTagAccess
);
724 SERIALIZE_ARRAY(scratchPad
,8);
725 SERIALIZE_SCALAR(cpu_mondo_head
);
726 SERIALIZE_SCALAR(cpu_mondo_tail
);
727 SERIALIZE_SCALAR(dev_mondo_head
);
728 SERIALIZE_SCALAR(dev_mondo_tail
);
729 SERIALIZE_SCALAR(res_error_head
);
730 SERIALIZE_SCALAR(res_error_tail
);
731 SERIALIZE_SCALAR(nres_error_head
);
732 SERIALIZE_SCALAR(nres_error_tail
);
735 void MiscRegFile::unserialize(Checkpoint
* cp
, const std::string
& section
)
737 UNSERIALIZE_SCALAR(pstate
);
738 UNSERIALIZE_SCALAR(tba
);
739 // UNSERIALIZE_SCALAR(y);
740 UNSERIALIZE_SCALAR(pil
);
741 UNSERIALIZE_SCALAR(gl
);
742 UNSERIALIZE_SCALAR(cwp
);
743 UNSERIALIZE_ARRAY(tt
, MaxTL
);
744 // UNSERIALIZE_SCALAR(ccr);
745 UNSERIALIZE_SCALAR(asi
);
746 UNSERIALIZE_SCALAR(tl
);
747 UNSERIALIZE_ARRAY(tpc
, MaxTL
);
748 UNSERIALIZE_ARRAY(tnpc
, MaxTL
);
749 UNSERIALIZE_ARRAY(tstate
, MaxTL
);
750 UNSERIALIZE_SCALAR(tick
);
751 // UNSERIALIZE_SCALAR(cansave);
752 // UNSERIALIZE_SCALAR(canrestore);
753 // UNSERIALIZE_SCALAR(otherwin);
754 // UNSERIALIZE_SCALAR(cleanwin);
755 // UNSERIALIZE_SCALAR(wstate);
756 UNSERIALIZE_SCALAR(fsr
);
757 UNSERIALIZE_SCALAR(fprs
);
758 UNSERIALIZE_SCALAR(hpstate
);
759 UNSERIALIZE_ARRAY(htstate
, MaxTL
);
760 UNSERIALIZE_SCALAR(htba
);
761 UNSERIALIZE_SCALAR(hstick_cmpr
);
762 UNSERIALIZE_SCALAR(strandStatusReg
);
763 UNSERIALIZE_SCALAR(priContext
);
764 UNSERIALIZE_SCALAR(secContext
);
765 UNSERIALIZE_SCALAR(partId
);
766 UNSERIALIZE_SCALAR(lsuCtrlReg
);
767 UNSERIALIZE_SCALAR(iTlbC0TsbPs0
);
768 UNSERIALIZE_SCALAR(iTlbC0TsbPs1
);
769 UNSERIALIZE_SCALAR(iTlbC0Config
);
770 UNSERIALIZE_SCALAR(iTlbCXTsbPs0
);
771 UNSERIALIZE_SCALAR(iTlbCXTsbPs1
);
772 UNSERIALIZE_SCALAR(iTlbCXConfig
);
773 UNSERIALIZE_SCALAR(iTlbSfsr
);
774 UNSERIALIZE_SCALAR(iTlbTagAccess
);
775 UNSERIALIZE_SCALAR(dTlbC0TsbPs0
);
776 UNSERIALIZE_SCALAR(dTlbC0TsbPs1
);
777 UNSERIALIZE_SCALAR(dTlbC0Config
);
778 UNSERIALIZE_SCALAR(dTlbCXTsbPs0
);
779 UNSERIALIZE_SCALAR(dTlbCXTsbPs1
);
780 UNSERIALIZE_SCALAR(dTlbSfsr
);
781 UNSERIALIZE_SCALAR(dTlbSfar
);
782 UNSERIALIZE_SCALAR(dTlbTagAccess
);
783 UNSERIALIZE_ARRAY(scratchPad
,8);
784 UNSERIALIZE_SCALAR(cpu_mondo_head
);
785 UNSERIALIZE_SCALAR(cpu_mondo_tail
);
786 UNSERIALIZE_SCALAR(dev_mondo_head
);
787 UNSERIALIZE_SCALAR(dev_mondo_tail
);
788 UNSERIALIZE_SCALAR(res_error_head
);
789 UNSERIALIZE_SCALAR(res_error_tail
);
790 UNSERIALIZE_SCALAR(nres_error_head
);
791 UNSERIALIZE_SCALAR(nres_error_tail
);}