Changes to support automatic renaming of the shadow registers at decode time. This...
[gem5.git] / arch / alpha / ev5.cc
1 /*
2 * Copyright (c) 2002-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
29 #include "arch/alpha/tlb.hh"
30 #include "arch/alpha/isa_traits.hh"
31 #include "arch/alpha/osfpal.hh"
32 #include "base/kgdb.h"
33 #include "base/remote_gdb.hh"
34 #include "base/stats/events.hh"
35 #include "config/full_system.hh"
36 #include "cpu/base.hh"
37 #include "cpu/exec_context.hh"
38 #include "cpu/fast/cpu.hh"
39 #include "kern/kernel_stats.hh"
40 #include "sim/debug.hh"
41 #include "sim/sim_events.hh"
42
43 #if FULL_SYSTEM
44
45 using namespace EV5;
46
47 ////////////////////////////////////////////////////////////////////////
48 //
49 // Machine dependent functions
50 //
51 void
52 AlphaISA::initCPU(RegFile *regs, int cpuId)
53 {
54 initIPRs(&regs->miscRegs, cpuId);
55
56 regs->intRegFile[16] = cpuId;
57 regs->intRegFile[0] = cpuId;
58
59 regs->pc = regs->miscRegs.readReg(IPR_PAL_BASE) + (new ResetFault)->vect();
60 regs->npc = regs->pc + sizeof(MachInst);
61 }
62
63 ////////////////////////////////////////////////////////////////////////
64 //
65 //
66 //
67 void
68 AlphaISA::initIPRs(MiscRegFile *miscRegs, int cpuId)
69 {
70 miscRegs->clearIprs();
71
72 miscRegs->setReg(IPR_PAL_BASE, PalBase);
73 miscRegs->setReg(IPR_MCSR, 0x6);
74 miscRegs->setReg(IPR_PALtemp16, cpuId);
75 }
76
77
78 template <class CPU>
79 void
80 AlphaISA::processInterrupts(CPU *cpu)
81 {
82 //Check if there are any outstanding interrupts
83 //Handle the interrupts
84 int ipl = 0;
85 int summary = 0;
86
87 cpu->checkInterrupts = false;
88
89 if (cpu->readMiscReg(IPR_ASTRR))
90 panic("asynchronous traps not implemented\n");
91
92 if (cpu->readMiscReg(IPR_SIRR)) {
93 for (int i = INTLEVEL_SOFTWARE_MIN;
94 i < INTLEVEL_SOFTWARE_MAX; i++) {
95 if (cpu->readMiscReg(IPR_SIRR) & (ULL(1) << i)) {
96 // See table 4-19 of the 21164 hardware reference
97 ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
98 summary |= (ULL(1) << i);
99 }
100 }
101 }
102
103 uint64_t interrupts = cpu->intr_status();
104
105 if (interrupts) {
106 for (int i = INTLEVEL_EXTERNAL_MIN;
107 i < INTLEVEL_EXTERNAL_MAX; i++) {
108 if (interrupts & (ULL(1) << i)) {
109 // See table 4-19 of the 21164 hardware reference
110 ipl = i;
111 summary |= (ULL(1) << i);
112 }
113 }
114 }
115
116 if (ipl && ipl > cpu->readMiscReg(IPR_IPLR)) {
117 cpu->setMiscReg(IPR_ISR, summary);
118 cpu->setMiscReg(IPR_INTID, ipl);
119 cpu->trap(new InterruptFault);
120 DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
121 cpu->readMiscReg(IPR_IPLR), ipl, summary);
122 }
123
124 }
125
126 template <class CPU>
127 void
128 AlphaISA::zeroRegisters(CPU *cpu)
129 {
130 // Insure ISA semantics
131 // (no longer very clean due to the change in setIntReg() in the
132 // cpu model. Consider changing later.)
133 cpu->xc->setIntReg(ZeroReg, 0);
134 cpu->xc->setFloatRegDouble(ZeroReg, 0.0);
135 }
136
137 void
138 ExecContext::ev5_temp_trap(Fault fault)
139 {
140 DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name(), regs.pc);
141 cpu->recordEvent(csprintf("Fault %s", fault->name()));
142
143 assert(!misspeculating());
144 kernelStats->fault(fault);
145
146 if (fault->isA<ArithmeticFault>())
147 panic("Arithmetic traps are unimplemented!");
148
149 // exception restart address
150 if (!fault->isA<InterruptFault>() || !inPalMode())
151 setMiscReg(AlphaISA::IPR_EXC_ADDR, regs.pc);
152
153 if (fault->isA<PalFault>() || fault->isA<ArithmeticFault>() /* ||
154 fault == InterruptFault && !inPalMode() */) {
155 // traps... skip faulting instruction.
156 setMiscReg(AlphaISA::IPR_EXC_ADDR,
157 readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4);
158 }
159
160 regs.pc = readMiscReg(AlphaISA::IPR_PAL_BASE) +
161 (dynamic_cast<AlphaFault *>(fault.get()))->vect();
162 regs.npc = regs.pc + sizeof(MachInst);
163 }
164
165
166 void
167 AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc)
168 {
169 bool use_pc = (fault == NoFault);
170
171 if (fault->isA<ArithmeticFault>())
172 panic("arithmetic faults NYI...");
173
174 // compute exception restart address
175 if (use_pc || fault->isA<PalFault>() || fault->isA<ArithmeticFault>()) {
176 // traps... skip faulting instruction
177 regs->miscRegs.setReg(IPR_EXC_ADDR, regs->pc + 4);
178 } else {
179 // fault, post fault at excepting instruction
180 regs->miscRegs.setReg(IPR_EXC_ADDR, regs->pc);
181 }
182
183 // jump to expection address (PAL PC bit set here as well...)
184 if (!use_pc)
185 regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) +
186 (dynamic_cast<AlphaFault *>(fault.get()))->vect();
187 else
188 regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + pc;
189
190 // that's it! (orders of magnitude less painful than x86)
191 }
192
193 Fault
194 ExecContext::hwrei()
195 {
196 if (!inPalMode())
197 return new UnimplementedOpcodeFault;
198
199 setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR));
200
201 if (!misspeculating()) {
202 kernelStats->hwrei();
203
204 cpu->checkInterrupts = true;
205 }
206
207 // FIXME: XXX check for interrupts? XXX
208 return NoFault;
209 }
210
211 void
212 AlphaISA::MiscRegFile::clearIprs()
213 {
214 bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg));
215 }
216
217 AlphaISA::MiscReg
218 AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc)
219 {
220 uint64_t retval = 0; // return value, default 0
221
222 switch (idx) {
223 case AlphaISA::IPR_PALtemp0:
224 case AlphaISA::IPR_PALtemp1:
225 case AlphaISA::IPR_PALtemp2:
226 case AlphaISA::IPR_PALtemp3:
227 case AlphaISA::IPR_PALtemp4:
228 case AlphaISA::IPR_PALtemp5:
229 case AlphaISA::IPR_PALtemp6:
230 case AlphaISA::IPR_PALtemp7:
231 case AlphaISA::IPR_PALtemp8:
232 case AlphaISA::IPR_PALtemp9:
233 case AlphaISA::IPR_PALtemp10:
234 case AlphaISA::IPR_PALtemp11:
235 case AlphaISA::IPR_PALtemp12:
236 case AlphaISA::IPR_PALtemp13:
237 case AlphaISA::IPR_PALtemp14:
238 case AlphaISA::IPR_PALtemp15:
239 case AlphaISA::IPR_PALtemp16:
240 case AlphaISA::IPR_PALtemp17:
241 case AlphaISA::IPR_PALtemp18:
242 case AlphaISA::IPR_PALtemp19:
243 case AlphaISA::IPR_PALtemp20:
244 case AlphaISA::IPR_PALtemp21:
245 case AlphaISA::IPR_PALtemp22:
246 case AlphaISA::IPR_PALtemp23:
247 case AlphaISA::IPR_PAL_BASE:
248
249 case AlphaISA::IPR_IVPTBR:
250 case AlphaISA::IPR_DC_MODE:
251 case AlphaISA::IPR_MAF_MODE:
252 case AlphaISA::IPR_ISR:
253 case AlphaISA::IPR_EXC_ADDR:
254 case AlphaISA::IPR_IC_PERR_STAT:
255 case AlphaISA::IPR_DC_PERR_STAT:
256 case AlphaISA::IPR_MCSR:
257 case AlphaISA::IPR_ASTRR:
258 case AlphaISA::IPR_ASTER:
259 case AlphaISA::IPR_SIRR:
260 case AlphaISA::IPR_ICSR:
261 case AlphaISA::IPR_ICM:
262 case AlphaISA::IPR_DTB_CM:
263 case AlphaISA::IPR_IPLR:
264 case AlphaISA::IPR_INTID:
265 case AlphaISA::IPR_PMCTR:
266 // no side-effect
267 retval = ipr[idx];
268 break;
269
270 case AlphaISA::IPR_CC:
271 retval |= ipr[idx] & ULL(0xffffffff00000000);
272 retval |= xc->cpu->curCycle() & ULL(0x00000000ffffffff);
273 break;
274
275 case AlphaISA::IPR_VA:
276 retval = ipr[idx];
277 break;
278
279 case AlphaISA::IPR_VA_FORM:
280 case AlphaISA::IPR_MM_STAT:
281 case AlphaISA::IPR_IFAULT_VA_FORM:
282 case AlphaISA::IPR_EXC_MASK:
283 case AlphaISA::IPR_EXC_SUM:
284 retval = ipr[idx];
285 break;
286
287 case AlphaISA::IPR_DTB_PTE:
288 {
289 AlphaISA::PTE &pte = xc->dtb->index(!xc->misspeculating());
290
291 retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32;
292 retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8;
293 retval |= ((u_int64_t)pte.xwe & ULL(0xf)) << 12;
294 retval |= ((u_int64_t)pte.fonr & ULL(0x1)) << 1;
295 retval |= ((u_int64_t)pte.fonw & ULL(0x1))<< 2;
296 retval |= ((u_int64_t)pte.asma & ULL(0x1)) << 4;
297 retval |= ((u_int64_t)pte.asn & ULL(0x7f)) << 57;
298 }
299 break;
300
301 // write only registers
302 case AlphaISA::IPR_HWINT_CLR:
303 case AlphaISA::IPR_SL_XMIT:
304 case AlphaISA::IPR_DC_FLUSH:
305 case AlphaISA::IPR_IC_FLUSH:
306 case AlphaISA::IPR_ALT_MODE:
307 case AlphaISA::IPR_DTB_IA:
308 case AlphaISA::IPR_DTB_IAP:
309 case AlphaISA::IPR_ITB_IA:
310 case AlphaISA::IPR_ITB_IAP:
311 fault = new UnimplementedOpcodeFault;
312 break;
313
314 default:
315 // invalid IPR
316 fault = new UnimplementedOpcodeFault;
317 break;
318 }
319
320 return retval;
321 }
322
323 #ifdef DEBUG
324 // Cause the simulator to break when changing to the following IPL
325 int break_ipl = -1;
326 #endif
327
328 Fault
329 AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
330 {
331 uint64_t old;
332
333 if (xc->misspeculating())
334 return NoFault;
335
336 switch (idx) {
337 case AlphaISA::IPR_PALtemp0:
338 case AlphaISA::IPR_PALtemp1:
339 case AlphaISA::IPR_PALtemp2:
340 case AlphaISA::IPR_PALtemp3:
341 case AlphaISA::IPR_PALtemp4:
342 case AlphaISA::IPR_PALtemp5:
343 case AlphaISA::IPR_PALtemp6:
344 case AlphaISA::IPR_PALtemp7:
345 case AlphaISA::IPR_PALtemp8:
346 case AlphaISA::IPR_PALtemp9:
347 case AlphaISA::IPR_PALtemp10:
348 case AlphaISA::IPR_PALtemp11:
349 case AlphaISA::IPR_PALtemp12:
350 case AlphaISA::IPR_PALtemp13:
351 case AlphaISA::IPR_PALtemp14:
352 case AlphaISA::IPR_PALtemp15:
353 case AlphaISA::IPR_PALtemp16:
354 case AlphaISA::IPR_PALtemp17:
355 case AlphaISA::IPR_PALtemp18:
356 case AlphaISA::IPR_PALtemp19:
357 case AlphaISA::IPR_PALtemp20:
358 case AlphaISA::IPR_PALtemp21:
359 case AlphaISA::IPR_PALtemp22:
360 case AlphaISA::IPR_PAL_BASE:
361 case AlphaISA::IPR_IC_PERR_STAT:
362 case AlphaISA::IPR_DC_PERR_STAT:
363 case AlphaISA::IPR_PMCTR:
364 // write entire quad w/ no side-effect
365 ipr[idx] = val;
366 break;
367
368 case AlphaISA::IPR_CC_CTL:
369 // This IPR resets the cycle counter. We assume this only
370 // happens once... let's verify that.
371 assert(ipr[idx] == 0);
372 ipr[idx] = 1;
373 break;
374
375 case AlphaISA::IPR_CC:
376 // This IPR only writes the upper 64 bits. It's ok to write
377 // all 64 here since we mask out the lower 32 in rpcc (see
378 // isa_desc).
379 ipr[idx] = val;
380 break;
381
382 case AlphaISA::IPR_PALtemp23:
383 // write entire quad w/ no side-effect
384 old = ipr[idx];
385 ipr[idx] = val;
386 xc->kernelStats->context(old, val);
387 break;
388
389 case AlphaISA::IPR_DTB_PTE:
390 // write entire quad w/ no side-effect, tag is forthcoming
391 ipr[idx] = val;
392 break;
393
394 case AlphaISA::IPR_EXC_ADDR:
395 // second least significant bit in PC is always zero
396 ipr[idx] = val & ~2;
397 break;
398
399 case AlphaISA::IPR_ASTRR:
400 case AlphaISA::IPR_ASTER:
401 // only write least significant four bits - privilege mask
402 ipr[idx] = val & 0xf;
403 break;
404
405 case AlphaISA::IPR_IPLR:
406 #ifdef DEBUG
407 if (break_ipl != -1 && break_ipl == (val & 0x1f))
408 debug_break();
409 #endif
410
411 // only write least significant five bits - interrupt level
412 ipr[idx] = val & 0x1f;
413 xc->kernelStats->swpipl(ipr[idx]);
414 break;
415
416 case AlphaISA::IPR_DTB_CM:
417 if (val & 0x18)
418 xc->kernelStats->mode(Kernel::user);
419 else
420 xc->kernelStats->mode(Kernel::kernel);
421
422 case AlphaISA::IPR_ICM:
423 // only write two mode bits - processor mode
424 ipr[idx] = val & 0x18;
425 break;
426
427 case AlphaISA::IPR_ALT_MODE:
428 // only write two mode bits - processor mode
429 ipr[idx] = val & 0x18;
430 break;
431
432 case AlphaISA::IPR_MCSR:
433 // more here after optimization...
434 ipr[idx] = val;
435 break;
436
437 case AlphaISA::IPR_SIRR:
438 // only write software interrupt mask
439 ipr[idx] = val & 0x7fff0;
440 break;
441
442 case AlphaISA::IPR_ICSR:
443 ipr[idx] = val & ULL(0xffffff0300);
444 break;
445
446 case AlphaISA::IPR_IVPTBR:
447 case AlphaISA::IPR_MVPTBR:
448 ipr[idx] = val & ULL(0xffffffffc0000000);
449 break;
450
451 case AlphaISA::IPR_DC_TEST_CTL:
452 ipr[idx] = val & 0x1ffb;
453 break;
454
455 case AlphaISA::IPR_DC_MODE:
456 case AlphaISA::IPR_MAF_MODE:
457 ipr[idx] = val & 0x3f;
458 break;
459
460 case AlphaISA::IPR_ITB_ASN:
461 ipr[idx] = val & 0x7f0;
462 break;
463
464 case AlphaISA::IPR_DTB_ASN:
465 ipr[idx] = val & ULL(0xfe00000000000000);
466 break;
467
468 case AlphaISA::IPR_EXC_SUM:
469 case AlphaISA::IPR_EXC_MASK:
470 // any write to this register clears it
471 ipr[idx] = 0;
472 break;
473
474 case AlphaISA::IPR_INTID:
475 case AlphaISA::IPR_SL_RCV:
476 case AlphaISA::IPR_MM_STAT:
477 case AlphaISA::IPR_ITB_PTE_TEMP:
478 case AlphaISA::IPR_DTB_PTE_TEMP:
479 // read-only registers
480 return new UnimplementedOpcodeFault;
481
482 case AlphaISA::IPR_HWINT_CLR:
483 case AlphaISA::IPR_SL_XMIT:
484 case AlphaISA::IPR_DC_FLUSH:
485 case AlphaISA::IPR_IC_FLUSH:
486 // the following are write only
487 ipr[idx] = val;
488 break;
489
490 case AlphaISA::IPR_DTB_IA:
491 // really a control write
492 ipr[idx] = 0;
493
494 xc->dtb->flushAll();
495 break;
496
497 case AlphaISA::IPR_DTB_IAP:
498 // really a control write
499 ipr[idx] = 0;
500
501 xc->dtb->flushProcesses();
502 break;
503
504 case AlphaISA::IPR_DTB_IS:
505 // really a control write
506 ipr[idx] = val;
507
508 xc->dtb->flushAddr(val, DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
509 break;
510
511 case AlphaISA::IPR_DTB_TAG: {
512 struct AlphaISA::PTE pte;
513
514 // FIXME: granularity hints NYI...
515 if (DTB_PTE_GH(ipr[AlphaISA::IPR_DTB_PTE]) != 0)
516 panic("PTE GH field != 0");
517
518 // write entire quad
519 ipr[idx] = val;
520
521 // construct PTE for new entry
522 pte.ppn = DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]);
523 pte.xre = DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]);
524 pte.xwe = DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]);
525 pte.fonr = DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]);
526 pte.fonw = DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]);
527 pte.asma = DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]);
528 pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]);
529
530 // insert new TAG/PTE value into data TLB
531 xc->dtb->insert(val, pte);
532 }
533 break;
534
535 case AlphaISA::IPR_ITB_PTE: {
536 struct AlphaISA::PTE pte;
537
538 // FIXME: granularity hints NYI...
539 if (ITB_PTE_GH(val) != 0)
540 panic("PTE GH field != 0");
541
542 // write entire quad
543 ipr[idx] = val;
544
545 // construct PTE for new entry
546 pte.ppn = ITB_PTE_PPN(val);
547 pte.xre = ITB_PTE_XRE(val);
548 pte.xwe = 0;
549 pte.fonr = ITB_PTE_FONR(val);
550 pte.fonw = ITB_PTE_FONW(val);
551 pte.asma = ITB_PTE_ASMA(val);
552 pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]);
553
554 // insert new TAG/PTE value into data TLB
555 xc->itb->insert(ipr[AlphaISA::IPR_ITB_TAG], pte);
556 }
557 break;
558
559 case AlphaISA::IPR_ITB_IA:
560 // really a control write
561 ipr[idx] = 0;
562
563 xc->itb->flushAll();
564 break;
565
566 case AlphaISA::IPR_ITB_IAP:
567 // really a control write
568 ipr[idx] = 0;
569
570 xc->itb->flushProcesses();
571 break;
572
573 case AlphaISA::IPR_ITB_IS:
574 // really a control write
575 ipr[idx] = val;
576
577 xc->itb->flushAddr(val, ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]));
578 break;
579
580 default:
581 // invalid IPR
582 return new UnimplementedOpcodeFault;
583 }
584
585 // no error...
586 return NoFault;
587 }
588
589 /**
590 * Check for special simulator handling of specific PAL calls.
591 * If return value is false, actual PAL call will be suppressed.
592 */
593 bool
594 ExecContext::simPalCheck(int palFunc)
595 {
596 kernelStats->callpal(palFunc);
597
598 switch (palFunc) {
599 case PAL::halt:
600 halt();
601 if (--System::numSystemsRunning == 0)
602 new SimExitEvent("all cpus halted");
603 break;
604
605 case PAL::bpt:
606 case PAL::bugchk:
607 if (system->breakpoint())
608 return false;
609 break;
610 }
611
612 return true;
613 }
614
615 //Forward instantiation for FastCPU object
616 template
617 void AlphaISA::processInterrupts(FastCPU *xc);
618
619 //Forward instantiation for FastCPU object
620 template
621 void AlphaISA::zeroRegisters(FastCPU *xc);
622
623 #endif // FULL_SYSTEM