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",
58 return miscRegName
[index
];
63 PSTATE_MASK
= (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
66 void MiscRegFile::clear()
78 memset(tpc
, 0, sizeof(tpc
));
79 memset(tnpc
, 0, sizeof(tnpc
));
80 memset(tstate
, 0, sizeof(tstate
));
81 memset(tt
, 0, sizeof(tt
));
92 //In a T1, bit 11 is apparently always 1
94 memset(htstate
, 0, sizeof(htstate
));
98 //This is set this way in Legion for some reason
99 strandStatusReg
= 0x50000;
126 memset(scratchPad
, 0, sizeof(scratchPad
));
129 MiscReg
MiscRegFile::readReg(int miscReg
)
143 panic("PCR not implemented\n");
145 panic("PIC not implemented\n");
148 case MISCREG_SOFTINT
:
150 case MISCREG_TICK_CMPR
:
154 case MISCREG_STICK_CMPR
:
157 /** Privilged Registers */
166 case MISCREG_PRIVTICK
:
167 panic("Priviliged access to tick registers not implemented\n");
178 case MISCREG_CANSAVE
:
180 case MISCREG_CANRESTORE
:
182 case MISCREG_CLEANWIN
:
184 case MISCREG_OTHERWIN
:
191 /** Hyper privileged registers */
192 case MISCREG_HPSTATE
:
194 case MISCREG_HTSTATE
:
195 return htstate
[tl
-1];
197 panic("HINTP not implemented\n");
201 return NWindows
| MaxTL
<< 8 | MaxGL
<< 16;
202 case MISCREG_STRAND_STS_REG
:
203 return strandStatusReg
;
204 case MISCREG_HSTICK_CMPR
:
207 /** Floating Point Status Register */
211 case MISCREG_MMU_P_CONTEXT
:
213 case MISCREG_MMU_S_CONTEXT
:
215 case MISCREG_MMU_PART_ID
:
217 case MISCREG_MMU_LSU_CTRL
:
220 case MISCREG_MMU_ITLB_C0_TSB_PS0
:
222 case MISCREG_MMU_ITLB_C0_TSB_PS1
:
224 case MISCREG_MMU_ITLB_C0_CONFIG
:
226 case MISCREG_MMU_ITLB_CX_TSB_PS0
:
228 case MISCREG_MMU_ITLB_CX_TSB_PS1
:
230 case MISCREG_MMU_ITLB_CX_CONFIG
:
232 case MISCREG_MMU_ITLB_SFSR
:
234 case MISCREG_MMU_ITLB_TAG_ACCESS
:
235 return iTlbTagAccess
;
237 case MISCREG_MMU_DTLB_C0_TSB_PS0
:
239 case MISCREG_MMU_DTLB_C0_TSB_PS1
:
241 case MISCREG_MMU_DTLB_C0_CONFIG
:
243 case MISCREG_MMU_DTLB_CX_TSB_PS0
:
245 case MISCREG_MMU_DTLB_CX_TSB_PS1
:
247 case MISCREG_MMU_DTLB_CX_CONFIG
:
249 case MISCREG_MMU_DTLB_SFSR
:
251 case MISCREG_MMU_DTLB_SFAR
:
253 case MISCREG_MMU_DTLB_TAG_ACCESS
:
254 return dTlbTagAccess
;
256 case MISCREG_SCRATCHPAD_R0
:
257 return scratchPad
[0];
258 case MISCREG_SCRATCHPAD_R1
:
259 return scratchPad
[1];
260 case MISCREG_SCRATCHPAD_R2
:
261 return scratchPad
[2];
262 case MISCREG_SCRATCHPAD_R3
:
263 return scratchPad
[3];
264 case MISCREG_SCRATCHPAD_R4
:
265 return scratchPad
[4];
266 case MISCREG_SCRATCHPAD_R5
:
267 return scratchPad
[5];
268 case MISCREG_SCRATCHPAD_R6
:
269 return scratchPad
[6];
270 case MISCREG_SCRATCHPAD_R7
:
271 return scratchPad
[7];
272 case MISCREG_QUEUE_CPU_MONDO_HEAD
:
273 return cpu_mondo_head
;
274 case MISCREG_QUEUE_CPU_MONDO_TAIL
:
275 return cpu_mondo_tail
;
276 case MISCREG_QUEUE_DEV_MONDO_HEAD
:
277 return dev_mondo_head
;
278 case MISCREG_QUEUE_DEV_MONDO_TAIL
:
279 return dev_mondo_tail
;
280 case MISCREG_QUEUE_RES_ERROR_HEAD
:
281 return res_error_head
;
282 case MISCREG_QUEUE_RES_ERROR_TAIL
:
283 return res_error_tail
;
284 case MISCREG_QUEUE_NRES_ERROR_HEAD
:
285 return nres_error_head
;
286 case MISCREG_QUEUE_NRES_ERROR_TAIL
:
287 return nres_error_tail
;
289 panic("Miscellaneous register %d not implemented\n", miscReg
);
293 MiscReg
MiscRegFile::readRegWithEffect(int miscReg
, ThreadContext
* tc
)
296 // tick and stick are aliased to each other in niagra
299 case MISCREG_PRIVTICK
:
300 // I'm not sure why legion ignores the lowest two bits, but we'll go
302 // change from curCycle() to instCount() until we're done with legion
303 DPRINTFN("Instruction Count when STICK read: %#X\n",
304 tc
->getCpuPtr()->instCount());
305 return mbits(tc
->getCpuPtr()->instCount() - (tick
&
306 mask(63)),62,2) | mbits(tick
,63,63) ;
308 panic("FPU not implemented\n");
311 panic("Performance Instrumentation not impl\n");
312 /** Floating Point Status Register */
314 panic("Floating Point not implemented\n");
315 case MISCREG_SOFTINT_CLR
:
316 case MISCREG_SOFTINT_SET
:
317 panic("Can read from softint clr/set\n");
318 case MISCREG_SOFTINT
:
319 case MISCREG_TICK_CMPR
:
320 case MISCREG_STICK_CMPR
:
321 case MISCREG_HPSTATE
:
323 case MISCREG_HTSTATE
:
326 case MISCREG_STRAND_STS_REG
:
327 case MISCREG_HSTICK_CMPR
:
328 case MISCREG_QUEUE_CPU_MONDO_HEAD
:
329 case MISCREG_QUEUE_CPU_MONDO_TAIL
:
330 case MISCREG_QUEUE_DEV_MONDO_HEAD
:
331 case MISCREG_QUEUE_DEV_MONDO_TAIL
:
332 case MISCREG_QUEUE_RES_ERROR_HEAD
:
333 case MISCREG_QUEUE_RES_ERROR_TAIL
:
334 case MISCREG_QUEUE_NRES_ERROR_HEAD
:
335 case MISCREG_QUEUE_NRES_ERROR_TAIL
:
337 return readFSRegWithEffect(miscReg
, tc
);
339 panic("Accessing Fullsystem register is SE mode\n");
343 return readReg(miscReg
);
346 void MiscRegFile::setReg(int miscReg
, const MiscReg
&val
)
365 panic("PCR not implemented\n");
367 panic("PIC not implemented\n");
371 case MISCREG_SOFTINT
:
374 case MISCREG_TICK_CMPR
:
380 case MISCREG_STICK_CMPR
:
384 /** Privilged Registers */
397 case MISCREG_PRIVTICK
:
398 panic("Priviliged access to tick regesiters not implemented\n");
400 // clear lower 7 bits on writes.
401 tba
= val
& ULL(~0x7FFF);
404 pstate
= (val
& PSTATE_MASK
);
415 case MISCREG_CANSAVE
:
418 case MISCREG_CANRESTORE
:
421 case MISCREG_CLEANWIN
:
424 case MISCREG_OTHERWIN
:
434 /** Hyper privileged registers */
435 case MISCREG_HPSTATE
:
438 case MISCREG_HTSTATE
:
442 panic("HINTP not implemented\n");
446 case MISCREG_STRAND_STS_REG
:
447 strandStatusReg
= val
;
449 case MISCREG_HSTICK_CMPR
:
453 /** Floating Point Status Register */
458 case MISCREG_MMU_P_CONTEXT
:
461 case MISCREG_MMU_S_CONTEXT
:
464 case MISCREG_MMU_PART_ID
:
467 case MISCREG_MMU_LSU_CTRL
:
471 case MISCREG_MMU_ITLB_C0_TSB_PS0
:
474 case MISCREG_MMU_ITLB_C0_TSB_PS1
:
477 case MISCREG_MMU_ITLB_C0_CONFIG
:
480 case MISCREG_MMU_ITLB_CX_TSB_PS0
:
483 case MISCREG_MMU_ITLB_CX_TSB_PS1
:
486 case MISCREG_MMU_ITLB_CX_CONFIG
:
489 case MISCREG_MMU_ITLB_SFSR
:
492 case MISCREG_MMU_ITLB_TAG_ACCESS
:
496 case MISCREG_MMU_DTLB_C0_TSB_PS0
:
499 case MISCREG_MMU_DTLB_C0_TSB_PS1
:
502 case MISCREG_MMU_DTLB_C0_CONFIG
:
505 case MISCREG_MMU_DTLB_CX_TSB_PS0
:
508 case MISCREG_MMU_DTLB_CX_TSB_PS1
:
511 case MISCREG_MMU_DTLB_CX_CONFIG
:
514 case MISCREG_MMU_DTLB_SFSR
:
517 case MISCREG_MMU_DTLB_SFAR
:
520 case MISCREG_MMU_DTLB_TAG_ACCESS
:
524 case MISCREG_SCRATCHPAD_R0
:
527 case MISCREG_SCRATCHPAD_R1
:
530 case MISCREG_SCRATCHPAD_R2
:
533 case MISCREG_SCRATCHPAD_R3
:
536 case MISCREG_SCRATCHPAD_R4
:
539 case MISCREG_SCRATCHPAD_R5
:
542 case MISCREG_SCRATCHPAD_R6
:
545 case MISCREG_SCRATCHPAD_R7
:
548 case MISCREG_QUEUE_CPU_MONDO_HEAD
:
549 cpu_mondo_head
= val
;
551 case MISCREG_QUEUE_CPU_MONDO_TAIL
:
552 cpu_mondo_tail
= val
;
554 case MISCREG_QUEUE_DEV_MONDO_HEAD
:
555 dev_mondo_head
= val
;
557 case MISCREG_QUEUE_DEV_MONDO_TAIL
:
558 dev_mondo_tail
= val
;
560 case MISCREG_QUEUE_RES_ERROR_HEAD
:
561 res_error_head
= val
;
563 case MISCREG_QUEUE_RES_ERROR_TAIL
:
564 res_error_tail
= val
;
566 case MISCREG_QUEUE_NRES_ERROR_HEAD
:
567 nres_error_head
= val
;
569 case MISCREG_QUEUE_NRES_ERROR_TAIL
:
570 nres_error_tail
= val
;
574 panic("Miscellaneous register %d not implemented\n", miscReg
);
578 void MiscRegFile::setRegWithEffect(int miscReg
,
579 const MiscReg
&val
, ThreadContext
* tc
)
581 const uint64_t Bit64
= (1ULL << 63);
585 // change from curCycle() to instCount() until we're done with legion
586 tick
= tc
->getCpuPtr()->instCount() - val
& ~Bit64
;
590 //Configure the fpu based on the fprs
593 //Set up performance counting based on pcr value
596 pstate
= val
& PSTATE_MASK
;
602 tc
->changeRegFileContext(CONTEXT_CWP
, val
);
605 tc
->changeRegFileContext(CONTEXT_GLOBALS
, val
);
608 case MISCREG_SOFTINT
:
609 case MISCREG_TICK_CMPR
:
610 case MISCREG_STICK_CMPR
:
611 case MISCREG_HPSTATE
:
613 case MISCREG_HTSTATE
:
616 case MISCREG_STRAND_STS_REG
:
617 case MISCREG_HSTICK_CMPR
:
618 case MISCREG_QUEUE_CPU_MONDO_HEAD
:
619 case MISCREG_QUEUE_CPU_MONDO_TAIL
:
620 case MISCREG_QUEUE_DEV_MONDO_HEAD
:
621 case MISCREG_QUEUE_DEV_MONDO_TAIL
:
622 case MISCREG_QUEUE_RES_ERROR_HEAD
:
623 case MISCREG_QUEUE_RES_ERROR_TAIL
:
624 case MISCREG_QUEUE_NRES_ERROR_HEAD
:
625 case MISCREG_QUEUE_NRES_ERROR_TAIL
:
627 setFSRegWithEffect(miscReg
, val
, tc
);
630 panic("Accessing Fullsystem register is SE mode\n");
633 setReg(miscReg
, val
);
636 void MiscRegFile::serialize(std::ostream
& os
)
638 SERIALIZE_SCALAR(pstate
);
639 SERIALIZE_SCALAR(tba
);
641 SERIALIZE_SCALAR(pil
);
642 SERIALIZE_SCALAR(gl
);
643 SERIALIZE_SCALAR(cwp
);
644 SERIALIZE_ARRAY(tt
, MaxTL
);
645 SERIALIZE_SCALAR(ccr
);
646 SERIALIZE_SCALAR(asi
);
647 SERIALIZE_SCALAR(tl
);
648 SERIALIZE_ARRAY(tpc
, MaxTL
);
649 SERIALIZE_ARRAY(tnpc
, MaxTL
);
650 SERIALIZE_ARRAY(tstate
, MaxTL
);
651 SERIALIZE_SCALAR(tick
);
652 SERIALIZE_SCALAR(cansave
);
653 SERIALIZE_SCALAR(canrestore
);
654 SERIALIZE_SCALAR(otherwin
);
655 SERIALIZE_SCALAR(cleanwin
);
656 SERIALIZE_SCALAR(wstate
);
657 SERIALIZE_SCALAR(fsr
);
658 SERIALIZE_SCALAR(fprs
);
659 SERIALIZE_SCALAR(hpstate
);
660 SERIALIZE_ARRAY(htstate
, MaxTL
);
661 SERIALIZE_SCALAR(htba
);
662 SERIALIZE_SCALAR(hstick_cmpr
);
663 SERIALIZE_SCALAR(strandStatusReg
);
664 SERIALIZE_SCALAR(priContext
);
665 SERIALIZE_SCALAR(secContext
);
666 SERIALIZE_SCALAR(partId
);
667 SERIALIZE_SCALAR(lsuCtrlReg
);
668 SERIALIZE_SCALAR(iTlbC0TsbPs0
);
669 SERIALIZE_SCALAR(iTlbC0TsbPs1
);
670 SERIALIZE_SCALAR(iTlbC0Config
);
671 SERIALIZE_SCALAR(iTlbCXTsbPs0
);
672 SERIALIZE_SCALAR(iTlbCXTsbPs1
);
673 SERIALIZE_SCALAR(iTlbCXConfig
);
674 SERIALIZE_SCALAR(iTlbSfsr
);
675 SERIALIZE_SCALAR(iTlbTagAccess
);
676 SERIALIZE_SCALAR(dTlbC0TsbPs0
);
677 SERIALIZE_SCALAR(dTlbC0TsbPs1
);
678 SERIALIZE_SCALAR(dTlbC0Config
);
679 SERIALIZE_SCALAR(dTlbCXTsbPs0
);
680 SERIALIZE_SCALAR(dTlbCXTsbPs1
);
681 SERIALIZE_SCALAR(dTlbSfsr
);
682 SERIALIZE_SCALAR(dTlbSfar
);
683 SERIALIZE_SCALAR(dTlbTagAccess
);
684 SERIALIZE_ARRAY(scratchPad
,8);
685 SERIALIZE_SCALAR(cpu_mondo_head
);
686 SERIALIZE_SCALAR(cpu_mondo_tail
);
687 SERIALIZE_SCALAR(dev_mondo_head
);
688 SERIALIZE_SCALAR(dev_mondo_tail
);
689 SERIALIZE_SCALAR(res_error_head
);
690 SERIALIZE_SCALAR(res_error_tail
);
691 SERIALIZE_SCALAR(nres_error_head
);
692 SERIALIZE_SCALAR(nres_error_tail
);
695 void MiscRegFile::unserialize(Checkpoint
* cp
, const std::string
& section
)
697 UNSERIALIZE_SCALAR(pstate
);
698 UNSERIALIZE_SCALAR(tba
);
699 UNSERIALIZE_SCALAR(y
);
700 UNSERIALIZE_SCALAR(pil
);
701 UNSERIALIZE_SCALAR(gl
);
702 UNSERIALIZE_SCALAR(cwp
);
703 UNSERIALIZE_ARRAY(tt
, MaxTL
);
704 UNSERIALIZE_SCALAR(ccr
);
705 UNSERIALIZE_SCALAR(asi
);
706 UNSERIALIZE_SCALAR(tl
);
707 UNSERIALIZE_ARRAY(tpc
, MaxTL
);
708 UNSERIALIZE_ARRAY(tnpc
, MaxTL
);
709 UNSERIALIZE_ARRAY(tstate
, MaxTL
);
710 UNSERIALIZE_SCALAR(tick
);
711 UNSERIALIZE_SCALAR(cansave
);
712 UNSERIALIZE_SCALAR(canrestore
);
713 UNSERIALIZE_SCALAR(otherwin
);
714 UNSERIALIZE_SCALAR(cleanwin
);
715 UNSERIALIZE_SCALAR(wstate
);
716 UNSERIALIZE_SCALAR(fsr
);
717 UNSERIALIZE_SCALAR(fprs
);
718 UNSERIALIZE_SCALAR(hpstate
);
719 UNSERIALIZE_ARRAY(htstate
, MaxTL
);
720 UNSERIALIZE_SCALAR(htba
);
721 UNSERIALIZE_SCALAR(hstick_cmpr
);
722 UNSERIALIZE_SCALAR(strandStatusReg
);
723 UNSERIALIZE_SCALAR(priContext
);
724 UNSERIALIZE_SCALAR(secContext
);
725 UNSERIALIZE_SCALAR(partId
);
726 UNSERIALIZE_SCALAR(lsuCtrlReg
);
727 UNSERIALIZE_SCALAR(iTlbC0TsbPs0
);
728 UNSERIALIZE_SCALAR(iTlbC0TsbPs1
);
729 UNSERIALIZE_SCALAR(iTlbC0Config
);
730 UNSERIALIZE_SCALAR(iTlbCXTsbPs0
);
731 UNSERIALIZE_SCALAR(iTlbCXTsbPs1
);
732 UNSERIALIZE_SCALAR(iTlbCXConfig
);
733 UNSERIALIZE_SCALAR(iTlbSfsr
);
734 UNSERIALIZE_SCALAR(iTlbTagAccess
);
735 UNSERIALIZE_SCALAR(dTlbC0TsbPs0
);
736 UNSERIALIZE_SCALAR(dTlbC0TsbPs1
);
737 UNSERIALIZE_SCALAR(dTlbC0Config
);
738 UNSERIALIZE_SCALAR(dTlbCXTsbPs0
);
739 UNSERIALIZE_SCALAR(dTlbCXTsbPs1
);
740 UNSERIALIZE_SCALAR(dTlbSfsr
);
741 UNSERIALIZE_SCALAR(dTlbSfar
);
742 UNSERIALIZE_SCALAR(dTlbTagAccess
);
743 UNSERIALIZE_ARRAY(scratchPad
,8);
744 UNSERIALIZE_SCALAR(cpu_mondo_head
);
745 UNSERIALIZE_SCALAR(cpu_mondo_tail
);
746 UNSERIALIZE_SCALAR(dev_mondo_head
);
747 UNSERIALIZE_SCALAR(dev_mondo_tail
);
748 UNSERIALIZE_SCALAR(res_error_head
);
749 UNSERIALIZE_SCALAR(res_error_tail
);
750 UNSERIALIZE_SCALAR(nres_error_head
);
751 UNSERIALIZE_SCALAR(nres_error_tail
);}