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