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", "pc", "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
];
65 void MiscRegFile::reset()
77 memset(tpc
, 0, sizeof(tpc
));
78 memset(tnpc
, 0, sizeof(tnpc
));
79 memset(tstate
, 0, sizeof(tstate
));
80 memset(tt
, 0, sizeof(tt
));
91 //In a T1, bit 11 is apparently always 1
93 memset(htstate
, 0, sizeof(htstate
));
99 implicitInstAsi
= ASI_PRIMARY
;
100 implicitDataAsi
= ASI_PRIMARY
;
103 MiscReg
MiscRegFile::readReg(int miscReg
)
117 panic("PCR not implemented\n");
119 panic("PIC not implemented\n");
122 case MISCREG_SOFTINT
:
124 case MISCREG_TICK_CMPR
:
128 case MISCREG_STICK_CMPR
:
131 /** Privilged Registers */
140 case MISCREG_PRIVTICK
:
141 panic("Priviliged access to tick registers not implemented\n");
152 case MISCREG_CANSAVE
:
154 case MISCREG_CANRESTORE
:
156 case MISCREG_CLEANWIN
:
158 case MISCREG_OTHERWIN
:
165 /** Hyper privileged registers */
166 case MISCREG_HPSTATE
:
168 case MISCREG_HTSTATE
:
169 return htstate
[tl
-1];
171 panic("HINTP not implemented\n");
175 return NWindows
| MaxTL
<< 8 | MaxGL
<< 16;
176 case MISCREG_STRAND_STS_REG
:
177 return strandStatusReg
;
178 case MISCREG_HSTICK_CMPR
:
181 /** Floating Point Status Register */
185 panic("Miscellaneous register %d not implemented\n", miscReg
);
189 MiscReg
MiscRegFile::readRegWithEffect(int miscReg
, ThreadContext
* tc
)
193 case MISCREG_PRIVTICK
:
194 return tc
->getCpuPtr()->curCycle() - (tick
& mask(63)) |
195 (tick
& ~(mask(63))) << 63;
197 panic("FPU not implemented\n");
200 panic("Performance Instrumentation not impl\n");
201 /** Floating Point Status Register */
203 panic("Floating Point not implemented\n");
204 //We'll include this only in FS so we don't need the SparcSystem type around
209 sys
= dynamic_cast<SparcSystem
*>(tc
->getSystemPtr());
211 return curTick
/Clock::Int::ns
- sys
->sysTick
| (stick
& ~(mask(63)));
214 return NWindows
| MaxTL
<< 8 | MaxGL
<< 16;
216 return readReg(miscReg
);
219 void MiscRegFile::setReg(int miscReg
, const MiscReg
&val
)
238 panic("PCR not implemented\n");
240 panic("PIC not implemented\n");
244 case MISCREG_SOFTINT
:
247 case MISCREG_TICK_CMPR
:
253 case MISCREG_STICK_CMPR
:
257 /** Privilged Registers */
270 case MISCREG_PRIVTICK
:
271 panic("Priviliged access to tick regesiters not implemented\n");
273 // clear lower 7 bits on writes.
274 tba
= val
& ULL(~0x7FFF);
288 case MISCREG_CANSAVE
:
291 case MISCREG_CANRESTORE
:
294 case MISCREG_CLEANWIN
:
297 case MISCREG_OTHERWIN
:
307 /** Hyper privileged registers */
308 case MISCREG_HPSTATE
:
311 case MISCREG_HTSTATE
:
315 panic("HINTP not implemented\n");
319 case MISCREG_STRAND_STS_REG
:
320 strandStatusReg
= val
;
322 case MISCREG_HSTICK_CMPR
:
326 /** Floating Point Status Register */
331 panic("Miscellaneous register %d not implemented\n", miscReg
);
335 inline void MiscRegFile::setImplicitAsis()
337 //The spec seems to use trap level to indicate the privilege level of the
338 //processor. It's unclear whether the implicit ASIs should directly depend
339 //on the trap level, or if they should really be based on the privelege
343 implicitInstAsi
= implicitDataAsi
=
344 (pstate
& (1 << 9)) ? ASI_PRIMARY_LITTLE
: ASI_PRIMARY
;
346 else if(tl
<= MaxPTL
)
348 implicitInstAsi
= ASI_NUCLEUS
;
349 implicitDataAsi
= (pstate
& (1 << 9)) ? ASI_NUCLEUS_LITTLE
: ASI_NUCLEUS
;
353 //This is supposed to force physical addresses to match the spec.
354 //It might not because of context values and partition values.
355 implicitInstAsi
= implicitDataAsi
= ASI_REAL
;
359 void MiscRegFile::setRegWithEffect(int miscReg
,
360 const MiscReg
&val
, ThreadContext
* tc
)
362 const uint64_t Bit64
= (1ULL << 63);
369 tick
= tc
->getCpuPtr()->curCycle() - val
& ~Bit64
;
373 //Configure the fpu based on the fprs
376 //Set up performance counting based on pcr value
387 tc
->changeRegFileContext(CONTEXT_CWP
, val
);
390 tc
->changeRegFileContext(CONTEXT_GLOBALS
, val
);
392 case MISCREG_SOFTINT
:
393 //We need to inject interrupts, and or notify the interrupt
394 //object that it needs to use a different interrupt level.
395 //Any newly appropriate interrupts will happen when the cpu gets
396 //around to checking for them. This might not be quite what we
399 case MISCREG_SOFTINT_CLR
:
400 //Do whatever this is supposed to do...
402 case MISCREG_SOFTINT_SET
:
403 //Do whatever this is supposed to do...
406 case MISCREG_TICK_CMPR
:
407 if (tickCompare
== NULL
)
408 tickCompare
= new TickCompareEvent(this, tc
);
409 setReg(miscReg
, val
);
410 if ((tick_cmpr
& mask(63)) && tickCompare
->scheduled())
411 tickCompare
->deschedule();
412 time
= (tick_cmpr
& mask(63)) - (tick
& mask(63));
413 if (!(tick_cmpr
& ~mask(63)) && time
> 0)
414 tickCompare
->schedule(time
* tc
->getCpuPtr()->cycles(1));
418 //We need to inject interrupts, and or notify the interrupt
419 //object that it needs to use a different interrupt level.
420 //Any newly appropriate interrupts will happen when the cpu gets
421 //around to checking for them. This might not be quite what we
424 //We'll include this only in FS so we don't need the SparcSystem type around
428 sys
= dynamic_cast<SparcSystem
*>(tc
->getSystemPtr());
430 sys
->sysTick
= curTick
/Clock::Int::ns
- val
& ~Bit64
;
431 stick
|= val
& Bit64
;
433 case MISCREG_STICK_CMPR
:
434 if (sTickCompare
== NULL
)
435 sTickCompare
= new STickCompareEvent(this, tc
);
436 sys
= dynamic_cast<SparcSystem
*>(tc
->getSystemPtr());
438 if ((stick_cmpr
& ~mask(63)) && sTickCompare
->scheduled())
439 sTickCompare
->deschedule();
440 time
= (stick_cmpr
& mask(63)) - sys
->sysTick
;
441 if (!(stick_cmpr
& ~mask(63)) && time
> 0)
442 sTickCompare
->schedule(time
* Clock::Int::ns
);
444 case MISCREG_HSTICK_CMPR
:
445 if (hSTickCompare
== NULL
)
446 hSTickCompare
= new HSTickCompareEvent(this, tc
);
447 sys
= dynamic_cast<SparcSystem
*>(tc
->getSystemPtr());
449 if ((hstick_cmpr
& ~mask(63)) && hSTickCompare
->scheduled())
450 hSTickCompare
->deschedule();
451 int64_t time
= (hstick_cmpr
& mask(63)) - sys
->sysTick
;
452 if (!(hstick_cmpr
& ~mask(63)) && time
> 0)
453 hSTickCompare
->schedule(time
* Clock::Int::ns
);
457 setReg(miscReg
, val
);
460 void MiscRegFile::serialize(std::ostream
& os
)
462 SERIALIZE_SCALAR(pstate
);
463 SERIALIZE_SCALAR(tba
);
465 SERIALIZE_SCALAR(pil
);
466 SERIALIZE_SCALAR(gl
);
467 SERIALIZE_SCALAR(cwp
);
468 SERIALIZE_ARRAY(tt
, MaxTL
);
469 SERIALIZE_SCALAR(ccr
);
470 SERIALIZE_SCALAR(asi
);
471 SERIALIZE_SCALAR(tl
);
472 SERIALIZE_ARRAY(tpc
, MaxTL
);
473 SERIALIZE_ARRAY(tnpc
, MaxTL
);
474 SERIALIZE_ARRAY(tstate
, MaxTL
);
475 SERIALIZE_SCALAR(tick
);
476 SERIALIZE_SCALAR(cansave
);
477 SERIALIZE_SCALAR(canrestore
);
478 SERIALIZE_SCALAR(otherwin
);
479 SERIALIZE_SCALAR(cleanwin
);
480 SERIALIZE_SCALAR(wstate
);
481 SERIALIZE_SCALAR(fsr
);
482 SERIALIZE_SCALAR(fprs
);
483 SERIALIZE_SCALAR(hpstate
);
484 SERIALIZE_ARRAY(htstate
, MaxTL
);
485 SERIALIZE_SCALAR(htba
);
486 SERIALIZE_SCALAR(hstick_cmpr
);
487 SERIALIZE_SCALAR((int)implicitInstAsi
);
488 SERIALIZE_SCALAR((int)implicitDataAsi
);
491 void MiscRegFile::unserialize(Checkpoint
* cp
, const std::string
& section
)
493 UNSERIALIZE_SCALAR(pstate
);
494 UNSERIALIZE_SCALAR(tba
);
495 UNSERIALIZE_SCALAR(y
);
496 UNSERIALIZE_SCALAR(pil
);
497 UNSERIALIZE_SCALAR(gl
);
498 UNSERIALIZE_SCALAR(cwp
);
499 UNSERIALIZE_ARRAY(tt
, MaxTL
);
500 UNSERIALIZE_SCALAR(ccr
);
501 UNSERIALIZE_SCALAR(asi
);
502 UNSERIALIZE_SCALAR(tl
);
503 UNSERIALIZE_ARRAY(tpc
, MaxTL
);
504 UNSERIALIZE_ARRAY(tnpc
, MaxTL
);
505 UNSERIALIZE_ARRAY(tstate
, MaxTL
);
506 UNSERIALIZE_SCALAR(tick
);
507 UNSERIALIZE_SCALAR(cansave
);
508 UNSERIALIZE_SCALAR(canrestore
);
509 UNSERIALIZE_SCALAR(otherwin
);
510 UNSERIALIZE_SCALAR(cleanwin
);
511 UNSERIALIZE_SCALAR(wstate
);
512 UNSERIALIZE_SCALAR(fsr
);
513 UNSERIALIZE_SCALAR(fprs
);
514 UNSERIALIZE_SCALAR(hpstate
);
515 UNSERIALIZE_ARRAY(htstate
, MaxTL
);
516 UNSERIALIZE_SCALAR(htba
);
517 UNSERIALIZE_SCALAR(hstick_cmpr
);
519 UNSERIALIZE_SCALAR(temp
);
520 implicitInstAsi
= (ASI
)temp
;
521 UNSERIALIZE_SCALAR(temp
);
522 implicitDataAsi
= (ASI
)temp
;
527 MiscRegFile::processTickCompare(ThreadContext
*tc
)
529 panic("tick compare not implemented\n");
533 MiscRegFile::processSTickCompare(ThreadContext
*tc
)
535 panic("tick compare not implemented\n");
539 MiscRegFile::processHSTickCompare(ThreadContext
*tc
)
541 panic("tick compare not implemented\n");