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"
41 #include "arch/sparc/system.hh"
44 using namespace SparcISA
;
49 //These functions map register indices to names
50 string
SparcISA::getMiscRegName(RegIndex index
)
52 static::string miscRegName
[NumMiscRegs
] =
53 {"y", "ccr", "asi", "tick", "fprs", "pcr", "pic",
54 "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
55 "stick", "stick_cmpr",
56 "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
57 "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
59 "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
62 return miscRegName
[index
];
67 PSTATE_MASK
= (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
70 void MiscRegFile::clear()
82 memset(tpc
, 0, sizeof(tpc
));
83 memset(tnpc
, 0, sizeof(tnpc
));
84 memset(tstate
, 0, sizeof(tstate
));
85 memset(tt
, 0, sizeof(tt
));
96 //In a T1, bit 11 is apparently always 1
98 memset(htstate
, 0, sizeof(htstate
));
102 //This is set this way in Legion for some reason
103 strandStatusReg
= 0x50000;
130 memset(scratchPad
, 0, sizeof(scratchPad
));
133 MiscReg
MiscRegFile::readReg(int miscReg
)
147 panic("PCR not implemented\n");
149 panic("PIC not implemented\n");
152 case MISCREG_SOFTINT
:
154 case MISCREG_TICK_CMPR
:
158 case MISCREG_STICK_CMPR
:
161 /** Privilged Registers */
170 case MISCREG_PRIVTICK
:
171 panic("Priviliged access to tick registers not implemented\n");
182 case MISCREG_CANSAVE
:
184 case MISCREG_CANRESTORE
:
186 case MISCREG_CLEANWIN
:
188 case MISCREG_OTHERWIN
:
195 /** Hyper privileged registers */
196 case MISCREG_HPSTATE
:
198 case MISCREG_HTSTATE
:
199 return htstate
[tl
-1];
201 panic("HINTP not implemented\n");
205 return NWindows
| MaxTL
<< 8 | MaxGL
<< 16;
206 case MISCREG_STRAND_STS_REG
:
207 return strandStatusReg
;
208 case MISCREG_HSTICK_CMPR
:
211 /** Floating Point Status Register */
215 case MISCREG_MMU_P_CONTEXT
:
217 case MISCREG_MMU_S_CONTEXT
:
219 case MISCREG_MMU_PART_ID
:
221 case MISCREG_MMU_LSU_CTRL
:
224 case MISCREG_MMU_ITLB_C0_TSB_PS0
:
226 case MISCREG_MMU_ITLB_C0_TSB_PS1
:
228 case MISCREG_MMU_ITLB_C0_CONFIG
:
230 case MISCREG_MMU_ITLB_CX_TSB_PS0
:
232 case MISCREG_MMU_ITLB_CX_TSB_PS1
:
234 case MISCREG_MMU_ITLB_CX_CONFIG
:
236 case MISCREG_MMU_ITLB_SFSR
:
238 case MISCREG_MMU_ITLB_TAG_ACCESS
:
239 return iTlbTagAccess
;
241 case MISCREG_MMU_DTLB_C0_TSB_PS0
:
243 case MISCREG_MMU_DTLB_C0_TSB_PS1
:
245 case MISCREG_MMU_DTLB_C0_CONFIG
:
247 case MISCREG_MMU_DTLB_CX_TSB_PS0
:
249 case MISCREG_MMU_DTLB_CX_TSB_PS1
:
251 case MISCREG_MMU_DTLB_CX_CONFIG
:
253 case MISCREG_MMU_DTLB_SFSR
:
255 case MISCREG_MMU_DTLB_SFAR
:
257 case MISCREG_MMU_DTLB_TAG_ACCESS
:
258 return dTlbTagAccess
;
260 case MISCREG_SCRATCHPAD_R0
:
261 return scratchPad
[0];
262 case MISCREG_SCRATCHPAD_R1
:
263 return scratchPad
[1];
264 case MISCREG_SCRATCHPAD_R2
:
265 return scratchPad
[2];
266 case MISCREG_SCRATCHPAD_R3
:
267 return scratchPad
[3];
268 case MISCREG_SCRATCHPAD_R4
:
269 return scratchPad
[4];
270 case MISCREG_SCRATCHPAD_R5
:
271 return scratchPad
[5];
272 case MISCREG_SCRATCHPAD_R6
:
273 return scratchPad
[6];
274 case MISCREG_SCRATCHPAD_R7
:
275 return scratchPad
[7];
278 panic("Miscellaneous register %d not implemented\n", miscReg
);
282 MiscReg
MiscRegFile::readRegWithEffect(int miscReg
, ThreadContext
* tc
)
285 // tick and stick are aliased to each other in niagra
288 case MISCREG_PRIVTICK
:
289 // I'm not sure why legion ignores the lowest two bits, but we'll go
291 // change from curCycle() to instCount() until we're done with legion
292 DPRINTFN("Instruction Count when STICK read: %#X\n",
293 tc
->getCpuPtr()->instCount());
294 uint64_t t1
= mbits(tc
->getCpuPtr()->instCount() - (tick
&
296 uint64_t t2
= mbits(tick
,63,63) ;
299 panic("FPU not implemented\n");
302 panic("Performance Instrumentation not impl\n");
303 /** Floating Point Status Register */
305 panic("Floating Point not implemented\n");
306 //We'll include this only in FS so we don't need the SparcSystem type around
311 sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
313 return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63)));
316 return NWindows
| MaxTL
<< 8 | MaxGL
<< 16;
318 return readReg(miscReg
);
321 void MiscRegFile::setReg(int miscReg
, const MiscReg
&val
)
340 panic("PCR not implemented\n");
342 panic("PIC not implemented\n");
346 case MISCREG_SOFTINT
:
349 case MISCREG_TICK_CMPR
:
355 case MISCREG_STICK_CMPR
:
359 /** Privilged Registers */
372 case MISCREG_PRIVTICK
:
373 panic("Priviliged access to tick regesiters not implemented\n");
375 // clear lower 7 bits on writes.
376 tba
= val
& ULL(~0x7FFF);
379 pstate
= (val
& PSTATE_MASK
);
390 case MISCREG_CANSAVE
:
393 case MISCREG_CANRESTORE
:
396 case MISCREG_CLEANWIN
:
399 case MISCREG_OTHERWIN
:
409 /** Hyper privileged registers */
410 case MISCREG_HPSTATE
:
413 case MISCREG_HTSTATE
:
417 panic("HINTP not implemented\n");
421 case MISCREG_STRAND_STS_REG
:
422 strandStatusReg
= val
;
424 case MISCREG_HSTICK_CMPR
:
428 /** Floating Point Status Register */
433 case MISCREG_MMU_P_CONTEXT
:
436 case MISCREG_MMU_S_CONTEXT
:
439 case MISCREG_MMU_PART_ID
:
442 case MISCREG_MMU_LSU_CTRL
:
446 case MISCREG_MMU_ITLB_C0_TSB_PS0
:
449 case MISCREG_MMU_ITLB_C0_TSB_PS1
:
452 case MISCREG_MMU_ITLB_C0_CONFIG
:
455 case MISCREG_MMU_ITLB_CX_TSB_PS0
:
458 case MISCREG_MMU_ITLB_CX_TSB_PS1
:
461 case MISCREG_MMU_ITLB_CX_CONFIG
:
464 case MISCREG_MMU_ITLB_SFSR
:
467 case MISCREG_MMU_ITLB_TAG_ACCESS
:
471 case MISCREG_MMU_DTLB_C0_TSB_PS0
:
474 case MISCREG_MMU_DTLB_C0_TSB_PS1
:
477 case MISCREG_MMU_DTLB_C0_CONFIG
:
480 case MISCREG_MMU_DTLB_CX_TSB_PS0
:
483 case MISCREG_MMU_DTLB_CX_TSB_PS1
:
486 case MISCREG_MMU_DTLB_CX_CONFIG
:
489 case MISCREG_MMU_DTLB_SFSR
:
492 case MISCREG_MMU_DTLB_SFAR
:
495 case MISCREG_MMU_DTLB_TAG_ACCESS
:
499 case MISCREG_SCRATCHPAD_R0
:
501 case MISCREG_SCRATCHPAD_R1
:
503 case MISCREG_SCRATCHPAD_R2
:
505 case MISCREG_SCRATCHPAD_R3
:
507 case MISCREG_SCRATCHPAD_R4
:
509 case MISCREG_SCRATCHPAD_R5
:
511 case MISCREG_SCRATCHPAD_R6
:
513 case MISCREG_SCRATCHPAD_R7
:
517 panic("Miscellaneous register %d not implemented\n", miscReg
);
521 void MiscRegFile::setRegWithEffect(int miscReg
,
522 const MiscReg
&val
, ThreadContext
* tc
)
524 const uint64_t Bit64
= (1ULL << 63);
532 // change from curCycle() to instCount() until we're done with legion
533 tick
= tc
->getCpuPtr()->instCount() - val
& ~Bit64
;
537 //Configure the fpu based on the fprs
540 //Set up performance counting based on pcr value
543 pstate
= val
& PSTATE_MASK
;
549 tc
->changeRegFileContext(CONTEXT_CWP
, val
);
552 tc
->changeRegFileContext(CONTEXT_GLOBALS
, val
);
554 case MISCREG_SOFTINT
:
555 //We need to inject interrupts, and or notify the interrupt
556 //object that it needs to use a different interrupt level.
557 //Any newly appropriate interrupts will happen when the cpu gets
558 //around to checking for them. This might not be quite what we
561 case MISCREG_SOFTINT_CLR
:
562 //Do whatever this is supposed to do...
564 case MISCREG_SOFTINT_SET
:
565 //Do whatever this is supposed to do...
568 case MISCREG_TICK_CMPR
:
569 if (tickCompare
== NULL
)
570 tickCompare
= new TickCompareEvent(this, tc
);
571 setReg(miscReg
, val
);
572 if ((tick_cmpr
& mask(63)) && tickCompare
->scheduled())
573 tickCompare
->deschedule();
574 time
= (tick_cmpr
& mask(63)) - (tick
& mask(63));
575 if (!(tick_cmpr
& ~mask(63)) && time
> 0)
576 tickCompare
->schedule(time
* tc
->getCpuPtr()->cycles(1));
580 //We need to inject interrupts, and or notify the interrupt
581 //object that it needs to use a different interrupt level.
582 //Any newly appropriate interrupts will happen when the cpu gets
583 //around to checking for them. This might not be quite what we
586 //We'll include this only in FS so we don't need the SparcSystem type around
589 // @todo figure out how we're actualy going to do this. In niagra the
590 // registers are aliased to the same thing (see tick above)
591 /*case MISCREG_STICK:
592 sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
594 sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64;
595 stick |= val & Bit64;
597 case MISCREG_STICK_CMPR
:
598 if (sTickCompare
== NULL
)
599 sTickCompare
= new STickCompareEvent(this, tc
);
600 sys
= dynamic_cast<SparcSystem
*>(tc
->getSystemPtr());
602 if ((stick_cmpr
& ~mask(63)) && sTickCompare
->scheduled())
603 sTickCompare
->deschedule();
604 time
= (stick_cmpr
& mask(63)) - sys
->sysTick
;
605 if (!(stick_cmpr
& ~mask(63)) && time
> 0)
606 sTickCompare
->schedule(time
* Clock::Int::ns
);
608 case MISCREG_HSTICK_CMPR
:
609 if (hSTickCompare
== NULL
)
610 hSTickCompare
= new HSTickCompareEvent(this, tc
);
611 sys
= dynamic_cast<SparcSystem
*>(tc
->getSystemPtr());
613 if ((hstick_cmpr
& ~mask(63)) && hSTickCompare
->scheduled())
614 hSTickCompare
->deschedule();
615 int64_t time
= (hstick_cmpr
& mask(63)) - sys
->sysTick
;
616 if (!(hstick_cmpr
& ~mask(63)) && time
> 0)
617 hSTickCompare
->schedule(time
* Clock::Int::ns
);
621 setReg(miscReg
, val
);
624 void MiscRegFile::serialize(std::ostream
& os
)
626 SERIALIZE_SCALAR(pstate
);
627 SERIALIZE_SCALAR(tba
);
629 SERIALIZE_SCALAR(pil
);
630 SERIALIZE_SCALAR(gl
);
631 SERIALIZE_SCALAR(cwp
);
632 SERIALIZE_ARRAY(tt
, MaxTL
);
633 SERIALIZE_SCALAR(ccr
);
634 SERIALIZE_SCALAR(asi
);
635 SERIALIZE_SCALAR(tl
);
636 SERIALIZE_ARRAY(tpc
, MaxTL
);
637 SERIALIZE_ARRAY(tnpc
, MaxTL
);
638 SERIALIZE_ARRAY(tstate
, MaxTL
);
639 SERIALIZE_SCALAR(tick
);
640 SERIALIZE_SCALAR(cansave
);
641 SERIALIZE_SCALAR(canrestore
);
642 SERIALIZE_SCALAR(otherwin
);
643 SERIALIZE_SCALAR(cleanwin
);
644 SERIALIZE_SCALAR(wstate
);
645 SERIALIZE_SCALAR(fsr
);
646 SERIALIZE_SCALAR(fprs
);
647 SERIALIZE_SCALAR(hpstate
);
648 SERIALIZE_ARRAY(htstate
, MaxTL
);
649 SERIALIZE_SCALAR(htba
);
650 SERIALIZE_SCALAR(hstick_cmpr
);
651 SERIALIZE_SCALAR(strandStatusReg
);
652 SERIALIZE_SCALAR(priContext
);
653 SERIALIZE_SCALAR(secContext
);
654 SERIALIZE_SCALAR(partId
);
655 SERIALIZE_SCALAR(lsuCtrlReg
);
656 SERIALIZE_SCALAR(iTlbC0TsbPs0
);
657 SERIALIZE_SCALAR(iTlbC0TsbPs1
);
658 SERIALIZE_SCALAR(iTlbC0Config
);
659 SERIALIZE_SCALAR(iTlbCXTsbPs0
);
660 SERIALIZE_SCALAR(iTlbCXTsbPs1
);
661 SERIALIZE_SCALAR(iTlbCXConfig
);
662 SERIALIZE_SCALAR(iTlbSfsr
);
663 SERIALIZE_SCALAR(iTlbTagAccess
);
664 SERIALIZE_SCALAR(dTlbC0TsbPs0
);
665 SERIALIZE_SCALAR(dTlbC0TsbPs1
);
666 SERIALIZE_SCALAR(dTlbC0Config
);
667 SERIALIZE_SCALAR(dTlbCXTsbPs0
);
668 SERIALIZE_SCALAR(dTlbCXTsbPs1
);
669 SERIALIZE_SCALAR(dTlbSfsr
);
670 SERIALIZE_SCALAR(dTlbSfar
);
671 SERIALIZE_SCALAR(dTlbTagAccess
);
672 SERIALIZE_ARRAY(scratchPad
,8);
675 void MiscRegFile::unserialize(Checkpoint
* cp
, const std::string
& section
)
677 UNSERIALIZE_SCALAR(pstate
);
678 UNSERIALIZE_SCALAR(tba
);
679 UNSERIALIZE_SCALAR(y
);
680 UNSERIALIZE_SCALAR(pil
);
681 UNSERIALIZE_SCALAR(gl
);
682 UNSERIALIZE_SCALAR(cwp
);
683 UNSERIALIZE_ARRAY(tt
, MaxTL
);
684 UNSERIALIZE_SCALAR(ccr
);
685 UNSERIALIZE_SCALAR(asi
);
686 UNSERIALIZE_SCALAR(tl
);
687 UNSERIALIZE_ARRAY(tpc
, MaxTL
);
688 UNSERIALIZE_ARRAY(tnpc
, MaxTL
);
689 UNSERIALIZE_ARRAY(tstate
, MaxTL
);
690 UNSERIALIZE_SCALAR(tick
);
691 UNSERIALIZE_SCALAR(cansave
);
692 UNSERIALIZE_SCALAR(canrestore
);
693 UNSERIALIZE_SCALAR(otherwin
);
694 UNSERIALIZE_SCALAR(cleanwin
);
695 UNSERIALIZE_SCALAR(wstate
);
696 UNSERIALIZE_SCALAR(fsr
);
697 UNSERIALIZE_SCALAR(fprs
);
698 UNSERIALIZE_SCALAR(hpstate
);
699 UNSERIALIZE_ARRAY(htstate
, MaxTL
);
700 UNSERIALIZE_SCALAR(htba
);
701 UNSERIALIZE_SCALAR(hstick_cmpr
);
702 UNSERIALIZE_SCALAR(strandStatusReg
);
703 UNSERIALIZE_SCALAR(priContext
);
704 UNSERIALIZE_SCALAR(secContext
);
705 UNSERIALIZE_SCALAR(partId
);
706 UNSERIALIZE_SCALAR(lsuCtrlReg
);
707 UNSERIALIZE_SCALAR(iTlbC0TsbPs0
);
708 UNSERIALIZE_SCALAR(iTlbC0TsbPs1
);
709 UNSERIALIZE_SCALAR(iTlbC0Config
);
710 UNSERIALIZE_SCALAR(iTlbCXTsbPs0
);
711 UNSERIALIZE_SCALAR(iTlbCXTsbPs1
);
712 UNSERIALIZE_SCALAR(iTlbCXConfig
);
713 UNSERIALIZE_SCALAR(iTlbSfsr
);
714 UNSERIALIZE_SCALAR(iTlbTagAccess
);
715 UNSERIALIZE_SCALAR(dTlbC0TsbPs0
);
716 UNSERIALIZE_SCALAR(dTlbC0TsbPs1
);
717 UNSERIALIZE_SCALAR(dTlbC0Config
);
718 UNSERIALIZE_SCALAR(dTlbCXTsbPs0
);
719 UNSERIALIZE_SCALAR(dTlbCXTsbPs1
);
720 UNSERIALIZE_SCALAR(dTlbSfsr
);
721 UNSERIALIZE_SCALAR(dTlbSfar
);
722 UNSERIALIZE_SCALAR(dTlbTagAccess
);
723 UNSERIALIZE_ARRAY(scratchPad
,8);}
727 MiscRegFile::processTickCompare(ThreadContext
*tc
)
729 panic("tick compare not implemented\n");
733 MiscRegFile::processSTickCompare(ThreadContext
*tc
)
735 panic("tick compare not implemented\n");
739 MiscRegFile::processHSTickCompare(ThreadContext
*tc
)
741 panic("tick compare not implemented\n");