Make things compile in SE again.
[gem5.git] / src / arch / sparc / miscregfile.cc
1 /*
2 * Copyright (c) 2003-2005 The Regents of The University of Michigan
3 * All rights reserved.
4 *
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.
15 *
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.
27 *
28 * Authors: Gabe Black
29 * Ali Saidi
30 */
31
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"
37
38 #if FULL_SYSTEM
39 #include "arch/sparc/system.hh"
40 #endif
41
42 using namespace SparcISA;
43 using namespace std;
44
45 class Checkpoint;
46
47 //These functions map register indices to names
48 string SparcISA::getMiscRegName(RegIndex index)
49 {
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",
56 "wstate", "gl",
57 "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
58 "hstick_cmpr",
59 "fsr"};
60 return miscRegName[index];
61 }
62
63 void MiscRegFile::reset()
64 {
65 }
66
67 MiscReg MiscRegFile::readReg(int miscReg)
68 {
69 switch (miscReg) {
70 case MISCREG_Y:
71 return y;
72 case MISCREG_CCR:
73 return ccr;
74 case MISCREG_ASI:
75 return asi;
76 case MISCREG_FPRS:
77 return fprs;
78 case MISCREG_TICK:
79 return tick;
80 case MISCREG_PCR:
81 case MISCREG_PIC:
82 panic("ASR number %d not implemented\n", miscReg - AsrStart);
83 case MISCREG_GSR:
84 return gsr;
85 case MISCREG_SOFTINT:
86 return softint;
87 case MISCREG_TICK_CMPR:
88 return tick_cmpr;
89 case MISCREG_STICK:
90 return stick;
91 case MISCREG_STICK_CMPR:
92 return stick_cmpr;
93
94 /** Privilged Registers */
95 case MISCREG_TPC:
96 return tpc[tl-1];
97 case MISCREG_TNPC:
98 return tnpc[tl-1];
99 case MISCREG_TSTATE:
100 return tstate[tl-1];
101 case MISCREG_TT:
102 return tt[tl-1];
103 case MISCREG_PRIVTICK:
104 panic("Priviliged access to tick registers not implemented\n");
105 case MISCREG_TBA:
106 return tba;
107 case MISCREG_PSTATE:
108 return pstate;
109 case MISCREG_TL:
110 return tl;
111 case MISCREG_PIL:
112 return pil;
113 case MISCREG_CWP:
114 return cwp;
115 case MISCREG_CANSAVE:
116 return cansave;
117 case MISCREG_CANRESTORE:
118 return canrestore;
119 case MISCREG_CLEANWIN:
120 return cleanwin;
121 case MISCREG_OTHERWIN:
122 return otherwin;
123 case MISCREG_WSTATE:
124 return wstate;
125 case MISCREG_GL:
126 return gl;
127
128 /** Hyper privileged registers */
129 case MISCREG_HPSTATE:
130 return hpstate;
131 case MISCREG_HTSTATE:
132 return htstate[tl-1];
133 case MISCREG_HINTP:
134 panic("HINTP not implemented\n");
135 case MISCREG_HTBA:
136 return htba;
137 case MISCREG_HVER:
138 return NWindows | MaxTL << 8 | MaxGL << 16;
139 case MISCREG_STRAND_STS_REG:
140 return strandStatusReg;
141 case MISCREG_HSTICK_CMPR:
142 return hstick_cmpr;
143
144 /** Floating Point Status Register */
145 case MISCREG_FSR:
146 return fsr;
147 default:
148 panic("Miscellaneous register %d not implemented\n", miscReg);
149 }
150 }
151
152 MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc)
153 {
154 switch (miscReg) {
155 case MISCREG_TICK:
156 case MISCREG_PRIVTICK:
157 return tc->getCpuPtr()->curCycle() - tickFields.counter |
158 tickFields.npt << 63;
159 case MISCREG_FPRS:
160 panic("FPU not implemented\n");
161 case MISCREG_PCR:
162 case MISCREG_PIC:
163 panic("Performance Instrumentation not impl\n");
164 /** Floating Point Status Register */
165 case MISCREG_FSR:
166 panic("Floating Point not implemented\n");
167 //We'll include this only in FS so we don't need the SparcSystem type around
168 //in SE.
169 #if FULL_SYSTEM
170 case MISCREG_STICK:
171 SparcSystem *sys;
172 sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
173 assert(sys != NULL);
174 return curTick/Clock::Int::ns - sys->sysTick | stickFields.npt << 63;
175 #endif
176 case MISCREG_HVER:
177 return NWindows | MaxTL << 8 | MaxGL << 16;
178 }
179 return readReg(miscReg);
180 }
181
182 void MiscRegFile::setReg(int miscReg, const MiscReg &val)
183 {
184 switch (miscReg) {
185 case MISCREG_Y:
186 y = val;
187 break;
188 case MISCREG_CCR:
189 ccr = val;
190 break;
191 case MISCREG_ASI:
192 asi = val;
193 break;
194 case MISCREG_FPRS:
195 fprs = val;
196 break;
197 case MISCREG_TICK:
198 tick = val;
199 break;
200 case MISCREG_PCR:
201 case MISCREG_PIC:
202 panic("ASR number %d not implemented\n", miscReg - AsrStart);
203 case MISCREG_GSR:
204 gsr = val;
205 break;
206 case MISCREG_SOFTINT:
207 softint = val;
208 break;
209 case MISCREG_TICK_CMPR:
210 tick_cmpr = val;
211 break;
212 case MISCREG_STICK:
213 stick = val;
214 break;
215 case MISCREG_STICK_CMPR:
216 stick_cmpr = val;
217 break;
218
219 /** Privilged Registers */
220 case MISCREG_TPC:
221 tpc[tl-1] = val;
222 break;
223 case MISCREG_TNPC:
224 tnpc[tl-1] = val;
225 break;
226 case MISCREG_TSTATE:
227 tstate[tl-1] = val;
228 break;
229 case MISCREG_TT:
230 tt[tl-1] = val;
231 break;
232 case MISCREG_PRIVTICK:
233 panic("Priviliged access to tick regesiters not implemented\n");
234 case MISCREG_TBA:
235 // clear lower 7 bits on writes.
236 tba = val & ULL(~0x7FFF);
237 break;
238 case MISCREG_PSTATE:
239 pstate = val;
240 break;
241 case MISCREG_TL:
242 tl = val;
243 break;
244 case MISCREG_PIL:
245 pil = val;
246 break;
247 case MISCREG_CWP:
248 cwp = val;
249 break;
250 case MISCREG_CANSAVE:
251 cansave = val;
252 break;
253 case MISCREG_CANRESTORE:
254 canrestore = val;
255 break;
256 case MISCREG_CLEANWIN:
257 cleanwin = val;
258 break;
259 case MISCREG_OTHERWIN:
260 otherwin = val;
261 break;
262 case MISCREG_WSTATE:
263 wstate = val;
264 break;
265 case MISCREG_GL:
266 gl = val;
267 break;
268
269 /** Hyper privileged registers */
270 case MISCREG_HPSTATE:
271 hpstate = val;
272 break;
273 case MISCREG_HTSTATE:
274 htstate[tl-1] = val;
275 break;
276 case MISCREG_HINTP:
277 panic("HINTP not implemented\n");
278 case MISCREG_HTBA:
279 htba = val;
280 break;
281 case MISCREG_STRAND_STS_REG:
282 strandStatusReg = val;
283 break;
284 case MISCREG_HSTICK_CMPR:
285 hstick_cmpr = val;
286 break;
287
288 /** Floating Point Status Register */
289 case MISCREG_FSR:
290 fsr = val;
291 break;
292 default:
293 panic("Miscellaneous register %d not implemented\n", miscReg);
294 }
295 }
296
297 inline void MiscRegFile::setImplicitAsis()
298 {
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
302 //bits
303 if(tl == 0)
304 {
305 implicitInstAsi = implicitDataAsi =
306 pstateFields.cle ? ASI_PRIMARY_LITTLE : ASI_PRIMARY;
307 }
308 else if(tl <= MaxPTL)
309 {
310 implicitInstAsi = ASI_NUCLEUS;
311 implicitDataAsi = pstateFields.cle ? ASI_NUCLEUS_LITTLE : ASI_NUCLEUS;
312 }
313 else
314 {
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;
318 }
319 }
320
321 void MiscRegFile::setRegWithEffect(int miscReg,
322 const MiscReg &val, ThreadContext * tc)
323 {
324 const uint64_t Bit64 = (1ULL << 63);
325 #if FULL_SYSTEM
326 uint64_t time;
327 SparcSystem *sys;
328 #endif
329 switch (miscReg) {
330 case MISCREG_TICK:
331 tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64;
332 tickFields.npt = val & Bit64 ? 1 : 0;
333 break;
334 case MISCREG_FPRS:
335 //Configure the fpu based on the fprs
336 break;
337 case MISCREG_PCR:
338 //Set up performance counting based on pcr value
339 break;
340 case MISCREG_PSTATE:
341 pstate = val;
342 setImplicitAsis();
343 return;
344 case MISCREG_TL:
345 tl = val;
346 setImplicitAsis();
347 return;
348 case MISCREG_CWP:
349 tc->changeRegFileContext(CONTEXT_CWP, val);
350 break;
351 case MISCREG_GL:
352 tc->changeRegFileContext(CONTEXT_GLOBALS, val);
353 break;
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
359 //want.
360 break;
361 case MISCREG_SOFTINT_CLR:
362 //Do whatever this is supposed to do...
363 break;
364 case MISCREG_SOFTINT_SET:
365 //Do whatever this is supposed to do...
366 break;
367 #if FULL_SYSTEM
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));
377 break;
378 #endif
379 case MISCREG_PIL:
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
384 //want.
385 break;
386 //We'll include this only in FS so we don't need the SparcSystem type around
387 //in SE.
388 #if FULL_SYSTEM
389 case MISCREG_STICK:
390 sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
391 assert(sys != NULL);
392 sys->sysTick = curTick/Clock::Int::ns - val & ~Bit64;
393 stickFields.npt = val & Bit64 ? 1 : 0;
394 break;
395 case MISCREG_STICK_CMPR:
396 if (sTickCompare == NULL)
397 sTickCompare = new STickCompareEvent(this, tc);
398 sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
399 assert(sys != NULL);
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);
405 break;
406 case MISCREG_HSTICK_CMPR:
407 if (hSTickCompare == NULL)
408 hSTickCompare = new HSTickCompareEvent(this, tc);
409 sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr());
410 assert(sys != NULL);
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);
416 break;
417 #endif
418 }
419 setReg(miscReg, val);
420 }
421
422 void MiscRegFile::serialize(std::ostream & os)
423 {
424 SERIALIZE_SCALAR(pstate);
425 SERIALIZE_SCALAR(tba);
426 SERIALIZE_SCALAR(y);
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);
451 }
452
453 void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
454 {
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);
480 int temp;
481 UNSERIALIZE_SCALAR(temp);
482 implicitInstAsi = (ASI)temp;
483 UNSERIALIZE_SCALAR(temp);
484 implicitDataAsi = (ASI)temp;
485 }
486
487 #if FULL_SYSTEM
488 void
489 MiscRegFile::processTickCompare(ThreadContext *tc)
490 {
491 panic("tick compare not implemented\n");
492 }
493
494 void
495 MiscRegFile::processSTickCompare(ThreadContext *tc)
496 {
497 panic("tick compare not implemented\n");
498 }
499
500 void
501 MiscRegFile::processHSTickCompare(ThreadContext *tc)
502 {
503 panic("tick compare not implemented\n");
504 }
505 #endif