From: Kevin Lim Date: Mon, 27 Feb 2006 16:44:35 +0000 (-0500) Subject: Changes to put all the misc regs within the misc reg file. This includes the FPCR... X-Git-Tag: m5_2.0_beta1~87^2~35^2~1^2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=70b35bab5778799805fe9b6040b23eb1885dbfc3;p=gem5.git Changes to put all the misc regs within the misc reg file. This includes the FPCR, Uniq, lock flag, lock addr, and IPRs. They are now accessed by calling readMiscReg()/setMiscReg() on the XC. Old IPR accesses are supported by using readMiscRegWithEffect() and setMiscRegWithEffect() (names may change in the future). arch/alpha/alpha_memory.cc: Change accesses to IPR to go through the XC. arch/alpha/ev5.cc: Change accesses for IPRs to go through the misc regs. arch/alpha/isa/decoder.isa: Change accesses to IPRs to go through the misc regs. readIpr() and setIpr() are now changed to calls to readMiscRegWithEffect() and setMiscRegWithEffect(). arch/alpha/isa/fp.isa: Change accesses to IPRs and Fpcr to go through the misc regs. arch/alpha/isa/main.isa: Add support for all misc regs being accessed through readMiscReg() and setMiscReg(). Instead of readUniq and readFpcr, they are replaced by calls with Uniq_DepTag and Fpcr_DepTag passed in as the register index. arch/alpha/isa_traits.hh: Change the MiscRegFile to a class that handles all accesses to MiscRegs, which in Alpha include the FPCR, Uniq, Lock Addr, Lock Flag, and IPRs. Two flavors of accesses are supported: normal register reads/writes, and reads/writes with effect. The latter are basically the original read/write IPR functions, while the former are normal reads/writes. The lock flag and lock addr registers are added to the dependence tags in order to support being accessed through the misc regs. arch/alpha/stacktrace.cc: cpu/simple/cpu.cc: dev/sinic.cc: Change accesses to the IPRs to go through the XC. arch/alpha/vtophys.cc: Change access to the IPR to go through the XC. arch/isa_parser.py: Change generation of code for control registers to use the readMiscReg and setMiscReg functions. base/remote_gdb.cc: Change accesses to the IPR to go through the XC. cpu/exec_context.hh: Use the miscRegs to access the lock addr, lock flag, and other misc registers. cpu/o3/alpha_cpu.hh: cpu/simple/cpu.hh: Support interface for reading and writing misc registers, which replaces readUniq, readFpcr, readIpr, and their set functions. cpu/o3/alpha_cpu_impl.hh: Change accesses to the IPRs to go through the miscRegs. For now comment out some of the accesses to the misc regs until the proxy exec context is completed. cpu/o3/alpha_dyn_inst.hh: Change accesses to misc regs to use readMiscReg and setMiscReg. cpu/o3/alpha_dyn_inst_impl.hh: Remove old misc reg accessors. cpu/o3/cpu.cc: Comment out old misc reg accesses until the proxy exec context is completed. cpu/o3/cpu.hh: Change accesses to the misc regs. cpu/o3/regfile.hh: Remove old access methods for the misc regs, replace them with readMiscReg and setMiscReg. They are dummy functions for now until the proxy exec context is completed. kern/kernel_stats.cc: kern/system_events.cc: Have accesses to the IPRs go through the XC. kern/tru64/tru64.hh: Have accesses to the misc regs use the new access methods. --HG-- extra : convert_revision : e32e0a3fe99522e17294bbe106ff5591cb1a9d76 --- 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() - { - return this->regFile.readUniq(); - } - - void setUniq(uint64_t val) + MiscReg readMiscReg(int misc_reg) { - this->regFile.setUniq(val); + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return 0; } - uint64_t readFpcr() + Fault setMiscReg(int misc_reg, const MiscReg &val) { - 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; + } + + MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + { + // Dummy function for now. + // @todo: Fix this once reg file gets fixed. + return 0; + } - uint64_t readFpcr(); - void setFpcr(uint64_t val); + 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() - { - return miscRegs.uniq; - } - - void setUniq(uint64_t val) - { - miscRegs.uniq = val; - } - - uint64_t readFpcr() + MiscReg readMiscReg(int misc_reg) { - return miscRegs.fpcr; + // Dummy function for now. + // @todo: Fix this once proxy XC is used. + return 0; } - void setFpcr(uint64_t val) + Fault setMiscReg(int misc_reg, const MiscReg &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); + } + + MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault) + { + return xc->readMiscRegWithEffect(misc_reg, fault); + } - uint64_t readFpcr() { return xc->readFpcr(); } - void setFpcr(uint64_t val) { xc->setFpcr(val); } + 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);