isa.cc (7741:340b6f01d69b) isa.cc (8232:b28d06a175be)
1/*
2 * Copyright (c) 2009 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 */
30
31#include "arch/sparc/asi.hh"
32#include "arch/sparc/isa.hh"
33#include "base/bitfield.hh"
34#include "base/trace.hh"
35#include "config/full_system.hh"
36#include "cpu/base.hh"
37#include "cpu/thread_context.hh"
1/*
2 * Copyright (c) 2009 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 */
30
31#include "arch/sparc/asi.hh"
32#include "arch/sparc/isa.hh"
33#include "base/bitfield.hh"
34#include "base/trace.hh"
35#include "config/full_system.hh"
36#include "cpu/base.hh"
37#include "cpu/thread_context.hh"
38#include "debug/MiscRegs.hh"
39#include "debug/Timer.hh"
38
39namespace SparcISA
40{
41
42enum RegMask
43{
44 PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
45};
46
47void
48ISA::reloadRegMap()
49{
50 installGlobals(gl, CurrentGlobalsOffset);
51 installWindow(cwp, CurrentWindowOffset);
52 // Microcode registers.
53 for (int i = 0; i < NumMicroIntRegs; i++)
54 intRegMap[MicroIntOffset + i] = i + TotalGlobals + NWindows * 16;
55 installGlobals(gl, NextGlobalsOffset);
56 installWindow(cwp - 1, NextWindowOffset);
57 installGlobals(gl, PreviousGlobalsOffset);
58 installWindow(cwp + 1, PreviousWindowOffset);
59}
60
61void
62ISA::installWindow(int cwp, int offset)
63{
64 assert(offset >= 0 && offset + NumWindowedRegs <= NumIntRegs);
65 RegIndex *mapChunk = intRegMap + offset;
66 for (int i = 0; i < NumWindowedRegs; i++)
67 mapChunk[i] = TotalGlobals +
68 ((i - cwp * RegsPerWindow + TotalWindowed) % (TotalWindowed));
69}
70
71void
72ISA::installGlobals(int gl, int offset)
73{
74 assert(offset >= 0 && offset + NumGlobalRegs <= NumIntRegs);
75 RegIndex *mapChunk = intRegMap + offset;
76 mapChunk[0] = 0;
77 for (int i = 1; i < NumGlobalRegs; i++)
78 mapChunk[i] = i + gl * NumGlobalRegs;
79}
80
81void
82ISA::clear()
83{
84 cwp = 0;
85 gl = 0;
86 reloadRegMap();
87
88 // y = 0;
89 // ccr = 0;
90 asi = 0;
91 tick = ULL(1) << 63;
92 fprs = 0;
93 gsr = 0;
94 softint = 0;
95 tick_cmpr = 0;
96 stick = 0;
97 stick_cmpr = 0;
98 memset(tpc, 0, sizeof(tpc));
99 memset(tnpc, 0, sizeof(tnpc));
100 memset(tstate, 0, sizeof(tstate));
101 memset(tt, 0, sizeof(tt));
102 tba = 0;
103 pstate = 0;
104 tl = 0;
105 pil = 0;
106 // cansave = 0;
107 // canrestore = 0;
108 // cleanwin = 0;
109 // otherwin = 0;
110 // wstate = 0;
111 // In a T1, bit 11 is apparently always 1
112 hpstate = (1 << 11);
113 memset(htstate, 0, sizeof(htstate));
114 hintp = 0;
115 htba = 0;
116 hstick_cmpr = 0;
117 // This is set this way in Legion for some reason
118 strandStatusReg = 0x50000;
119 fsr = 0;
120
121 priContext = 0;
122 secContext = 0;
123 partId = 0;
124 lsuCtrlReg = 0;
125
126 memset(scratchPad, 0, sizeof(scratchPad));
127
128 cpu_mondo_head = 0;
129 cpu_mondo_tail = 0;
130 dev_mondo_head = 0;
131 dev_mondo_tail = 0;
132 res_error_head = 0;
133 res_error_tail = 0;
134 nres_error_head = 0;
135 nres_error_tail = 0;
136
137#if FULL_SYSTEM
138 // If one of these events is active, it's not obvious to me how to get
139 // rid of it cleanly. For now we'll just assert that they're not.
140 if (tickCompare != NULL && sTickCompare != NULL && hSTickCompare != NULL)
141 panic("Tick comparison event active when clearing the ISA object.\n");
142#endif
143}
144
145MiscReg
146ISA::readMiscRegNoEffect(int miscReg)
147{
148
149 // The three miscRegs are moved up from the switch statement
150 // due to more frequent calls.
151
152 if (miscReg == MISCREG_GL)
153 return gl;
154 if (miscReg == MISCREG_CWP)
155 return cwp;
156 if (miscReg == MISCREG_TLB_DATA) {
157 /* Package up all the data for the tlb:
158 * 6666555555555544444444443333333333222222222211111111110000000000
159 * 3210987654321098765432109876543210987654321098765432109876543210
160 * secContext | priContext | |tl|partid| |||||^hpriv
161 * ||||^red
162 * |||^priv
163 * ||^am
164 * |^lsuim
165 * ^lsudm
166 */
167 return bits((uint64_t)hpstate,2,2) |
168 bits((uint64_t)hpstate,5,5) << 1 |
169 bits((uint64_t)pstate,3,2) << 2 |
170 bits((uint64_t)lsuCtrlReg,3,2) << 4 |
171 bits((uint64_t)partId,7,0) << 8 |
172 bits((uint64_t)tl,2,0) << 16 |
173 (uint64_t)priContext << 32 |
174 (uint64_t)secContext << 48;
175 }
176
177 switch (miscReg) {
178 // case MISCREG_TLB_DATA:
179 // [original contents see above]
180 // case MISCREG_Y:
181 // return y;
182 // case MISCREG_CCR:
183 // return ccr;
184 case MISCREG_ASI:
185 return asi;
186 case MISCREG_FPRS:
187 return fprs;
188 case MISCREG_TICK:
189 return tick;
190 case MISCREG_PCR:
191 panic("PCR not implemented\n");
192 case MISCREG_PIC:
193 panic("PIC not implemented\n");
194 case MISCREG_GSR:
195 return gsr;
196 case MISCREG_SOFTINT:
197 return softint;
198 case MISCREG_TICK_CMPR:
199 return tick_cmpr;
200 case MISCREG_STICK:
201 return stick;
202 case MISCREG_STICK_CMPR:
203 return stick_cmpr;
204
205 /** Privilged Registers */
206 case MISCREG_TPC:
207 return tpc[tl-1];
208 case MISCREG_TNPC:
209 return tnpc[tl-1];
210 case MISCREG_TSTATE:
211 return tstate[tl-1];
212 case MISCREG_TT:
213 return tt[tl-1];
214 case MISCREG_PRIVTICK:
215 panic("Priviliged access to tick registers not implemented\n");
216 case MISCREG_TBA:
217 return tba;
218 case MISCREG_PSTATE:
219 return pstate;
220 case MISCREG_TL:
221 return tl;
222 case MISCREG_PIL:
223 return pil;
224 // CWP, GL moved
225 // case MISCREG_CWP:
226 // return cwp;
227 // case MISCREG_CANSAVE:
228 // return cansave;
229 // case MISCREG_CANRESTORE:
230 // return canrestore;
231 // case MISCREG_CLEANWIN:
232 // return cleanwin;
233 // case MISCREG_OTHERWIN:
234 // return otherwin;
235 // case MISCREG_WSTATE:
236 // return wstate;
237 // case MISCREG_GL:
238 // return gl;
239
240 /** Hyper privileged registers */
241 case MISCREG_HPSTATE:
242 return hpstate;
243 case MISCREG_HTSTATE:
244 return htstate[tl-1];
245 case MISCREG_HINTP:
246 return hintp;
247 case MISCREG_HTBA:
248 return htba;
249 case MISCREG_STRAND_STS_REG:
250 return strandStatusReg;
251 case MISCREG_HSTICK_CMPR:
252 return hstick_cmpr;
253
254 /** Floating Point Status Register */
255 case MISCREG_FSR:
256 DPRINTF(MiscRegs, "FSR read as: %#x\n", fsr);
257 return fsr;
258
259 case MISCREG_MMU_P_CONTEXT:
260 return priContext;
261 case MISCREG_MMU_S_CONTEXT:
262 return secContext;
263 case MISCREG_MMU_PART_ID:
264 return partId;
265 case MISCREG_MMU_LSU_CTRL:
266 return lsuCtrlReg;
267
268 case MISCREG_SCRATCHPAD_R0:
269 return scratchPad[0];
270 case MISCREG_SCRATCHPAD_R1:
271 return scratchPad[1];
272 case MISCREG_SCRATCHPAD_R2:
273 return scratchPad[2];
274 case MISCREG_SCRATCHPAD_R3:
275 return scratchPad[3];
276 case MISCREG_SCRATCHPAD_R4:
277 return scratchPad[4];
278 case MISCREG_SCRATCHPAD_R5:
279 return scratchPad[5];
280 case MISCREG_SCRATCHPAD_R6:
281 return scratchPad[6];
282 case MISCREG_SCRATCHPAD_R7:
283 return scratchPad[7];
284 case MISCREG_QUEUE_CPU_MONDO_HEAD:
285 return cpu_mondo_head;
286 case MISCREG_QUEUE_CPU_MONDO_TAIL:
287 return cpu_mondo_tail;
288 case MISCREG_QUEUE_DEV_MONDO_HEAD:
289 return dev_mondo_head;
290 case MISCREG_QUEUE_DEV_MONDO_TAIL:
291 return dev_mondo_tail;
292 case MISCREG_QUEUE_RES_ERROR_HEAD:
293 return res_error_head;
294 case MISCREG_QUEUE_RES_ERROR_TAIL:
295 return res_error_tail;
296 case MISCREG_QUEUE_NRES_ERROR_HEAD:
297 return nres_error_head;
298 case MISCREG_QUEUE_NRES_ERROR_TAIL:
299 return nres_error_tail;
300 default:
301 panic("Miscellaneous register %d not implemented\n", miscReg);
302 }
303}
304
305MiscReg
306ISA::readMiscReg(int miscReg, ThreadContext * tc)
307{
308 switch (miscReg) {
309 // tick and stick are aliased to each other in niagra
310 // well store the tick data in stick and the interrupt bit in tick
311 case MISCREG_STICK:
312 case MISCREG_TICK:
313 case MISCREG_PRIVTICK:
314 // I'm not sure why legion ignores the lowest two bits, but we'll go
315 // with it
316 // change from curCycle() to instCount() until we're done with legion
317 DPRINTF(Timer, "Instruction Count when TICK read: %#X stick=%#X\n",
318 tc->getCpuPtr()->instCount(), stick);
319 return mbits(tc->getCpuPtr()->instCount() + (int64_t)stick,62,2) |
320 mbits(tick,63,63);
321 case MISCREG_FPRS:
322 // in legion if fp is enabled du and dl are set
323 return fprs | 0x3;
324 case MISCREG_PCR:
325 case MISCREG_PIC:
326 panic("Performance Instrumentation not impl\n");
327 case MISCREG_SOFTINT_CLR:
328 case MISCREG_SOFTINT_SET:
329 panic("Can read from softint clr/set\n");
330 case MISCREG_SOFTINT:
331 case MISCREG_TICK_CMPR:
332 case MISCREG_STICK_CMPR:
333 case MISCREG_HINTP:
334 case MISCREG_HTSTATE:
335 case MISCREG_HTBA:
336 case MISCREG_HVER:
337 case MISCREG_STRAND_STS_REG:
338 case MISCREG_HSTICK_CMPR:
339 case MISCREG_QUEUE_CPU_MONDO_HEAD:
340 case MISCREG_QUEUE_CPU_MONDO_TAIL:
341 case MISCREG_QUEUE_DEV_MONDO_HEAD:
342 case MISCREG_QUEUE_DEV_MONDO_TAIL:
343 case MISCREG_QUEUE_RES_ERROR_HEAD:
344 case MISCREG_QUEUE_RES_ERROR_TAIL:
345 case MISCREG_QUEUE_NRES_ERROR_HEAD:
346 case MISCREG_QUEUE_NRES_ERROR_TAIL:
347#if FULL_SYSTEM
348 case MISCREG_HPSTATE:
349 return readFSReg(miscReg, tc);
350#else
351 case MISCREG_HPSTATE:
352 // HPSTATE is special because because sometimes in privilege
353 // checks for instructions it will read HPSTATE to make sure
354 // the priv. level is ok So, we'll just have to tell it it
355 // isn't, instead of panicing.
356 return 0;
357
358 panic("Accessing Fullsystem register %d in SE mode\n", miscReg);
359#endif
360
361 }
362 return readMiscRegNoEffect(miscReg);
363}
364
365void
366ISA::setMiscRegNoEffect(int miscReg, MiscReg val)
367{
368 switch (miscReg) {
369// case MISCREG_Y:
370// y = val;
371// break;
372// case MISCREG_CCR:
373// ccr = val;
374// break;
375 case MISCREG_ASI:
376 asi = val;
377 break;
378 case MISCREG_FPRS:
379 fprs = val;
380 break;
381 case MISCREG_TICK:
382 tick = val;
383 break;
384 case MISCREG_PCR:
385 panic("PCR not implemented\n");
386 case MISCREG_PIC:
387 panic("PIC not implemented\n");
388 case MISCREG_GSR:
389 gsr = val;
390 break;
391 case MISCREG_SOFTINT:
392 softint = val;
393 break;
394 case MISCREG_TICK_CMPR:
395 tick_cmpr = val;
396 break;
397 case MISCREG_STICK:
398 stick = val;
399 break;
400 case MISCREG_STICK_CMPR:
401 stick_cmpr = val;
402 break;
403
404 /** Privilged Registers */
405 case MISCREG_TPC:
406 tpc[tl-1] = val;
407 break;
408 case MISCREG_TNPC:
409 tnpc[tl-1] = val;
410 break;
411 case MISCREG_TSTATE:
412 tstate[tl-1] = val;
413 break;
414 case MISCREG_TT:
415 tt[tl-1] = val;
416 break;
417 case MISCREG_PRIVTICK:
418 panic("Priviliged access to tick regesiters not implemented\n");
419 case MISCREG_TBA:
420 // clear lower 7 bits on writes.
421 tba = val & ULL(~0x7FFF);
422 break;
423 case MISCREG_PSTATE:
424 pstate = (val & PSTATE_MASK);
425 break;
426 case MISCREG_TL:
427 tl = val;
428 break;
429 case MISCREG_PIL:
430 pil = val;
431 break;
432 case MISCREG_CWP:
433 cwp = val;
434 break;
435// case MISCREG_CANSAVE:
436// cansave = val;
437// break;
438// case MISCREG_CANRESTORE:
439// canrestore = val;
440// break;
441// case MISCREG_CLEANWIN:
442// cleanwin = val;
443// break;
444// case MISCREG_OTHERWIN:
445// otherwin = val;
446// break;
447// case MISCREG_WSTATE:
448// wstate = val;
449// break;
450 case MISCREG_GL:
451 gl = val;
452 break;
453
454 /** Hyper privileged registers */
455 case MISCREG_HPSTATE:
456 hpstate = val;
457 break;
458 case MISCREG_HTSTATE:
459 htstate[tl-1] = val;
460 break;
461 case MISCREG_HINTP:
462 hintp = val;
463 case MISCREG_HTBA:
464 htba = val;
465 break;
466 case MISCREG_STRAND_STS_REG:
467 strandStatusReg = val;
468 break;
469 case MISCREG_HSTICK_CMPR:
470 hstick_cmpr = val;
471 break;
472
473 /** Floating Point Status Register */
474 case MISCREG_FSR:
475 fsr = val;
476 DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr);
477 break;
478
479 case MISCREG_MMU_P_CONTEXT:
480 priContext = val;
481 break;
482 case MISCREG_MMU_S_CONTEXT:
483 secContext = val;
484 break;
485 case MISCREG_MMU_PART_ID:
486 partId = val;
487 break;
488 case MISCREG_MMU_LSU_CTRL:
489 lsuCtrlReg = val;
490 break;
491
492 case MISCREG_SCRATCHPAD_R0:
493 scratchPad[0] = val;
494 break;
495 case MISCREG_SCRATCHPAD_R1:
496 scratchPad[1] = val;
497 break;
498 case MISCREG_SCRATCHPAD_R2:
499 scratchPad[2] = val;
500 break;
501 case MISCREG_SCRATCHPAD_R3:
502 scratchPad[3] = val;
503 break;
504 case MISCREG_SCRATCHPAD_R4:
505 scratchPad[4] = val;
506 break;
507 case MISCREG_SCRATCHPAD_R5:
508 scratchPad[5] = val;
509 break;
510 case MISCREG_SCRATCHPAD_R6:
511 scratchPad[6] = val;
512 break;
513 case MISCREG_SCRATCHPAD_R7:
514 scratchPad[7] = val;
515 break;
516 case MISCREG_QUEUE_CPU_MONDO_HEAD:
517 cpu_mondo_head = val;
518 break;
519 case MISCREG_QUEUE_CPU_MONDO_TAIL:
520 cpu_mondo_tail = val;
521 break;
522 case MISCREG_QUEUE_DEV_MONDO_HEAD:
523 dev_mondo_head = val;
524 break;
525 case MISCREG_QUEUE_DEV_MONDO_TAIL:
526 dev_mondo_tail = val;
527 break;
528 case MISCREG_QUEUE_RES_ERROR_HEAD:
529 res_error_head = val;
530 break;
531 case MISCREG_QUEUE_RES_ERROR_TAIL:
532 res_error_tail = val;
533 break;
534 case MISCREG_QUEUE_NRES_ERROR_HEAD:
535 nres_error_head = val;
536 break;
537 case MISCREG_QUEUE_NRES_ERROR_TAIL:
538 nres_error_tail = val;
539 break;
540 default:
541 panic("Miscellaneous register %d not implemented\n", miscReg);
542 }
543}
544
545void
546ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc)
547{
548 MiscReg new_val = val;
549
550 switch (miscReg) {
551 case MISCREG_STICK:
552 case MISCREG_TICK:
553 // stick and tick are same thing on niagra
554 // use stick for offset and tick for holding intrrupt bit
555 stick = mbits(val,62,0) - tc->getCpuPtr()->instCount();
556 tick = mbits(val,63,63);
557 DPRINTF(Timer, "Writing TICK=%#X\n", val);
558 break;
559 case MISCREG_FPRS:
560 // Configure the fpu based on the fprs
561 break;
562 case MISCREG_PCR:
563 // Set up performance counting based on pcr value
564 break;
565 case MISCREG_PSTATE:
566 pstate = val & PSTATE_MASK;
567 return;
568 case MISCREG_TL:
569 tl = val;
570#if FULL_SYSTEM
571 if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
572 tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
573 else
574 tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
575#endif
576 return;
577 case MISCREG_CWP:
578 new_val = val >= NWindows ? NWindows - 1 : val;
579 if (val >= NWindows)
580 new_val = NWindows - 1;
581
582 installWindow(new_val, CurrentWindowOffset);
583 installWindow(new_val - 1, NextWindowOffset);
584 installWindow(new_val + 1, PreviousWindowOffset);
585 break;
586 case MISCREG_GL:
587 installGlobals(val, CurrentGlobalsOffset);
588 installGlobals(val, NextGlobalsOffset);
589 installGlobals(val, PreviousGlobalsOffset);
590 break;
591 case MISCREG_PIL:
592 case MISCREG_SOFTINT:
593 case MISCREG_SOFTINT_SET:
594 case MISCREG_SOFTINT_CLR:
595 case MISCREG_TICK_CMPR:
596 case MISCREG_STICK_CMPR:
597 case MISCREG_HINTP:
598 case MISCREG_HTSTATE:
599 case MISCREG_HTBA:
600 case MISCREG_HVER:
601 case MISCREG_STRAND_STS_REG:
602 case MISCREG_HSTICK_CMPR:
603 case MISCREG_QUEUE_CPU_MONDO_HEAD:
604 case MISCREG_QUEUE_CPU_MONDO_TAIL:
605 case MISCREG_QUEUE_DEV_MONDO_HEAD:
606 case MISCREG_QUEUE_DEV_MONDO_TAIL:
607 case MISCREG_QUEUE_RES_ERROR_HEAD:
608 case MISCREG_QUEUE_RES_ERROR_TAIL:
609 case MISCREG_QUEUE_NRES_ERROR_HEAD:
610 case MISCREG_QUEUE_NRES_ERROR_TAIL:
611#if FULL_SYSTEM
612 case MISCREG_HPSTATE:
613 setFSReg(miscReg, val, tc);
614 return;
615#else
616 case MISCREG_HPSTATE:
617 // HPSTATE is special because normal trap processing saves HPSTATE when
618 // it goes into a trap, and restores it when it returns.
619 return;
620 panic("Accessing Fullsystem register %d to %#x in SE mode\n",
621 miscReg, val);
622#endif
623 }
624 setMiscRegNoEffect(miscReg, new_val);
625}
626
627void
628ISA::serialize(EventManager *em, std::ostream &os)
629{
630 SERIALIZE_SCALAR(asi);
631 SERIALIZE_SCALAR(tick);
632 SERIALIZE_SCALAR(fprs);
633 SERIALIZE_SCALAR(gsr);
634 SERIALIZE_SCALAR(softint);
635 SERIALIZE_SCALAR(tick_cmpr);
636 SERIALIZE_SCALAR(stick);
637 SERIALIZE_SCALAR(stick_cmpr);
638 SERIALIZE_ARRAY(tpc,MaxTL);
639 SERIALIZE_ARRAY(tnpc,MaxTL);
640 SERIALIZE_ARRAY(tstate,MaxTL);
641 SERIALIZE_ARRAY(tt,MaxTL);
642 SERIALIZE_SCALAR(tba);
643 SERIALIZE_SCALAR(pstate);
644 SERIALIZE_SCALAR(tl);
645 SERIALIZE_SCALAR(pil);
646 SERIALIZE_SCALAR(cwp);
647 SERIALIZE_SCALAR(gl);
648 SERIALIZE_SCALAR(hpstate);
649 SERIALIZE_ARRAY(htstate,MaxTL);
650 SERIALIZE_SCALAR(hintp);
651 SERIALIZE_SCALAR(htba);
652 SERIALIZE_SCALAR(hstick_cmpr);
653 SERIALIZE_SCALAR(strandStatusReg);
654 SERIALIZE_SCALAR(fsr);
655 SERIALIZE_SCALAR(priContext);
656 SERIALIZE_SCALAR(secContext);
657 SERIALIZE_SCALAR(partId);
658 SERIALIZE_SCALAR(lsuCtrlReg);
659 SERIALIZE_ARRAY(scratchPad,8);
660 SERIALIZE_SCALAR(cpu_mondo_head);
661 SERIALIZE_SCALAR(cpu_mondo_tail);
662 SERIALIZE_SCALAR(dev_mondo_head);
663 SERIALIZE_SCALAR(dev_mondo_tail);
664 SERIALIZE_SCALAR(res_error_head);
665 SERIALIZE_SCALAR(res_error_tail);
666 SERIALIZE_SCALAR(nres_error_head);
667 SERIALIZE_SCALAR(nres_error_tail);
668#if FULL_SYSTEM
669 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
670 ThreadContext *tc = NULL;
671 BaseCPU *cpu = NULL;
672 int tc_num = 0;
673 bool tick_intr_sched = true;
674
675 if (tickCompare)
676 tc = tickCompare->getTC();
677 else if (sTickCompare)
678 tc = sTickCompare->getTC();
679 else if (hSTickCompare)
680 tc = hSTickCompare->getTC();
681 else
682 tick_intr_sched = false;
683
684 SERIALIZE_SCALAR(tick_intr_sched);
685
686 if (tc) {
687 cpu = tc->getCpuPtr();
688 tc_num = cpu->findContext(tc);
689 if (tickCompare && tickCompare->scheduled())
690 tick_cmp = tickCompare->when();
691 if (sTickCompare && sTickCompare->scheduled())
692 stick_cmp = sTickCompare->when();
693 if (hSTickCompare && hSTickCompare->scheduled())
694 hstick_cmp = hSTickCompare->when();
695
696 SERIALIZE_OBJPTR(cpu);
697 SERIALIZE_SCALAR(tc_num);
698 SERIALIZE_SCALAR(tick_cmp);
699 SERIALIZE_SCALAR(stick_cmp);
700 SERIALIZE_SCALAR(hstick_cmp);
701 }
702#endif
703}
704
705void
706ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
707{
708 UNSERIALIZE_SCALAR(asi);
709 UNSERIALIZE_SCALAR(tick);
710 UNSERIALIZE_SCALAR(fprs);
711 UNSERIALIZE_SCALAR(gsr);
712 UNSERIALIZE_SCALAR(softint);
713 UNSERIALIZE_SCALAR(tick_cmpr);
714 UNSERIALIZE_SCALAR(stick);
715 UNSERIALIZE_SCALAR(stick_cmpr);
716 UNSERIALIZE_ARRAY(tpc,MaxTL);
717 UNSERIALIZE_ARRAY(tnpc,MaxTL);
718 UNSERIALIZE_ARRAY(tstate,MaxTL);
719 UNSERIALIZE_ARRAY(tt,MaxTL);
720 UNSERIALIZE_SCALAR(tba);
721 UNSERIALIZE_SCALAR(pstate);
722 UNSERIALIZE_SCALAR(tl);
723 UNSERIALIZE_SCALAR(pil);
724 UNSERIALIZE_SCALAR(cwp);
725 UNSERIALIZE_SCALAR(gl);
726 reloadRegMap();
727 UNSERIALIZE_SCALAR(hpstate);
728 UNSERIALIZE_ARRAY(htstate,MaxTL);
729 UNSERIALIZE_SCALAR(hintp);
730 UNSERIALIZE_SCALAR(htba);
731 UNSERIALIZE_SCALAR(hstick_cmpr);
732 UNSERIALIZE_SCALAR(strandStatusReg);
733 UNSERIALIZE_SCALAR(fsr);
734 UNSERIALIZE_SCALAR(priContext);
735 UNSERIALIZE_SCALAR(secContext);
736 UNSERIALIZE_SCALAR(partId);
737 UNSERIALIZE_SCALAR(lsuCtrlReg);
738 UNSERIALIZE_ARRAY(scratchPad,8);
739 UNSERIALIZE_SCALAR(cpu_mondo_head);
740 UNSERIALIZE_SCALAR(cpu_mondo_tail);
741 UNSERIALIZE_SCALAR(dev_mondo_head);
742 UNSERIALIZE_SCALAR(dev_mondo_tail);
743 UNSERIALIZE_SCALAR(res_error_head);
744 UNSERIALIZE_SCALAR(res_error_tail);
745 UNSERIALIZE_SCALAR(nres_error_head);
746 UNSERIALIZE_SCALAR(nres_error_tail);
747
748#if FULL_SYSTEM
749 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
750 ThreadContext *tc = NULL;
751 BaseCPU *cpu = NULL;
752 int tc_num;
753 bool tick_intr_sched;
754 UNSERIALIZE_SCALAR(tick_intr_sched);
755 if (tick_intr_sched) {
756 UNSERIALIZE_OBJPTR(cpu);
757 if (cpu) {
758 UNSERIALIZE_SCALAR(tc_num);
759 UNSERIALIZE_SCALAR(tick_cmp);
760 UNSERIALIZE_SCALAR(stick_cmp);
761 UNSERIALIZE_SCALAR(hstick_cmp);
762 tc = cpu->getContext(tc_num);
763
764 if (tick_cmp) {
765 tickCompare = new TickCompareEvent(this, tc);
766 em->schedule(tickCompare, tick_cmp);
767 }
768 if (stick_cmp) {
769 sTickCompare = new STickCompareEvent(this, tc);
770 em->schedule(sTickCompare, stick_cmp);
771 }
772 if (hstick_cmp) {
773 hSTickCompare = new HSTickCompareEvent(this, tc);
774 em->schedule(hSTickCompare, hstick_cmp);
775 }
776 }
777 }
778
779 #endif
780}
781
782}
40
41namespace SparcISA
42{
43
44enum RegMask
45{
46 PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12)
47};
48
49void
50ISA::reloadRegMap()
51{
52 installGlobals(gl, CurrentGlobalsOffset);
53 installWindow(cwp, CurrentWindowOffset);
54 // Microcode registers.
55 for (int i = 0; i < NumMicroIntRegs; i++)
56 intRegMap[MicroIntOffset + i] = i + TotalGlobals + NWindows * 16;
57 installGlobals(gl, NextGlobalsOffset);
58 installWindow(cwp - 1, NextWindowOffset);
59 installGlobals(gl, PreviousGlobalsOffset);
60 installWindow(cwp + 1, PreviousWindowOffset);
61}
62
63void
64ISA::installWindow(int cwp, int offset)
65{
66 assert(offset >= 0 && offset + NumWindowedRegs <= NumIntRegs);
67 RegIndex *mapChunk = intRegMap + offset;
68 for (int i = 0; i < NumWindowedRegs; i++)
69 mapChunk[i] = TotalGlobals +
70 ((i - cwp * RegsPerWindow + TotalWindowed) % (TotalWindowed));
71}
72
73void
74ISA::installGlobals(int gl, int offset)
75{
76 assert(offset >= 0 && offset + NumGlobalRegs <= NumIntRegs);
77 RegIndex *mapChunk = intRegMap + offset;
78 mapChunk[0] = 0;
79 for (int i = 1; i < NumGlobalRegs; i++)
80 mapChunk[i] = i + gl * NumGlobalRegs;
81}
82
83void
84ISA::clear()
85{
86 cwp = 0;
87 gl = 0;
88 reloadRegMap();
89
90 // y = 0;
91 // ccr = 0;
92 asi = 0;
93 tick = ULL(1) << 63;
94 fprs = 0;
95 gsr = 0;
96 softint = 0;
97 tick_cmpr = 0;
98 stick = 0;
99 stick_cmpr = 0;
100 memset(tpc, 0, sizeof(tpc));
101 memset(tnpc, 0, sizeof(tnpc));
102 memset(tstate, 0, sizeof(tstate));
103 memset(tt, 0, sizeof(tt));
104 tba = 0;
105 pstate = 0;
106 tl = 0;
107 pil = 0;
108 // cansave = 0;
109 // canrestore = 0;
110 // cleanwin = 0;
111 // otherwin = 0;
112 // wstate = 0;
113 // In a T1, bit 11 is apparently always 1
114 hpstate = (1 << 11);
115 memset(htstate, 0, sizeof(htstate));
116 hintp = 0;
117 htba = 0;
118 hstick_cmpr = 0;
119 // This is set this way in Legion for some reason
120 strandStatusReg = 0x50000;
121 fsr = 0;
122
123 priContext = 0;
124 secContext = 0;
125 partId = 0;
126 lsuCtrlReg = 0;
127
128 memset(scratchPad, 0, sizeof(scratchPad));
129
130 cpu_mondo_head = 0;
131 cpu_mondo_tail = 0;
132 dev_mondo_head = 0;
133 dev_mondo_tail = 0;
134 res_error_head = 0;
135 res_error_tail = 0;
136 nres_error_head = 0;
137 nres_error_tail = 0;
138
139#if FULL_SYSTEM
140 // If one of these events is active, it's not obvious to me how to get
141 // rid of it cleanly. For now we'll just assert that they're not.
142 if (tickCompare != NULL && sTickCompare != NULL && hSTickCompare != NULL)
143 panic("Tick comparison event active when clearing the ISA object.\n");
144#endif
145}
146
147MiscReg
148ISA::readMiscRegNoEffect(int miscReg)
149{
150
151 // The three miscRegs are moved up from the switch statement
152 // due to more frequent calls.
153
154 if (miscReg == MISCREG_GL)
155 return gl;
156 if (miscReg == MISCREG_CWP)
157 return cwp;
158 if (miscReg == MISCREG_TLB_DATA) {
159 /* Package up all the data for the tlb:
160 * 6666555555555544444444443333333333222222222211111111110000000000
161 * 3210987654321098765432109876543210987654321098765432109876543210
162 * secContext | priContext | |tl|partid| |||||^hpriv
163 * ||||^red
164 * |||^priv
165 * ||^am
166 * |^lsuim
167 * ^lsudm
168 */
169 return bits((uint64_t)hpstate,2,2) |
170 bits((uint64_t)hpstate,5,5) << 1 |
171 bits((uint64_t)pstate,3,2) << 2 |
172 bits((uint64_t)lsuCtrlReg,3,2) << 4 |
173 bits((uint64_t)partId,7,0) << 8 |
174 bits((uint64_t)tl,2,0) << 16 |
175 (uint64_t)priContext << 32 |
176 (uint64_t)secContext << 48;
177 }
178
179 switch (miscReg) {
180 // case MISCREG_TLB_DATA:
181 // [original contents see above]
182 // case MISCREG_Y:
183 // return y;
184 // case MISCREG_CCR:
185 // return ccr;
186 case MISCREG_ASI:
187 return asi;
188 case MISCREG_FPRS:
189 return fprs;
190 case MISCREG_TICK:
191 return tick;
192 case MISCREG_PCR:
193 panic("PCR not implemented\n");
194 case MISCREG_PIC:
195 panic("PIC not implemented\n");
196 case MISCREG_GSR:
197 return gsr;
198 case MISCREG_SOFTINT:
199 return softint;
200 case MISCREG_TICK_CMPR:
201 return tick_cmpr;
202 case MISCREG_STICK:
203 return stick;
204 case MISCREG_STICK_CMPR:
205 return stick_cmpr;
206
207 /** Privilged Registers */
208 case MISCREG_TPC:
209 return tpc[tl-1];
210 case MISCREG_TNPC:
211 return tnpc[tl-1];
212 case MISCREG_TSTATE:
213 return tstate[tl-1];
214 case MISCREG_TT:
215 return tt[tl-1];
216 case MISCREG_PRIVTICK:
217 panic("Priviliged access to tick registers not implemented\n");
218 case MISCREG_TBA:
219 return tba;
220 case MISCREG_PSTATE:
221 return pstate;
222 case MISCREG_TL:
223 return tl;
224 case MISCREG_PIL:
225 return pil;
226 // CWP, GL moved
227 // case MISCREG_CWP:
228 // return cwp;
229 // case MISCREG_CANSAVE:
230 // return cansave;
231 // case MISCREG_CANRESTORE:
232 // return canrestore;
233 // case MISCREG_CLEANWIN:
234 // return cleanwin;
235 // case MISCREG_OTHERWIN:
236 // return otherwin;
237 // case MISCREG_WSTATE:
238 // return wstate;
239 // case MISCREG_GL:
240 // return gl;
241
242 /** Hyper privileged registers */
243 case MISCREG_HPSTATE:
244 return hpstate;
245 case MISCREG_HTSTATE:
246 return htstate[tl-1];
247 case MISCREG_HINTP:
248 return hintp;
249 case MISCREG_HTBA:
250 return htba;
251 case MISCREG_STRAND_STS_REG:
252 return strandStatusReg;
253 case MISCREG_HSTICK_CMPR:
254 return hstick_cmpr;
255
256 /** Floating Point Status Register */
257 case MISCREG_FSR:
258 DPRINTF(MiscRegs, "FSR read as: %#x\n", fsr);
259 return fsr;
260
261 case MISCREG_MMU_P_CONTEXT:
262 return priContext;
263 case MISCREG_MMU_S_CONTEXT:
264 return secContext;
265 case MISCREG_MMU_PART_ID:
266 return partId;
267 case MISCREG_MMU_LSU_CTRL:
268 return lsuCtrlReg;
269
270 case MISCREG_SCRATCHPAD_R0:
271 return scratchPad[0];
272 case MISCREG_SCRATCHPAD_R1:
273 return scratchPad[1];
274 case MISCREG_SCRATCHPAD_R2:
275 return scratchPad[2];
276 case MISCREG_SCRATCHPAD_R3:
277 return scratchPad[3];
278 case MISCREG_SCRATCHPAD_R4:
279 return scratchPad[4];
280 case MISCREG_SCRATCHPAD_R5:
281 return scratchPad[5];
282 case MISCREG_SCRATCHPAD_R6:
283 return scratchPad[6];
284 case MISCREG_SCRATCHPAD_R7:
285 return scratchPad[7];
286 case MISCREG_QUEUE_CPU_MONDO_HEAD:
287 return cpu_mondo_head;
288 case MISCREG_QUEUE_CPU_MONDO_TAIL:
289 return cpu_mondo_tail;
290 case MISCREG_QUEUE_DEV_MONDO_HEAD:
291 return dev_mondo_head;
292 case MISCREG_QUEUE_DEV_MONDO_TAIL:
293 return dev_mondo_tail;
294 case MISCREG_QUEUE_RES_ERROR_HEAD:
295 return res_error_head;
296 case MISCREG_QUEUE_RES_ERROR_TAIL:
297 return res_error_tail;
298 case MISCREG_QUEUE_NRES_ERROR_HEAD:
299 return nres_error_head;
300 case MISCREG_QUEUE_NRES_ERROR_TAIL:
301 return nres_error_tail;
302 default:
303 panic("Miscellaneous register %d not implemented\n", miscReg);
304 }
305}
306
307MiscReg
308ISA::readMiscReg(int miscReg, ThreadContext * tc)
309{
310 switch (miscReg) {
311 // tick and stick are aliased to each other in niagra
312 // well store the tick data in stick and the interrupt bit in tick
313 case MISCREG_STICK:
314 case MISCREG_TICK:
315 case MISCREG_PRIVTICK:
316 // I'm not sure why legion ignores the lowest two bits, but we'll go
317 // with it
318 // change from curCycle() to instCount() until we're done with legion
319 DPRINTF(Timer, "Instruction Count when TICK read: %#X stick=%#X\n",
320 tc->getCpuPtr()->instCount(), stick);
321 return mbits(tc->getCpuPtr()->instCount() + (int64_t)stick,62,2) |
322 mbits(tick,63,63);
323 case MISCREG_FPRS:
324 // in legion if fp is enabled du and dl are set
325 return fprs | 0x3;
326 case MISCREG_PCR:
327 case MISCREG_PIC:
328 panic("Performance Instrumentation not impl\n");
329 case MISCREG_SOFTINT_CLR:
330 case MISCREG_SOFTINT_SET:
331 panic("Can read from softint clr/set\n");
332 case MISCREG_SOFTINT:
333 case MISCREG_TICK_CMPR:
334 case MISCREG_STICK_CMPR:
335 case MISCREG_HINTP:
336 case MISCREG_HTSTATE:
337 case MISCREG_HTBA:
338 case MISCREG_HVER:
339 case MISCREG_STRAND_STS_REG:
340 case MISCREG_HSTICK_CMPR:
341 case MISCREG_QUEUE_CPU_MONDO_HEAD:
342 case MISCREG_QUEUE_CPU_MONDO_TAIL:
343 case MISCREG_QUEUE_DEV_MONDO_HEAD:
344 case MISCREG_QUEUE_DEV_MONDO_TAIL:
345 case MISCREG_QUEUE_RES_ERROR_HEAD:
346 case MISCREG_QUEUE_RES_ERROR_TAIL:
347 case MISCREG_QUEUE_NRES_ERROR_HEAD:
348 case MISCREG_QUEUE_NRES_ERROR_TAIL:
349#if FULL_SYSTEM
350 case MISCREG_HPSTATE:
351 return readFSReg(miscReg, tc);
352#else
353 case MISCREG_HPSTATE:
354 // HPSTATE is special because because sometimes in privilege
355 // checks for instructions it will read HPSTATE to make sure
356 // the priv. level is ok So, we'll just have to tell it it
357 // isn't, instead of panicing.
358 return 0;
359
360 panic("Accessing Fullsystem register %d in SE mode\n", miscReg);
361#endif
362
363 }
364 return readMiscRegNoEffect(miscReg);
365}
366
367void
368ISA::setMiscRegNoEffect(int miscReg, MiscReg val)
369{
370 switch (miscReg) {
371// case MISCREG_Y:
372// y = val;
373// break;
374// case MISCREG_CCR:
375// ccr = val;
376// break;
377 case MISCREG_ASI:
378 asi = val;
379 break;
380 case MISCREG_FPRS:
381 fprs = val;
382 break;
383 case MISCREG_TICK:
384 tick = val;
385 break;
386 case MISCREG_PCR:
387 panic("PCR not implemented\n");
388 case MISCREG_PIC:
389 panic("PIC not implemented\n");
390 case MISCREG_GSR:
391 gsr = val;
392 break;
393 case MISCREG_SOFTINT:
394 softint = val;
395 break;
396 case MISCREG_TICK_CMPR:
397 tick_cmpr = val;
398 break;
399 case MISCREG_STICK:
400 stick = val;
401 break;
402 case MISCREG_STICK_CMPR:
403 stick_cmpr = val;
404 break;
405
406 /** Privilged Registers */
407 case MISCREG_TPC:
408 tpc[tl-1] = val;
409 break;
410 case MISCREG_TNPC:
411 tnpc[tl-1] = val;
412 break;
413 case MISCREG_TSTATE:
414 tstate[tl-1] = val;
415 break;
416 case MISCREG_TT:
417 tt[tl-1] = val;
418 break;
419 case MISCREG_PRIVTICK:
420 panic("Priviliged access to tick regesiters not implemented\n");
421 case MISCREG_TBA:
422 // clear lower 7 bits on writes.
423 tba = val & ULL(~0x7FFF);
424 break;
425 case MISCREG_PSTATE:
426 pstate = (val & PSTATE_MASK);
427 break;
428 case MISCREG_TL:
429 tl = val;
430 break;
431 case MISCREG_PIL:
432 pil = val;
433 break;
434 case MISCREG_CWP:
435 cwp = val;
436 break;
437// case MISCREG_CANSAVE:
438// cansave = val;
439// break;
440// case MISCREG_CANRESTORE:
441// canrestore = val;
442// break;
443// case MISCREG_CLEANWIN:
444// cleanwin = val;
445// break;
446// case MISCREG_OTHERWIN:
447// otherwin = val;
448// break;
449// case MISCREG_WSTATE:
450// wstate = val;
451// break;
452 case MISCREG_GL:
453 gl = val;
454 break;
455
456 /** Hyper privileged registers */
457 case MISCREG_HPSTATE:
458 hpstate = val;
459 break;
460 case MISCREG_HTSTATE:
461 htstate[tl-1] = val;
462 break;
463 case MISCREG_HINTP:
464 hintp = val;
465 case MISCREG_HTBA:
466 htba = val;
467 break;
468 case MISCREG_STRAND_STS_REG:
469 strandStatusReg = val;
470 break;
471 case MISCREG_HSTICK_CMPR:
472 hstick_cmpr = val;
473 break;
474
475 /** Floating Point Status Register */
476 case MISCREG_FSR:
477 fsr = val;
478 DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr);
479 break;
480
481 case MISCREG_MMU_P_CONTEXT:
482 priContext = val;
483 break;
484 case MISCREG_MMU_S_CONTEXT:
485 secContext = val;
486 break;
487 case MISCREG_MMU_PART_ID:
488 partId = val;
489 break;
490 case MISCREG_MMU_LSU_CTRL:
491 lsuCtrlReg = val;
492 break;
493
494 case MISCREG_SCRATCHPAD_R0:
495 scratchPad[0] = val;
496 break;
497 case MISCREG_SCRATCHPAD_R1:
498 scratchPad[1] = val;
499 break;
500 case MISCREG_SCRATCHPAD_R2:
501 scratchPad[2] = val;
502 break;
503 case MISCREG_SCRATCHPAD_R3:
504 scratchPad[3] = val;
505 break;
506 case MISCREG_SCRATCHPAD_R4:
507 scratchPad[4] = val;
508 break;
509 case MISCREG_SCRATCHPAD_R5:
510 scratchPad[5] = val;
511 break;
512 case MISCREG_SCRATCHPAD_R6:
513 scratchPad[6] = val;
514 break;
515 case MISCREG_SCRATCHPAD_R7:
516 scratchPad[7] = val;
517 break;
518 case MISCREG_QUEUE_CPU_MONDO_HEAD:
519 cpu_mondo_head = val;
520 break;
521 case MISCREG_QUEUE_CPU_MONDO_TAIL:
522 cpu_mondo_tail = val;
523 break;
524 case MISCREG_QUEUE_DEV_MONDO_HEAD:
525 dev_mondo_head = val;
526 break;
527 case MISCREG_QUEUE_DEV_MONDO_TAIL:
528 dev_mondo_tail = val;
529 break;
530 case MISCREG_QUEUE_RES_ERROR_HEAD:
531 res_error_head = val;
532 break;
533 case MISCREG_QUEUE_RES_ERROR_TAIL:
534 res_error_tail = val;
535 break;
536 case MISCREG_QUEUE_NRES_ERROR_HEAD:
537 nres_error_head = val;
538 break;
539 case MISCREG_QUEUE_NRES_ERROR_TAIL:
540 nres_error_tail = val;
541 break;
542 default:
543 panic("Miscellaneous register %d not implemented\n", miscReg);
544 }
545}
546
547void
548ISA::setMiscReg(int miscReg, MiscReg val, ThreadContext * tc)
549{
550 MiscReg new_val = val;
551
552 switch (miscReg) {
553 case MISCREG_STICK:
554 case MISCREG_TICK:
555 // stick and tick are same thing on niagra
556 // use stick for offset and tick for holding intrrupt bit
557 stick = mbits(val,62,0) - tc->getCpuPtr()->instCount();
558 tick = mbits(val,63,63);
559 DPRINTF(Timer, "Writing TICK=%#X\n", val);
560 break;
561 case MISCREG_FPRS:
562 // Configure the fpu based on the fprs
563 break;
564 case MISCREG_PCR:
565 // Set up performance counting based on pcr value
566 break;
567 case MISCREG_PSTATE:
568 pstate = val & PSTATE_MASK;
569 return;
570 case MISCREG_TL:
571 tl = val;
572#if FULL_SYSTEM
573 if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv))
574 tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0);
575 else
576 tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0);
577#endif
578 return;
579 case MISCREG_CWP:
580 new_val = val >= NWindows ? NWindows - 1 : val;
581 if (val >= NWindows)
582 new_val = NWindows - 1;
583
584 installWindow(new_val, CurrentWindowOffset);
585 installWindow(new_val - 1, NextWindowOffset);
586 installWindow(new_val + 1, PreviousWindowOffset);
587 break;
588 case MISCREG_GL:
589 installGlobals(val, CurrentGlobalsOffset);
590 installGlobals(val, NextGlobalsOffset);
591 installGlobals(val, PreviousGlobalsOffset);
592 break;
593 case MISCREG_PIL:
594 case MISCREG_SOFTINT:
595 case MISCREG_SOFTINT_SET:
596 case MISCREG_SOFTINT_CLR:
597 case MISCREG_TICK_CMPR:
598 case MISCREG_STICK_CMPR:
599 case MISCREG_HINTP:
600 case MISCREG_HTSTATE:
601 case MISCREG_HTBA:
602 case MISCREG_HVER:
603 case MISCREG_STRAND_STS_REG:
604 case MISCREG_HSTICK_CMPR:
605 case MISCREG_QUEUE_CPU_MONDO_HEAD:
606 case MISCREG_QUEUE_CPU_MONDO_TAIL:
607 case MISCREG_QUEUE_DEV_MONDO_HEAD:
608 case MISCREG_QUEUE_DEV_MONDO_TAIL:
609 case MISCREG_QUEUE_RES_ERROR_HEAD:
610 case MISCREG_QUEUE_RES_ERROR_TAIL:
611 case MISCREG_QUEUE_NRES_ERROR_HEAD:
612 case MISCREG_QUEUE_NRES_ERROR_TAIL:
613#if FULL_SYSTEM
614 case MISCREG_HPSTATE:
615 setFSReg(miscReg, val, tc);
616 return;
617#else
618 case MISCREG_HPSTATE:
619 // HPSTATE is special because normal trap processing saves HPSTATE when
620 // it goes into a trap, and restores it when it returns.
621 return;
622 panic("Accessing Fullsystem register %d to %#x in SE mode\n",
623 miscReg, val);
624#endif
625 }
626 setMiscRegNoEffect(miscReg, new_val);
627}
628
629void
630ISA::serialize(EventManager *em, std::ostream &os)
631{
632 SERIALIZE_SCALAR(asi);
633 SERIALIZE_SCALAR(tick);
634 SERIALIZE_SCALAR(fprs);
635 SERIALIZE_SCALAR(gsr);
636 SERIALIZE_SCALAR(softint);
637 SERIALIZE_SCALAR(tick_cmpr);
638 SERIALIZE_SCALAR(stick);
639 SERIALIZE_SCALAR(stick_cmpr);
640 SERIALIZE_ARRAY(tpc,MaxTL);
641 SERIALIZE_ARRAY(tnpc,MaxTL);
642 SERIALIZE_ARRAY(tstate,MaxTL);
643 SERIALIZE_ARRAY(tt,MaxTL);
644 SERIALIZE_SCALAR(tba);
645 SERIALIZE_SCALAR(pstate);
646 SERIALIZE_SCALAR(tl);
647 SERIALIZE_SCALAR(pil);
648 SERIALIZE_SCALAR(cwp);
649 SERIALIZE_SCALAR(gl);
650 SERIALIZE_SCALAR(hpstate);
651 SERIALIZE_ARRAY(htstate,MaxTL);
652 SERIALIZE_SCALAR(hintp);
653 SERIALIZE_SCALAR(htba);
654 SERIALIZE_SCALAR(hstick_cmpr);
655 SERIALIZE_SCALAR(strandStatusReg);
656 SERIALIZE_SCALAR(fsr);
657 SERIALIZE_SCALAR(priContext);
658 SERIALIZE_SCALAR(secContext);
659 SERIALIZE_SCALAR(partId);
660 SERIALIZE_SCALAR(lsuCtrlReg);
661 SERIALIZE_ARRAY(scratchPad,8);
662 SERIALIZE_SCALAR(cpu_mondo_head);
663 SERIALIZE_SCALAR(cpu_mondo_tail);
664 SERIALIZE_SCALAR(dev_mondo_head);
665 SERIALIZE_SCALAR(dev_mondo_tail);
666 SERIALIZE_SCALAR(res_error_head);
667 SERIALIZE_SCALAR(res_error_tail);
668 SERIALIZE_SCALAR(nres_error_head);
669 SERIALIZE_SCALAR(nres_error_tail);
670#if FULL_SYSTEM
671 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
672 ThreadContext *tc = NULL;
673 BaseCPU *cpu = NULL;
674 int tc_num = 0;
675 bool tick_intr_sched = true;
676
677 if (tickCompare)
678 tc = tickCompare->getTC();
679 else if (sTickCompare)
680 tc = sTickCompare->getTC();
681 else if (hSTickCompare)
682 tc = hSTickCompare->getTC();
683 else
684 tick_intr_sched = false;
685
686 SERIALIZE_SCALAR(tick_intr_sched);
687
688 if (tc) {
689 cpu = tc->getCpuPtr();
690 tc_num = cpu->findContext(tc);
691 if (tickCompare && tickCompare->scheduled())
692 tick_cmp = tickCompare->when();
693 if (sTickCompare && sTickCompare->scheduled())
694 stick_cmp = sTickCompare->when();
695 if (hSTickCompare && hSTickCompare->scheduled())
696 hstick_cmp = hSTickCompare->when();
697
698 SERIALIZE_OBJPTR(cpu);
699 SERIALIZE_SCALAR(tc_num);
700 SERIALIZE_SCALAR(tick_cmp);
701 SERIALIZE_SCALAR(stick_cmp);
702 SERIALIZE_SCALAR(hstick_cmp);
703 }
704#endif
705}
706
707void
708ISA::unserialize(EventManager *em, Checkpoint *cp, const std::string &section)
709{
710 UNSERIALIZE_SCALAR(asi);
711 UNSERIALIZE_SCALAR(tick);
712 UNSERIALIZE_SCALAR(fprs);
713 UNSERIALIZE_SCALAR(gsr);
714 UNSERIALIZE_SCALAR(softint);
715 UNSERIALIZE_SCALAR(tick_cmpr);
716 UNSERIALIZE_SCALAR(stick);
717 UNSERIALIZE_SCALAR(stick_cmpr);
718 UNSERIALIZE_ARRAY(tpc,MaxTL);
719 UNSERIALIZE_ARRAY(tnpc,MaxTL);
720 UNSERIALIZE_ARRAY(tstate,MaxTL);
721 UNSERIALIZE_ARRAY(tt,MaxTL);
722 UNSERIALIZE_SCALAR(tba);
723 UNSERIALIZE_SCALAR(pstate);
724 UNSERIALIZE_SCALAR(tl);
725 UNSERIALIZE_SCALAR(pil);
726 UNSERIALIZE_SCALAR(cwp);
727 UNSERIALIZE_SCALAR(gl);
728 reloadRegMap();
729 UNSERIALIZE_SCALAR(hpstate);
730 UNSERIALIZE_ARRAY(htstate,MaxTL);
731 UNSERIALIZE_SCALAR(hintp);
732 UNSERIALIZE_SCALAR(htba);
733 UNSERIALIZE_SCALAR(hstick_cmpr);
734 UNSERIALIZE_SCALAR(strandStatusReg);
735 UNSERIALIZE_SCALAR(fsr);
736 UNSERIALIZE_SCALAR(priContext);
737 UNSERIALIZE_SCALAR(secContext);
738 UNSERIALIZE_SCALAR(partId);
739 UNSERIALIZE_SCALAR(lsuCtrlReg);
740 UNSERIALIZE_ARRAY(scratchPad,8);
741 UNSERIALIZE_SCALAR(cpu_mondo_head);
742 UNSERIALIZE_SCALAR(cpu_mondo_tail);
743 UNSERIALIZE_SCALAR(dev_mondo_head);
744 UNSERIALIZE_SCALAR(dev_mondo_tail);
745 UNSERIALIZE_SCALAR(res_error_head);
746 UNSERIALIZE_SCALAR(res_error_tail);
747 UNSERIALIZE_SCALAR(nres_error_head);
748 UNSERIALIZE_SCALAR(nres_error_tail);
749
750#if FULL_SYSTEM
751 Tick tick_cmp = 0, stick_cmp = 0, hstick_cmp = 0;
752 ThreadContext *tc = NULL;
753 BaseCPU *cpu = NULL;
754 int tc_num;
755 bool tick_intr_sched;
756 UNSERIALIZE_SCALAR(tick_intr_sched);
757 if (tick_intr_sched) {
758 UNSERIALIZE_OBJPTR(cpu);
759 if (cpu) {
760 UNSERIALIZE_SCALAR(tc_num);
761 UNSERIALIZE_SCALAR(tick_cmp);
762 UNSERIALIZE_SCALAR(stick_cmp);
763 UNSERIALIZE_SCALAR(hstick_cmp);
764 tc = cpu->getContext(tc_num);
765
766 if (tick_cmp) {
767 tickCompare = new TickCompareEvent(this, tc);
768 em->schedule(tickCompare, tick_cmp);
769 }
770 if (stick_cmp) {
771 sTickCompare = new STickCompareEvent(this, tc);
772 em->schedule(sTickCompare, stick_cmp);
773 }
774 if (hstick_cmp) {
775 hSTickCompare = new HSTickCompareEvent(this, tc);
776 em->schedule(hSTickCompare, hstick_cmp);
777 }
778 }
779 }
780
781 #endif
782}
783
784}