Only issue responses if we aren;t already blocked
[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 "cpu/base.hh"
35 #include "cpu/thread_context.hh"
36
37 using namespace SparcISA;
38 using namespace std;
39
40 class Checkpoint;
41
42 //These functions map register indices to names
43 string SparcISA::getMiscRegName(RegIndex index)
44 {
45 static::string miscRegName[NumMiscRegs] =
46 {"y", "ccr", "asi", "tick", "pc", "fprs", "pcr", "pic",
47 "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr",
48 "stick", "stick_cmpr",
49 "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl",
50 "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
51 "wstate", "gl",
52 "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg",
53 "hstick_cmpr",
54 "fsr"};
55 return miscRegName[index];
56 }
57
58 #if FULL_SYSTEM
59
60 //XXX These need an implementation someplace
61 /** Fullsystem only register version of ReadRegWithEffect() */
62 MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc);
63 /** Fullsystem only register version of SetRegWithEffect() */
64 Fault MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val,
65 ThreadContext * tc);
66 #endif
67
68 void MiscRegFile::reset()
69 {
70 pstateFields.pef = 0; //No FPU
71 //pstateFields.pef = 1; //FPU
72 #if FULL_SYSTEM
73 //For SPARC, when a system is first started, there is a power
74 //on reset Trap which sets the processor into the following state.
75 //Bits that aren't set aren't defined on startup.
76 tl = MaxTL;
77 gl = MaxGL;
78
79 tickFields.counter = 0; //The TICK register is unreadable bya
80 tickFields.npt = 1; //The TICK register is unreadable by by !priv
81
82 softint = 0; // Clear all the soft interrupt bits
83 tick_cmprFields.int_dis = 1; // disable timer compare interrupts
84 tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
85 stickFields.npt = 1; //The TICK register is unreadable by by !priv
86 stick_cmprFields.int_dis = 1; // disable timer compare interrupts
87 stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
88
89
90 tt[tl] = power_on_reset;
91 pstate = 0; // fields 0 but pef
92 pstateFields.pef = 1;
93
94 hpstate = 0;
95 hpstateFields.red = 1;
96 hpstateFields.hpriv = 1;
97 hpstateFields.tlz = 0; // this is a guess
98 hintp = 0; // no interrupts pending
99 hstick_cmprFields.int_dis = 1; // disable timer compare interrupts
100 hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing
101 #else
102 /* //This sets up the initial state of the processor for usermode processes
103 pstateFields.priv = 0; //Process runs in user mode
104 pstateFields.ie = 1; //Interrupts are enabled
105 fsrFields.rd = 0; //Round to nearest
106 fsrFields.tem = 0; //Floating point traps not enabled
107 fsrFields.ns = 0; //Non standard mode off
108 fsrFields.qne = 0; //Floating point queue is empty
109 fsrFields.aexc = 0; //No accrued exceptions
110 fsrFields.cexc = 0; //No current exceptions
111
112 //Register window management registers
113 otherwin = 0; //No windows contain info from other programs
114 canrestore = 0; //There are no windows to pop
115 cansave = MaxTL - 2; //All windows are available to save into
116 cleanwin = MaxTL;*/
117 #endif
118 }
119
120 MiscReg MiscRegFile::readReg(int miscReg)
121 {
122 switch (miscReg) {
123 case MISCREG_Y:
124 return y;
125 case MISCREG_CCR:
126 return ccr;
127 case MISCREG_ASI:
128 return asi;
129 case MISCREG_FPRS:
130 return fprs;
131 case MISCREG_TICK:
132 return tick;
133 case MISCREG_PCR:
134 case MISCREG_PIC:
135 panic("ASR number %d not implemented\n", miscReg - AsrStart);
136 case MISCREG_GSR:
137 return gsr;
138 case MISCREG_SOFTINT:
139 return softint;
140 case MISCREG_TICK_CMPR:
141 return tick_cmpr;
142 case MISCREG_STICK:
143 return stick;
144 case MISCREG_STICK_CMPR:
145 return stick_cmpr;
146
147 /** Privilged Registers */
148 case MISCREG_TPC:
149 return tpc[tl-1];
150 case MISCREG_TNPC:
151 return tnpc[tl-1];
152 case MISCREG_TSTATE:
153 return tstate[tl-1];
154 case MISCREG_TT:
155 return tt[tl-1];
156 case MISCREG_PRIVTICK:
157 panic("Priviliged access to tick registers not implemented\n");
158 case MISCREG_TBA:
159 return tba;
160 case MISCREG_PSTATE:
161 return pstate;
162 case MISCREG_TL:
163 return tl;
164 case MISCREG_PIL:
165 return pil;
166 case MISCREG_CWP:
167 return cwp;
168 case MISCREG_CANSAVE:
169 return cansave;
170 case MISCREG_CANRESTORE:
171 return canrestore;
172 case MISCREG_CLEANWIN:
173 return cleanwin;
174 case MISCREG_OTHERWIN:
175 return otherwin;
176 case MISCREG_WSTATE:
177 return wstate;
178 case MISCREG_GL:
179 return gl;
180
181 /** Hyper privileged registers */
182 case MISCREG_HPSTATE:
183 return hpstate;
184 case MISCREG_HTSTATE:
185 return htstate[tl-1];
186 case MISCREG_HINTP:
187 panic("HINTP not implemented\n");
188 case MISCREG_HTBA:
189 return htba;
190 case MISCREG_HVER:
191 return NWindows | MaxTL << 8 | MaxGL << 16;
192 case MISCREG_STRAND_STS_REG:
193 return strandStatusReg;
194 case MISCREG_HSTICK_CMPR:
195 return hstick_cmpr;
196
197 /** Floating Point Status Register */
198 case MISCREG_FSR:
199 return fsr;
200 default:
201 panic("Miscellaneous register %d not implemented\n", miscReg);
202 }
203 }
204
205 MiscReg MiscRegFile::readRegWithEffect(int miscReg,
206 Fault &fault, ThreadContext * tc)
207 {
208 fault = NoFault;
209 switch (miscReg) {
210 case MISCREG_Y:
211 case MISCREG_CCR:
212 case MISCREG_ASI:
213 return readReg(miscReg);
214
215 case MISCREG_TICK:
216 case MISCREG_PRIVTICK:
217 // Check for reading privilege
218 if (tickFields.npt && !isNonPriv()) {
219 fault = new PrivilegedAction;
220 return 0;
221 }
222 return tc->getCpuPtr()->curCycle() - tickFields.counter |
223 tickFields.npt << 63;
224 case MISCREG_PC:
225 return tc->readPC();
226 case MISCREG_FPRS:
227 fault = new UnimpFault("FPU not implemented\n");
228 return 0;
229 case MISCREG_PCR:
230 fault = new UnimpFault("Performance Instrumentation not impl\n");
231 return 0;
232 case MISCREG_PIC:
233 fault = new UnimpFault("Performance Instrumentation not impl\n");
234 return 0;
235 case MISCREG_GSR:
236 return readReg(miscReg);
237
238 /** Privilged Registers */
239 case MISCREG_TPC:
240 case MISCREG_TNPC:
241 case MISCREG_TSTATE:
242 case MISCREG_TT:
243 if (tl == 0) {
244 fault = new IllegalInstruction;
245 return 0;
246 } // NOTE THE FALL THROUGH!
247 case MISCREG_PSTATE:
248 case MISCREG_TL:
249 return readReg(miscReg);
250
251 case MISCREG_TBA:
252 return readReg(miscReg) & ULL(~0x7FFF);
253
254 case MISCREG_PIL:
255
256 case MISCREG_CWP:
257 case MISCREG_CANSAVE:
258 case MISCREG_CANRESTORE:
259 case MISCREG_CLEANWIN:
260 case MISCREG_OTHERWIN:
261 case MISCREG_WSTATE:
262 case MISCREG_GL:
263 return readReg(miscReg);
264
265 /** Floating Point Status Register */
266 case MISCREG_FSR:
267 panic("Floating Point not implemented\n");
268 default:
269 #if FULL_SYSTEM
270 return readFSRegWithEffect(miscReg, fault, tc);
271 #else
272 fault = new IllegalInstruction;
273 return 0;
274 #endif
275 }
276 }
277
278 Fault MiscRegFile::setReg(int miscReg, const MiscReg &val)
279 {
280 switch (miscReg) {
281 case MISCREG_Y:
282 y = val;
283 return NoFault;
284 case MISCREG_CCR:
285 ccr = val;
286 return NoFault;
287 case MISCREG_ASI:
288 asi = val;
289 return NoFault;
290 case MISCREG_FPRS:
291 fprs = val;
292 return NoFault;
293 case MISCREG_TICK:
294 tick = val;
295 return NoFault;
296 case MISCREG_PCR:
297 case MISCREG_PIC:
298 panic("ASR number %d not implemented\n", miscReg - AsrStart);
299 case MISCREG_GSR:
300 gsr = val;
301 case MISCREG_SOFTINT:
302 softint = val;
303 return NoFault;
304 case MISCREG_TICK_CMPR:
305 tick_cmpr = val;
306 return NoFault;
307 case MISCREG_STICK:
308 stick = val;
309 return NoFault;
310 case MISCREG_STICK_CMPR:
311 stick_cmpr = val;
312 return NoFault;
313
314 /** Privilged Registers */
315 case MISCREG_TPC:
316 tpc[tl-1] = val;
317 return NoFault;
318 case MISCREG_TNPC:
319 tnpc[tl-1] = val;
320 return NoFault;
321 case MISCREG_TSTATE:
322 tstate[tl-1] = val;
323 return NoFault;
324 case MISCREG_TT:
325 tt[tl-1] = val;
326 return NoFault;
327 case MISCREG_PRIVTICK:
328 panic("Priviliged access to tick regesiters not implemented\n");
329 case MISCREG_TBA:
330 tba = val;
331 return NoFault;
332 case MISCREG_PSTATE:
333 pstate = val;
334 return NoFault;
335 case MISCREG_TL:
336 tl = val;
337 return NoFault;
338 case MISCREG_PIL:
339 pil = val;
340 return NoFault;
341 case MISCREG_CWP:
342 cwp = val;
343 return NoFault;
344 case MISCREG_CANSAVE:
345 cansave = val;
346 return NoFault;
347 case MISCREG_CANRESTORE:
348 canrestore = val;
349 return NoFault;
350 case MISCREG_CLEANWIN:
351 cleanwin = val;
352 return NoFault;
353 case MISCREG_OTHERWIN:
354 otherwin = val;
355 return NoFault;
356 case MISCREG_WSTATE:
357 wstate = val;
358 return NoFault;
359 case MISCREG_GL:
360 gl = val;
361 return NoFault;
362
363 /** Hyper privileged registers */
364 case MISCREG_HPSTATE:
365 hpstate = val;
366 return NoFault;
367 case MISCREG_HTSTATE:
368 htstate[tl-1] = val;
369 return NoFault;
370 case MISCREG_HINTP:
371 panic("HINTP not implemented\n");
372 case MISCREG_HTBA:
373 htba = val;
374 return NoFault;
375 case MISCREG_STRAND_STS_REG:
376 strandStatusReg = val;
377 return NoFault;
378 case MISCREG_HSTICK_CMPR:
379 hstick_cmpr = val;
380 return NoFault;
381
382 /** Floating Point Status Register */
383 case MISCREG_FSR:
384 fsr = val;
385 return NoFault;
386 default:
387 panic("Miscellaneous register %d not implemented\n", miscReg);
388 }
389 }
390
391 Fault MiscRegFile::setRegWithEffect(int miscReg,
392 const MiscReg &val, ThreadContext * tc)
393 {
394 const uint64_t Bit64 = (1ULL << 63);
395 switch (miscReg) {
396 case MISCREG_Y:
397 case MISCREG_CCR:
398 case MISCREG_ASI:
399 setReg(miscReg, val);
400 return NoFault;
401 case MISCREG_PRIVTICK:
402 case MISCREG_TICK:
403 if (isNonPriv())
404 return new PrivilegedOpcode;
405 if (isPriv())
406 return new PrivilegedAction;
407 tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64;
408 tickFields.npt = val & Bit64 ? 1 : 0;
409 return NoFault;
410 case MISCREG_PC:
411 return new IllegalInstruction;
412 case MISCREG_FPRS:
413 return new UnimpFault("FPU not implemented\n");
414 case MISCREG_PCR:
415 return new UnimpFault("Performance Instrumentation not impl\n");
416 case MISCREG_PIC:
417 return new UnimpFault("Performance Instrumentation not impl\n");
418 case MISCREG_GSR:
419 return setReg(miscReg, val);
420
421 /** Privilged Registers */
422 case MISCREG_TPC:
423 case MISCREG_TNPC:
424 case MISCREG_TSTATE:
425 case MISCREG_TT:
426 if (tl == 0)
427 return new IllegalInstruction;
428 setReg(miscReg, val);
429 return NoFault;
430
431 case MISCREG_TBA:
432 // clear lower 7 bits on writes.
433 setReg(miscReg, val & ULL(~0x7FFF));
434 return NoFault;
435
436 case MISCREG_PSTATE:
437 setReg(miscReg, val);
438 return NoFault;
439
440 case MISCREG_TL:
441 if (isHyperPriv() && val > MaxTL)
442 setReg(miscReg, MaxTL);
443 else if (isPriv() && !isHyperPriv() && val > MaxPTL)
444 setReg(miscReg, MaxPTL);
445 else
446 setReg(miscReg, val);
447 return NoFault;
448
449 case MISCREG_CWP:
450 tc->changeRegFileContext(CONTEXT_CWP, val);
451 case MISCREG_CANSAVE:
452 case MISCREG_CANRESTORE:
453 case MISCREG_CLEANWIN:
454 case MISCREG_OTHERWIN:
455 case MISCREG_WSTATE:
456 setReg(miscReg, val);
457 return NoFault;
458
459 case MISCREG_GL:
460 int newval;
461 if (isHyperPriv() && val > MaxGL)
462 newval = MaxGL;
463 else if (isPriv() && !isHyperPriv() && val > MaxPGL)
464 newval = MaxPGL;
465 else
466 newval = val;
467 tc->changeRegFileContext(CONTEXT_GLOBALS, newval);
468 setReg(miscReg, newval);
469 return NoFault;
470
471 /** Floating Point Status Register */
472 case MISCREG_FSR:
473 panic("Floating Point not implemented\n");
474 default:
475 #if FULL_SYSTEM
476 setFSRegWithEffect(miscReg, val, tc);
477 #else
478 return new IllegalInstruction;
479 #endif
480 }
481 }
482
483 void MiscRegFile::serialize(std::ostream & os)
484 {
485 SERIALIZE_SCALAR(pstate);
486 SERIALIZE_SCALAR(tba);
487 SERIALIZE_SCALAR(y);
488 SERIALIZE_SCALAR(pil);
489 SERIALIZE_SCALAR(gl);
490 SERIALIZE_SCALAR(cwp);
491 SERIALIZE_ARRAY(tt, MaxTL);
492 SERIALIZE_SCALAR(ccr);
493 SERIALIZE_SCALAR(asi);
494 SERIALIZE_SCALAR(tl);
495 SERIALIZE_ARRAY(tpc, MaxTL);
496 SERIALIZE_ARRAY(tnpc, MaxTL);
497 SERIALIZE_ARRAY(tstate, MaxTL);
498 SERIALIZE_SCALAR(tick);
499 SERIALIZE_SCALAR(cansave);
500 SERIALIZE_SCALAR(canrestore);
501 SERIALIZE_SCALAR(otherwin);
502 SERIALIZE_SCALAR(cleanwin);
503 SERIALIZE_SCALAR(wstate);
504 SERIALIZE_SCALAR(fsr);
505 SERIALIZE_SCALAR(fprs);
506 SERIALIZE_SCALAR(hpstate);
507 SERIALIZE_ARRAY(htstate, MaxTL);
508 SERIALIZE_SCALAR(htba);
509 SERIALIZE_SCALAR(hstick_cmpr);
510 }
511
512 void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
513 {
514 UNSERIALIZE_SCALAR(pstate);
515 UNSERIALIZE_SCALAR(tba);
516 UNSERIALIZE_SCALAR(y);
517 UNSERIALIZE_SCALAR(pil);
518 UNSERIALIZE_SCALAR(gl);
519 UNSERIALIZE_SCALAR(cwp);
520 UNSERIALIZE_ARRAY(tt, MaxTL);
521 UNSERIALIZE_SCALAR(ccr);
522 UNSERIALIZE_SCALAR(asi);
523 UNSERIALIZE_SCALAR(tl);
524 UNSERIALIZE_ARRAY(tpc, MaxTL);
525 UNSERIALIZE_ARRAY(tnpc, MaxTL);
526 UNSERIALIZE_ARRAY(tstate, MaxTL);
527 UNSERIALIZE_SCALAR(tick);
528 UNSERIALIZE_SCALAR(cansave);
529 UNSERIALIZE_SCALAR(canrestore);
530 UNSERIALIZE_SCALAR(otherwin);
531 UNSERIALIZE_SCALAR(cleanwin);
532 UNSERIALIZE_SCALAR(wstate);
533 UNSERIALIZE_SCALAR(fsr);
534 UNSERIALIZE_SCALAR(fprs);
535 UNSERIALIZE_SCALAR(hpstate);
536 UNSERIALIZE_ARRAY(htstate, MaxTL);
537 UNSERIALIZE_SCALAR(htba);
538 UNSERIALIZE_SCALAR(hstick_cmpr);
539 }
540