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/miscregfile.hh"
33 #include "base/trace.hh"
34 #include "config/full_system.hh"
35 #include "cpu/base.hh"
36 #include "cpu/thread_context.hh"
39 #include "arch/sparc/system.hh"
42 using namespace SparcISA
;
47 //These functions map register indices to names
48 string
SparcISA::getMiscRegName(RegIndex index
)
50 static::string miscRegName
[NumMiscRegs
] =
51 {"y", "ccr", "asi", "tick", "pc", "fprs", "pcr", "pic",
52 "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
53 "stick", "stick_cmpr",
54 "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
55 "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
57 "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
60 return miscRegName
[index
];
63 void MiscRegFile::reset()
67 MiscReg
MiscRegFile::readReg(int miscReg
)
82 panic("ASR number %d not implemented\n", miscReg
- AsrStart
);
87 case MISCREG_TICK_CMPR
:
91 case MISCREG_STICK_CMPR
:
94 /** Privilged Registers */
103 case MISCREG_PRIVTICK
:
104 panic("Priviliged access to tick registers not implemented\n");
115 case MISCREG_CANSAVE
:
117 case MISCREG_CANRESTORE
:
119 case MISCREG_CLEANWIN
:
121 case MISCREG_OTHERWIN
:
128 /** Hyper privileged registers */
129 case MISCREG_HPSTATE
:
131 case MISCREG_HTSTATE
:
132 return htstate
[tl
-1];
134 panic("HINTP not implemented\n");
138 return NWindows
| MaxTL
<< 8 | MaxGL
<< 16;
139 case MISCREG_STRAND_STS_REG
:
140 return strandStatusReg
;
141 case MISCREG_HSTICK_CMPR
:
144 /** Floating Point Status Register */
148 panic("Miscellaneous register %d not implemented\n", miscReg
);
152 MiscReg
MiscRegFile::readRegWithEffect(int miscReg
, ThreadContext
* tc
)
156 case MISCREG_PRIVTICK
:
157 return tc
->getCpuPtr()->curCycle() - tickFields
.counter
|
158 tickFields
.npt
<< 63;
160 panic("FPU not implemented\n");
163 panic("Performance Instrumentation not impl\n");
164 /** Floating Point Status Register */
166 panic("Floating Point not implemented\n");
167 //We'll include this only in FS so we don't need the SparcSystem type around
172 sys
= dynamic_cast<SparcSystem
*>(tc
->getSystemPtr());
174 return curTick
/Clock::Int::ns
- sys
->sysTick
| stickFields
.npt
<< 63;
177 return NWindows
| MaxTL
<< 8 | MaxGL
<< 16;
179 return readReg(miscReg
);
182 void MiscRegFile::setReg(int miscReg
, const MiscReg
&val
)
202 panic("ASR number %d not implemented\n", miscReg
- AsrStart
);
206 case MISCREG_SOFTINT
:
209 case MISCREG_TICK_CMPR
:
215 case MISCREG_STICK_CMPR
:
219 /** Privilged Registers */
232 case MISCREG_PRIVTICK
:
233 panic("Priviliged access to tick regesiters not implemented\n");
235 // clear lower 7 bits on writes.
236 tba
= val
& ULL(~0x7FFF);
250 case MISCREG_CANSAVE
:
253 case MISCREG_CANRESTORE
:
256 case MISCREG_CLEANWIN
:
259 case MISCREG_OTHERWIN
:
269 /** Hyper privileged registers */
270 case MISCREG_HPSTATE
:
273 case MISCREG_HTSTATE
:
277 panic("HINTP not implemented\n");
281 case MISCREG_STRAND_STS_REG
:
282 strandStatusReg
= val
;
284 case MISCREG_HSTICK_CMPR
:
288 /** Floating Point Status Register */
293 panic("Miscellaneous register %d not implemented\n", miscReg
);
297 inline void MiscRegFile::setImplicitAsis()
299 //The spec seems to use trap level to indicate the privilege level of the
300 //processor. It's unclear whether the implicit ASIs should directly depend
301 //on the trap level, or if they should really be based on the privelege
305 implicitInstAsi
= implicitDataAsi
=
306 pstateFields
.cle
? ASI_PRIMARY_LITTLE
: ASI_PRIMARY
;
308 else if(tl
<= MaxPTL
)
310 implicitInstAsi
= ASI_NUCLEUS
;
311 implicitDataAsi
= pstateFields
.cle
? ASI_NUCLEUS_LITTLE
: ASI_NUCLEUS
;
315 //This is supposed to force physical addresses to match the spec.
316 //It might not because of context values and partition values.
317 implicitInstAsi
= implicitDataAsi
= ASI_REAL
;
321 void MiscRegFile::setRegWithEffect(int miscReg
,
322 const MiscReg
&val
, ThreadContext
* tc
)
324 const uint64_t Bit64
= (1ULL << 63);
331 tickFields
.counter
= tc
->getCpuPtr()->curCycle() - val
& ~Bit64
;
332 tickFields
.npt
= val
& Bit64
? 1 : 0;
335 //Configure the fpu based on the fprs
338 //Set up performance counting based on pcr value
349 tc
->changeRegFileContext(CONTEXT_CWP
, val
);
352 tc
->changeRegFileContext(CONTEXT_GLOBALS
, val
);
354 case MISCREG_SOFTINT
:
355 //We need to inject interrupts, and or notify the interrupt
356 //object that it needs to use a different interrupt level.
357 //Any newly appropriate interrupts will happen when the cpu gets
358 //around to checking for them. This might not be quite what we
361 case MISCREG_SOFTINT_CLR
:
362 //Do whatever this is supposed to do...
364 case MISCREG_SOFTINT_SET
:
365 //Do whatever this is supposed to do...
368 case MISCREG_TICK_CMPR
:
369 if (tickCompare
== NULL
)
370 tickCompare
= new TickCompareEvent(this, tc
);
371 setReg(miscReg
, val
);
372 if (tick_cmprFields
.int_dis
&& tickCompare
->scheduled())
373 tickCompare
->deschedule();
374 time
= tick_cmprFields
.tick_cmpr
- tickFields
.counter
;
375 if (!tick_cmprFields
.int_dis
&& time
> 0)
376 tickCompare
->schedule(time
* tc
->getCpuPtr()->cycles(1));
380 //We need to inject interrupts, and or notify the interrupt
381 //object that it needs to use a different interrupt level.
382 //Any newly appropriate interrupts will happen when the cpu gets
383 //around to checking for them. This might not be quite what we
386 //We'll include this only in FS so we don't need the SparcSystem type around
390 sys
= dynamic_cast<SparcSystem
*>(tc
->getSystemPtr());
392 sys
->sysTick
= curTick
/Clock::Int::ns
- val
& ~Bit64
;
393 stickFields
.npt
= val
& Bit64
? 1 : 0;
395 case MISCREG_STICK_CMPR
:
396 if (sTickCompare
== NULL
)
397 sTickCompare
= new STickCompareEvent(this, tc
);
398 sys
= dynamic_cast<SparcSystem
*>(tc
->getSystemPtr());
400 if (stick_cmprFields
.int_dis
&& sTickCompare
->scheduled())
401 sTickCompare
->deschedule();
402 time
= stick_cmprFields
.tick_cmpr
- sys
->sysTick
;
403 if (!stick_cmprFields
.int_dis
&& time
> 0)
404 sTickCompare
->schedule(time
* Clock::Int::ns
);
406 case MISCREG_HSTICK_CMPR
:
407 if (hSTickCompare
== NULL
)
408 hSTickCompare
= new HSTickCompareEvent(this, tc
);
409 sys
= dynamic_cast<SparcSystem
*>(tc
->getSystemPtr());
411 if (hstick_cmprFields
.int_dis
&& hSTickCompare
->scheduled())
412 hSTickCompare
->deschedule();
413 int64_t time
= hstick_cmprFields
.tick_cmpr
- sys
->sysTick
;
414 if (!hstick_cmprFields
.int_dis
&& time
> 0)
415 hSTickCompare
->schedule(time
* Clock::Int::ns
);
419 setReg(miscReg
, val
);
422 void MiscRegFile::serialize(std::ostream
& os
)
424 SERIALIZE_SCALAR(pstate
);
425 SERIALIZE_SCALAR(tba
);
427 SERIALIZE_SCALAR(pil
);
428 SERIALIZE_SCALAR(gl
);
429 SERIALIZE_SCALAR(cwp
);
430 SERIALIZE_ARRAY(tt
, MaxTL
);
431 SERIALIZE_SCALAR(ccr
);
432 SERIALIZE_SCALAR(asi
);
433 SERIALIZE_SCALAR(tl
);
434 SERIALIZE_ARRAY(tpc
, MaxTL
);
435 SERIALIZE_ARRAY(tnpc
, MaxTL
);
436 SERIALIZE_ARRAY(tstate
, MaxTL
);
437 SERIALIZE_SCALAR(tick
);
438 SERIALIZE_SCALAR(cansave
);
439 SERIALIZE_SCALAR(canrestore
);
440 SERIALIZE_SCALAR(otherwin
);
441 SERIALIZE_SCALAR(cleanwin
);
442 SERIALIZE_SCALAR(wstate
);
443 SERIALIZE_SCALAR(fsr
);
444 SERIALIZE_SCALAR(fprs
);
445 SERIALIZE_SCALAR(hpstate
);
446 SERIALIZE_ARRAY(htstate
, MaxTL
);
447 SERIALIZE_SCALAR(htba
);
448 SERIALIZE_SCALAR(hstick_cmpr
);
449 SERIALIZE_SCALAR((int)implicitInstAsi
);
450 SERIALIZE_SCALAR((int)implicitDataAsi
);
453 void MiscRegFile::unserialize(Checkpoint
* cp
, const std::string
& section
)
455 UNSERIALIZE_SCALAR(pstate
);
456 UNSERIALIZE_SCALAR(tba
);
457 UNSERIALIZE_SCALAR(y
);
458 UNSERIALIZE_SCALAR(pil
);
459 UNSERIALIZE_SCALAR(gl
);
460 UNSERIALIZE_SCALAR(cwp
);
461 UNSERIALIZE_ARRAY(tt
, MaxTL
);
462 UNSERIALIZE_SCALAR(ccr
);
463 UNSERIALIZE_SCALAR(asi
);
464 UNSERIALIZE_SCALAR(tl
);
465 UNSERIALIZE_ARRAY(tpc
, MaxTL
);
466 UNSERIALIZE_ARRAY(tnpc
, MaxTL
);
467 UNSERIALIZE_ARRAY(tstate
, MaxTL
);
468 UNSERIALIZE_SCALAR(tick
);
469 UNSERIALIZE_SCALAR(cansave
);
470 UNSERIALIZE_SCALAR(canrestore
);
471 UNSERIALIZE_SCALAR(otherwin
);
472 UNSERIALIZE_SCALAR(cleanwin
);
473 UNSERIALIZE_SCALAR(wstate
);
474 UNSERIALIZE_SCALAR(fsr
);
475 UNSERIALIZE_SCALAR(fprs
);
476 UNSERIALIZE_SCALAR(hpstate
);
477 UNSERIALIZE_ARRAY(htstate
, MaxTL
);
478 UNSERIALIZE_SCALAR(htba
);
479 UNSERIALIZE_SCALAR(hstick_cmpr
);
481 UNSERIALIZE_SCALAR(temp
);
482 implicitInstAsi
= (ASI
)temp
;
483 UNSERIALIZE_SCALAR(temp
);
484 implicitDataAsi
= (ASI
)temp
;
489 MiscRegFile::processTickCompare(ThreadContext
*tc
)
491 panic("tick compare not implemented\n");
495 MiscRegFile::processSTickCompare(ThreadContext
*tc
)
497 panic("tick compare not implemented\n");
501 MiscRegFile::processHSTickCompare(ThreadContext
*tc
)
503 panic("tick compare not implemented\n");