36 #include "debug/Quiesce.hh"
37 #include "debug/Timer.hh"
41 using namespace SparcISA;
51 if (pil < 14 && softint & 0x10000)
55 if (pil < 14 && softint & 0x1)
61 for (
int bit = 15; bit > 0; --bit) {
62 if (1 << bit & softint && bit > pil)
74 {
"asi",
"tick",
"fprs",
"pcr",
"pic",
75 "gsr",
"softint_set",
"softint_clr",
"softint",
"tick_cmpr",
76 "stick",
"stick_cmpr",
77 "tpc",
"tnpc",
"tstate",
"tt",
"privtick",
"tba",
"pstate",
"tl",
80 "hpstate",
"htstate",
"hintp",
"htba",
"hver",
"strand_sts_reg",
82 "fsr",
"prictx",
"secctx",
"partId",
"lsuCtrlReg",
83 "scratch0",
"scratch1",
"scratch2",
"scratch3",
"scratch4",
84 "scratch5",
"scratch6",
"scratch7",
"cpuMondoHead",
"cpuMondoTail",
85 "devMondoHead",
"devMondoTail",
"resErrorHead",
"resErrorTail",
86 "nresErrorHead",
"nresErrorTail",
"TlbData" };
87 return miscRegName[
index];
99 setMiscRegNoEffect(miscReg, val);;
108 if (tickCompare == NULL)
110 setMiscRegNoEffect(miscReg, val);
111 if ((tick_cmpr & ~
mask(63)) && tickCompare->scheduled())
112 cpu->deschedule(tickCompare);
113 time = (tick_cmpr &
mask(63)) - (tick &
mask(63));
114 if (!(tick_cmpr & ~
mask(63)) && time > 0) {
115 if (tickCompare->scheduled())
116 cpu->deschedule(tickCompare);
117 cpu->schedule(tickCompare, cpu->clockEdge(
Cycles(time)));
119 DPRINTF(Timer,
"writing to TICK compare register value %#X\n", val);
123 if (sTickCompare == NULL)
125 setMiscRegNoEffect(miscReg, val);
126 if ((stick_cmpr & ~
mask(63)) && sTickCompare->scheduled())
127 cpu->deschedule(sTickCompare);
128 time = ((int64_t)(stick_cmpr &
mask(63)) - (int64_t)stick) -
130 if (!(stick_cmpr & ~
mask(63)) && time > 0) {
131 if (sTickCompare->scheduled())
132 cpu->deschedule(sTickCompare);
133 cpu->schedule(sTickCompare, cpu->clockEdge(
Cycles(time)));
135 DPRINTF(Timer,
"writing to sTICK compare register value %#X\n", val);
139 setMiscRegNoEffect(miscReg, val);
142 setMiscRegNoEffect(miscReg, val);
147 panic(
"Shouldn't be writing HVER\n");
150 setMiscRegNoEffect(miscReg, val);
154 cpu->clearInterrupt(0,
IT_HINTP, 0);
159 setMiscRegNoEffect(miscReg, val &
ULL(~0x7FFF));
164 setMiscRegNoEffect(miscReg, val);
165 if (cpu_mondo_head != cpu_mondo_tail)
172 setMiscRegNoEffect(miscReg, val);
173 if (dev_mondo_head != dev_mondo_tail)
180 setMiscRegNoEffect(miscReg, val);
181 if (res_error_head != res_error_tail)
188 setMiscRegNoEffect(miscReg, val);
193 if (hSTickCompare == NULL)
195 setMiscRegNoEffect(miscReg, val);
196 if ((hstick_cmpr & ~
mask(63)) && hSTickCompare->scheduled())
197 cpu->deschedule(hSTickCompare);
198 time = ((int64_t)(hstick_cmpr &
mask(63)) - (int64_t)stick) -
200 if (!(hstick_cmpr & ~
mask(63)) && time > 0) {
201 if (hSTickCompare->scheduled())
202 cpu->deschedule(hSTickCompare);
203 cpu->schedule(hSTickCompare, cpu->clockEdge(
Cycles(time)));
205 DPRINTF(Timer,
"writing to hsTICK compare register value %#X\n", val);
210 HPSTATE newVal =
val;
213 setMiscRegNoEffect(miscReg, newVal);
215 if (newVal.tlz &&
tl == 0 && !newVal.hpriv)
222 setMiscRegNoEffect(miscReg, val);
227 panic(
"No support for setting spec_en bit\n");
228 setMiscRegNoEffect(miscReg,
bits(val,0,0));
229 if (!
bits(val,0,0)) {
230 DPRINTF(Quiesce,
"Cpu executed quiescing instruction\n");
239 panic(
"Invalid write to FS misc register %s\n",
267 return readMiscRegNoEffect(miscReg) ;
270 return readMiscRegNoEffect(miscReg) &
ULL(~0x7FFF);
273 return ULL(0x3e) << 48 |
285 temp = readMiscRegNoEffect(miscReg) & (STS::active | STS::speculative);
295 temp |= STS::st_run << (STS::shft_fsm0 -
296 ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
300 temp |= STS::st_idle << (STS::shft_fsm0 -
301 ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
304 temp |= STS::st_halt << (STS::shft_fsm0 -
305 ((x & 0x3) * (STS::shft_fsm0-STS::shft_fsm1)));
308 panic(
"What state are we in?!\n");
314 panic(
"Invalid read to FS misc register\n");
321 panic(
"tick compare not implemented\n");
333 delay = ((int64_t)(stick_cmpr &
mask(63)) - (int64_t)stick) -
335 assert(delay >= 0 &&
"stick compare missed interrupt cycle");
338 DPRINTF(Timer,
"STick compare cycle reached at %#x\n",
339 (stick_cmpr &
mask(63)));
344 cpu->schedule(sTickCompare, cpu->clockEdge(
Cycles(delay)));
360 delay = ((int64_t)(hstick_cmpr &
mask(63)) - (int64_t)stick) -
362 assert(delay >= 0 &&
"hstick compare missed interrupt cycle");
365 DPRINTF(Timer,
"HSTick compare cycle reached at %#x\n",
366 (stick_cmpr &
mask(63)));
372 cpu->schedule(hSTickCompare, cpu->clockEdge(
Cycles(delay)));
virtual System * getSystemPtr()=0
void setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc)
MiscReg readFSReg(int miscReg, ThreadContext *tc)
Cycles is a wrapper class for representing cycle counts, i.e.
void processSTickCompare(ThreadContext *tc)
virtual MiscReg readMiscRegNoEffect(int misc_reg) const =0
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
virtual BaseCPU * getCpuPtr()=0
const char *const miscRegName[]
ThreadContext is the external interface to all thread state for anything outside of the CPU...
void processTickCompare(ThreadContext *tc)
Process a tick compare event and generate an interrupt on the cpu if appropriate. ...
void processHSTickCompare(ThreadContext *tc)
Hyper privileged registers.
static string getMiscRegName(RegIndex index)
std::vector< ThreadContext * > threadContexts
virtual void suspend()=0
Set the status to Suspended.
#define ULL(N)
uint64_t constant
virtual int contextId() const =0
virtual Status status() const =0
void checkSoftInt(ThreadContext *tc)
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
virtual TheISA::Kernel::Statistics * getKernelStats()=0