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(®s, 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(®s, 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