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