diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc index d00186d95..fb619d8b3 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -293,12 +293,11 @@ AlphaITB::regStats() void AlphaITB::fault(Addr pc, ExecContext *xc) const { - uint64_t *ipr = xc->regs.ipr; - if (!xc->misspeculating()) { - ipr[AlphaISA::IPR_ITB_TAG] = pc; - ipr[AlphaISA::IPR_IFAULT_VA_FORM] = - ipr[AlphaISA::IPR_IVPTBR] | (AlphaISA::VAddr(pc).vpn() << 3); + xc->setMiscReg(AlphaISA::IPR_ITB_TAG, pc); + xc->setMiscReg(AlphaISA::IPR_IFAULT_VA_FORM, + xc->readMiscReg(AlphaISA::IPR_IVPTBR) | + (AlphaISA::VAddr(pc).vpn() << 3)); } } @@ -306,7 +305,7 @@ AlphaITB::fault(Addr pc, ExecContext *xc) const Fault AlphaITB::translate(MemReqPtr &req) const { - InternalProcReg *ipr = req->xc->regs.ipr; + ExecContext *xc = req->xc; if (AlphaISA::PcPAL(req->vaddr)) { // strip off PAL PC marker (lsb is 1) @@ -329,13 +328,13 @@ AlphaITB::translate(MemReqPtr &req) const // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5 // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6 #if ALPHA_TLASER - if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && + if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && VAddrSpaceEV5(req->vaddr) == 2) { #else if (VAddrSpaceEV6(req->vaddr) == 0x7e) { #endif // only valid in kernel mode - if (ICM_CM(ipr[AlphaISA::IPR_ICM]) != + if (ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM)) != AlphaISA::mode_kernel) { fault(req->vaddr, req->xc); acv++; @@ -354,8 +353,9 @@ AlphaITB::translate(MemReqPtr &req) const } else { // not a physical address: need to look up pte + int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN)); AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->vaddr).vpn(), - DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + asn); if (!pte) { fault(req->vaddr, req->xc); @@ -367,7 +367,8 @@ AlphaITB::translate(MemReqPtr &req) const (AlphaISA::VAddr(req->vaddr).offset() & ~3); // check permissions for this access - if (!(pte->xre & (1 << ICM_CM(ipr[AlphaISA::IPR_ICM])))) { + if (!(pte->xre & + (1 << ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM))))) { // instruction access fault fault(req->vaddr, req->xc); acv++; @@ -469,7 +470,6 @@ AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const { ExecContext *xc = req->xc; AlphaISA::VAddr vaddr = req->vaddr; - uint64_t *ipr = xc->regs.ipr; // Set fault address and flags. Even though we're modeling an // EV5, we use the EV6 technique of not latching fault registers @@ -479,17 +479,17 @@ AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const if (!xc->misspeculating() && !(req->flags & VPTE) && !(req->flags & NO_FAULT)) { // set VA register with faulting address - ipr[AlphaISA::IPR_VA] = req->vaddr; + xc->setMiscReg(AlphaISA::IPR_VA, req->vaddr); // set MM_STAT register flags - ipr[AlphaISA::IPR_MM_STAT] = + xc->setMiscReg(AlphaISA::IPR_MM_STAT, (((Opcode(xc->getInst()) & 0x3f) << 11) | ((Ra(xc->getInst()) & 0x1f) << 6) - | (flags & 0x3f)); + | (flags & 0x3f))); // set VA_FORM register with faulting formatted address - ipr[AlphaISA::IPR_VA_FORM] = - ipr[AlphaISA::IPR_MVPTBR] | (vaddr.vpn() << 3); + xc->setMiscReg(AlphaISA::IPR_VA_FORM, + xc->readMiscReg(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3)); } } @@ -497,11 +497,11 @@ Fault AlphaDTB::translate(MemReqPtr &req, bool write) const { RegFile *regs = &req->xc->regs; + ExecContext *xc = req->xc; Addr pc = regs->pc; - InternalProcReg *ipr = regs->ipr; AlphaISA::mode_type mode = - (AlphaISA::mode_type)DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]); + (AlphaISA::mode_type)DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)); /** @@ -516,7 +516,8 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const if (pc & 0x1) { mode = (req->flags & ALTMODE) ? - (AlphaISA::mode_type)ALT_MODE_AM(ipr[AlphaISA::IPR_ALT_MODE]) + (AlphaISA::mode_type)ALT_MODE_AM( + xc->readMiscReg(AlphaISA::IPR_ALT_MODE)) : AlphaISA::mode_kernel; } @@ -535,14 +536,14 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const // Check for "superpage" mapping #if ALPHA_TLASER - if ((MCSR_SP(ipr[AlphaISA::IPR_MCSR]) & 2) && + if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && VAddrSpaceEV5(req->vaddr) == 2) { #else if (VAddrSpaceEV6(req->vaddr) == 0x7e) { #endif // only valid in kernel mode - if (DTB_CM_CM(ipr[AlphaISA::IPR_DTB_CM]) != + if (DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)) != AlphaISA::mode_kernel) { fault(req, ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK)); @@ -566,9 +567,11 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const else read_accesses++; + int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN)); + // not a physical address: need to look up pte AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->vaddr).vpn(), - DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + asn); if (!pte) { // page fault diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index 14b87b16f..f292c6c46 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -72,14 +72,14 @@ AlphaISA::swap_palshadow(RegFile *regs, bool use_shadow) void AlphaISA::initCPU(RegFile *regs, int cpuId) { - initIPRs(regs, cpuId); + initIPRs(®s->miscRegs, cpuId); // CPU comes up with PAL regs enabled swap_palshadow(regs, true); regs->intRegFile[16] = cpuId; regs->intRegFile[0] = cpuId; - regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr(ResetFault); + regs->pc = regs->miscRegs.readReg(IPR_PAL_BASE) + fault_addr(ResetFault); regs->npc = regs->pc + sizeof(MachInst); } @@ -109,14 +109,13 @@ const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = { // // void -AlphaISA::initIPRs(RegFile *regs, int cpuId) +AlphaISA::initIPRs(MiscRegFile *miscRegs, int cpuId) { - uint64_t *ipr = regs->ipr; + miscRegs->clearIprs(); - bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg)); - ipr[IPR_PAL_BASE] = PalBase; - ipr[IPR_MCSR] = 0x6; - ipr[IPR_PALtemp16] = cpuId; + miscRegs->setReg(IPR_PAL_BASE, PalBase); + miscRegs->setReg(IPR_MCSR, 0x6); + miscRegs->setReg(IPR_PALtemp16, cpuId); } @@ -128,17 +127,16 @@ AlphaISA::processInterrupts(CPU *cpu) //Handle the interrupts int ipl = 0; int summary = 0; - IntReg *ipr = cpu->getIprPtr(); cpu->checkInterrupts = false; - if (ipr[IPR_ASTRR]) + if (cpu->readMiscReg(IPR_ASTRR)) panic("asynchronous traps not implemented\n"); - if (ipr[IPR_SIRR]) { + if (cpu->readMiscReg(IPR_SIRR)) { for (int i = INTLEVEL_SOFTWARE_MIN; i < INTLEVEL_SOFTWARE_MAX; i++) { - if (ipr[IPR_SIRR] & (ULL(1) << i)) { + if (cpu->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { // See table 4-19 of the 21164 hardware reference ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; summary |= (ULL(1) << i); @@ -159,12 +157,12 @@ AlphaISA::processInterrupts(CPU *cpu) } } - if (ipl && ipl > ipr[IPR_IPLR]) { - ipr[IPR_ISR] = summary; - ipr[IPR_INTID] = ipl; + if (ipl && ipl > cpu->readMiscReg(IPR_IPLR)) { + cpu->setMiscReg(IPR_ISR, summary); + cpu->setMiscReg(IPR_INTID, ipl); cpu->trap(InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - ipr[IPR_IPLR], ipl, summary); + cpu->readMiscReg(IPR_IPLR), ipl, summary); } } @@ -192,22 +190,21 @@ ExecContext::ev5_trap(Fault fault) if (fault == ArithmeticFault) panic("Arithmetic traps are unimplemented!"); - AlphaISA::InternalProcReg *ipr = regs.ipr; - // exception restart address if (fault != InterruptFault || !inPalMode()) - ipr[AlphaISA::IPR_EXC_ADDR] = regs.pc; + setMiscReg(AlphaISA::IPR_EXC_ADDR, regs.pc); if (fault == PalFault || fault == ArithmeticFault /* || fault == InterruptFault && !inPalMode() */) { // traps... skip faulting instruction - ipr[AlphaISA::IPR_EXC_ADDR] += 4; + setMiscReg(AlphaISA::IPR_EXC_ADDR, + readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4); } if (!inPalMode()) AlphaISA::swap_palshadow(®s, true); - regs.pc = ipr[AlphaISA::IPR_PAL_BASE] + AlphaISA::fault_addr(fault); + regs.pc = readMiscReg(AlphaISA::IPR_PAL_BASE) + AlphaISA::fault_addr(fault); regs.npc = regs.pc + sizeof(MachInst); } @@ -215,7 +212,6 @@ ExecContext::ev5_trap(Fault fault) void AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) { - InternalProcReg *ipr = regs->ipr; bool use_pc = (fault == NoFault); if (fault == ArithmeticFault) @@ -224,17 +220,18 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) // compute exception restart address if (use_pc || fault == PalFault || fault == ArithmeticFault) { // traps... skip faulting instruction - ipr[IPR_EXC_ADDR] = regs->pc + 4; + regs->miscRegs.setReg(IPR_EXC_ADDR, regs->pc + 4); } else { // fault, post fault at excepting instruction - ipr[IPR_EXC_ADDR] = regs->pc; + regs->miscRegs.setReg(IPR_EXC_ADDR, regs->pc); } // jump to expection address (PAL PC bit set here as well...) if (!use_pc) - regs->npc = ipr[IPR_PAL_BASE] + fault_addr(fault); + regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + + fault_addr(fault); else - regs->npc = ipr[IPR_PAL_BASE] + pc; + regs->npc = regs->miscRegs.readReg(IPR_PAL_BASE) + pc; // that's it! (orders of magnitude less painful than x86) } @@ -242,17 +239,15 @@ AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc) Fault ExecContext::hwrei() { - uint64_t *ipr = regs.ipr; - if (!inPalMode()) return UnimplementedOpcodeFault; - setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); + setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR)); if (!misspeculating()) { kernelStats->hwrei(); - if ((ipr[AlphaISA::IPR_EXC_ADDR] & 1) == 0) + if ((readMiscReg(AlphaISA::IPR_EXC_ADDR) & 1) == 0) AlphaISA::swap_palshadow(®s, false); cpu->checkInterrupts = true; @@ -262,10 +257,15 @@ ExecContext::hwrei() return NoFault; } -uint64_t -ExecContext::readIpr(int idx, Fault &fault) +void +AlphaISA::MiscRegFile::clearIprs() +{ + bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg)); +} + +AlphaISA::MiscReg +AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc) { - uint64_t *ipr = regs.ipr; uint64_t retval = 0; // return value, default 0 switch (idx) { @@ -318,7 +318,7 @@ ExecContext::readIpr(int idx, Fault &fault) case AlphaISA::IPR_CC: retval |= ipr[idx] & ULL(0xffffffff00000000); - retval |= cpu->curCycle() & ULL(0x00000000ffffffff); + retval |= xc->cpu->curCycle() & ULL(0x00000000ffffffff); break; case AlphaISA::IPR_VA: @@ -335,7 +335,7 @@ ExecContext::readIpr(int idx, Fault &fault) case AlphaISA::IPR_DTB_PTE: { - AlphaISA::PTE &pte = dtb->index(!misspeculating()); + AlphaISA::PTE &pte = xc->dtb->index(!xc->misspeculating()); retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32; retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8; @@ -375,12 +375,11 @@ int break_ipl = -1; #endif Fault -ExecContext::setIpr(int idx, uint64_t val) +AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc) { - uint64_t *ipr = regs.ipr; uint64_t old; - if (misspeculating()) + if (xc->misspeculating()) return NoFault; switch (idx) { @@ -433,7 +432,7 @@ ExecContext::setIpr(int idx, uint64_t val) // write entire quad w/ no side-effect old = ipr[idx]; ipr[idx] = val; - kernelStats->context(old, val); + xc->kernelStats->context(old, val); break; case AlphaISA::IPR_DTB_PTE: @@ -460,14 +459,14 @@ ExecContext::setIpr(int idx, uint64_t val) // only write least significant five bits - interrupt level ipr[idx] = val & 0x1f; - kernelStats->swpipl(ipr[idx]); + xc->kernelStats->swpipl(ipr[idx]); break; case AlphaISA::IPR_DTB_CM: if (val & 0x18) - kernelStats->mode(Kernel::user); + xc->kernelStats->mode(Kernel::user); else - kernelStats->mode(Kernel::kernel); + xc->kernelStats->mode(Kernel::kernel); case AlphaISA::IPR_ICM: // only write two mode bits - processor mode @@ -541,21 +540,21 @@ ExecContext::setIpr(int idx, uint64_t val) // really a control write ipr[idx] = 0; - dtb->flushAll(); + xc->dtb->flushAll(); break; case AlphaISA::IPR_DTB_IAP: // really a control write ipr[idx] = 0; - dtb->flushProcesses(); + xc->dtb->flushProcesses(); break; case AlphaISA::IPR_DTB_IS: // really a control write ipr[idx] = val; - dtb->flushAddr(val, DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + xc->dtb->flushAddr(val, DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); break; case AlphaISA::IPR_DTB_TAG: { @@ -578,7 +577,7 @@ ExecContext::setIpr(int idx, uint64_t val) pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); // insert new TAG/PTE value into data TLB - dtb->insert(val, pte); + xc->dtb->insert(val, pte); } break; @@ -602,7 +601,7 @@ ExecContext::setIpr(int idx, uint64_t val) pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); // insert new TAG/PTE value into data TLB - itb->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); + xc->itb->insert(ipr[AlphaISA::IPR_ITB_TAG], pte); } break; @@ -610,21 +609,21 @@ ExecContext::setIpr(int idx, uint64_t val) // really a control write ipr[idx] = 0; - itb->flushAll(); + xc->itb->flushAll(); break; case AlphaISA::IPR_ITB_IAP: // really a control write ipr[idx] = 0; - itb->flushProcesses(); + xc->itb->flushProcesses(); break; case AlphaISA::IPR_ITB_IS: // really a control write ipr[idx] = val; - itb->flushAddr(val, ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); + xc->itb->flushAddr(val, ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); break; default: diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa index 37b15416b..c72f14a71 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -618,7 +618,7 @@ decode OPCODE default Unknown::unknown() { /* Rb is a fake dependency so here is a fun way to get * the parser to understand that. */ - Ra = xc->readIpr(AlphaISA::IPR_CC, fault) + (Rb & 0); + Ra = xc->readMiscRegWithEffect(AlphaISA::IPR_CC, fault) + (Rb & 0); #else Ra = curTick; @@ -670,7 +670,7 @@ decode OPCODE default Unknown::unknown() { 0x00: CallPal::call_pal({{ if (!palValid || (palPriv - && xc->readIpr(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { + && xc->readMiscRegWithEffect(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { // invalid pal function code, or attempt to do privileged // PAL call in non-kernel mode fault = UnimplementedOpcodeFault; @@ -682,8 +682,8 @@ decode OPCODE default Unknown::unknown() { if (dopal) { AlphaISA::swap_palshadow(&xc->xcBase()->regs, true); - xc->setIpr(AlphaISA::IPR_EXC_ADDR, NPC); - NPC = xc->readIpr(AlphaISA::IPR_PAL_BASE, fault) + palOffset; + xc->setMiscRegWithEffect(AlphaISA::IPR_EXC_ADDR, NPC); + NPC = xc->readMiscRegWithEffect(AlphaISA::IPR_PAL_BASE, fault) + palOffset; } } }}, IsNonSpeculative); @@ -732,7 +732,7 @@ decode OPCODE default Unknown::unknown() { fault = UnimplementedOpcodeFault; } else { - Ra = xc->readIpr(ipr_index, fault); + Ra = xc->readMiscRegWithEffect(ipr_index, fault); } }}); 0x1d: hw_mtpr({{ @@ -741,7 +741,7 @@ decode OPCODE default Unknown::unknown() { fault = UnimplementedOpcodeFault; } else { - xc->setIpr(ipr_index, Ra); + xc->setMiscRegWithEffect(ipr_index, Ra); if (traceData) { traceData->setData(Ra); } } }}); diff --git a/arch/alpha/isa/fp.isa b/arch/alpha/isa/fp.isa index 7e81fb830..20a564045 100644 --- a/arch/alpha/isa/fp.isa +++ b/arch/alpha/isa/fp.isa @@ -35,7 +35,7 @@ output exec {{ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) { Fault fault = NoFault; // dummy... this ipr access should not fault - if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) { + if (!EV5::ICSR_FPE(xc->readMiscRegWithEffect(AlphaISA::IPR_ICSR, fault))) { fault = FloatEnableFault; } return fault; @@ -217,7 +217,8 @@ def template FloatingPointExecute {{ if (roundingMode == Normal) { %(code)s; } else { - fesetround(getC99RoundingMode(xc->readFpcr())); + fesetround(getC99RoundingMode( + xc->readMiscReg(AlphaISA::Fpcr_DepTag))); %(code)s; fesetround(FE_TONEAREST); } diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index b8d03c0be..ad9c2a55e 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -161,8 +161,8 @@ def operands {{ 'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3), 'Mem': ('Mem', 'uq', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), 'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4), - 'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1), - 'FPCR': (' ControlReg', 'uq', 'Fpcr', None, 1), + 'Runiq': ('ControlReg', 'uq', 'TheISA::Uniq_DepTag', None, 1), + 'FPCR': (' ControlReg', 'uq', 'TheISA::Fpcr_DepTag', None, 1), # The next two are hacks for non-full-system call-pal emulation 'R0': ('IntReg', 'uq', '0', None, 1), 'R16': ('IntReg', 'uq', '16', None, 1), @@ -194,6 +194,8 @@ output header {{ FP_Base_DepTag = AlphaISA::FP_Base_DepTag, Fpcr_DepTag = AlphaISA::Fpcr_DepTag, Uniq_DepTag = AlphaISA::Uniq_DepTag, + Lock_Flag_DepTag = AlphaISA::Lock_Flag_DepTag, + Lock_Addr_DepTag = AlphaISA::Lock_Addr_DepTag, IPR_Base_DepTag = AlphaISA::IPR_Base_DepTag }; diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index f47e90f86..938ba696e 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -38,6 +38,7 @@ using namespace LittleEndianGuest; #include "sim/host.hh" #include "sim/faults.hh" +class ExecContext; class FastCPU; class FullCPU; class Checkpoint; @@ -64,6 +65,7 @@ namespace AlphaISA NumIntRegs = 32, NumFloatRegs = 32, + // @todo: Figure out what this number really should be. NumMiscRegs = 32, MaxRegsOfAnyType = 32, @@ -106,7 +108,9 @@ namespace AlphaISA Ctrl_Base_DepTag = 64, Fpcr_DepTag = 64, // floating point control register Uniq_DepTag = 65, - IPR_Base_DepTag = 66 + Lock_Flag_DepTag = 66, + Lock_Addr_DepTag = 67, + IPR_Base_DepTag = 68 }; typedef uint64_t IntReg; @@ -123,15 +127,6 @@ namespace AlphaISA double d[NumFloatRegs]; // double-precision floating point view } FloatRegFile; - // control register file contents - typedef uint64_t MiscReg; - typedef struct { - uint64_t fpcr; // floating point condition codes - uint64_t uniq; // process-unique register - bool lock_flag; // lock flag for LL/SC - Addr lock_addr; // lock address for LL/SC - } MiscRegFile; - extern const Addr PageShift; extern const Addr PageBytes; extern const Addr PageMask; @@ -149,6 +144,39 @@ extern const Addr PageOffset; }; #endif + // control register file contents + typedef uint64_t MiscReg; + class MiscRegFile { + protected: + uint64_t fpcr; // floating point condition codes + uint64_t uniq; // process-unique register + bool lock_flag; // lock flag for LL/SC + Addr lock_addr; // lock address for LL/SC + + public: + MiscReg readReg(int misc_reg); + + MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc); + + Fault setReg(int misc_reg, const MiscReg &val); + + Fault setRegWithEffect(int misc_reg, const MiscReg &val, + ExecContext *xc); + +#if FULL_SYSTEM + void clearIprs(); + + protected: + InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs + + private: + MiscReg readIpr(int idx, Fault &fault, ExecContext *xc); + + Fault setIpr(int idx, uint64_t val, ExecContext *xc); +#endif + friend class RegFile; + }; + enum { TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs + NumInternalProcRegs @@ -172,11 +200,12 @@ extern const Addr PageOffset; Addr npc; // next-cycle program counter #if FULL_SYSTEM IntReg palregs[NumIntRegs]; // PAL shadow registers - InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs int intrflag; // interrupt flag bool pal_shadow; // using pal_shadow registers - inline int instAsid() { return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } - inline int dataAsid() { return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } + inline int instAsid() + { return EV5::ITB_ASN_ASN(miscRegs.ipr[IPR_ITB_ASN]); } + inline int dataAsid() + { return EV5::DTB_ASN_ASN(miscRegs.ipr[IPR_DTB_ASN]); } #endif // FULL_SYSTEM void serialize(std::ostream &os); diff --git a/arch/alpha/stacktrace.cc b/arch/alpha/stacktrace.cc index 30ed07d9d..89b6b73a9 100644 --- a/arch/alpha/stacktrace.cc +++ b/arch/alpha/stacktrace.cc @@ -124,7 +124,7 @@ StackTrace::trace(ExecContext *_xc, bool is_call) { xc = _xc; - bool usermode = (xc->regs.ipr[AlphaISA::IPR_DTB_CM] & 0x18) != 0; + bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; Addr pc = xc->regs.npc; bool kernel = xc->system->kernelStart <= pc && pc <= xc->system->kernelEnd; @@ -196,22 +196,22 @@ StackTrace::trace(ExecContext *_xc, bool is_call) bool StackTrace::isEntry(Addr addr) { - if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp12]) + if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp12)) return true; - if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp7]) + if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp7)) return true; - if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp11]) + if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp11)) return true; - if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp21]) + if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp21)) return true; - if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp9]) + if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp9)) return true; - if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp2]) + if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp2)) return true; return false; diff --git a/arch/alpha/vtophys.cc b/arch/alpha/vtophys.cc index 3ffa4bd14..1d70196c5 100644 --- a/arch/alpha/vtophys.cc +++ b/arch/alpha/vtophys.cc @@ -82,7 +82,7 @@ Addr vtophys(ExecContext *xc, Addr addr) { AlphaISA::VAddr vaddr = addr; - Addr ptbr = xc->regs.ipr[AlphaISA::IPR_PALtemp20]; + Addr ptbr = xc->readMiscReg(AlphaISA::IPR_PALtemp20); Addr paddr = 0; //@todo Andrew couldn't remember why he commented some of this code //so I put it back in. Perhaps something to do with gdb debugging? diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 6508ca02a..5185ed573 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1263,10 +1263,10 @@ class ControlRegOperand(Operand): def makeConstructor(self): c = '' if self.is_src: - c += '\n\t_srcRegIdx[%d] = %s_DepTag;' % \ + c += '\n\t_srcRegIdx[%d] = %s;' % \ (self.src_reg_idx, self.reg_spec) if self.is_dest: - c += '\n\t_destRegIdx[%d] = %s_DepTag;' % \ + c += '\n\t_destRegIdx[%d] = %s;' % \ (self.dest_reg_idx, self.reg_spec) return c @@ -1274,7 +1274,7 @@ class ControlRegOperand(Operand): bit_select = 0 if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to read control register as FP') - base = 'xc->read%s()' % self.reg_spec + base = 'xc->readMiscReg(%s)' % self.reg_spec if self.size == self.dflt_size: return '%s = %s;\n' % (self.base_name, base) else: @@ -1284,7 +1284,7 @@ class ControlRegOperand(Operand): def makeWrite(self): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to write control register as FP') - wb = 'xc->set%s(%s);\n' % (self.reg_spec, self.base_name) + wb = 'xc->setMiscReg(%s, %s);\n' % (self.reg_spec, self.base_name) wb += 'if (traceData) { traceData->setData(%s); }' % \ self.base_name return wb diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc index 17ec21fed..5f1a2db2c 100644 --- a/base/remote_gdb.cc +++ b/base/remote_gdb.cc @@ -371,7 +371,7 @@ RemoteGDB::acc(Addr va, size_t len) if (AlphaISA::PcPAL(va) || va < 0x10000) return true; - Addr ptbr = context->regs.ipr[AlphaISA::IPR_PALtemp20]; + Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20); TheISA::PageTableEntry pte = kernel_pte_lookup(pmem, ptbr, va); if (!pte.valid()) { DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh index 3e0d77254..88b12c301 100644 --- a/cpu/exec_context.hh +++ b/cpu/exec_context.hh @@ -71,6 +71,7 @@ class ExecContext typedef TheISA::RegFile RegFile; typedef TheISA::MachInst MachInst; typedef TheISA::MiscRegFile MiscRegFile; + typedef TheISA::MiscReg MiscReg; public: enum Status { @@ -270,8 +271,8 @@ class ExecContext #if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { MiscRegFile *cregs = &req->xc->regs.miscRegs; - cregs->lock_addr = req->paddr; - cregs->lock_flag = true; + cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr); + cregs->setReg(TheISA::Lock_Flag_DepTag, true); } #endif @@ -297,10 +298,12 @@ class ExecContext req->result = 2; req->xc->storeCondFailures = 0;//Needed? [RGD] } else { - req->result = cregs->lock_flag; - if (!cregs->lock_flag || - ((cregs->lock_addr & ~0xf) != (req->paddr & ~0xf))) { - cregs->lock_flag = false; + bool lock_flag = cregs->readReg(TheISA::Lock_Flag_DepTag); + Addr lock_addr = cregs->readReg(TheISA::Lock_Addr_DepTag); + req->result = lock_flag; + if (!lock_flag || + ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { + cregs->setReg(TheISA::Lock_Flag_DepTag, false); if (((++req->xc->storeCondFailures) % 100000) == 0) { std::cerr << "Warning: " << req->xc->storeCondFailures @@ -321,8 +324,9 @@ class ExecContext // through. for (int i = 0; i < system->execContexts.size(); i++){ cregs = &system->execContexts[i]->regs.miscRegs; - if ((cregs->lock_addr & ~0xf) == (req->paddr & ~0xf)) { - cregs->lock_flag = false; + if ((cregs->readReg(TheISA::Lock_Addr_DepTag) & ~0xf) == + (req->paddr & ~0xf)) { + cregs->setReg(TheISA::Lock_Flag_DepTag, false); } } @@ -398,29 +402,27 @@ class ExecContext regs.npc = val; } - uint64_t readUniq() + MiscReg readMiscReg(int misc_reg) { - return regs.miscRegs.uniq; + return regs.miscRegs.readReg(misc_reg); } - void setUniq(uint64_t val) + MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) { - regs.miscRegs.uniq = val; + return regs.miscRegs.readRegWithEffect(misc_reg, fault, this); } - uint64_t readFpcr() + Fault setMiscReg(int misc_reg, const MiscReg &val) { - return regs.miscRegs.fpcr; + return regs.miscRegs.setReg(misc_reg, val); } - void setFpcr(uint64_t val) + Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) { - regs.miscRegs.fpcr = val; + return regs.miscRegs.setRegWithEffect(misc_reg, val, this); } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault); - Fault setIpr(int idx, uint64_t val); int readIntrFlag() { return regs.intrflag; } void setIntrFlag(int val) { regs.intrflag = val; } Fault hwrei(); diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh index b35bcf9e3..47ea532a6 100644 --- a/cpu/o3/alpha_cpu.hh +++ b/cpu/o3/alpha_cpu.hh @@ -41,6 +41,8 @@ class AlphaFullCPU : public FullO3CPU { protected: typedef TheISA::IntReg IntReg; + typedef TheISA::MiscReg MiscReg; + public: typedef typename Impl::Params Params; @@ -111,33 +113,24 @@ class AlphaFullCPU : public FullO3CPU // Later on may want to remove this misc stuff from the regfile and // have it handled at this level. Might prove to be an issue when // trying to rename source/destination registers... - uint64_t readUniq() + MiscReg readMiscReg(int misc_reg) { - return this->regFile.readUniq(); + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return 0; } - void setUniq(uint64_t val) + Fault setMiscReg(int misc_reg, const MiscReg &val) { - this->regFile.setUniq(val); - } - - uint64_t readFpcr() - { - return this->regFile.readFpcr(); - } - - void setFpcr(uint64_t val) - { - this->regFile.setFpcr(val); + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return NoFault; } // Most of the full system code and syscall emulation is not yet // implemented. These functions do show what the final interface will // look like. #if FULL_SYSTEM - uint64_t *getIpr(); - uint64_t readIpr(int idx, Fault &fault); - Fault setIpr(int idx, uint64_t val); int readIntrFlag(); void setIntrFlag(int val); Fault hwrei(); @@ -216,8 +209,8 @@ class AlphaFullCPU : public FullO3CPU #if FULL_SYSTEM && defined(TARGET_ALPHA) if (req->flags & LOCKED) { MiscRegFile *cregs = &req->xc->regs.miscRegs; - cregs->lock_addr = req->paddr; - cregs->lock_flag = true; + cregs->setReg(TheISA::Lock_Addr_DepTag, req->paddr); + cregs->setReg(TheISA::Lock_Flag_DepTag, true); } #endif @@ -242,22 +235,24 @@ class AlphaFullCPU : public FullO3CPU // If this is a store conditional, act appropriately if (req->flags & LOCKED) { - cregs = &this->xc->regs.miscRegs; + cregs = &req->xc->regs.miscRegs; if (req->flags & UNCACHEABLE) { // Don't update result register (see stq_c in isa_desc) req->result = 2; req->xc->storeCondFailures = 0;//Needed? [RGD] } else { - req->result = cregs->lock_flag; - if (!cregs->lock_flag || - ((cregs->lock_addr & ~0xf) != (req->paddr & ~0xf))) { - cregs->lock_flag = false; + bool lock_flag = cregs->readReg(TheISA::Lock_Flag_DepTag); + Addr lock_addr = cregs->readReg(TheISA::Lock_Addr_DepTag); + req->result = lock_flag; + if (!lock_flag || + ((lock_addr & ~0xf) != (req->paddr & ~0xf))) { + cregs->setReg(TheISA::Lock_Flag_DepTag, false); if (((++req->xc->storeCondFailures) % 100000) == 0) { std::cerr << "Warning: " << req->xc->storeCondFailures << " consecutive store conditional failures " - << "on cpu " << this->cpu_id + << "on cpu " << req->xc->cpu_id << std::endl; } return NoFault; @@ -273,8 +268,9 @@ class AlphaFullCPU : public FullO3CPU // through. for (int i = 0; i < this->system->execContexts.size(); i++){ cregs = &this->system->execContexts[i]->regs.miscRegs; - if ((cregs->lock_addr & ~0xf) == (req->paddr & ~0xf)) { - cregs->lock_flag = false; + if ((cregs->readReg(TheISA::Lock_Addr_DepTag) & ~0xf) == + (req->paddr & ~0xf)) { + cregs->setReg(TheISA::Lock_Flag_DepTag, false); } } diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh index 7ec1ba663..bd4e34914 100644 --- a/cpu/o3/alpha_cpu_impl.hh +++ b/cpu/o3/alpha_cpu_impl.hh @@ -179,12 +179,12 @@ AlphaFullCPU::copyToXC() this->xc->regs.floatRegFile.q[i] = this->regFile.readFloatRegInt(renamed_reg); } - +/* this->xc->regs.miscRegs.fpcr = this->regFile.miscRegs.fpcr; this->xc->regs.miscRegs.uniq = this->regFile.miscRegs.uniq; this->xc->regs.miscRegs.lock_flag = this->regFile.miscRegs.lock_flag; this->xc->regs.miscRegs.lock_addr = this->regFile.miscRegs.lock_addr; - +*/ this->xc->regs.pc = this->rob.readHeadPC(); this->xc->regs.npc = this->xc->regs.pc+4; @@ -221,13 +221,13 @@ AlphaFullCPU::copyFromXC() this->regFile.setFloatRegInt(renamed_reg, this->xc->regs.floatRegFile.q[i]); } - + /* // Then loop through the misc registers. this->regFile.miscRegs.fpcr = this->xc->regs.miscRegs.fpcr; this->regFile.miscRegs.uniq = this->xc->regs.miscRegs.uniq; this->regFile.miscRegs.lock_flag = this->xc->regs.miscRegs.lock_flag; this->regFile.miscRegs.lock_addr = this->xc->regs.miscRegs.lock_addr; - + */ // Then finally set the PC and the next PC. // regFile.pc = xc->regs.pc; // regFile.npc = xc->regs.npc; @@ -237,27 +237,6 @@ AlphaFullCPU::copyFromXC() #if FULL_SYSTEM -template -uint64_t * -AlphaFullCPU::getIpr() -{ - return this->regFile.getIpr(); -} - -template -uint64_t -AlphaFullCPU::readIpr(int idx, Fault &fault) -{ - return this->regFile.readIpr(idx, fault); -} - -template -Fault -AlphaFullCPU::setIpr(int idx, uint64_t val) -{ - return this->regFile.setIpr(idx, val); -} - template int AlphaFullCPU::readIntrFlag() @@ -277,16 +256,14 @@ template Fault AlphaFullCPU::hwrei() { - uint64_t *ipr = getIpr(); - if (!inPalMode()) return UnimplementedOpcodeFault; - this->setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]); + this->setNextPC(this->regFile.miscRegs.readReg(AlphaISA::IPR_EXC_ADDR)); // kernelStats.hwrei(); - if ((ipr[AlphaISA::IPR_EXC_ADDR] & 1) == 0) + if ((this->regFile.miscRegs.readReg(AlphaISA::IPR_EXC_ADDR) & 1) == 0) // AlphaISA::swap_palshadow(®s, false); this->checkInterrupts = true; @@ -337,22 +314,23 @@ AlphaFullCPU::trap(Fault fault) if (fault == ArithmeticFault) panic("Arithmetic traps are unimplemented!"); - AlphaISA::InternalProcReg *ipr = getIpr(); - // exception restart address - Get the commit PC if (fault != InterruptFault || !inPalMode(PC)) - ipr[AlphaISA::IPR_EXC_ADDR] = PC; + this->regFile.miscRegs.setReg(AlphaISA::IPR_EXC_ADDR, PC); if (fault == PalFault || fault == ArithmeticFault /* || fault == InterruptFault && !PC_PAL(regs.pc) */) { // traps... skip faulting instruction - ipr[AlphaISA::IPR_EXC_ADDR] += 4; + AlphaISA::MiscReg ipr_exc_addr = + this->regFile.miscRegs.readReg(AlphaISA::IPR_EXC_ADDR); + this->regFile.miscRegs.setReg(AlphaISA::IPR_EXC_ADDR, + ipr_exc_addr + 4); } if (!inPalMode(PC)) swapPALShadow(true); - this->regFile.setPC( ipr[AlphaISA::IPR_PAL_BASE] + + this->regFile.setPC(this->regFile.miscRegs.readReg(AlphaISA::IPR_PAL_BASE) + AlphaISA::fault_addr(fault) ); this->regFile.setNextPC(PC + sizeof(MachInst)); } diff --git a/cpu/o3/alpha_dyn_inst.hh b/cpu/o3/alpha_dyn_inst.hh index f282c287c..e7f7d3a57 100644 --- a/cpu/o3/alpha_dyn_inst.hh +++ b/cpu/o3/alpha_dyn_inst.hh @@ -54,6 +54,8 @@ class AlphaDynInst : public BaseDynInst typedef TheISA::RegIndex RegIndex; /** Integer register index type. */ typedef TheISA::IntReg IntReg; + /** Misc register index type. */ + typedef TheISA::MiscReg MiscReg; enum { MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs @@ -75,15 +77,35 @@ class AlphaDynInst : public BaseDynInst } public: - uint64_t readUniq(); - void setUniq(uint64_t val); + MiscReg readMiscReg(int misc_reg) + { + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return 0; + } - uint64_t readFpcr(); - void setFpcr(uint64_t val); + MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + { + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return 0; + } + + Fault setMiscReg(int misc_reg, const MiscReg &val) + { + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return NoFault; + } + + Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + { + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return NoFault; + } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault); - Fault setIpr(int idx, uint64_t val); Fault hwrei(); int readIntrFlag(); void setIntrFlag(int val); diff --git a/cpu/o3/alpha_dyn_inst_impl.hh b/cpu/o3/alpha_dyn_inst_impl.hh index eebe7675a..96b7d3430 100644 --- a/cpu/o3/alpha_dyn_inst_impl.hh +++ b/cpu/o3/alpha_dyn_inst_impl.hh @@ -67,49 +67,7 @@ AlphaDynInst::AlphaDynInst(StaticInstPtr &_staticInst) } } -template -uint64_t -AlphaDynInst::readUniq() -{ - return this->cpu->readUniq(); -} - -template -void -AlphaDynInst::setUniq(uint64_t val) -{ - this->cpu->setUniq(val); -} - -template -uint64_t -AlphaDynInst::readFpcr() -{ - return this->cpu->readFpcr(); -} - -template -void -AlphaDynInst::setFpcr(uint64_t val) -{ - this->cpu->setFpcr(val); -} - #if FULL_SYSTEM -template -uint64_t -AlphaDynInst::readIpr(int idx, Fault &fault) -{ - return this->cpu->readIpr(idx, fault); -} - -template -Fault -AlphaDynInst::setIpr(int idx, uint64_t val) -{ - return this->cpu->setIpr(idx, val); -} - template Fault AlphaDynInst::hwrei() diff --git a/cpu/o3/cpu.cc b/cpu/o3/cpu.cc index 706657887..a8c620028 100644 --- a/cpu/o3/cpu.cc +++ b/cpu/o3/cpu.cc @@ -264,13 +264,13 @@ FullO3CPU::init() regFile.floatRegFile[i].d = src_xc->regs.floatRegFile.d[i]; regFile.floatRegFile[i].q = src_xc->regs.floatRegFile.q[i]; } - +/* // Then loop through the misc registers. regFile.miscRegs.fpcr = src_xc->regs.miscRegs.fpcr; regFile.miscRegs.uniq = src_xc->regs.miscRegs.uniq; regFile.miscRegs.lock_flag = src_xc->regs.miscRegs.lock_flag; regFile.miscRegs.lock_addr = src_xc->regs.miscRegs.lock_addr; - +*/ // Then finally set the PC and the next PC. regFile.pc = src_xc->regs.pc; regFile.npc = src_xc->regs.npc; diff --git a/cpu/o3/cpu.hh b/cpu/o3/cpu.hh index 321d61dce..09d9c3d66 100644 --- a/cpu/o3/cpu.hh +++ b/cpu/o3/cpu.hh @@ -152,11 +152,11 @@ class FullO3CPU : public BaseFullCPU /** Get instruction asid. */ int getInstAsid() - { return ITB_ASN_ASN(regFile.getIpr()[TheISA::IPR_ITB_ASN]); } + { return ITB_ASN_ASN(regFile.miscRegs.readReg(TheISA::IPR_ITB_ASN)); } /** Get data asid. */ int getDataAsid() - { return DTB_ASN_ASN(regFile.getIpr()[TheISA::IPR_DTB_ASN]); } + { return DTB_ASN_ASN(regFile.miscRegs.readReg(TheISA::IPR_DTB_ASN)); } #else bool validInstAddr(Addr addr) { return thread[0]->validInstAddr(addr); } diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh index ee7b8858e..1bc7159f6 100644 --- a/cpu/o3/regfile.hh +++ b/cpu/o3/regfile.hh @@ -56,6 +56,8 @@ class PhysRegFile typedef TheISA::IntReg IntReg; typedef TheISA::FloatReg FloatReg; typedef TheISA::MiscRegFile MiscRegFile; + typedef TheISA::MiscReg MiscReg; + //Note that most of the definitions of the IntReg, FloatReg, etc. exist //within the Impl/ISA class and not within this PhysRegFile class. @@ -194,30 +196,21 @@ class PhysRegFile //Consider leaving this stuff and below in some implementation specific //file as opposed to the general register file. Or have a derived class. - uint64_t readUniq() + MiscReg readMiscReg(int misc_reg) { - return miscRegs.uniq; + // Dummy function for now. + // @todo: Fix this once proxy XC is used. + return 0; } - void setUniq(uint64_t val) + Fault setMiscReg(int misc_reg, const MiscReg &val) { - miscRegs.uniq = val; - } - - uint64_t readFpcr() - { - return miscRegs.fpcr; - } - - void setFpcr(uint64_t val) - { - miscRegs.fpcr = val; + // Dummy function for now. + // @todo: Fix this once proxy XC is used. + return NoFault; } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault); - Fault setIpr(int idx, uint64_t val); - InternalProcReg *getIpr() { return ipr; } int readIntrFlag() { return intrflag; } void setIntrFlag(int val) { intrflag = val; } #endif @@ -272,368 +265,4 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs, memset(floatRegFile, 0, sizeof(*floatRegFile)); } -#if FULL_SYSTEM - -//Problem: This code doesn't make sense at the RegFile level because it -//needs things such as the itb and dtb. Either put it at the CPU level or -//the DynInst level. -template -uint64_t -PhysRegFile::readIpr(int idx, Fault &fault) -{ - uint64_t retval = 0; // return value, default 0 - - switch (idx) { - case TheISA::IPR_PALtemp0: - case TheISA::IPR_PALtemp1: - case TheISA::IPR_PALtemp2: - case TheISA::IPR_PALtemp3: - case TheISA::IPR_PALtemp4: - case TheISA::IPR_PALtemp5: - case TheISA::IPR_PALtemp6: - case TheISA::IPR_PALtemp7: - case TheISA::IPR_PALtemp8: - case TheISA::IPR_PALtemp9: - case TheISA::IPR_PALtemp10: - case TheISA::IPR_PALtemp11: - case TheISA::IPR_PALtemp12: - case TheISA::IPR_PALtemp13: - case TheISA::IPR_PALtemp14: - case TheISA::IPR_PALtemp15: - case TheISA::IPR_PALtemp16: - case TheISA::IPR_PALtemp17: - case TheISA::IPR_PALtemp18: - case TheISA::IPR_PALtemp19: - case TheISA::IPR_PALtemp20: - case TheISA::IPR_PALtemp21: - case TheISA::IPR_PALtemp22: - case TheISA::IPR_PALtemp23: - case TheISA::IPR_PAL_BASE: - - case TheISA::IPR_IVPTBR: - case TheISA::IPR_DC_MODE: - case TheISA::IPR_MAF_MODE: - case TheISA::IPR_ISR: - case TheISA::IPR_EXC_ADDR: - case TheISA::IPR_IC_PERR_STAT: - case TheISA::IPR_DC_PERR_STAT: - case TheISA::IPR_MCSR: - case TheISA::IPR_ASTRR: - case TheISA::IPR_ASTER: - case TheISA::IPR_SIRR: - case TheISA::IPR_ICSR: - case TheISA::IPR_ICM: - case TheISA::IPR_DTB_CM: - case TheISA::IPR_IPLR: - case TheISA::IPR_INTID: - case TheISA::IPR_PMCTR: - // no side-effect - retval = ipr[idx]; - break; - - case TheISA::IPR_CC: - retval |= ipr[idx] & ULL(0xffffffff00000000); - retval |= curTick & ULL(0x00000000ffffffff); - break; - - case TheISA::IPR_VA: - retval = ipr[idx]; - break; - - case TheISA::IPR_VA_FORM: - case TheISA::IPR_MM_STAT: - case TheISA::IPR_IFAULT_VA_FORM: - case TheISA::IPR_EXC_MASK: - case TheISA::IPR_EXC_SUM: - retval = ipr[idx]; - break; - - case TheISA::IPR_DTB_PTE: - { - TheISA::PTE &pte = cpu->dtb->index(1); - - retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32; - retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8; - retval |= ((u_int64_t)pte.xwe & ULL(0xf)) << 12; - retval |= ((u_int64_t)pte.fonr & ULL(0x1)) << 1; - retval |= ((u_int64_t)pte.fonw & ULL(0x1))<< 2; - retval |= ((u_int64_t)pte.asma & ULL(0x1)) << 4; - retval |= ((u_int64_t)pte.asn & ULL(0x7f)) << 57; - } - break; - - // write only registers - case TheISA::IPR_HWINT_CLR: - case TheISA::IPR_SL_XMIT: - case TheISA::IPR_DC_FLUSH: - case TheISA::IPR_IC_FLUSH: - case TheISA::IPR_ALT_MODE: - case TheISA::IPR_DTB_IA: - case TheISA::IPR_DTB_IAP: - case TheISA::IPR_ITB_IA: - case TheISA::IPR_ITB_IAP: - fault = UnimplementedOpcodeFault; - break; - - default: - // invalid IPR - fault = UnimplementedOpcodeFault; - break; - } - - return retval; -} - -extern int break_ipl; - -template -Fault -PhysRegFile::setIpr(int idx, uint64_t val) -{ - uint64_t old; - - switch (idx) { - case TheISA::IPR_PALtemp0: - case TheISA::IPR_PALtemp1: - case TheISA::IPR_PALtemp2: - case TheISA::IPR_PALtemp3: - case TheISA::IPR_PALtemp4: - case TheISA::IPR_PALtemp5: - case TheISA::IPR_PALtemp6: - case TheISA::IPR_PALtemp7: - case TheISA::IPR_PALtemp8: - case TheISA::IPR_PALtemp9: - case TheISA::IPR_PALtemp10: - case TheISA::IPR_PALtemp11: - case TheISA::IPR_PALtemp12: - case TheISA::IPR_PALtemp13: - case TheISA::IPR_PALtemp14: - case TheISA::IPR_PALtemp15: - case TheISA::IPR_PALtemp16: - case TheISA::IPR_PALtemp17: - case TheISA::IPR_PALtemp18: - case TheISA::IPR_PALtemp19: - case TheISA::IPR_PALtemp20: - case TheISA::IPR_PALtemp21: - case TheISA::IPR_PALtemp22: - case TheISA::IPR_PAL_BASE: - case TheISA::IPR_IC_PERR_STAT: - case TheISA::IPR_DC_PERR_STAT: - case TheISA::IPR_PMCTR: - // write entire quad w/ no side-effect - ipr[idx] = val; - break; - - case TheISA::IPR_CC_CTL: - // This IPR resets the cycle counter. We assume this only - // happens once... let's verify that. - assert(ipr[idx] == 0); - ipr[idx] = 1; - break; - - case TheISA::IPR_CC: - // This IPR only writes the upper 64 bits. It's ok to write - // all 64 here since we mask out the lower 32 in rpcc (see - // isa_desc). - ipr[idx] = val; - break; - - case TheISA::IPR_PALtemp23: - // write entire quad w/ no side-effect - old = ipr[idx]; - ipr[idx] = val; - break; - - case TheISA::IPR_DTB_PTE: - // write entire quad w/ no side-effect, tag is forthcoming - ipr[idx] = val; - break; - - case TheISA::IPR_EXC_ADDR: - // second least significant bit in PC is always zero - ipr[idx] = val & ~2; - break; - - case TheISA::IPR_ASTRR: - case TheISA::IPR_ASTER: - // only write least significant four bits - privilege mask - ipr[idx] = val & 0xf; - break; - - case TheISA::IPR_IPLR: - // only write least significant five bits - interrupt level - ipr[idx] = val & 0x1f; - break; - - case TheISA::IPR_DTB_CM: - - case TheISA::IPR_ICM: - // only write two mode bits - processor mode - ipr[idx] = val & 0x18; - break; - - case TheISA::IPR_ALT_MODE: - // only write two mode bits - processor mode - ipr[idx] = val & 0x18; - break; - - case TheISA::IPR_MCSR: - // more here after optimization... - ipr[idx] = val; - break; - - case TheISA::IPR_SIRR: - // only write software interrupt mask - ipr[idx] = val & 0x7fff0; - break; - - case TheISA::IPR_ICSR: - ipr[idx] = val & ULL(0xffffff0300); - break; - - case TheISA::IPR_IVPTBR: - case TheISA::IPR_MVPTBR: - ipr[idx] = val & ULL(0xffffffffc0000000); - break; - - case TheISA::IPR_DC_TEST_CTL: - ipr[idx] = val & 0x1ffb; - break; - - case TheISA::IPR_DC_MODE: - case TheISA::IPR_MAF_MODE: - ipr[idx] = val & 0x3f; - break; - - case TheISA::IPR_ITB_ASN: - ipr[idx] = val & 0x7f0; - break; - - case TheISA::IPR_DTB_ASN: - ipr[idx] = val & ULL(0xfe00000000000000); - break; - - case TheISA::IPR_EXC_SUM: - case TheISA::IPR_EXC_MASK: - // any write to this register clears it - ipr[idx] = 0; - break; - - case TheISA::IPR_INTID: - case TheISA::IPR_SL_RCV: - case TheISA::IPR_MM_STAT: - case TheISA::IPR_ITB_PTE_TEMP: - case TheISA::IPR_DTB_PTE_TEMP: - // read-only registers - return UnimplementedOpcodeFault; - - case TheISA::IPR_HWINT_CLR: - case TheISA::IPR_SL_XMIT: - case TheISA::IPR_DC_FLUSH: - case TheISA::IPR_IC_FLUSH: - // the following are write only - ipr[idx] = val; - break; - - case TheISA::IPR_DTB_IA: - // really a control write - ipr[idx] = 0; - - cpu->dtb->flushAll(); - break; - - case TheISA::IPR_DTB_IAP: - // really a control write - ipr[idx] = 0; - - cpu->dtb->flushProcesses(); - break; - - case TheISA::IPR_DTB_IS: - // really a control write - ipr[idx] = val; - - cpu->dtb->flushAddr(val, DTB_ASN_ASN(ipr[TheISA::IPR_DTB_ASN])); - break; - - case TheISA::IPR_DTB_TAG: { - struct TheISA::PTE pte; - - // FIXME: granularity hints NYI... - if (DTB_PTE_GH(ipr[TheISA::IPR_DTB_PTE]) != 0) - panic("PTE GH field != 0"); - - // write entire quad - ipr[idx] = val; - - // construct PTE for new entry - pte.ppn = DTB_PTE_PPN(ipr[TheISA::IPR_DTB_PTE]); - pte.xre = DTB_PTE_XRE(ipr[TheISA::IPR_DTB_PTE]); - pte.xwe = DTB_PTE_XWE(ipr[TheISA::IPR_DTB_PTE]); - pte.fonr = DTB_PTE_FONR(ipr[TheISA::IPR_DTB_PTE]); - pte.fonw = DTB_PTE_FONW(ipr[TheISA::IPR_DTB_PTE]); - pte.asma = DTB_PTE_ASMA(ipr[TheISA::IPR_DTB_PTE]); - pte.asn = DTB_ASN_ASN(ipr[TheISA::IPR_DTB_ASN]); - - // insert new TAG/PTE value into data TLB - cpu->dtb->insert(val, pte); - } - break; - - case TheISA::IPR_ITB_PTE: { - struct TheISA::PTE pte; - - // FIXME: granularity hints NYI... - if (ITB_PTE_GH(val) != 0) - panic("PTE GH field != 0"); - - // write entire quad - ipr[idx] = val; - - // construct PTE for new entry - pte.ppn = ITB_PTE_PPN(val); - pte.xre = ITB_PTE_XRE(val); - pte.xwe = 0; - pte.fonr = ITB_PTE_FONR(val); - pte.fonw = ITB_PTE_FONW(val); - pte.asma = ITB_PTE_ASMA(val); - pte.asn = ITB_ASN_ASN(ipr[TheISA::IPR_ITB_ASN]); - - // insert new TAG/PTE value into data TLB - cpu->itb->insert(ipr[TheISA::IPR_ITB_TAG], pte); - } - break; - - case TheISA::IPR_ITB_IA: - // really a control write - ipr[idx] = 0; - - cpu->itb->flushAll(); - break; - - case TheISA::IPR_ITB_IAP: - // really a control write - ipr[idx] = 0; - - cpu->itb->flushProcesses(); - break; - - case TheISA::IPR_ITB_IS: - // really a control write - ipr[idx] = val; - - cpu->itb->flushAddr(val, ITB_ASN_ASN(ipr[TheISA::IPR_ITB_ASN])); - break; - - default: - // invalid IPR - return UnimplementedOpcodeFault; - } - - // no error... - return NoFault; -} - -#endif // #if FULL_SYSTEM - #endif // __CPU_O3_CPU_REGFILE_HH__ diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 944bdbb0a..dd2d53c17 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -659,12 +659,11 @@ SimpleCPU::tick() int ipl = 0; int summary = 0; checkInterrupts = false; - IntReg *ipr = xc->regs.ipr; - if (xc->regs.ipr[IPR_SIRR]) { + if (xc->readMiscReg(IPR_SIRR)) { for (int i = INTLEVEL_SOFTWARE_MIN; i < INTLEVEL_SOFTWARE_MAX; i++) { - if (ipr[IPR_SIRR] & (ULL(1) << i)) { + if (xc->readMiscReg(IPR_SIRR) & (ULL(1) << i)) { // See table 4-19 of 21164 hardware reference ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; summary |= (ULL(1) << i); @@ -682,16 +681,16 @@ SimpleCPU::tick() } } - if (ipr[IPR_ASTRR]) + if (xc->readMiscReg(IPR_ASTRR)) panic("asynchronous traps not implemented\n"); - if (ipl && ipl > xc->regs.ipr[IPR_IPLR]) { - ipr[IPR_ISR] = summary; - ipr[IPR_INTID] = ipl; + if (ipl && ipl > xc->readMiscReg(IPR_IPLR)) { + xc->setMiscReg(IPR_ISR, summary); + xc->setMiscReg(IPR_INTID, ipl); xc->ev5_trap(InterruptFault); DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - ipr[IPR_IPLR], ipl, summary); + xc->readMiscReg(IPR_IPLR), ipl, summary); } } #endif @@ -782,7 +781,7 @@ SimpleCPU::tick() } if (xc->profile) { - bool usermode = (xc->regs.ipr[AlphaISA::IPR_DTB_CM] & 0x18) != 0; + bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0; xc->profilePC = usermode ? 1 : xc->regs.pc; ProfileNode *node = xc->profile->consume(xc, inst); if (node) diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index ed7b1e29b..3bc905be1 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -65,6 +65,7 @@ class SimpleCPU : public BaseCPU { protected: typedef TheISA::MachInst MachInst; + typedef TheISA::MiscReg MiscReg; public: // main simulation loop (one cycle) void tick(); @@ -321,15 +322,27 @@ class SimpleCPU : public BaseCPU uint64_t readPC() { return xc->readPC(); } void setNextPC(uint64_t val) { xc->setNextPC(val); } - uint64_t readUniq() { return xc->readUniq(); } - void setUniq(uint64_t val) { xc->setUniq(val); } + MiscReg readMiscReg(int misc_reg) + { + return xc->readMiscReg(misc_reg); + } - uint64_t readFpcr() { return xc->readFpcr(); } - void setFpcr(uint64_t val) { xc->setFpcr(val); } + MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + { + return xc->readMiscRegWithEffect(misc_reg, fault); + } + + Fault setMiscReg(int misc_reg, const MiscReg &val) + { + return xc->setMiscReg(misc_reg, val); + } + + Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val) + { + return xc->setMiscRegWithEffect(misc_reg, val); + } #if FULL_SYSTEM - uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); } - Fault setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); } Fault hwrei() { return xc->hwrei(); } int readIntrFlag() { return xc->readIntrFlag(); } void setIntrFlag(int val) { xc->setIntrFlag(val); } diff --git a/dev/sinic.cc b/dev/sinic.cc index c499d2f49..84f5c70df 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -376,7 +376,7 @@ Device::read(MemReqPtr &req, uint8_t *data) Fault Device::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data) { - int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff; + int cpu = (req->xc->readMiscReg(TheISA::IPR_PALtemp16) >> 8) & 0xff; Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; @@ -472,7 +472,7 @@ Device::write(MemReqPtr &req, const uint8_t *data) Fault Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) { - int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff; + int cpu = (req->xc->readMiscReg(TheISA::IPR_PALtemp16) >> 8) & 0xff; Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc index 50bbaee00..3beeaa14a 100644 --- a/kern/kernel_stats.cc +++ b/kern/kernel_stats.cc @@ -240,7 +240,7 @@ Statistics::swpipl(int ipl) void Statistics::mode(cpu_mode newmode) { - Addr pcbb = xc->regs.ipr[AlphaISA::IPR_PALtemp23]; + Addr pcbb = xc->readMiscReg(AlphaISA::IPR_PALtemp23); if ((newmode == kernel || newmode == interrupt) && pcbb == idleProcess) diff --git a/kern/system_events.cc b/kern/system_events.cc index 55595b9b6..91625e60a 100644 --- a/kern/system_events.cc +++ b/kern/system_events.cc @@ -67,7 +67,7 @@ FnEvent::process(ExecContext *xc) void IdleStartEvent::process(ExecContext *xc) { - xc->kernelStats->setIdleProcess(xc->regs.ipr[AlphaISA::IPR_PALtemp23]); + xc->kernelStats->setIdleProcess(xc->readMiscReg(AlphaISA::IPR_PALtemp23)); remove(); } diff --git a/kern/tru64/tru64.hh b/kern/tru64/tru64.hh index 1579a54d8..ad568cb0c 100644 --- a/kern/tru64/tru64.hh +++ b/kern/tru64/tru64.hh @@ -729,7 +729,7 @@ class Tru64 { regs->floatRegFile.q[i] = htog(sc->sc_fpregs[i]); } - regs->miscRegs.fpcr = htog(sc->sc_fpcr); + xc->setMiscReg(TheISA::Fpcr_DepTag, htog(sc->sc_fpcr)); return 0; } @@ -889,7 +889,7 @@ class Tru64 { ssp->nxm_sysevent = htog(0); if (i == 0) { - uint64_t uniq = xc->regs.miscRegs.uniq; + uint64_t uniq = xc->readMiscReg(TheISA::Uniq_DepTag); ssp->nxm_u.pth_id = htog(uniq + gtoh(attrp->nxm_uniq_offset)); ssp->nxm_u.nxm_active = htog(uniq | 1); } @@ -924,7 +924,7 @@ class Tru64 { ec->regs.intRegFile[TheISA::ArgumentReg0] = gtoh(attrp->registers.a0); ec->regs.intRegFile[27/*t12*/] = gtoh(attrp->registers.pc); ec->regs.intRegFile[TheISA::StackPointerReg] = gtoh(attrp->registers.sp); - ec->regs.miscRegs.uniq = uniq_val; + ec->setMiscReg(TheISA::Uniq_DepTag, uniq_val); ec->regs.pc = gtoh(attrp->registers.pc); ec->regs.npc = gtoh(attrp->registers.pc) + sizeof(TheISA::MachInst);