ev5.cc revision 732
12623SN/A/* $Id$ */
22623SN/A
32623SN/A#include "arch/alpha/alpha_memory.hh"
42623SN/A#include "arch/alpha/isa_traits.hh"
52623SN/A#include "arch/alpha/osfpal.hh"
62623SN/A#include "base/kgdb.h"
72623SN/A#include "base/remote_gdb.hh"
82623SN/A#include "base/stats/events.hh"
92623SN/A#include "cpu/exec_context.hh"
102623SN/A#include "sim/debug.hh"
112623SN/A#include "sim/sim_events.hh"
122623SN/A
132623SN/A#ifdef FULL_SYSTEM
142623SN/A
152623SN/A#ifndef SYSTEM_EV5
162623SN/A#error This code is only valid for EV5 systems
172623SN/A#endif
182623SN/A
192623SN/A////////////////////////////////////////////////////////////////////////
202623SN/A//
212623SN/A//
222623SN/A//
232623SN/Avoid
242623SN/AAlphaISA::swap_palshadow(RegFile *regs, bool use_shadow)
252623SN/A{
262623SN/A    if (regs->pal_shadow == use_shadow)
272665Ssaidi@eecs.umich.edu        panic("swap_palshadow: wrong PAL shadow state");
282665Ssaidi@eecs.umich.edu
292623SN/A    regs->pal_shadow = use_shadow;
302623SN/A
312623SN/A    for (int i = 0; i < NumIntRegs; i++) {
322623SN/A        if (reg_redir[i]) {
332623SN/A            IntReg temp = regs->intRegFile[i];
342623SN/A            regs->intRegFile[i] = regs->palregs[i];
352623SN/A            regs->palregs[i] = temp;
365529Snate@binkert.org        }
375529Snate@binkert.org    }
382623SN/A}
392623SN/A
402623SN/A////////////////////////////////////////////////////////////////////////
412623SN/A//
425529Snate@binkert.org//  Machine dependent functions
432623SN/A//
442623SN/Avoid
452623SN/AAlphaISA::initCPU(RegFile *regs)
462623SN/A{
472623SN/A    initIPRs(regs);
482839Sktlim@umich.edu    // CPU comes up with PAL regs enabled
492798Sktlim@umich.edu    swap_palshadow(regs, true);
502623SN/A
512623SN/A    regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr[Reset_Fault];
525728Sgblack@eecs.umich.edu    regs->npc = regs->pc + sizeof(MachInst);
535728Sgblack@eecs.umich.edu}
545728Sgblack@eecs.umich.edu
555728Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////
565728Sgblack@eecs.umich.edu//
575728Sgblack@eecs.umich.edu// alpha exceptions - value equals trap address, update with MD_FAULT_TYPE
585728Sgblack@eecs.umich.edu//
595728Sgblack@eecs.umich.eduAddr
605728Sgblack@eecs.umich.eduAlphaISA::fault_addr[Num_Faults] = {
615728Sgblack@eecs.umich.edu    0x0000,	/* No_Fault */
625728Sgblack@eecs.umich.edu    0x0001,	/* Reset_Fault */
635728Sgblack@eecs.umich.edu    0x0401,	/* Machine_Check_Fault */
645728Sgblack@eecs.umich.edu    0x0501,	/* Arithmetic_Fault */
655728Sgblack@eecs.umich.edu    0x0101,	/* Interrupt_Fault */
665728Sgblack@eecs.umich.edu    0x0201,	/* Ndtb_Miss_Fault */
675728Sgblack@eecs.umich.edu    0x0281,	/* Pdtb_Miss_Fault */
685728Sgblack@eecs.umich.edu    0x0301,	/* Alignment_Fault */
695728Sgblack@eecs.umich.edu    0x0381,	/* DTB_Fault_Fault */
705728Sgblack@eecs.umich.edu    0x0381,	/* DTB_Acv_Fault */
715728Sgblack@eecs.umich.edu    0x0181,	/* ITB_Miss_Fault */
725728Sgblack@eecs.umich.edu    0x0181,	/* ITB_Fault_Fault */
735728Sgblack@eecs.umich.edu    0x0081,	/* ITB_Acv_Fault */
745728Sgblack@eecs.umich.edu    0x0481,	/* Unimplemented_Opcode_Fault */
755728Sgblack@eecs.umich.edu    0x0581,	/* Fen_Fault */
765728Sgblack@eecs.umich.edu    0x2001,	/* Pal_Fault */
775728Sgblack@eecs.umich.edu    0x0501,	/* Integer_Overflow_Fault: maps to Arithmetic_Fault */
785728Sgblack@eecs.umich.edu};
795728Sgblack@eecs.umich.edu
805728Sgblack@eecs.umich.educonst int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = {
815728Sgblack@eecs.umich.edu    /*  0 */ 0, 0, 0, 0, 0, 0, 0, 0,
825728Sgblack@eecs.umich.edu    /*  8 */ 1, 1, 1, 1, 1, 1, 1, 0,
835728Sgblack@eecs.umich.edu    /* 16 */ 0, 0, 0, 0, 0, 0, 0, 0,
845728Sgblack@eecs.umich.edu    /* 24 */ 0, 1, 0, 0, 0, 0, 0, 0 };
855728Sgblack@eecs.umich.edu
865728Sgblack@eecs.umich.edu////////////////////////////////////////////////////////////////////////
875728Sgblack@eecs.umich.edu//
885728Sgblack@eecs.umich.edu//
895728Sgblack@eecs.umich.edu//
905728Sgblack@eecs.umich.eduvoid
915728Sgblack@eecs.umich.eduAlphaISA::initIPRs(RegFile *regs)
925728Sgblack@eecs.umich.edu{
935728Sgblack@eecs.umich.edu    uint64_t *ipr = regs->ipr;
945728Sgblack@eecs.umich.edu
955728Sgblack@eecs.umich.edu    bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg));
965728Sgblack@eecs.umich.edu    ipr[IPR_PAL_BASE] = PAL_BASE;
975728Sgblack@eecs.umich.edu    ipr[IPR_MCSR] = 0x6;
985728Sgblack@eecs.umich.edu}
995894Sgblack@eecs.umich.edu
1005894Sgblack@eecs.umich.edu
1015894Sgblack@eecs.umich.eduvoid
1025894Sgblack@eecs.umich.eduExecContext::ev5_trap(Fault fault)
1035894Sgblack@eecs.umich.edu{
1045894Sgblack@eecs.umich.edu    Stats::recordEvent(csprintf("Fault %s", FaultName(fault)));
1056023Snate@binkert.org
1066023Snate@binkert.org    assert(!misspeculating());
1075894Sgblack@eecs.umich.edu    kernelStats.fault(fault);
1085894Sgblack@eecs.umich.edu
1096023Snate@binkert.org    if (fault == Arithmetic_Fault)
1106023Snate@binkert.org        panic("Arithmetic traps are unimplemented!");
1116023Snate@binkert.org
1125894Sgblack@eecs.umich.edu    AlphaISA::InternalProcReg *ipr = regs.ipr;
1135894Sgblack@eecs.umich.edu
1145894Sgblack@eecs.umich.edu    // exception restart address
1155894Sgblack@eecs.umich.edu    if (fault != Interrupt_Fault || !PC_PAL(regs.pc))
1165894Sgblack@eecs.umich.edu        ipr[AlphaISA::IPR_EXC_ADDR] = regs.pc;
1175894Sgblack@eecs.umich.edu
1185894Sgblack@eecs.umich.edu    if (fault == Pal_Fault || fault == Arithmetic_Fault /* ||
1195894Sgblack@eecs.umich.edu        fault == Interrupt_Fault && !PC_PAL(regs.pc) */) {
1205894Sgblack@eecs.umich.edu        // traps...  skip faulting instruction
1215894Sgblack@eecs.umich.edu        ipr[AlphaISA::IPR_EXC_ADDR] += 4;
1225894Sgblack@eecs.umich.edu    }
1235894Sgblack@eecs.umich.edu
1246023Snate@binkert.org    if (!PC_PAL(regs.pc))
1255894Sgblack@eecs.umich.edu        AlphaISA::swap_palshadow(&regs, true);
1265894Sgblack@eecs.umich.edu
1275894Sgblack@eecs.umich.edu    regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + AlphaISA::fault_addr[fault];
1286023Snate@binkert.org    regs.npc = regs.pc + sizeof(MachInst);
1296023Snate@binkert.org}
1306023Snate@binkert.org
1316023Snate@binkert.org
1326023Snate@binkert.orgvoid
1335894Sgblack@eecs.umich.eduAlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc)
1345894Sgblack@eecs.umich.edu{
1356023Snate@binkert.org    InternalProcReg *ipr = regs->ipr;
1366023Snate@binkert.org    bool use_pc = (fault == No_Fault);
1375894Sgblack@eecs.umich.edu
1386023Snate@binkert.org    if (fault == Arithmetic_Fault)
1396023Snate@binkert.org        panic("arithmetic faults NYI...");
1405894Sgblack@eecs.umich.edu
1415894Sgblack@eecs.umich.edu    // compute exception restart address
1425894Sgblack@eecs.umich.edu    if (use_pc || fault == Pal_Fault || fault == Arithmetic_Fault) {
1435894Sgblack@eecs.umich.edu        // traps...  skip faulting instruction
1445894Sgblack@eecs.umich.edu        ipr[IPR_EXC_ADDR] = regs->pc + 4;
1455894Sgblack@eecs.umich.edu    } else {
1465894Sgblack@eecs.umich.edu        // fault, post fault at excepting instruction
1475894Sgblack@eecs.umich.edu        ipr[IPR_EXC_ADDR] = regs->pc;
1485894Sgblack@eecs.umich.edu    }
1495894Sgblack@eecs.umich.edu
1505894Sgblack@eecs.umich.edu    // jump to expection address (PAL PC bit set here as well...)
1515894Sgblack@eecs.umich.edu    if (!use_pc)
1525894Sgblack@eecs.umich.edu        regs->npc = ipr[IPR_PAL_BASE] + fault_addr[fault];
1535894Sgblack@eecs.umich.edu    else
1545894Sgblack@eecs.umich.edu        regs->npc = ipr[IPR_PAL_BASE] + pc;
1556023Snate@binkert.org
1565894Sgblack@eecs.umich.edu    // that's it! (orders of magnitude less painful than x86)
1575894Sgblack@eecs.umich.edu}
1586023Snate@binkert.org
1595894Sgblack@eecs.umich.edubool AlphaISA::check_interrupts = false;
1606023Snate@binkert.org
1616023Snate@binkert.orgFault
1625894Sgblack@eecs.umich.eduExecContext::hwrei()
1635894Sgblack@eecs.umich.edu{
1645894Sgblack@eecs.umich.edu    uint64_t *ipr = regs.ipr;
1655894Sgblack@eecs.umich.edu
1665894Sgblack@eecs.umich.edu    if (!PC_PAL(regs.pc))
1676023Snate@binkert.org        return Unimplemented_Opcode_Fault;
1686023Snate@binkert.org
1695894Sgblack@eecs.umich.edu    setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]);
1705894Sgblack@eecs.umich.edu
1715894Sgblack@eecs.umich.edu    if (!misspeculating()) {
1725894Sgblack@eecs.umich.edu        kernelStats.hwrei();
1735894Sgblack@eecs.umich.edu
1745894Sgblack@eecs.umich.edu        if ((ipr[AlphaISA::IPR_EXC_ADDR] & 1) == 0)
1755894Sgblack@eecs.umich.edu            AlphaISA::swap_palshadow(&regs, false);
1765894Sgblack@eecs.umich.edu
1776023Snate@binkert.org        AlphaISA::check_interrupts = true;
1786023Snate@binkert.org    }
1795894Sgblack@eecs.umich.edu
1805894Sgblack@eecs.umich.edu    // FIXME: XXX check for interrupts? XXX
1815894Sgblack@eecs.umich.edu    return No_Fault;
1826023Snate@binkert.org}
1836023Snate@binkert.org
1845894Sgblack@eecs.umich.eduuint64_t
1855894Sgblack@eecs.umich.eduExecContext::readIpr(int idx, Fault &fault)
1865894Sgblack@eecs.umich.edu{
1875894Sgblack@eecs.umich.edu    uint64_t *ipr = regs.ipr;
1885894Sgblack@eecs.umich.edu    uint64_t retval = 0;	// return value, default 0
1895894Sgblack@eecs.umich.edu
1905894Sgblack@eecs.umich.edu    switch (idx) {
1915894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp0:
1925894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp1:
1935894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp2:
1945894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp3:
1956023Snate@binkert.org      case AlphaISA::IPR_PALtemp4:
1965894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp5:
1975894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp6:
1985894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp7:
1995894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp8:
2005894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp9:
2015894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp10:
2025894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp11:
2035894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp12:
2045894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp13:
2055894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp14:
2065894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp15:
2075894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp16:
2085894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp17:
2095894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp18:
2105894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp19:
2115894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp20:
2125894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp21:
2135894Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp22:
2145744Sgblack@eecs.umich.edu      case AlphaISA::IPR_PALtemp23:
2155728Sgblack@eecs.umich.edu      case AlphaISA::IPR_PAL_BASE:
2165728Sgblack@eecs.umich.edu
2175728Sgblack@eecs.umich.edu      case AlphaISA::IPR_IVPTBR:
2185728Sgblack@eecs.umich.edu      case AlphaISA::IPR_DC_MODE:
2192623SN/A      case AlphaISA::IPR_MAF_MODE:
2202623SN/A      case AlphaISA::IPR_ISR:
2212623SN/A      case AlphaISA::IPR_EXC_ADDR:
2222623SN/A      case AlphaISA::IPR_IC_PERR_STAT:
2232948Ssaidi@eecs.umich.edu      case AlphaISA::IPR_DC_PERR_STAT:
2242623SN/A      case AlphaISA::IPR_MCSR:
2252623SN/A      case AlphaISA::IPR_ASTRR:
2262623SN/A      case AlphaISA::IPR_ASTER:
2272948Ssaidi@eecs.umich.edu      case AlphaISA::IPR_SIRR:
2283401Sktlim@umich.edu      case AlphaISA::IPR_ICSR:
2292623SN/A      case AlphaISA::IPR_ICM:
2302623SN/A      case AlphaISA::IPR_DTB_CM:
2313647Srdreslin@umich.edu      case AlphaISA::IPR_IPLR:
2323647Srdreslin@umich.edu      case AlphaISA::IPR_INTID:
2332623SN/A      case AlphaISA::IPR_PMCTR:
2342623SN/A        // no side-effect
2353349Sbinkertn@umich.edu        retval = ipr[idx];
2362623SN/A        break;
2373349Sbinkertn@umich.edu
2382623SN/A      case AlphaISA::IPR_CC:
2392623SN/A        retval |= ipr[idx] & ULL(0xffffffff00000000);
2402623SN/A        retval |= curTick  & ULL(0x00000000ffffffff);
2412623SN/A        break;
2424475Sstever@eecs.umich.edu
2434475Sstever@eecs.umich.edu      case AlphaISA::IPR_VA:
2442948Ssaidi@eecs.umich.edu        // SFX: unlocks interrupt status registers
2452948Ssaidi@eecs.umich.edu        retval = ipr[idx];
2462948Ssaidi@eecs.umich.edu
2473349Sbinkertn@umich.edu        if (!misspeculating())
2482948Ssaidi@eecs.umich.edu            regs.intrlock = false;
2492948Ssaidi@eecs.umich.edu        break;
2505606Snate@binkert.org
2515336Shines@cs.fsu.edu      case AlphaISA::IPR_VA_FORM:
2523349Sbinkertn@umich.edu      case AlphaISA::IPR_MM_STAT:
2532948Ssaidi@eecs.umich.edu      case AlphaISA::IPR_IFAULT_VA_FORM:
2542948Ssaidi@eecs.umich.edu      case AlphaISA::IPR_EXC_MASK:
2552623SN/A      case AlphaISA::IPR_EXC_SUM:
2562623SN/A        retval = ipr[idx];
2572623SN/A        break;
2582623SN/A
2592623SN/A      case AlphaISA::IPR_DTB_PTE:
2602623SN/A        {
2612948Ssaidi@eecs.umich.edu            AlphaISA::PTE &pte = dtb->index(!misspeculating());
2622948Ssaidi@eecs.umich.edu
2632623SN/A            retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32;
2642623SN/A            retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8;
2652623SN/A            retval |= ((u_int64_t)pte.xwe & ULL(0xf)) << 12;
2662623SN/A            retval |= ((u_int64_t)pte.fonr & ULL(0x1)) << 1;
2673349Sbinkertn@umich.edu            retval |= ((u_int64_t)pte.fonw & ULL(0x1))<< 2;
2682623SN/A            retval |= ((u_int64_t)pte.asma & ULL(0x1)) << 4;
2692657Ssaidi@eecs.umich.edu            retval |= ((u_int64_t)pte.asn & ULL(0x7f)) << 57;
2702948Ssaidi@eecs.umich.edu        }
2712948Ssaidi@eecs.umich.edu        break;
2722948Ssaidi@eecs.umich.edu
2732948Ssaidi@eecs.umich.edu        // write only registers
2742948Ssaidi@eecs.umich.edu      case AlphaISA::IPR_HWINT_CLR:
2752948Ssaidi@eecs.umich.edu      case AlphaISA::IPR_SL_XMIT:
2762948Ssaidi@eecs.umich.edu      case AlphaISA::IPR_DC_FLUSH:
2775336Shines@cs.fsu.edu      case AlphaISA::IPR_IC_FLUSH:
2782948Ssaidi@eecs.umich.edu      case AlphaISA::IPR_ALT_MODE:
2792948Ssaidi@eecs.umich.edu      case AlphaISA::IPR_DTB_IA:
2802948Ssaidi@eecs.umich.edu      case AlphaISA::IPR_DTB_IAP:
2812948Ssaidi@eecs.umich.edu      case AlphaISA::IPR_ITB_IA:
2822623SN/A      case AlphaISA::IPR_ITB_IAP:
2832623SN/A        fault = Unimplemented_Opcode_Fault;
2842623SN/A        break;
2852623SN/A
2862623SN/A      default:
2872623SN/A        // invalid IPR
2882948Ssaidi@eecs.umich.edu        fault = Unimplemented_Opcode_Fault;
2892948Ssaidi@eecs.umich.edu        break;
2902623SN/A    }
2912623SN/A
2924192Sktlim@umich.edu    return retval;
2934192Sktlim@umich.edu}
2942623SN/A
2952623SN/A#ifdef DEBUG
2963349Sbinkertn@umich.edu// Cause the simulator to break when changing to the following IPL
2972623SN/Aint break_ipl = -1;
2982657Ssaidi@eecs.umich.edu#endif
2992948Ssaidi@eecs.umich.edu
3002948Ssaidi@eecs.umich.eduFault
3012948Ssaidi@eecs.umich.eduExecContext::setIpr(int idx, uint64_t val)
3022948Ssaidi@eecs.umich.edu{
3032948Ssaidi@eecs.umich.edu    uint64_t *ipr = regs.ipr;
3042948Ssaidi@eecs.umich.edu    uint64_t old;
3055336Shines@cs.fsu.edu
3062948Ssaidi@eecs.umich.edu    if (misspeculating())
3072948Ssaidi@eecs.umich.edu        return No_Fault;
3082948Ssaidi@eecs.umich.edu
3092948Ssaidi@eecs.umich.edu    switch (idx) {
3102623SN/A      case AlphaISA::IPR_PALtemp0:
3112623SN/A      case AlphaISA::IPR_PALtemp1:
3122623SN/A      case AlphaISA::IPR_PALtemp2:
3132623SN/A      case AlphaISA::IPR_PALtemp3:
3142623SN/A      case AlphaISA::IPR_PALtemp4:
3153349Sbinkertn@umich.edu      case AlphaISA::IPR_PALtemp5:
3163349Sbinkertn@umich.edu      case AlphaISA::IPR_PALtemp6:
3172623SN/A      case AlphaISA::IPR_PALtemp7:
3183222Sktlim@umich.edu      case AlphaISA::IPR_PALtemp8:
3193170Sstever@eecs.umich.edu      case AlphaISA::IPR_PALtemp9:
3202623SN/A      case AlphaISA::IPR_PALtemp10:
3212623SN/A      case AlphaISA::IPR_PALtemp11:
3222856Srdreslin@umich.edu      case AlphaISA::IPR_PALtemp12:
3232856Srdreslin@umich.edu      case AlphaISA::IPR_PALtemp13:
3242623SN/A      case AlphaISA::IPR_PALtemp14:
3252623SN/A      case AlphaISA::IPR_PALtemp15:
3262623SN/A      case AlphaISA::IPR_PALtemp16:
3272901Ssaidi@eecs.umich.edu      case AlphaISA::IPR_PALtemp17:
3282798Sktlim@umich.edu      case AlphaISA::IPR_PALtemp18:
3292798Sktlim@umich.edu      case AlphaISA::IPR_PALtemp19:
3302798Sktlim@umich.edu      case AlphaISA::IPR_PALtemp20:
3312623SN/A      case AlphaISA::IPR_PALtemp21:
3322623SN/A      case AlphaISA::IPR_PALtemp22:
3332623SN/A      case AlphaISA::IPR_PAL_BASE:
3342623SN/A      case AlphaISA::IPR_IC_PERR_STAT:
3352623SN/A      case AlphaISA::IPR_DC_PERR_STAT:
3362623SN/A      case AlphaISA::IPR_PMCTR:
3372623SN/A        // write entire quad w/ no side-effect
3382623SN/A        ipr[idx] = val;
3392623SN/A        break;
3402623SN/A
3412623SN/A      case AlphaISA::IPR_CC_CTL:
3422623SN/A        // This IPR resets the cycle counter.  We assume this only
3435894Sgblack@eecs.umich.edu        // happens once... let's verify that.
3443349Sbinkertn@umich.edu        assert(ipr[idx] == 0);
3455894Sgblack@eecs.umich.edu        ipr[idx] = 1;
3462644Sstever@eecs.umich.edu        break;
3474471Sstever@eecs.umich.edu
3485315Sstever@gmail.com      case AlphaISA::IPR_CC:
3495315Sstever@gmail.com        // This IPR only writes the upper 64 bits.  It's ok to write
3505315Sstever@gmail.com        // all 64 here since we mask out the lower 32 in rpcc (see
3515315Sstever@gmail.com        // isa_desc).
3525315Sstever@gmail.com        ipr[idx] = val;
3535315Sstever@gmail.com        break;
3542798Sktlim@umich.edu
3554471Sstever@eecs.umich.edu      case AlphaISA::IPR_PALtemp23:
3564471Sstever@eecs.umich.edu        // write entire quad w/ no side-effect
3575710Scws3k@cs.virginia.edu        old = ipr[idx];
3584471Sstever@eecs.umich.edu        ipr[idx] = val;
3595103Ssaidi@eecs.umich.edu        kernelStats.context(old, val);
3605103Ssaidi@eecs.umich.edu        break;
3615103Ssaidi@eecs.umich.edu
3625103Ssaidi@eecs.umich.edu      case AlphaISA::IPR_DTB_PTE:
3635103Ssaidi@eecs.umich.edu        // write entire quad w/ no side-effect, tag is forthcoming
3645336Shines@cs.fsu.edu        ipr[idx] = val;
3655103Ssaidi@eecs.umich.edu        break;
3665103Ssaidi@eecs.umich.edu
3672839Sktlim@umich.edu      case AlphaISA::IPR_EXC_ADDR:
3682623SN/A        // second least significant bit in PC is always zero
3692623SN/A        ipr[idx] = val & ~2;
3702623SN/A        break;
371
372      case AlphaISA::IPR_ASTRR:
373      case AlphaISA::IPR_ASTER:
374        // only write least significant four bits - privilege mask
375        ipr[idx] = val & 0xf;
376        break;
377
378      case AlphaISA::IPR_IPLR:
379#ifdef DEBUG
380        if (break_ipl != -1 && break_ipl == (val & 0x1f))
381            debug_break();
382#endif
383
384        // only write least significant five bits - interrupt level
385        ipr[idx] = val & 0x1f;
386        kernelStats.swpipl(ipr[idx]);
387        break;
388
389      case AlphaISA::IPR_DTB_CM:
390        kernelStats.mode((val & 0x18) != 0);
391
392      case AlphaISA::IPR_ICM:
393        // only write two mode bits - processor mode
394        ipr[idx] = val & 0x18;
395        break;
396
397      case AlphaISA::IPR_ALT_MODE:
398        // only write two mode bits - processor mode
399        ipr[idx] = val & 0x18;
400        break;
401
402      case AlphaISA::IPR_MCSR:
403        // more here after optimization...
404        ipr[idx] = val;
405        break;
406
407      case AlphaISA::IPR_SIRR:
408        // only write software interrupt mask
409        ipr[idx] = val & 0x7fff0;
410        break;
411
412      case AlphaISA::IPR_ICSR:
413        ipr[idx] = val & ULL(0xffffff0300);
414        break;
415
416      case AlphaISA::IPR_IVPTBR:
417      case AlphaISA::IPR_MVPTBR:
418        ipr[idx] = val & ULL(0xffffffffc0000000);
419        break;
420
421      case AlphaISA::IPR_DC_TEST_CTL:
422        ipr[idx] = val & 0x1ffb;
423        break;
424
425      case AlphaISA::IPR_DC_MODE:
426      case AlphaISA::IPR_MAF_MODE:
427        ipr[idx] = val & 0x3f;
428        break;
429
430      case AlphaISA::IPR_ITB_ASN:
431        ipr[idx] = val & 0x7f0;
432        break;
433
434      case AlphaISA::IPR_DTB_ASN:
435        ipr[idx] = val & ULL(0xfe00000000000000);
436        break;
437
438      case AlphaISA::IPR_EXC_SUM:
439      case AlphaISA::IPR_EXC_MASK:
440        // any write to this register clears it
441        ipr[idx] = 0;
442        break;
443
444      case AlphaISA::IPR_INTID:
445      case AlphaISA::IPR_SL_RCV:
446      case AlphaISA::IPR_MM_STAT:
447      case AlphaISA::IPR_ITB_PTE_TEMP:
448      case AlphaISA::IPR_DTB_PTE_TEMP:
449        // read-only registers
450        return Unimplemented_Opcode_Fault;
451
452      case AlphaISA::IPR_HWINT_CLR:
453      case AlphaISA::IPR_SL_XMIT:
454      case AlphaISA::IPR_DC_FLUSH:
455      case AlphaISA::IPR_IC_FLUSH:
456        // the following are write only
457        ipr[idx] = val;
458        break;
459
460      case AlphaISA::IPR_DTB_IA:
461        // really a control write
462        ipr[idx] = 0;
463
464        dtb->flushAll();
465        break;
466
467      case AlphaISA::IPR_DTB_IAP:
468        // really a control write
469        ipr[idx] = 0;
470
471        dtb->flushProcesses();
472        break;
473
474      case AlphaISA::IPR_DTB_IS:
475        // really a control write
476        ipr[idx] = val;
477
478        dtb->flushAddr(val, DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
479        break;
480
481      case AlphaISA::IPR_DTB_TAG: {
482          struct AlphaISA::PTE pte;
483
484          // FIXME: granularity hints NYI...
485          if (DTB_PTE_GH(ipr[AlphaISA::IPR_DTB_PTE]) != 0)
486              panic("PTE GH field != 0");
487
488          // write entire quad
489          ipr[idx] = val;
490
491          // construct PTE for new entry
492          pte.ppn = DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]);
493          pte.xre = DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]);
494          pte.xwe = DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]);
495          pte.fonr = DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]);
496          pte.fonw = DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]);
497          pte.asma = DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]);
498          pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]);
499
500          // insert new TAG/PTE value into data TLB
501          dtb->insert(val, pte);
502      }
503        break;
504
505      case AlphaISA::IPR_ITB_PTE: {
506          struct AlphaISA::PTE pte;
507
508          // FIXME: granularity hints NYI...
509          if (ITB_PTE_GH(val) != 0)
510              panic("PTE GH field != 0");
511
512          // write entire quad
513          ipr[idx] = val;
514
515          // construct PTE for new entry
516          pte.ppn = ITB_PTE_PPN(val);
517          pte.xre = ITB_PTE_XRE(val);
518          pte.xwe = 0;
519          pte.fonr = ITB_PTE_FONR(val);
520          pte.fonw = ITB_PTE_FONW(val);
521          pte.asma = ITB_PTE_ASMA(val);
522          pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]);
523
524          // insert new TAG/PTE value into data TLB
525          itb->insert(ipr[AlphaISA::IPR_ITB_TAG], pte);
526      }
527        break;
528
529      case AlphaISA::IPR_ITB_IA:
530        // really a control write
531        ipr[idx] = 0;
532
533        itb->flushAll();
534        break;
535
536      case AlphaISA::IPR_ITB_IAP:
537        // really a control write
538        ipr[idx] = 0;
539
540        itb->flushProcesses();
541        break;
542
543      case AlphaISA::IPR_ITB_IS:
544        // really a control write
545        ipr[idx] = val;
546
547        itb->flushAddr(val, ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]));
548        break;
549
550      default:
551        // invalid IPR
552        return Unimplemented_Opcode_Fault;
553    }
554
555    // no error...
556    return No_Fault;
557}
558
559/**
560 * Check for special simulator handling of specific PAL calls.
561 * If return value is false, actual PAL call will be suppressed.
562 */
563bool
564ExecContext::simPalCheck(int palFunc)
565{
566    kernelStats.callpal(palFunc);
567
568    switch (palFunc) {
569      case PAL::halt:
570        halt();
571        if (--System::numSystemsRunning == 0)
572            new SimExitEvent("all cpus halted");
573        break;
574
575      case PAL::bpt:
576      case PAL::bugchk:
577        if (system->breakpoint())
578            return false;
579        break;
580    }
581
582    return true;
583}
584
585#endif // FULL_SYSTEM
586