diff options
Diffstat (limited to 'src/arch/alpha')
66 files changed, 3080 insertions, 2705 deletions
diff --git a/src/arch/alpha/AlphaInterrupts.py b/src/arch/alpha/AlphaInterrupts.py new file mode 100644 index 000000000..ecfcf5c21 --- /dev/null +++ b/src/arch/alpha/AlphaInterrupts.py @@ -0,0 +1,33 @@ +# Copyright (c) 2008 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +from m5.SimObject import SimObject + +class AlphaInterrupts(SimObject): + type = 'AlphaInterrupts' + cxx_class = 'AlphaISA::Interrupts' diff --git a/src/arch/alpha/AlphaTLB.py b/src/arch/alpha/AlphaTLB.py index fec245b75..099327470 100644 --- a/src/arch/alpha/AlphaTLB.py +++ b/src/arch/alpha/AlphaTLB.py @@ -28,21 +28,20 @@ from m5.SimObject import SimObject from m5.params import * -class AlphaTLB(SimObject): + +from BaseTLB import BaseTLB + +class AlphaTLB(BaseTLB): type = 'AlphaTLB' abstract = True size = Param.Int("TLB size") class AlphaDTB(AlphaTLB): type = 'AlphaDTB' - cxx_namespace = 'AlphaISA' - cxx_class = 'DTB' - + cxx_class = 'AlphaISA::DTB' size = 64 class AlphaITB(AlphaTLB): type = 'AlphaITB' - cxx_namespace = 'AlphaISA' - cxx_class = 'ITB' - + cxx_class = 'AlphaISA::ITB' size = 48 diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript index 04bac3996..069db2551 100644 --- a/src/arch/alpha/SConscript +++ b/src/arch/alpha/SConscript @@ -47,9 +47,11 @@ if env['TARGET_ISA'] == 'alpha': SimObject('AlphaTLB.py') if env['FULL_SYSTEM']: + SimObject('AlphaInterrupts.py') SimObject('AlphaSystem.py') Source('idle_event.cc') + Source('interrupts.cc') Source('kernel_stats.cc') Source('osfpal.cc') Source('stacktrace.cc') diff --git a/src/arch/alpha/SConsopts b/src/arch/alpha/SConsopts index 633eeb06f..b418e27c8 100644 --- a/src/arch/alpha/SConsopts +++ b/src/arch/alpha/SConsopts @@ -33,5 +33,5 @@ Import('*') all_isa_list.append('alpha') # Alpha can be compiled with Turbolaser support instead of Tsunami -sticky_opts.Add(BoolOption('ALPHA_TLASER', +sticky_vars.Add(BoolVariable('ALPHA_TLASER', 'Model Alpha TurboLaser platform (vs. Tsunami)', False)) diff --git a/src/arch/alpha/aout_machdep.h b/src/arch/alpha/aout_machdep.h index 58991256a..bcf004d05 100644 --- a/src/arch/alpha/aout_machdep.h +++ b/src/arch/alpha/aout_machdep.h @@ -36,35 +36,35 @@ /// Funky Alpha 64-bit a.out header used for PAL code. /// struct aout_exechdr { - uint16_t magic; ///< magic number - uint16_t vstamp; ///< version stamp? - uint16_t bldrev; ///< ??? - uint16_t padcell; ///< padding - uint64_t tsize; ///< text segment size - uint64_t dsize; ///< data segment size - uint64_t bsize; ///< bss segment size - uint64_t entry; ///< entry point - uint64_t text_start; ///< text base address - uint64_t data_start; ///< data base address - uint64_t bss_start; ///< bss base address - uint32_t gprmask; ///< GPR mask (unused, AFAIK) - uint32_t fprmask; ///< FPR mask (unused, AFAIK) - uint64_t gp_value; ///< global pointer reg value + uint16_t magic; ///< magic number + uint16_t vstamp; ///< version stamp? + uint16_t bldrev; ///< ??? + uint16_t padcell; ///< padding + uint64_t tsize; ///< text segment size + uint64_t dsize; ///< data segment size + uint64_t bsize; ///< bss segment size + uint64_t entry; ///< entry point + uint64_t text_start; ///< text base address + uint64_t data_start; ///< data base address + uint64_t bss_start; ///< bss base address + uint32_t gprmask; ///< GPR mask (unused, AFAIK) + uint32_t fprmask; ///< FPR mask (unused, AFAIK) + uint64_t gp_value; ///< global pointer reg value }; -#define AOUT_LDPGSZ 8192 +#define AOUT_LDPGSZ 8192 -#define N_GETMAGIC(ex) ((ex).magic) +#define N_GETMAGIC(ex) ((ex).magic) #define N_BADMAX -#define N_TXTADDR(ex) ((ex).text_start) -#define N_DATADDR(ex) ((ex).data_start) -#define N_BSSADDR(ex) ((ex).bss_start) +#define N_TXTADDR(ex) ((ex).text_start) +#define N_DATADDR(ex) ((ex).data_start) +#define N_BSSADDR(ex) ((ex).bss_start) -#define N_TXTOFF(ex) \ +#define N_TXTOFF(ex) \ (N_GETMAGIC(ex) == ZMAGIC ? 0 : sizeof(struct aout_exechdr)) -#define N_DATOFF(ex) N_ALIGN(ex, N_TXTOFF(ex) + (ex).tsize) +#define N_DATOFF(ex) N_ALIGN(ex, N_TXTOFF(ex) + (ex).tsize) #endif /* !__AOUT_MACHDEP_H__*/ diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 5dc49623e..02497e282 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -35,32 +35,33 @@ #include "arch/alpha/osfpal.hh" #include "arch/alpha/tlb.hh" #include "arch/alpha/kgdb.h" +#include "base/cp_annotate.hh" +#include "base/debug.hh" #include "base/remote_gdb.hh" #include "base/stats/events.hh" #include "config/full_system.hh" #include "cpu/base.hh" #include "cpu/simple_thread.hh" #include "cpu/thread_context.hh" -#include "sim/debug.hh" #include "sim/sim_exit.hh" -#if FULL_SYSTEM +namespace AlphaISA { -using namespace EV5; +#if FULL_SYSTEM //////////////////////////////////////////////////////////////////////// // // Machine dependent functions // void -AlphaISA::initCPU(ThreadContext *tc, int cpuId) +initCPU(ThreadContext *tc, int cpuId) { initIPRs(tc, cpuId); tc->setIntReg(16, cpuId); tc->setIntReg(0, cpuId); - AlphaISA::AlphaFault *reset = new AlphaISA::ResetFault; + AlphaFault *reset = new ResetFault; tc->setPC(tc->readMiscRegNoEffect(IPR_PAL_BASE) + reset->vect()); tc->setNextPC(tc->readPC() + sizeof(MachInst)); @@ -71,7 +72,7 @@ AlphaISA::initCPU(ThreadContext *tc, int cpuId) template <class CPU> void -AlphaISA::processInterrupts(CPU *cpu) +processInterrupts(CPU *cpu) { //Check if there are any outstanding interrupts //Handle the interrupts @@ -117,7 +118,7 @@ AlphaISA::processInterrupts(CPU *cpu) template <class CPU> void -AlphaISA::zeroRegisters(CPU *cpu) +zeroRegisters(CPU *cpu) { // Insure ISA semantics // (no longer very clean due to the change in setIntReg() in the @@ -126,33 +127,16 @@ AlphaISA::zeroRegisters(CPU *cpu) cpu->thread->setFloatReg(ZeroReg, 0.0); } -Fault -SimpleThread::hwrei() -{ - if (!(readPC() & 0x3)) - return new UnimplementedOpcodeFault; - - setNextPC(readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR)); - - if (!misspeculating()) { - if (kernelStats) - kernelStats->hwrei(); - } - - // FIXME: XXX check for interrupts? XXX - return NoFault; -} - int -AlphaISA::MiscRegFile::getInstAsid() +MiscRegFile::getInstAsid() { - return EV5::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); + return ITB_ASN_ASN(ipr[IPR_ITB_ASN]); } int -AlphaISA::MiscRegFile::getDataAsid() +MiscRegFile::getDataAsid() { - return EV5::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); + return DTB_ASN_ASN(ipr[IPR_DTB_ASN]); } #endif @@ -162,90 +146,90 @@ AlphaISA::MiscRegFile::getDataAsid() // // void -AlphaISA::initIPRs(ThreadContext *tc, int cpuId) +initIPRs(ThreadContext *tc, int cpuId) { for (int i = 0; i < NumInternalProcRegs; ++i) { tc->setMiscRegNoEffect(i, 0); } - tc->setMiscRegNoEffect(IPR_PAL_BASE, EV5::PalBase); + tc->setMiscRegNoEffect(IPR_PAL_BASE, PalBase); tc->setMiscRegNoEffect(IPR_MCSR, 0x6); tc->setMiscRegNoEffect(IPR_PALtemp16, cpuId); } -AlphaISA::MiscReg -AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc) +MiscReg +MiscRegFile::readIpr(int idx, ThreadContext *tc) { - uint64_t retval = 0; // return value, default 0 + uint64_t retval = 0; // return value, default 0 switch (idx) { - case AlphaISA::IPR_PALtemp0: - case AlphaISA::IPR_PALtemp1: - case AlphaISA::IPR_PALtemp2: - case AlphaISA::IPR_PALtemp3: - case AlphaISA::IPR_PALtemp4: - case AlphaISA::IPR_PALtemp5: - case AlphaISA::IPR_PALtemp6: - case AlphaISA::IPR_PALtemp7: - case AlphaISA::IPR_PALtemp8: - case AlphaISA::IPR_PALtemp9: - case AlphaISA::IPR_PALtemp10: - case AlphaISA::IPR_PALtemp11: - case AlphaISA::IPR_PALtemp12: - case AlphaISA::IPR_PALtemp13: - case AlphaISA::IPR_PALtemp14: - case AlphaISA::IPR_PALtemp15: - case AlphaISA::IPR_PALtemp16: - case AlphaISA::IPR_PALtemp17: - case AlphaISA::IPR_PALtemp18: - case AlphaISA::IPR_PALtemp19: - case AlphaISA::IPR_PALtemp20: - case AlphaISA::IPR_PALtemp21: - case AlphaISA::IPR_PALtemp22: - case AlphaISA::IPR_PALtemp23: - case AlphaISA::IPR_PAL_BASE: - - case AlphaISA::IPR_IVPTBR: - case AlphaISA::IPR_DC_MODE: - case AlphaISA::IPR_MAF_MODE: - case AlphaISA::IPR_ISR: - case AlphaISA::IPR_EXC_ADDR: - case AlphaISA::IPR_IC_PERR_STAT: - case AlphaISA::IPR_DC_PERR_STAT: - case AlphaISA::IPR_MCSR: - case AlphaISA::IPR_ASTRR: - case AlphaISA::IPR_ASTER: - case AlphaISA::IPR_SIRR: - case AlphaISA::IPR_ICSR: - case AlphaISA::IPR_ICM: - case AlphaISA::IPR_DTB_CM: - case AlphaISA::IPR_IPLR: - case AlphaISA::IPR_INTID: - case AlphaISA::IPR_PMCTR: + case IPR_PALtemp0: + case IPR_PALtemp1: + case IPR_PALtemp2: + case IPR_PALtemp3: + case IPR_PALtemp4: + case IPR_PALtemp5: + case IPR_PALtemp6: + case IPR_PALtemp7: + case IPR_PALtemp8: + case IPR_PALtemp9: + case IPR_PALtemp10: + case IPR_PALtemp11: + case IPR_PALtemp12: + case IPR_PALtemp13: + case IPR_PALtemp14: + case IPR_PALtemp15: + case IPR_PALtemp16: + case IPR_PALtemp17: + case IPR_PALtemp18: + case IPR_PALtemp19: + case IPR_PALtemp20: + case IPR_PALtemp21: + case IPR_PALtemp22: + case IPR_PALtemp23: + case IPR_PAL_BASE: + + case IPR_IVPTBR: + case IPR_DC_MODE: + case IPR_MAF_MODE: + case IPR_ISR: + case IPR_EXC_ADDR: + case IPR_IC_PERR_STAT: + case IPR_DC_PERR_STAT: + case IPR_MCSR: + case IPR_ASTRR: + case IPR_ASTER: + case IPR_SIRR: + case IPR_ICSR: + case IPR_ICM: + case IPR_DTB_CM: + case IPR_IPLR: + case IPR_INTID: + case IPR_PMCTR: // no side-effect retval = ipr[idx]; break; - case AlphaISA::IPR_CC: + case IPR_CC: retval |= ipr[idx] & ULL(0xffffffff00000000); retval |= tc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff); break; - case AlphaISA::IPR_VA: + case IPR_VA: retval = ipr[idx]; break; - case AlphaISA::IPR_VA_FORM: - case AlphaISA::IPR_MM_STAT: - case AlphaISA::IPR_IFAULT_VA_FORM: - case AlphaISA::IPR_EXC_MASK: - case AlphaISA::IPR_EXC_SUM: + case IPR_VA_FORM: + case IPR_MM_STAT: + case IPR_IFAULT_VA_FORM: + case IPR_EXC_MASK: + case IPR_EXC_SUM: retval = ipr[idx]; break; - case AlphaISA::IPR_DTB_PTE: + case IPR_DTB_PTE: { - AlphaISA::TlbEntry &entry + TlbEntry &entry = tc->getDTBPtr()->index(!tc->misspeculating()); retval |= ((uint64_t)entry.ppn & ULL(0x7ffffff)) << 32; @@ -259,15 +243,15 @@ AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc) break; // write only registers - case AlphaISA::IPR_HWINT_CLR: - case AlphaISA::IPR_SL_XMIT: - case AlphaISA::IPR_DC_FLUSH: - case AlphaISA::IPR_IC_FLUSH: - case AlphaISA::IPR_ALT_MODE: - case AlphaISA::IPR_DTB_IA: - case AlphaISA::IPR_DTB_IAP: - case AlphaISA::IPR_ITB_IA: - case AlphaISA::IPR_ITB_IAP: + case IPR_HWINT_CLR: + case IPR_SL_XMIT: + case IPR_DC_FLUSH: + case IPR_IC_FLUSH: + case IPR_ALT_MODE: + case IPR_DTB_IA: + case IPR_DTB_IAP: + case IPR_ITB_IA: + case IPR_ITB_IAP: panic("Tried to read write only register %d\n", idx); break; @@ -286,7 +270,7 @@ int break_ipl = -1; #endif void -AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) +MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) { uint64_t old; @@ -294,52 +278,52 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) return; switch (idx) { - case AlphaISA::IPR_PALtemp0: - case AlphaISA::IPR_PALtemp1: - case AlphaISA::IPR_PALtemp2: - case AlphaISA::IPR_PALtemp3: - case AlphaISA::IPR_PALtemp4: - case AlphaISA::IPR_PALtemp5: - case AlphaISA::IPR_PALtemp6: - case AlphaISA::IPR_PALtemp7: - case AlphaISA::IPR_PALtemp8: - case AlphaISA::IPR_PALtemp9: - case AlphaISA::IPR_PALtemp10: - case AlphaISA::IPR_PALtemp11: - case AlphaISA::IPR_PALtemp12: - case AlphaISA::IPR_PALtemp13: - case AlphaISA::IPR_PALtemp14: - case AlphaISA::IPR_PALtemp15: - case AlphaISA::IPR_PALtemp16: - case AlphaISA::IPR_PALtemp17: - case AlphaISA::IPR_PALtemp18: - case AlphaISA::IPR_PALtemp19: - case AlphaISA::IPR_PALtemp20: - case AlphaISA::IPR_PALtemp21: - case AlphaISA::IPR_PALtemp22: - case AlphaISA::IPR_PAL_BASE: - case AlphaISA::IPR_IC_PERR_STAT: - case AlphaISA::IPR_DC_PERR_STAT: - case AlphaISA::IPR_PMCTR: + case IPR_PALtemp0: + case IPR_PALtemp1: + case IPR_PALtemp2: + case IPR_PALtemp3: + case IPR_PALtemp4: + case IPR_PALtemp5: + case IPR_PALtemp6: + case IPR_PALtemp7: + case IPR_PALtemp8: + case IPR_PALtemp9: + case IPR_PALtemp10: + case IPR_PALtemp11: + case IPR_PALtemp12: + case IPR_PALtemp13: + case IPR_PALtemp14: + case IPR_PALtemp15: + case IPR_PALtemp16: + case IPR_PALtemp17: + case IPR_PALtemp18: + case IPR_PALtemp19: + case IPR_PALtemp20: + case IPR_PALtemp21: + case IPR_PALtemp22: + case IPR_PAL_BASE: + case IPR_IC_PERR_STAT: + case IPR_DC_PERR_STAT: + case IPR_PMCTR: // write entire quad w/ no side-effect ipr[idx] = val; break; - case AlphaISA::IPR_CC_CTL: + case 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 AlphaISA::IPR_CC: + case 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 AlphaISA::IPR_PALtemp23: + case IPR_PALtemp23: // write entire quad w/ no side-effect old = ipr[idx]; ipr[idx] = val; @@ -349,23 +333,23 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) #endif break; - case AlphaISA::IPR_DTB_PTE: + case IPR_DTB_PTE: // write entire quad w/ no side-effect, tag is forthcoming ipr[idx] = val; break; - case AlphaISA::IPR_EXC_ADDR: + case IPR_EXC_ADDR: // second least significant bit in PC is always zero ipr[idx] = val & ~2; break; - case AlphaISA::IPR_ASTRR: - case AlphaISA::IPR_ASTER: + case IPR_ASTRR: + case IPR_ASTER: // only write least significant four bits - privilege mask ipr[idx] = val & 0xf; break; - case AlphaISA::IPR_IPLR: + case IPR_IPLR: #ifdef DEBUG if (break_ipl != -1 && break_ipl == (val & 0x1f)) debug_break(); @@ -379,175 +363,173 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) #endif break; - case AlphaISA::IPR_DTB_CM: + case IPR_DTB_CM: #if FULL_SYSTEM if (val & 0x18) { if (tc->getKernelStats()) - tc->getKernelStats()->mode(TheISA::Kernel::user, tc); + tc->getKernelStats()->mode(Kernel::user, tc); } else { if (tc->getKernelStats()) - tc->getKernelStats()->mode(TheISA::Kernel::kernel, tc); + tc->getKernelStats()->mode(Kernel::kernel, tc); } #endif - case AlphaISA::IPR_ICM: + case IPR_ICM: // only write two mode bits - processor mode ipr[idx] = val & 0x18; break; - case AlphaISA::IPR_ALT_MODE: + case IPR_ALT_MODE: // only write two mode bits - processor mode ipr[idx] = val & 0x18; break; - case AlphaISA::IPR_MCSR: + case IPR_MCSR: // more here after optimization... ipr[idx] = val; break; - case AlphaISA::IPR_SIRR: + case IPR_SIRR: // only write software interrupt mask ipr[idx] = val & 0x7fff0; break; - case AlphaISA::IPR_ICSR: + case IPR_ICSR: ipr[idx] = val & ULL(0xffffff0300); break; - case AlphaISA::IPR_IVPTBR: - case AlphaISA::IPR_MVPTBR: + case IPR_IVPTBR: + case IPR_MVPTBR: ipr[idx] = val & ULL(0xffffffffc0000000); break; - case AlphaISA::IPR_DC_TEST_CTL: + case IPR_DC_TEST_CTL: ipr[idx] = val & 0x1ffb; break; - case AlphaISA::IPR_DC_MODE: - case AlphaISA::IPR_MAF_MODE: + case IPR_DC_MODE: + case IPR_MAF_MODE: ipr[idx] = val & 0x3f; break; - case AlphaISA::IPR_ITB_ASN: + case IPR_ITB_ASN: ipr[idx] = val & 0x7f0; break; - case AlphaISA::IPR_DTB_ASN: + case IPR_DTB_ASN: ipr[idx] = val & ULL(0xfe00000000000000); break; - case AlphaISA::IPR_EXC_SUM: - case AlphaISA::IPR_EXC_MASK: + case IPR_EXC_SUM: + case IPR_EXC_MASK: // any write to this register clears it ipr[idx] = 0; break; - case AlphaISA::IPR_INTID: - case AlphaISA::IPR_SL_RCV: - case AlphaISA::IPR_MM_STAT: - case AlphaISA::IPR_ITB_PTE_TEMP: - case AlphaISA::IPR_DTB_PTE_TEMP: + case IPR_INTID: + case IPR_SL_RCV: + case IPR_MM_STAT: + case IPR_ITB_PTE_TEMP: + case IPR_DTB_PTE_TEMP: // read-only registers panic("Tried to write read only ipr %d\n", idx); - case AlphaISA::IPR_HWINT_CLR: - case AlphaISA::IPR_SL_XMIT: - case AlphaISA::IPR_DC_FLUSH: - case AlphaISA::IPR_IC_FLUSH: + case IPR_HWINT_CLR: + case IPR_SL_XMIT: + case IPR_DC_FLUSH: + case IPR_IC_FLUSH: // the following are write only ipr[idx] = val; break; - case AlphaISA::IPR_DTB_IA: + case IPR_DTB_IA: // really a control write ipr[idx] = 0; tc->getDTBPtr()->flushAll(); break; - case AlphaISA::IPR_DTB_IAP: + case IPR_DTB_IAP: // really a control write ipr[idx] = 0; tc->getDTBPtr()->flushProcesses(); break; - case AlphaISA::IPR_DTB_IS: + case IPR_DTB_IS: // really a control write ipr[idx] = val; - tc->getDTBPtr()->flushAddr(val, - EV5::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN])); + tc->getDTBPtr()->flushAddr(val, DTB_ASN_ASN(ipr[IPR_DTB_ASN])); break; - case AlphaISA::IPR_DTB_TAG: { - struct AlphaISA::TlbEntry entry; + case IPR_DTB_TAG: { + struct TlbEntry entry; // FIXME: granularity hints NYI... - if (EV5::DTB_PTE_GH(ipr[AlphaISA::IPR_DTB_PTE]) != 0) + if (DTB_PTE_GH(ipr[IPR_DTB_PTE]) != 0) panic("PTE GH field != 0"); // write entire quad ipr[idx] = val; // construct PTE for new entry - entry.ppn = EV5::DTB_PTE_PPN(ipr[AlphaISA::IPR_DTB_PTE]); - entry.xre = EV5::DTB_PTE_XRE(ipr[AlphaISA::IPR_DTB_PTE]); - entry.xwe = EV5::DTB_PTE_XWE(ipr[AlphaISA::IPR_DTB_PTE]); - entry.fonr = EV5::DTB_PTE_FONR(ipr[AlphaISA::IPR_DTB_PTE]); - entry.fonw = EV5::DTB_PTE_FONW(ipr[AlphaISA::IPR_DTB_PTE]); - entry.asma = EV5::DTB_PTE_ASMA(ipr[AlphaISA::IPR_DTB_PTE]); - entry.asn = EV5::DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]); + entry.ppn = DTB_PTE_PPN(ipr[IPR_DTB_PTE]); + entry.xre = DTB_PTE_XRE(ipr[IPR_DTB_PTE]); + entry.xwe = DTB_PTE_XWE(ipr[IPR_DTB_PTE]); + entry.fonr = DTB_PTE_FONR(ipr[IPR_DTB_PTE]); + entry.fonw = DTB_PTE_FONW(ipr[IPR_DTB_PTE]); + entry.asma = DTB_PTE_ASMA(ipr[IPR_DTB_PTE]); + entry.asn = DTB_ASN_ASN(ipr[IPR_DTB_ASN]); // insert new TAG/PTE value into data TLB tc->getDTBPtr()->insert(val, entry); } break; - case AlphaISA::IPR_ITB_PTE: { - struct AlphaISA::TlbEntry entry; + case IPR_ITB_PTE: { + struct TlbEntry entry; // FIXME: granularity hints NYI... - if (EV5::ITB_PTE_GH(val) != 0) + if (ITB_PTE_GH(val) != 0) panic("PTE GH field != 0"); // write entire quad ipr[idx] = val; // construct PTE for new entry - entry.ppn = EV5::ITB_PTE_PPN(val); - entry.xre = EV5::ITB_PTE_XRE(val); + entry.ppn = ITB_PTE_PPN(val); + entry.xre = ITB_PTE_XRE(val); entry.xwe = 0; - entry.fonr = EV5::ITB_PTE_FONR(val); - entry.fonw = EV5::ITB_PTE_FONW(val); - entry.asma = EV5::ITB_PTE_ASMA(val); - entry.asn = EV5::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]); + entry.fonr = ITB_PTE_FONR(val); + entry.fonw = ITB_PTE_FONW(val); + entry.asma = ITB_PTE_ASMA(val); + entry.asn = ITB_ASN_ASN(ipr[IPR_ITB_ASN]); // insert new TAG/PTE value into data TLB - tc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], entry); + tc->getITBPtr()->insert(ipr[IPR_ITB_TAG], entry); } break; - case AlphaISA::IPR_ITB_IA: + case IPR_ITB_IA: // really a control write ipr[idx] = 0; tc->getITBPtr()->flushAll(); break; - case AlphaISA::IPR_ITB_IAP: + case IPR_ITB_IAP: // really a control write ipr[idx] = 0; tc->getITBPtr()->flushProcesses(); break; - case AlphaISA::IPR_ITB_IS: + case IPR_ITB_IS: // really a control write ipr[idx] = val; - tc->getITBPtr()->flushAddr(val, - EV5::ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN])); + tc->getITBPtr()->flushAddr(val, ITB_ASN_ASN(ipr[IPR_ITB_ASN])); break; default: @@ -558,17 +540,38 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) // no error... } - void -AlphaISA::copyIprs(ThreadContext *src, ThreadContext *dest) +copyIprs(ThreadContext *src, ThreadContext *dest) { - for (int i = 0; i < NumInternalProcRegs; ++i) { + for (int i = 0; i < NumInternalProcRegs; ++i) dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i)); - } } +} // namespace AlphaISA + #if FULL_SYSTEM +using namespace AlphaISA; + +Fault +SimpleThread::hwrei() +{ + if (!(readPC() & 0x3)) + return new UnimplementedOpcodeFault; + + setNextPC(readMiscRegNoEffect(IPR_EXC_ADDR)); + + CPA::cpa()->swAutoBegin(tc, readNextPC()); + + if (!misspeculating()) { + if (kernelStats) + kernelStats->hwrei(); + } + + // FIXME: XXX check for interrupts? XXX + return NoFault; +} + /** * Check for special simulator handling of specific PAL calls. * If return value is false, actual PAL call will be suppressed. diff --git a/src/arch/alpha/ev5.hh b/src/arch/alpha/ev5.hh index 4dd225786..1915d822b 100644 --- a/src/arch/alpha/ev5.hh +++ b/src/arch/alpha/ev5.hh @@ -36,10 +36,7 @@ #include "config/alpha_tlaser.hh" #include "arch/alpha/isa_traits.hh" -namespace EV5 { - -//It seems like a safe assumption EV5 only applies to alpha -using namespace AlphaISA; +namespace AlphaISA { #if ALPHA_TLASER const uint64_t AsnMask = ULL(0x7f); @@ -51,8 +48,8 @@ const int VAddrImplBits = 43; const Addr VAddrImplMask = (ULL(1) << VAddrImplBits) - 1; const Addr VAddrUnImplMask = ~VAddrImplMask; inline Addr VAddrImpl(Addr a) { return a & VAddrImplMask; } -inline Addr VAddrVPN(Addr a) { return a >> AlphaISA::PageShift; } -inline Addr VAddrOffset(Addr a) { return a & AlphaISA::PageOffset; } +inline Addr VAddrVPN(Addr a) { return a >> PageShift; } +inline Addr VAddrOffset(Addr a) { return a & PageOffset; } inline Addr VAddrSpaceEV5(Addr a) { return a >> 41 & 0x3; } inline Addr VAddrSpaceEV6(Addr a) { return a >> 41 & 0x7f; } @@ -68,7 +65,9 @@ const Addr PAddrUncachedBit39 = ULL(0x8000000000); const Addr PAddrUncachedBit40 = ULL(0x10000000000); const Addr PAddrUncachedBit43 = ULL(0x80000000000); const Addr PAddrUncachedMask = ULL(0x807ffffffff); // Clear PA<42:35> -inline Addr Phys2K0Seg(Addr addr) + +inline Addr +Phys2K0Seg(Addr addr) { #if !ALPHA_TLASER if (addr & PAddrUncachedBit43) { @@ -76,12 +75,12 @@ inline Addr Phys2K0Seg(Addr addr) addr |= PAddrUncachedBit40; } #endif - return addr | AlphaISA::K0SegBase; + return addr | K0SegBase; } inline int DTB_ASN_ASN(uint64_t reg) { return reg >> 57 & AsnMask; } inline Addr DTB_PTE_PPN(uint64_t reg) -{ return reg >> 32 & (ULL(1) << PAddrImplBits - AlphaISA::PageShift) - 1; } +{ return reg >> 32 & ((ULL(1) << (PAddrImplBits - PageShift)) - 1); } inline int DTB_PTE_XRE(uint64_t reg) { return reg >> 8 & 0xf; } inline int DTB_PTE_XWE(uint64_t reg) { return reg >> 12 & 0xf; } inline int DTB_PTE_FONR(uint64_t reg) { return reg >> 1 & 0x1; } @@ -91,7 +90,7 @@ inline int DTB_PTE_ASMA(uint64_t reg) { return reg >> 4 & 0x1; } inline int ITB_ASN_ASN(uint64_t reg) { return reg >> 4 & AsnMask; } inline Addr ITB_PTE_PPN(uint64_t reg) -{ return reg >> 32 & (ULL(1) << PAddrImplBits - AlphaISA::PageShift) - 1; } +{ return reg >> 32 & ((ULL(1) << (PAddrImplBits - PageShift)) - 1); } inline int ITB_PTE_XRE(uint64_t reg) { return reg >> 8 & 0xf; } inline bool ITB_PTE_FONR(uint64_t reg) { return reg >> 1 & 0x1; } inline bool ITB_PTE_FONW(uint64_t reg) { return reg >> 2 & 0x1; } @@ -114,12 +113,12 @@ const uint64_t MM_STAT_FONW_MASK = ULL(0x0008); const uint64_t MM_STAT_FONR_MASK = ULL(0x0004); const uint64_t MM_STAT_ACV_MASK = ULL(0x0002); const uint64_t MM_STAT_WR_MASK = ULL(0x0001); -inline int Opcode(AlphaISA::MachInst inst) { return inst >> 26 & 0x3f; } -inline int Ra(AlphaISA::MachInst inst) { return inst >> 21 & 0x1f; } +inline int Opcode(MachInst inst) { return inst >> 26 & 0x3f; } +inline int Ra(MachInst inst) { return inst >> 21 & 0x1f; } const Addr PalBase = 0x4000; const Addr PalMax = 0x10000; -/* namespace EV5 */ } +} // namespace AlphaISA #endif // __ARCH_ALPHA_EV5_HH__ diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc index 20591b357..e93e16711 100644 --- a/src/arch/alpha/faults.cc +++ b/src/arch/alpha/faults.cc @@ -40,8 +40,7 @@ #include "mem/page_table.hh" #endif -namespace AlphaISA -{ +namespace AlphaISA { FaultName MachineCheckFault::_name = "mchk"; FaultVect MachineCheckFault::_vect = 0x0401; @@ -109,64 +108,67 @@ FaultStat IntegerOverflowFault::_count; #if FULL_SYSTEM -void AlphaFault::invoke(ThreadContext * tc) +void +AlphaFault::invoke(ThreadContext *tc) { FaultBase::invoke(tc); countStat()++; // exception restart address if (setRestartAddress() || !(tc->readPC() & 0x3)) - tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR, tc->readPC()); + tc->setMiscRegNoEffect(IPR_EXC_ADDR, tc->readPC()); if (skipFaultingInstruction()) { // traps... skip faulting instruction. - tc->setMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR, - tc->readMiscRegNoEffect(AlphaISA::IPR_EXC_ADDR) + 4); + tc->setMiscRegNoEffect(IPR_EXC_ADDR, + tc->readMiscRegNoEffect(IPR_EXC_ADDR) + 4); } - tc->setPC(tc->readMiscRegNoEffect(AlphaISA::IPR_PAL_BASE) + vect()); + tc->setPC(tc->readMiscRegNoEffect(IPR_PAL_BASE) + vect()); tc->setNextPC(tc->readPC() + sizeof(MachInst)); } -void ArithmeticFault::invoke(ThreadContext * tc) +void +ArithmeticFault::invoke(ThreadContext *tc) { FaultBase::invoke(tc); panic("Arithmetic traps are unimplemented!"); } -void DtbFault::invoke(ThreadContext * tc) +void +DtbFault::invoke(ThreadContext *tc) { // Set fault address and flags. Even though we're modeling an // EV5, we use the EV6 technique of not latching fault registers // on VPTE loads (instead of locking the registers until IPR_VA is // read, like the EV5). The EV6 approach is cleaner and seems to // work with EV5 PAL code, but not the other way around. - if (!tc->misspeculating() - && !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) { + if (!tc->misspeculating() && + reqFlags.noneSet(Request::VPTE|Request::NO_FAULT)) { // set VA register with faulting address - tc->setMiscRegNoEffect(AlphaISA::IPR_VA, vaddr); + tc->setMiscRegNoEffect(IPR_VA, vaddr); // set MM_STAT register flags - tc->setMiscRegNoEffect(AlphaISA::IPR_MM_STAT, - (((EV5::Opcode(tc->getInst()) & 0x3f) << 11) - | ((EV5::Ra(tc->getInst()) & 0x1f) << 6) - | (flags & 0x3f))); + tc->setMiscRegNoEffect(IPR_MM_STAT, + (((Opcode(tc->getInst()) & 0x3f) << 11) | + ((Ra(tc->getInst()) & 0x1f) << 6) | + (flags & 0x3f))); // set VA_FORM register with faulting formatted address - tc->setMiscRegNoEffect(AlphaISA::IPR_VA_FORM, - tc->readMiscRegNoEffect(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3)); + tc->setMiscRegNoEffect(IPR_VA_FORM, + tc->readMiscRegNoEffect(IPR_MVPTBR) | (vaddr.vpn() << 3)); } AlphaFault::invoke(tc); } -void ItbFault::invoke(ThreadContext * tc) +void +ItbFault::invoke(ThreadContext *tc) { if (!tc->misspeculating()) { - tc->setMiscRegNoEffect(AlphaISA::IPR_ITB_TAG, pc); - tc->setMiscRegNoEffect(AlphaISA::IPR_IFAULT_VA_FORM, - tc->readMiscRegNoEffect(AlphaISA::IPR_IVPTBR) | - (AlphaISA::VAddr(pc).vpn() << 3)); + tc->setMiscRegNoEffect(IPR_ITB_TAG, pc); + tc->setMiscRegNoEffect(IPR_IFAULT_VA_FORM, + tc->readMiscRegNoEffect(IPR_IVPTBR) | (VAddr(pc).vpn() << 3)); } AlphaFault::invoke(tc); @@ -174,12 +176,13 @@ void ItbFault::invoke(ThreadContext * tc) #else -void ItbPageFault::invoke(ThreadContext * tc) +void +ItbPageFault::invoke(ThreadContext *tc) { Process *p = tc->getProcessPtr(); TlbEntry entry; bool success = p->pTable->lookup(pc, entry); - if(!success) { + if (!success) { panic("Tried to execute unmapped address %#x.\n", pc); } else { VAddr vaddr(pc); @@ -187,16 +190,17 @@ void ItbPageFault::invoke(ThreadContext * tc) } } -void NDtbMissFault::invoke(ThreadContext * tc) +void +NDtbMissFault::invoke(ThreadContext *tc) { Process *p = tc->getProcessPtr(); TlbEntry entry; bool success = p->pTable->lookup(vaddr, entry); - if(!success) { + if (!success) { p->checkAndAllocNextPage(vaddr); success = p->pTable->lookup(vaddr, entry); } - if(!success) { + if (!success) { panic("Tried to access unmapped address %#x.\n", (Addr)vaddr); } else { tc->getDTBPtr()->insert(vaddr.page(), entry); diff --git a/src/arch/alpha/faults.hh b/src/arch/alpha/faults.hh index 74699b2b5..9d90c7719 100644 --- a/src/arch/alpha/faults.hh +++ b/src/arch/alpha/faults.hh @@ -29,18 +29,16 @@ * Kevin Lim */ -#ifndef __ALPHA_FAULTS_HH__ -#define __ALPHA_FAULTS_HH__ +#ifndef __ARCH_ALPHA_FAULTS_HH__ +#define __ARCH_ALPHA_FAULTS_HH__ +#include "arch/alpha/pagetable.hh" #include "config/full_system.hh" #include "sim/faults.hh" -#include "arch/alpha/pagetable.hh" - // The design of the "name" and "vect" functions is in sim/faults.hh -namespace AlphaISA -{ +namespace AlphaISA { typedef const Addr FaultVect; @@ -63,6 +61,7 @@ class MachineCheckFault : public AlphaFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -76,6 +75,7 @@ class AlignmentFault : public AlphaFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -94,6 +94,7 @@ class ResetFault : public AlphaFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -102,12 +103,14 @@ class ResetFault : public AlphaFault class ArithmeticFault : public AlphaFault { - protected: - bool skipFaultingInstruction() {return true;} private: static FaultName _name; static FaultVect _vect; static FaultStat _count; + + protected: + bool skipFaultingInstruction() {return true;} + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -119,12 +122,14 @@ class ArithmeticFault : public AlphaFault class InterruptFault : public AlphaFault { - protected: - bool setRestartAddress() {return false;} private: static FaultName _name; static FaultVect _vect; static FaultStat _count; + + protected: + bool setRestartAddress() {return false;} + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -134,11 +139,12 @@ class InterruptFault : public AlphaFault class DtbFault : public AlphaFault { protected: - AlphaISA::VAddr vaddr; - uint32_t reqFlags; + VAddr vaddr; + Request::Flags reqFlags; uint64_t flags; + public: - DtbFault(AlphaISA::VAddr _vaddr, uint32_t _reqFlags, uint64_t _flags) + DtbFault(VAddr _vaddr, Request::Flags _reqFlags, uint64_t _flags) : vaddr(_vaddr), reqFlags(_reqFlags), flags(_flags) { } FaultName name() const = 0; @@ -155,8 +161,9 @@ class NDtbMissFault : public DtbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: - NDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) + NDtbMissFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} @@ -173,8 +180,9 @@ class PDtbMissFault : public DtbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: - PDtbMissFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) + PDtbMissFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} @@ -188,8 +196,9 @@ class DtbPageFault : public DtbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: - DtbPageFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) + DtbPageFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} @@ -203,8 +212,9 @@ class DtbAcvFault : public DtbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: - DtbAcvFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) + DtbAcvFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} @@ -218,8 +228,9 @@ class DtbAlignmentFault : public DtbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: - DtbAlignmentFault(AlphaISA::VAddr vaddr, uint32_t reqFlags, uint64_t flags) + DtbAlignmentFault(VAddr vaddr, Request::Flags reqFlags, uint64_t flags) : DtbFault(vaddr, reqFlags, flags) { } FaultName name() const {return _name;} @@ -231,10 +242,9 @@ class ItbFault : public AlphaFault { protected: Addr pc; + public: - ItbFault(Addr _pc) - : pc(_pc) - { } + ItbFault(Addr _pc) : pc(_pc) { } FaultName name() const = 0; FaultVect vect() = 0; FaultStat & countStat() = 0; @@ -249,10 +259,9 @@ class ItbPageFault : public ItbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: - ItbPageFault(Addr pc) - : ItbFault(pc) - { } + ItbPageFault(Addr pc) : ItbFault(pc) { } FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} @@ -267,10 +276,9 @@ class ItbAcvFault : public ItbFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: - ItbAcvFault(Addr pc) - : ItbFault(pc) - { } + ItbAcvFault(Addr pc) : ItbFault(pc) { } FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} @@ -282,6 +290,7 @@ class UnimplementedOpcodeFault : public AlphaFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -294,6 +303,7 @@ class FloatEnableFault : public AlphaFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -302,12 +312,14 @@ class FloatEnableFault : public AlphaFault class PalFault : public AlphaFault { - protected: - bool skipFaultingInstruction() {return true;} private: static FaultName _name; static FaultVect _vect; static FaultStat _count; + + protected: + bool skipFaultingInstruction() {return true;} + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} @@ -320,12 +332,13 @@ class IntegerOverflowFault : public AlphaFault static FaultName _name; static FaultVect _vect; static FaultStat _count; + public: FaultName name() const {return _name;} FaultVect vect() {return _vect;} FaultStat & countStat() {return _count;} }; -} // AlphaISA namespace +} // namespace AlphaISA -#endif // __FAULTS_HH__ +#endif // __ARCH_ALPHA_FAULTS_HH__ diff --git a/src/arch/alpha/floatregfile.cc b/src/arch/alpha/floatregfile.cc index 512b0df95..192b0f1d4 100644 --- a/src/arch/alpha/floatregfile.cc +++ b/src/arch/alpha/floatregfile.cc @@ -30,20 +30,28 @@ * Kevin Lim */ +#include <cstring> + #include "arch/alpha/floatregfile.hh" #include "sim/serialize.hh" -namespace AlphaISA +namespace AlphaISA { +void +FloatRegFile::clear() { - void - FloatRegFile::serialize(std::ostream &os) - { - SERIALIZE_ARRAY(q, NumFloatRegs); - } + std::memset(d, 0, sizeof(d)); +} - void - FloatRegFile::unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_ARRAY(q, NumFloatRegs); - } +void +FloatRegFile::serialize(std::ostream &os) +{ + SERIALIZE_ARRAY(q, NumFloatRegs); } + +void +FloatRegFile::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ARRAY(q, NumFloatRegs); +} + +} // namespace AlphaISA diff --git a/src/arch/alpha/floatregfile.hh b/src/arch/alpha/floatregfile.hh index 0c5fe17a7..d5f9eec0f 100644 --- a/src/arch/alpha/floatregfile.hh +++ b/src/arch/alpha/floatregfile.hh @@ -32,37 +32,30 @@ #ifndef __ARCH_ALPHA_FLOATREGFILE_HH__ #define __ARCH_ALPHA_FLOATREGFILE_HH__ +#include <iosfwd> +#include <string> + #include "arch/alpha/isa_traits.hh" #include "arch/alpha/types.hh" -#include <cstring> -#include <iostream> - class Checkpoint; -namespace AlphaISA -{ - static inline std::string getFloatRegName(RegIndex) - { - return ""; - } - - class FloatRegFile - { - public: +namespace AlphaISA { - union { - uint64_t q[NumFloatRegs]; // integer qword view - double d[NumFloatRegs]; // double-precision floating point view - }; +class FloatRegFile +{ + public: + union { + uint64_t q[NumFloatRegs]; // integer qword view + double d[NumFloatRegs]; // double-precision floating point view + }; - void serialize(std::ostream &os); + void clear(); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); +}; - void clear() - { std::memset(d, 0, sizeof(d)); } - }; -} +} // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_FLOATREGFILE_HH__ diff --git a/src/arch/alpha/freebsd/system.cc b/src/arch/alpha/freebsd/system.cc index f666de604..e541b260c 100644 --- a/src/arch/alpha/freebsd/system.cc +++ b/src/arch/alpha/freebsd/system.cc @@ -62,29 +62,25 @@ FreebsdAlphaSystem::FreebsdAlphaSystem(Params *p) addKernelFuncEvent<SkipCalibrateClocksEvent>("calibrate_clocks"); } - FreebsdAlphaSystem::~FreebsdAlphaSystem() { delete skipDelayEvent; delete skipCalibrateClocks; } - void FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc) { Addr ppc_vaddr = 0; Addr timer_vaddr = 0; - assert(NumArgumentRegs >= 3); - ppc_vaddr = (Addr)tc->readIntReg(ArgumentReg[1]); - timer_vaddr = (Addr)tc->readIntReg(ArgumentReg[2]); + ppc_vaddr = (Addr)tc->readIntReg(17); + timer_vaddr = (Addr)tc->readIntReg(18); virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency); virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY); } - void FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ThreadContext *tc) { diff --git a/src/arch/alpha/freebsd/system.hh b/src/arch/alpha/freebsd/system.hh index 8e8493f97..48f6238c0 100644 --- a/src/arch/alpha/freebsd/system.hh +++ b/src/arch/alpha/freebsd/system.hh @@ -57,7 +57,6 @@ class FreebsdAlphaSystem : public AlphaSystem ~FreebsdAlphaSystem(); void doCalibrateClocks(ThreadContext *tc); - }; #endif // __ARCH_ALPHA_FREEBSD_SYSTEM_HH__ diff --git a/src/arch/alpha/idle_event.cc b/src/arch/alpha/idle_event.cc index f0f1eab7a..bb68782e7 100644 --- a/src/arch/alpha/idle_event.cc +++ b/src/arch/alpha/idle_event.cc @@ -33,13 +33,14 @@ #include "arch/alpha/kernel_stats.hh" #include "cpu/thread_context.hh" -using namespace TheISA; +using namespace AlphaISA; void IdleStartEvent::process(ThreadContext *tc) { - if (tc->getKernelStats()) - tc->getKernelStats()->setIdleProcess( - tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23), tc); + if (tc->getKernelStats()) { + MiscReg val = tc->readMiscRegNoEffect(IPR_PALtemp23); + tc->getKernelStats()->setIdleProcess(val, tc); + } remove(); } diff --git a/src/arch/alpha/interrupts.cc b/src/arch/alpha/interrupts.cc new file mode 100644 index 000000000..4b5dc5661 --- /dev/null +++ b/src/arch/alpha/interrupts.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2008 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Authors: Gabe Black + */ + +#include "arch/alpha/interrupts.hh" + +AlphaISA::Interrupts * +AlphaInterruptsParams::create() +{ + return new AlphaISA::Interrupts(this); +} diff --git a/src/arch/alpha/interrupts.hh b/src/arch/alpha/interrupts.hh index 6453edf97..f8e0ad4ef 100644 --- a/src/arch/alpha/interrupts.hh +++ b/src/arch/alpha/interrupts.hh @@ -35,142 +35,163 @@ #include "arch/alpha/faults.hh" #include "arch/alpha/isa_traits.hh" #include "base/compiler.hh" +#include "base/trace.hh" #include "cpu/thread_context.hh" +#include "params/AlphaInterrupts.hh" +#include "sim/sim_object.hh" -namespace AlphaISA +namespace AlphaISA { + +class Interrupts : public SimObject { - class Interrupts + private: + bool newInfoSet; + int newIpl; + int newSummary; + BaseCPU * cpu; + + protected: + uint64_t interrupts[NumInterruptLevels]; + uint64_t intstatus; + + public: + typedef AlphaInterruptsParams Params; + + const Params * + params() const { - protected: - uint64_t interrupts[NumInterruptLevels]; - uint64_t intstatus; - - public: - Interrupts() - { - memset(interrupts, 0, sizeof(interrupts)); - intstatus = 0; - newInfoSet = false; - } + return dynamic_cast<const Params *>(_params); + } - void post(int int_num, int index) - { - DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); + Interrupts(Params * p) : SimObject(p), cpu(NULL) + { + memset(interrupts, 0, sizeof(interrupts)); + intstatus = 0; + newInfoSet = false; + } - if (int_num < 0 || int_num >= NumInterruptLevels) - panic("int_num out of bounds\n"); + void + setCPU(BaseCPU * _cpu) + { + cpu = _cpu; + } - if (index < 0 || index >= sizeof(uint64_t) * 8) - panic("int_num out of bounds\n"); + void + post(int int_num, int index) + { + DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); - interrupts[int_num] |= 1 << index; - intstatus |= (ULL(1) << int_num); - } + if (int_num < 0 || int_num >= NumInterruptLevels) + panic("int_num out of bounds\n"); - void clear(int int_num, int index) - { - DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); + if (index < 0 || index >= (int)sizeof(uint64_t) * 8) + panic("int_num out of bounds\n"); - if (int_num < 0 || int_num >= TheISA::NumInterruptLevels) - panic("int_num out of bounds\n"); + interrupts[int_num] |= 1 << index; + intstatus |= (ULL(1) << int_num); + } - if (index < 0 || index >= sizeof(uint64_t) * 8) - panic("int_num out of bounds\n"); + void + clear(int int_num, int index) + { + DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); - interrupts[int_num] &= ~(1 << index); - if (interrupts[int_num] == 0) - intstatus &= ~(ULL(1) << int_num); - } + if (int_num < 0 || int_num >= NumInterruptLevels) + panic("int_num out of bounds\n"); - void clear_all() - { - DPRINTF(Interrupt, "Interrupts all cleared\n"); + if (index < 0 || index >= (int)sizeof(uint64_t) * 8) + panic("int_num out of bounds\n"); - memset(interrupts, 0, sizeof(interrupts)); - intstatus = 0; - } + interrupts[int_num] &= ~(1 << index); + if (interrupts[int_num] == 0) + intstatus &= ~(ULL(1) << int_num); + } - void serialize(std::ostream &os) - { - SERIALIZE_ARRAY(interrupts, NumInterruptLevels); - SERIALIZE_SCALAR(intstatus); - } + void + clearAll() + { + DPRINTF(Interrupt, "Interrupts all cleared\n"); - void unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels); - UNSERIALIZE_SCALAR(intstatus); - } + memset(interrupts, 0, sizeof(interrupts)); + intstatus = 0; + } - bool check_interrupts(ThreadContext * tc) const - { - return (intstatus != 0) && !(tc->readPC() & 0x3); - } + void + serialize(std::ostream &os) + { + SERIALIZE_ARRAY(interrupts, NumInterruptLevels); + SERIALIZE_SCALAR(intstatus); + } - Fault getInterrupt(ThreadContext * tc) - { - int ipl = 0; - int summary = 0; - - if (tc->readMiscRegNoEffect(IPR_ASTRR)) - panic("asynchronous traps not implemented\n"); - - if (tc->readMiscRegNoEffect(IPR_SIRR)) { - for (int i = INTLEVEL_SOFTWARE_MIN; - i < INTLEVEL_SOFTWARE_MAX; i++) { - if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) { - // See table 4-19 of 21164 hardware reference - ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; - summary |= (ULL(1) << i); - } - } - } + void + unserialize(Checkpoint *cp, const std::string §ion) + { + UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels); + UNSERIALIZE_SCALAR(intstatus); + } + + bool + checkInterrupts(ThreadContext *tc) const + { + return (intstatus != 0) && !(tc->readPC() & 0x3); + } - uint64_t interrupts = intstatus; - if (interrupts) { - for (int i = INTLEVEL_EXTERNAL_MIN; - i < INTLEVEL_EXTERNAL_MAX; i++) { - if (interrupts & (ULL(1) << i)) { - // See table 4-19 of 21164 hardware reference - ipl = i; - summary |= (ULL(1) << i); - } + Fault + getInterrupt(ThreadContext *tc) + { + int ipl = 0; + int summary = 0; + + if (tc->readMiscRegNoEffect(IPR_ASTRR)) + panic("asynchronous traps not implemented\n"); + + if (tc->readMiscRegNoEffect(IPR_SIRR)) { + for (int i = INTLEVEL_SOFTWARE_MIN; + i < INTLEVEL_SOFTWARE_MAX; i++) { + if (tc->readMiscRegNoEffect(IPR_SIRR) & (ULL(1) << i)) { + // See table 4-19 of 21164 hardware reference + ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1; + summary |= (ULL(1) << i); } } + } - if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) { - newIpl = ipl; - newSummary = summary; - newInfoSet = true; - DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", - tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary); - - return new InterruptFault; - } else { - return NoFault; + uint64_t interrupts = intstatus; + if (interrupts) { + for (int i = INTLEVEL_EXTERNAL_MIN; + i < INTLEVEL_EXTERNAL_MAX; i++) { + if (interrupts & (ULL(1) << i)) { + // See table 4-19 of 21164 hardware reference + ipl = i; + summary |= (ULL(1) << i); + } } } - void updateIntrInfo(ThreadContext *tc) - { - assert(newInfoSet); - tc->setMiscRegNoEffect(IPR_ISR, newSummary); - tc->setMiscRegNoEffect(IPR_INTID, newIpl); - newInfoSet = false; - } + if (ipl && ipl > tc->readMiscRegNoEffect(IPR_IPLR)) { + newIpl = ipl; + newSummary = summary; + newInfoSet = true; + DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n", + tc->readMiscRegNoEffect(IPR_IPLR), ipl, summary); - uint64_t get_vec(int int_num) - { - panic("Shouldn't be called for Alpha\n"); - M5_DUMMY_RETURN + return new InterruptFault; + } else { + return NoFault; } + } + + void + updateIntrInfo(ThreadContext *tc) + { + assert(newInfoSet); + tc->setMiscRegNoEffect(IPR_ISR, newSummary); + tc->setMiscRegNoEffect(IPR_INTID, newIpl); + newInfoSet = false; + } +}; - private: - bool newInfoSet; - int newIpl; - int newSummary; - }; -} +} // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_INTERRUPT_HH__ diff --git a/src/arch/alpha/intregfile.cc b/src/arch/alpha/intregfile.cc index 0188cb2cd..8f692f856 100644 --- a/src/arch/alpha/intregfile.cc +++ b/src/arch/alpha/intregfile.cc @@ -30,36 +30,45 @@ * Kevin Lim */ +#include <cstring> + #include "arch/alpha/isa_traits.hh" #include "arch/alpha/intregfile.hh" #include "sim/serialize.hh" -namespace AlphaISA -{ +namespace AlphaISA { + #if FULL_SYSTEM - const int reg_redir[AlphaISA::NumIntRegs] = { - /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, - /* 8 */ 32, 33, 34, 35, 36, 37, 38, 15, - /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, - /* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 }; +const int reg_redir[NumIntRegs] = { + /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, + /* 8 */ 32, 33, 34, 35, 36, 37, 38, 15, + /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, + /* 24 */ 24, 39, 26, 27, 28, 29, 30, 31 }; #else - const int reg_redir[AlphaISA::NumIntRegs] = { - /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, - /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, - /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, - /* 24 */ 24, 25, 26, 27, 28, 29, 30, 31 }; +const int reg_redir[NumIntRegs] = { + /* 0 */ 0, 1, 2, 3, 4, 5, 6, 7, + /* 8 */ 8, 9, 10, 11, 12, 13, 14, 15, + /* 16 */ 16, 17, 18, 19, 20, 21, 22, 23, + /* 24 */ 24, 25, 26, 27, 28, 29, 30, 31 }; #endif - void - IntRegFile::serialize(std::ostream &os) - { - SERIALIZE_ARRAY(regs, NumIntRegs); - } +void +IntRegFile::clear() +{ + std::memset(regs, 0, sizeof(regs)); +} + +void +IntRegFile::serialize(std::ostream &os) +{ + SERIALIZE_ARRAY(regs, NumIntRegs); +} - void - IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_ARRAY(regs, NumIntRegs); - } +void +IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ARRAY(regs, NumIntRegs); } +} // namespace AlphaISA + diff --git a/src/arch/alpha/intregfile.hh b/src/arch/alpha/intregfile.hh index dea160992..3aa7d92c4 100644 --- a/src/arch/alpha/intregfile.hh +++ b/src/arch/alpha/intregfile.hh @@ -32,47 +32,42 @@ #ifndef __ARCH_ALPHA_INTREGFILE_HH__ #define __ARCH_ALPHA_INTREGFILE_HH__ -#include "arch/alpha/types.hh" +#include <iosfwd> +#include <string> -#include <iostream> -#include <cstring> +#include "arch/alpha/types.hh" class Checkpoint; -namespace AlphaISA +namespace AlphaISA { + +// redirected register map, really only used for the full system case. +extern const int reg_redir[NumIntRegs]; + +class IntRegFile { - static inline std::string getIntRegName(RegIndex) + protected: + IntReg regs[NumIntRegs]; + + public: + IntReg + readReg(int intReg) { - return ""; + return regs[intReg]; } - // redirected register map, really only used for the full system case. - extern const int reg_redir[NumIntRegs]; - - class IntRegFile + void + setReg(int intReg, const IntReg &val) { - protected: - IntReg regs[NumIntRegs]; - - public: - - IntReg readReg(int intReg) - { - return regs[intReg]; - } - - void setReg(int intReg, const IntReg &val) - { - regs[intReg] = val; - } + regs[intReg] = val; + } - void serialize(std::ostream &os); + void clear(); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); +}; - void clear() - { std::memset(regs, 0, sizeof(regs)); } - }; -} +} // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_INTREGFILE_HH__ diff --git a/src/arch/alpha/ipr.cc b/src/arch/alpha/ipr.cc index 8e83102eb..502ada5eb 100644 --- a/src/arch/alpha/ipr.cc +++ b/src/arch/alpha/ipr.cc @@ -28,113 +28,115 @@ * Authors: Gabe Black */ -#include <assert.h> -#include <string.h> +#include <cassert> +#include <cstring> #include "arch/alpha/ipr.hh" -namespace AlphaISA +namespace AlphaISA { + +md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs] = { + + //Write only + RAW_IPR_HWINT_CLR, // H/W interrupt clear register + RAW_IPR_SL_XMIT, // serial line transmit register + RAW_IPR_DC_FLUSH, + RAW_IPR_IC_FLUSH, // instruction cache flush control + RAW_IPR_ALT_MODE, // alternate mode register + RAW_IPR_DTB_IA, // DTLB invalidate all register + RAW_IPR_DTB_IAP, // DTLB invalidate all process register + RAW_IPR_ITB_IA, // ITLB invalidate all register + RAW_IPR_ITB_IAP, // ITLB invalidate all process register + + //Read only + RAW_IPR_INTID, // interrupt ID register + RAW_IPR_SL_RCV, // serial line receive register + RAW_IPR_MM_STAT, // data MMU fault status register + RAW_IPR_ITB_PTE_TEMP, // ITLB page table entry temp register + RAW_IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register + + RAW_IPR_ISR, // interrupt summary register + RAW_IPR_ITB_TAG, // ITLB tag register + RAW_IPR_ITB_PTE, // ITLB page table entry register + RAW_IPR_ITB_ASN, // ITLB address space register + RAW_IPR_ITB_IS, // ITLB invalidate select register + RAW_IPR_SIRR, // software interrupt request register + RAW_IPR_ASTRR, // asynchronous system trap request register + RAW_IPR_ASTER, // asynchronous system trap enable register + RAW_IPR_EXC_ADDR, // exception address register + RAW_IPR_EXC_SUM, // exception summary register + RAW_IPR_EXC_MASK, // exception mask register + RAW_IPR_PAL_BASE, // PAL base address register + RAW_IPR_ICM, // instruction current mode + RAW_IPR_IPLR, // interrupt priority level register + RAW_IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register + RAW_IPR_IVPTBR, // virtual page table base register + RAW_IPR_ICSR, // instruction control and status register + RAW_IPR_IC_PERR_STAT, // inst cache parity error status register + RAW_IPR_PMCTR, // performance counter register + + // PAL temporary registers... + // register meanings gleaned from osfpal.s source code + RAW_IPR_PALtemp0, // local scratch + RAW_IPR_PALtemp1, // local scratch + RAW_IPR_PALtemp2, // entUna + RAW_IPR_PALtemp3, // CPU specific impure area pointer + RAW_IPR_PALtemp4, // memory management temp + RAW_IPR_PALtemp5, // memory management temp + RAW_IPR_PALtemp6, // memory management temp + RAW_IPR_PALtemp7, // entIF + RAW_IPR_PALtemp8, // intmask + RAW_IPR_PALtemp9, // entSys + RAW_IPR_PALtemp10, // ?? + RAW_IPR_PALtemp11, // entInt + RAW_IPR_PALtemp12, // entArith + RAW_IPR_PALtemp13, // reserved for platform specific PAL + RAW_IPR_PALtemp14, // reserved for platform specific PAL + RAW_IPR_PALtemp15, // reserved for platform specific PAL + RAW_IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0> + RAW_IPR_PALtemp17, // sysval + RAW_IPR_PALtemp18, // usp + RAW_IPR_PALtemp19, // ksp + RAW_IPR_PALtemp20, // PTBR + RAW_IPR_PALtemp21, // entMM + RAW_IPR_PALtemp22, // kgp + RAW_IPR_PALtemp23, // PCBB + + RAW_IPR_DTB_ASN, // DTLB address space number register + RAW_IPR_DTB_CM, // DTLB current mode register + RAW_IPR_DTB_TAG, // DTLB tag register + RAW_IPR_DTB_PTE, // DTLB page table entry register + + RAW_IPR_VA, // fault virtual address register + RAW_IPR_VA_FORM, // formatted virtual address register + RAW_IPR_MVPTBR, // MTU virtual page table base register + RAW_IPR_DTB_IS, // DTLB invalidate single register + RAW_IPR_CC, // cycle counter register + RAW_IPR_CC_CTL, // cycle counter control register + RAW_IPR_MCSR, // MTU control register + + RAW_IPR_DC_PERR_STAT, // Dcache parity error status register + RAW_IPR_DC_TEST_CTL, // Dcache test tag control register + RAW_IPR_DC_TEST_TAG, // Dcache test tag register + RAW_IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register + RAW_IPR_DC_MODE, // Dcache mode register + RAW_IPR_MAF_MODE // miss address file mode register +}; + +int IprToMiscRegIndex[MaxInternalProcRegs]; + +void +initializeIprTable() { - md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs] = - { - //Write only - RAW_IPR_HWINT_CLR, // H/W interrupt clear register - RAW_IPR_SL_XMIT, // serial line transmit register - RAW_IPR_DC_FLUSH, - RAW_IPR_IC_FLUSH, // instruction cache flush control - RAW_IPR_ALT_MODE, // alternate mode register - RAW_IPR_DTB_IA, // DTLB invalidate all register - RAW_IPR_DTB_IAP, // DTLB invalidate all process register - RAW_IPR_ITB_IA, // ITLB invalidate all register - RAW_IPR_ITB_IAP, // ITLB invalidate all process register - - //Read only - RAW_IPR_INTID, // interrupt ID register - RAW_IPR_SL_RCV, // serial line receive register - RAW_IPR_MM_STAT, // data MMU fault status register - RAW_IPR_ITB_PTE_TEMP, // ITLB page table entry temp register - RAW_IPR_DTB_PTE_TEMP, // DTLB page table entry temporary register - - RAW_IPR_ISR, // interrupt summary register - RAW_IPR_ITB_TAG, // ITLB tag register - RAW_IPR_ITB_PTE, // ITLB page table entry register - RAW_IPR_ITB_ASN, // ITLB address space register - RAW_IPR_ITB_IS, // ITLB invalidate select register - RAW_IPR_SIRR, // software interrupt request register - RAW_IPR_ASTRR, // asynchronous system trap request register - RAW_IPR_ASTER, // asynchronous system trap enable register - RAW_IPR_EXC_ADDR, // exception address register - RAW_IPR_EXC_SUM, // exception summary register - RAW_IPR_EXC_MASK, // exception mask register - RAW_IPR_PAL_BASE, // PAL base address register - RAW_IPR_ICM, // instruction current mode - RAW_IPR_IPLR, // interrupt priority level register - RAW_IPR_IFAULT_VA_FORM, // formatted faulting virtual addr register - RAW_IPR_IVPTBR, // virtual page table base register - RAW_IPR_ICSR, // instruction control and status register - RAW_IPR_IC_PERR_STAT, // inst cache parity error status register - RAW_IPR_PMCTR, // performance counter register - - // PAL temporary registers... - // register meanings gleaned from osfpal.s source code - RAW_IPR_PALtemp0, // local scratch - RAW_IPR_PALtemp1, // local scratch - RAW_IPR_PALtemp2, // entUna - RAW_IPR_PALtemp3, // CPU specific impure area pointer - RAW_IPR_PALtemp4, // memory management temp - RAW_IPR_PALtemp5, // memory management temp - RAW_IPR_PALtemp6, // memory management temp - RAW_IPR_PALtemp7, // entIF - RAW_IPR_PALtemp8, // intmask - RAW_IPR_PALtemp9, // entSys - RAW_IPR_PALtemp10, // ?? - RAW_IPR_PALtemp11, // entInt - RAW_IPR_PALtemp12, // entArith - RAW_IPR_PALtemp13, // reserved for platform specific PAL - RAW_IPR_PALtemp14, // reserved for platform specific PAL - RAW_IPR_PALtemp15, // reserved for platform specific PAL - RAW_IPR_PALtemp16, // scratch / whami<7:0> / mces<4:0> - RAW_IPR_PALtemp17, // sysval - RAW_IPR_PALtemp18, // usp - RAW_IPR_PALtemp19, // ksp - RAW_IPR_PALtemp20, // PTBR - RAW_IPR_PALtemp21, // entMM - RAW_IPR_PALtemp22, // kgp - RAW_IPR_PALtemp23, // PCBB - - RAW_IPR_DTB_ASN, // DTLB address space number register - RAW_IPR_DTB_CM, // DTLB current mode register - RAW_IPR_DTB_TAG, // DTLB tag register - RAW_IPR_DTB_PTE, // DTLB page table entry register - - RAW_IPR_VA, // fault virtual address register - RAW_IPR_VA_FORM, // formatted virtual address register - RAW_IPR_MVPTBR, // MTU virtual page table base register - RAW_IPR_DTB_IS, // DTLB invalidate single register - RAW_IPR_CC, // cycle counter register - RAW_IPR_CC_CTL, // cycle counter control register - RAW_IPR_MCSR, // MTU control register - - RAW_IPR_DC_PERR_STAT, // Dcache parity error status register - RAW_IPR_DC_TEST_CTL, // Dcache test tag control register - RAW_IPR_DC_TEST_TAG, // Dcache test tag register - RAW_IPR_DC_TEST_TAG_TEMP, // Dcache test tag temporary register - RAW_IPR_DC_MODE, // Dcache mode register - RAW_IPR_MAF_MODE // miss address file mode register - }; - - int IprToMiscRegIndex[MaxInternalProcRegs]; - - void initializeIprTable() - { - static bool initialized = false; - if(initialized) - return; - - memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int)); - - for(int x = 0; x < NumInternalProcRegs; x++) - IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x; - } + static bool initialized = false; + if (initialized) + return; + + memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int)); + + for (int x = 0; x < NumInternalProcRegs; x++) + IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x; } +} // namespace AlphaISA + diff --git a/src/arch/alpha/ipr.hh b/src/arch/alpha/ipr.hh index b55154764..4e7bf1fa4 100644 --- a/src/arch/alpha/ipr.hh +++ b/src/arch/alpha/ipr.hh @@ -32,206 +32,208 @@ #ifndef __ARCH_ALPHA_IPR_HH__ #define __ARCH_ALPHA_IPR_HH__ -namespace AlphaISA +namespace AlphaISA { + +//////////////////////////////////////////////////////////////////////// +// +// Internal Processor Reigsters +// +enum md_ipr_names { + RAW_IPR_ISR = 0x100, // interrupt summary + RAW_IPR_ITB_TAG = 0x101, // ITLB tag + RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry + RAW_IPR_ITB_ASN = 0x103, // ITLB address space + RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp + RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all + RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process + RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select + RAW_IPR_SIRR = 0x108, // software interrupt request + RAW_IPR_ASTRR = 0x109, // asynchronous system trap request + RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable + RAW_IPR_EXC_ADDR = 0x10b, // exception address + RAW_IPR_EXC_SUM = 0x10c, // exception summary + RAW_IPR_EXC_MASK = 0x10d, // exception mask + RAW_IPR_PAL_BASE = 0x10e, // PAL base address + RAW_IPR_ICM = 0x10f, // instruction current mode + RAW_IPR_IPLR = 0x110, // interrupt priority level + RAW_IPR_INTID = 0x111, // interrupt ID + RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr + RAW_IPR_IVPTBR = 0x113, // virtual page table base + RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear + RAW_IPR_SL_XMIT = 0x116, // serial line transmit + RAW_IPR_SL_RCV = 0x117, // serial line receive + RAW_IPR_ICSR = 0x118, // instruction control and status + RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control + RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status + RAW_IPR_PMCTR = 0x11c, // performance counter + + // PAL temporary registers... + // register meanings gleaned from osfpal.s source code + RAW_IPR_PALtemp0 = 0x140, // local scratch + RAW_IPR_PALtemp1 = 0x141, // local scratch + RAW_IPR_PALtemp2 = 0x142, // entUna + RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer + RAW_IPR_PALtemp4 = 0x144, // memory management temp + RAW_IPR_PALtemp5 = 0x145, // memory management temp + RAW_IPR_PALtemp6 = 0x146, // memory management temp + RAW_IPR_PALtemp7 = 0x147, // entIF + RAW_IPR_PALtemp8 = 0x148, // intmask + RAW_IPR_PALtemp9 = 0x149, // entSys + RAW_IPR_PALtemp10 = 0x14a, // ?? + RAW_IPR_PALtemp11 = 0x14b, // entInt + RAW_IPR_PALtemp12 = 0x14c, // entArith + RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL + RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL + RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL + RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0> + RAW_IPR_PALtemp17 = 0x151, // sysval + RAW_IPR_PALtemp18 = 0x152, // usp + RAW_IPR_PALtemp19 = 0x153, // ksp + RAW_IPR_PALtemp20 = 0x154, // PTBR + RAW_IPR_PALtemp21 = 0x155, // entMM + RAW_IPR_PALtemp22 = 0x156, // kgp + RAW_IPR_PALtemp23 = 0x157, // PCBB + + RAW_IPR_DTB_ASN = 0x200, // DTLB address space number + RAW_IPR_DTB_CM = 0x201, // DTLB current mode + RAW_IPR_DTB_TAG = 0x202, // DTLB tag + RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry + RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary + + RAW_IPR_MM_STAT = 0x205, // data MMU fault status + RAW_IPR_VA = 0x206, // fault virtual address + RAW_IPR_VA_FORM = 0x207, // formatted virtual address + RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base + RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process + RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all + RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single + RAW_IPR_ALT_MODE = 0x20c, // alternate mode + RAW_IPR_CC = 0x20d, // cycle counter + RAW_IPR_CC_CTL = 0x20e, // cycle counter control + RAW_IPR_MCSR = 0x20f, // MTU control + + RAW_IPR_DC_FLUSH = 0x210, + RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status + RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control + RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag + RAW_IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary + RAW_IPR_DC_MODE = 0x216, // Dcache mode + RAW_IPR_MAF_MODE = 0x217, // miss address file mode + + MaxInternalProcRegs // number of IPRs +}; + +enum MiscRegIpr { - //////////////////////////////////////////////////////////////////////// - // - // Internal Processor Reigsters - // - enum md_ipr_names - { - RAW_IPR_ISR = 0x100, // interrupt summary register - RAW_IPR_ITB_TAG = 0x101, // ITLB tag register - RAW_IPR_ITB_PTE = 0x102, // ITLB page table entry register - RAW_IPR_ITB_ASN = 0x103, // ITLB address space register - RAW_IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register - RAW_IPR_ITB_IA = 0x105, // ITLB invalidate all register - RAW_IPR_ITB_IAP = 0x106, // ITLB invalidate all process register - RAW_IPR_ITB_IS = 0x107, // ITLB invalidate select register - RAW_IPR_SIRR = 0x108, // software interrupt request register - RAW_IPR_ASTRR = 0x109, // asynchronous system trap request register - RAW_IPR_ASTER = 0x10a, // asynchronous system trap enable register - RAW_IPR_EXC_ADDR = 0x10b, // exception address register - RAW_IPR_EXC_SUM = 0x10c, // exception summary register - RAW_IPR_EXC_MASK = 0x10d, // exception mask register - RAW_IPR_PAL_BASE = 0x10e, // PAL base address register - RAW_IPR_ICM = 0x10f, // instruction current mode - RAW_IPR_IPLR = 0x110, // interrupt priority level register - RAW_IPR_INTID = 0x111, // interrupt ID register - RAW_IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register - RAW_IPR_IVPTBR = 0x113, // virtual page table base register - RAW_IPR_HWINT_CLR = 0x115, // H/W interrupt clear register - RAW_IPR_SL_XMIT = 0x116, // serial line transmit register - RAW_IPR_SL_RCV = 0x117, // serial line receive register - RAW_IPR_ICSR = 0x118, // instruction control and status register - RAW_IPR_IC_FLUSH = 0x119, // instruction cache flush control - RAW_IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register - RAW_IPR_PMCTR = 0x11c, // performance counter register - - // PAL temporary registers... - // register meanings gleaned from osfpal.s source code - RAW_IPR_PALtemp0 = 0x140, // local scratch - RAW_IPR_PALtemp1 = 0x141, // local scratch - RAW_IPR_PALtemp2 = 0x142, // entUna - RAW_IPR_PALtemp3 = 0x143, // CPU specific impure area pointer - RAW_IPR_PALtemp4 = 0x144, // memory management temp - RAW_IPR_PALtemp5 = 0x145, // memory management temp - RAW_IPR_PALtemp6 = 0x146, // memory management temp - RAW_IPR_PALtemp7 = 0x147, // entIF - RAW_IPR_PALtemp8 = 0x148, // intmask - RAW_IPR_PALtemp9 = 0x149, // entSys - RAW_IPR_PALtemp10 = 0x14a, // ?? - RAW_IPR_PALtemp11 = 0x14b, // entInt - RAW_IPR_PALtemp12 = 0x14c, // entArith - RAW_IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL - RAW_IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL - RAW_IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL - RAW_IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0> - RAW_IPR_PALtemp17 = 0x151, // sysval - RAW_IPR_PALtemp18 = 0x152, // usp - RAW_IPR_PALtemp19 = 0x153, // ksp - RAW_IPR_PALtemp20 = 0x154, // PTBR - RAW_IPR_PALtemp21 = 0x155, // entMM - RAW_IPR_PALtemp22 = 0x156, // kgp - RAW_IPR_PALtemp23 = 0x157, // PCBB - - RAW_IPR_DTB_ASN = 0x200, // DTLB address space number register - RAW_IPR_DTB_CM = 0x201, // DTLB current mode register - RAW_IPR_DTB_TAG = 0x202, // DTLB tag register - RAW_IPR_DTB_PTE = 0x203, // DTLB page table entry register - RAW_IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register - - RAW_IPR_MM_STAT = 0x205, // data MMU fault status register - RAW_IPR_VA = 0x206, // fault virtual address register - RAW_IPR_VA_FORM = 0x207, // formatted virtual address register - RAW_IPR_MVPTBR = 0x208, // MTU virtual page table base register - RAW_IPR_DTB_IAP = 0x209, // DTLB invalidate all process register - RAW_IPR_DTB_IA = 0x20a, // DTLB invalidate all register - RAW_IPR_DTB_IS = 0x20b, // DTLB invalidate single register - RAW_IPR_ALT_MODE = 0x20c, // alternate mode register - RAW_IPR_CC = 0x20d, // cycle counter register - RAW_IPR_CC_CTL = 0x20e, // cycle counter control register - RAW_IPR_MCSR = 0x20f, // MTU control register - - RAW_IPR_DC_FLUSH = 0x210, - RAW_IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register - RAW_IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register - RAW_IPR_DC_TEST_TAG = 0x214, // Dcache test tag register - RAW_IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register - RAW_IPR_DC_MODE = 0x216, // Dcache mode register - RAW_IPR_MAF_MODE = 0x217, // miss address file mode register - - MaxInternalProcRegs // number of IPR registers - }; - - enum MiscRegIpr - { - //Write only - MinWriteOnlyIpr, - IPR_HWINT_CLR = MinWriteOnlyIpr, - IPR_SL_XMIT, - IPR_DC_FLUSH, - IPR_IC_FLUSH, - IPR_ALT_MODE, - IPR_DTB_IA, - IPR_DTB_IAP, - IPR_ITB_IA, - MaxWriteOnlyIpr, - IPR_ITB_IAP = MaxWriteOnlyIpr, - - //Read only - MinReadOnlyIpr, - IPR_INTID = MinReadOnlyIpr, - IPR_SL_RCV, - IPR_MM_STAT, - IPR_ITB_PTE_TEMP, - MaxReadOnlyIpr, - IPR_DTB_PTE_TEMP = MaxReadOnlyIpr, - - IPR_ISR, - IPR_ITB_TAG, - IPR_ITB_PTE, - IPR_ITB_ASN, - IPR_ITB_IS, - IPR_SIRR, - IPR_ASTRR, - IPR_ASTER, - IPR_EXC_ADDR, - IPR_EXC_SUM, - IPR_EXC_MASK, - IPR_PAL_BASE, - IPR_ICM, - IPR_IPLR, - IPR_IFAULT_VA_FORM, - IPR_IVPTBR, - IPR_ICSR, - IPR_IC_PERR_STAT, - IPR_PMCTR, - - // PAL temporary registers... - // register meanings gleaned from osfpal.s source code - IPR_PALtemp0, - IPR_PALtemp1, - IPR_PALtemp2, - IPR_PALtemp3, - IPR_PALtemp4, - IPR_PALtemp5, - IPR_PALtemp6, - IPR_PALtemp7, - IPR_PALtemp8, - IPR_PALtemp9, - IPR_PALtemp10, - IPR_PALtemp11, - IPR_PALtemp12, - IPR_PALtemp13, - IPR_PALtemp14, - IPR_PALtemp15, - IPR_PALtemp16, - IPR_PALtemp17, - IPR_PALtemp18, - IPR_PALtemp19, - IPR_PALtemp20, - IPR_PALtemp21, - IPR_PALtemp22, - IPR_PALtemp23, - - IPR_DTB_ASN, - IPR_DTB_CM, - IPR_DTB_TAG, - IPR_DTB_PTE, - - IPR_VA, - IPR_VA_FORM, - IPR_MVPTBR, - IPR_DTB_IS, - IPR_CC, - IPR_CC_CTL, - IPR_MCSR, - - IPR_DC_PERR_STAT, - IPR_DC_TEST_CTL, - IPR_DC_TEST_TAG, - IPR_DC_TEST_TAG_TEMP, - IPR_DC_MODE, - IPR_MAF_MODE, - - NumInternalProcRegs // number of IPR registers - }; - - inline bool IprIsWritable(int index) - { - return index < MinReadOnlyIpr || index > MaxReadOnlyIpr; - } - - inline bool IprIsReadable(int index) - { - return index < MinWriteOnlyIpr || index > MaxWriteOnlyIpr; - } - - extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs]; - extern int IprToMiscRegIndex[MaxInternalProcRegs]; - - void initializeIprTable(); + //Write only + MinWriteOnlyIpr, + IPR_HWINT_CLR = MinWriteOnlyIpr, + IPR_SL_XMIT, + IPR_DC_FLUSH, + IPR_IC_FLUSH, + IPR_ALT_MODE, + IPR_DTB_IA, + IPR_DTB_IAP, + IPR_ITB_IA, + MaxWriteOnlyIpr, + IPR_ITB_IAP = MaxWriteOnlyIpr, + + //Read only + MinReadOnlyIpr, + IPR_INTID = MinReadOnlyIpr, + IPR_SL_RCV, + IPR_MM_STAT, + IPR_ITB_PTE_TEMP, + MaxReadOnlyIpr, + IPR_DTB_PTE_TEMP = MaxReadOnlyIpr, + + IPR_ISR, + IPR_ITB_TAG, + IPR_ITB_PTE, + IPR_ITB_ASN, + IPR_ITB_IS, + IPR_SIRR, + IPR_ASTRR, + IPR_ASTER, + IPR_EXC_ADDR, + IPR_EXC_SUM, + IPR_EXC_MASK, + IPR_PAL_BASE, + IPR_ICM, + IPR_IPLR, + IPR_IFAULT_VA_FORM, + IPR_IVPTBR, + IPR_ICSR, + IPR_IC_PERR_STAT, + IPR_PMCTR, + + // PAL temporary registers... + // register meanings gleaned from osfpal.s source code + IPR_PALtemp0, + IPR_PALtemp1, + IPR_PALtemp2, + IPR_PALtemp3, + IPR_PALtemp4, + IPR_PALtemp5, + IPR_PALtemp6, + IPR_PALtemp7, + IPR_PALtemp8, + IPR_PALtemp9, + IPR_PALtemp10, + IPR_PALtemp11, + IPR_PALtemp12, + IPR_PALtemp13, + IPR_PALtemp14, + IPR_PALtemp15, + IPR_PALtemp16, + IPR_PALtemp17, + IPR_PALtemp18, + IPR_PALtemp19, + IPR_PALtemp20, + IPR_PALtemp21, + IPR_PALtemp22, + IPR_PALtemp23, + + IPR_DTB_ASN, + IPR_DTB_CM, + IPR_DTB_TAG, + IPR_DTB_PTE, + + IPR_VA, + IPR_VA_FORM, + IPR_MVPTBR, + IPR_DTB_IS, + IPR_CC, + IPR_CC_CTL, + IPR_MCSR, + + IPR_DC_PERR_STAT, + IPR_DC_TEST_CTL, + IPR_DC_TEST_TAG, + IPR_DC_TEST_TAG_TEMP, + IPR_DC_MODE, + IPR_MAF_MODE, + + NumInternalProcRegs // number of IPR registers +}; + +inline bool +IprIsWritable(int index) +{ + return index < MinReadOnlyIpr || index > MaxReadOnlyIpr; +} + +inline bool +IprIsReadable(int index) +{ + return index < MinWriteOnlyIpr || index > MaxWriteOnlyIpr; } -#endif +extern md_ipr_names MiscRegIndexToIpr[NumInternalProcRegs]; +extern int IprToMiscRegIndex[MaxInternalProcRegs]; + +void initializeIprTable(); + +} // namespace AlphaISA + +#endif // __ARCH_ALPHA_IPR_HH__ diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 2177e8c4f..0b2a31410 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -638,7 +638,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->readMiscReg(AlphaISA::IPR_CC) + (Rb & 0); + Ra = xc->readMiscReg(IPR_CC) + (Rb & 0); #else Ra = curTick; @@ -690,7 +690,7 @@ decode OPCODE default Unknown::unknown() { 0x00: CallPal::call_pal({{ if (!palValid || (palPriv - && xc->readMiscReg(AlphaISA::IPR_ICM) != AlphaISA::mode_kernel)) { + && xc->readMiscReg(IPR_ICM) != mode_kernel)) { // invalid pal function code, or attempt to do privileged // PAL call in non-kernel mode fault = new UnimplementedOpcodeFault; @@ -701,8 +701,8 @@ decode OPCODE default Unknown::unknown() { bool dopal = xc->simPalCheck(palFunc); if (dopal) { - xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, NPC); - NPC = xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + palOffset; + xc->setMiscReg(IPR_EXC_ADDR, NPC); + NPC = xc->readMiscReg(IPR_PAL_BASE) + palOffset; } } }}, IsNonSpeculative); @@ -783,14 +783,19 @@ decode OPCODE default Unknown::unknown() { } } - format BasicOperate { - 0x1e: decode PALMODE { - 0: OpcdecFault::hw_rei(); - 1:hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore); + 0x1e: decode PALMODE { + 0: OpcdecFault::hw_rei(); + format BasicOperate { + 1: hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore); } + } + +#endif + format BasicOperate { // M5 special opcodes use the reserved 0x01 opcode space 0x01: decode M5FUNC { +#if FULL_SYSTEM 0x00: arm({{ PseudoInst::arm(xc->tcBase()); }}, IsNonSpeculative); @@ -806,22 +811,34 @@ decode OPCODE default Unknown::unknown() { 0x04: quiesceTime({{ R0 = PseudoInst::quiesceTime(xc->tcBase()); }}, IsNonSpeculative, IsUnverifiable); - 0x10: ivlb({{ - warn_once("Obsolete M5 instruction ivlb encountered.\n"); +#endif + 0x07: rpns({{ + R0 = PseudoInst::rpns(xc->tcBase()); + }}, IsNonSpeculative, IsUnverifiable); + 0x09: wakeCPU({{ + PseudoInst::wakeCPU(xc->tcBase(), R16); + }}, IsNonSpeculative, IsUnverifiable); + 0x10: deprecated_ivlb({{ + warn_once("Obsolete M5 ivlb instruction encountered.\n"); }}); - 0x11: ivle({{ - warn_once("Obsolete M5 instruction ivlb encountered.\n"); + 0x11: deprecated_ivle({{ + warn_once("Obsolete M5 ivlb instruction encountered.\n"); }}); - 0x20: m5exit_old({{ - PseudoInst::m5exit_old(xc->tcBase()); + 0x20: deprecated_exit ({{ + warn_once("deprecated M5 exit instruction encountered.\n"); + PseudoInst::m5exit(xc->tcBase(), 0); }}, No_OpClass, IsNonSpeculative); 0x21: m5exit({{ PseudoInst::m5exit(xc->tcBase(), R16); }}, No_OpClass, IsNonSpeculative); +#if FULL_SYSTEM 0x31: loadsymbol({{ PseudoInst::loadsymbol(xc->tcBase()); }}, No_OpClass, IsNonSpeculative); - 0x30: initparam({{ Ra = xc->tcBase()->getCpuPtr()->system->init_param; }}); + 0x30: initparam({{ + Ra = xc->tcBase()->getCpuPtr()->system->init_param; + }}); +#endif 0x40: resetstats({{ PseudoInst::resetstats(xc->tcBase(), R16, R17); }}, IsNonSpeculative); @@ -834,28 +851,93 @@ decode OPCODE default Unknown::unknown() { 0x43: m5checkpoint({{ PseudoInst::m5checkpoint(xc->tcBase(), R16, R17); }}, IsNonSpeculative); +#if FULL_SYSTEM 0x50: m5readfile({{ R0 = PseudoInst::readfile(xc->tcBase(), R16, R17, R18); }}, IsNonSpeculative); +#endif 0x51: m5break({{ PseudoInst::debugbreak(xc->tcBase()); }}, IsNonSpeculative); 0x52: m5switchcpu({{ PseudoInst::switchcpu(xc->tcBase()); }}, IsNonSpeculative); +#if FULL_SYSTEM 0x53: m5addsymbol({{ PseudoInst::addsymbol(xc->tcBase(), R16, R17); }}, IsNonSpeculative); +#endif 0x54: m5panic({{ panic("M5 panic instruction called at pc=%#x.", xc->readPC()); }}, IsNonSpeculative); - 0x55: m5anBegin({{ - PseudoInst::anBegin(xc->tcBase(), R16); +#define CPANN(lbl) CPA::cpa()->lbl(xc->tcBase()) + 0x55: decode RA { + 0x00: m5a_old({{ + panic("Deprecated M5 annotate instruction executed at pc=%#x\n", + xc->readPC()); + }}, IsNonSpeculative); + 0x01: m5a_bsm({{ + CPANN(swSmBegin); + }}, IsNonSpeculative); + 0x02: m5a_esm({{ + CPANN(swSmEnd); + }}, IsNonSpeculative); + 0x03: m5a_begin({{ + CPANN(swExplictBegin); + }}, IsNonSpeculative); + 0x04: m5a_end({{ + CPANN(swEnd); + }}, IsNonSpeculative); + 0x06: m5a_q({{ + CPANN(swQ); + }}, IsNonSpeculative); + 0x07: m5a_dq({{ + CPANN(swDq); + }}, IsNonSpeculative); + 0x08: m5a_wf({{ + CPANN(swWf); + }}, IsNonSpeculative); + 0x09: m5a_we({{ + CPANN(swWe); + }}, IsNonSpeculative); + 0x0C: m5a_sq({{ + CPANN(swSq); + }}, IsNonSpeculative); + 0x0D: m5a_aq({{ + CPANN(swAq); + }}, IsNonSpeculative); + 0x0E: m5a_pq({{ + CPANN(swPq); + }}, IsNonSpeculative); + 0x0F: m5a_l({{ + CPANN(swLink); + }}, IsNonSpeculative); + 0x10: m5a_identify({{ + CPANN(swIdentify); + }}, IsNonSpeculative); + 0x11: m5a_getid({{ + R0 = CPANN(swGetId); + }}, IsNonSpeculative); + 0x13: m5a_scl({{ + CPANN(swSyscallLink); + }}, IsNonSpeculative); + 0x14: m5a_rq({{ + CPANN(swRq); + }}, IsNonSpeculative); + } // M5 Annotate Operations +#undef CPANN + 0x56: m5reserved2({{ + warn("M5 reserved opcode ignored"); + }}, IsNonSpeculative); + 0x57: m5reserved3({{ + warn("M5 reserved opcode ignored"); }}, IsNonSpeculative); - 0x56: m5anWait({{ - PseudoInst::anWait(xc->tcBase(), R16, R17); + 0x58: m5reserved4({{ + warn("M5 reserved opcode ignored"); + }}, IsNonSpeculative); + 0x59: m5reserved5({{ + warn("M5 reserved opcode ignored"); }}, IsNonSpeculative); } } -#endif } diff --git a/src/arch/alpha/isa/fp.isa b/src/arch/alpha/isa/fp.isa index 773e7d10c..ed04d2a50 100644 --- a/src/arch/alpha/isa/fp.isa +++ b/src/arch/alpha/isa/fp.isa @@ -46,7 +46,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->readMiscReg(AlphaISA::IPR_ICSR))) { + if (!ICSR_FPE(xc->readMiscReg(IPR_ICSR))) { fault = new FloatEnableFault; } return fault; @@ -229,7 +229,7 @@ def template FloatingPointExecute {{ %(code)s; } else { m5_fesetround(getC99RoundingMode( - xc->readMiscRegNoEffect(AlphaISA::MISCREG_FPCR))); + xc->readMiscRegNoEffect(MISCREG_FPCR))); %(code)s; m5_fesetround(M5_FE_TONEAREST); } diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index d72dfe34a..aea44976c 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -68,9 +68,8 @@ using namespace AlphaISA; output exec {{ #include <math.h> -#if FULL_SYSTEM +#include "base/cp_annotate.hh" #include "sim/pseudo_inst.hh" -#endif #include "arch/alpha/ipr.hh" #include "base/fenv.hh" #include "config/ss_compatible_fp.hh" @@ -173,11 +172,11 @@ def operands {{ # Int regs default to unsigned, but code should not count on this. # For clarity, descriptions that depend on unsigned behavior should # explicitly specify '.uq'. - 'Ra': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RA] : RA', + 'Ra': ('IntReg', 'uq', 'PALMODE ? reg_redir[RA] : RA', 'IsInteger', 1), - 'Rb': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RB] : RB', + 'Rb': ('IntReg', 'uq', 'PALMODE ? reg_redir[RB] : RB', 'IsInteger', 2), - 'Rc': ('IntReg', 'uq', 'PALMODE ? AlphaISA::reg_redir[RC] : RC', + 'Rc': ('IntReg', 'uq', 'PALMODE ? reg_redir[RC] : RC', 'IsInteger', 3), 'Fa': ('FloatReg', 'df', 'FA', 'IsFloating', 1), 'Fb': ('FloatReg', 'df', 'FB', 'IsFloating', 2), diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa index fe0daf772..cd5e117ec 100644 --- a/src/arch/alpha/isa/mem.isa +++ b/src/arch/alpha/isa/mem.isa @@ -43,7 +43,7 @@ output header {{ protected: /// Memory request flags. See mem_req_base.hh. - unsigned memAccessFlags; + Request::Flags memAccessFlags; /// Pointer to EAComp object. const StaticInstPtr eaCompPtr; /// Pointer to MemAcc object. @@ -54,7 +54,7 @@ output header {{ StaticInstPtr _eaCompPtr = nullStaticInstPtr, StaticInstPtr _memAccPtr = nullStaticInstPtr) : AlphaStaticInst(mnem, _machInst, __opClass), - memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) + eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr) { } @@ -677,6 +677,7 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, inst_flags) if mem_flags: + mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';' iop.constructor += s memacc_iop.constructor += s diff --git a/src/arch/alpha/isa/pal.isa b/src/arch/alpha/isa/pal.isa index 294b92e2f..3d3b81600 100644 --- a/src/arch/alpha/isa/pal.isa +++ b/src/arch/alpha/isa/pal.isa @@ -174,11 +174,11 @@ output decoder {{ : Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr), disp(HW_LDST_DISP) { - memAccessFlags = 0; - if (HW_LDST_PHYS) memAccessFlags |= PHYSICAL; - if (HW_LDST_ALT) memAccessFlags |= ALTMODE; - if (HW_LDST_VPTE) memAccessFlags |= VPTE; - if (HW_LDST_LOCK) memAccessFlags |= LOCKED; + memAccessFlags.clear(); + if (HW_LDST_PHYS) memAccessFlags.set(Request::PHYSICAL); + if (HW_LDST_ALT) memAccessFlags.set(Request::ALTMODE); + if (HW_LDST_VPTE) memAccessFlags.set(Request::VPTE); + if (HW_LDST_LOCK) memAccessFlags.set(Request::LOCKED); } std::string diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh index be1d1b8bb..d37a769ea 100644 --- a/src/arch/alpha/isa_traits.hh +++ b/src/arch/alpha/isa_traits.hh @@ -42,142 +42,134 @@ namespace LittleEndianGuest {} class StaticInstPtr; -namespace AlphaISA +namespace AlphaISA { + +using namespace LittleEndianGuest; +using AlphaISAInst::MaxInstSrcRegs; +using AlphaISAInst::MaxInstDestRegs; + +// These enumerate all the registers for dependence tracking. +enum DependenceTags { + // 0..31 are the integer regs 0..31 + // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag) + FP_Base_DepTag = 40, + Ctrl_Base_DepTag = 72 +}; + +StaticInstPtr decodeInst(ExtMachInst); + +// Alpha Does NOT have a delay slot +#define ISA_HAS_DELAY_SLOT 0 + +const Addr PageShift = 13; +const Addr PageBytes = ULL(1) << PageShift; +const Addr PageMask = ~(PageBytes - 1); +const Addr PageOffset = PageBytes - 1; + +//////////////////////////////////////////////////////////////////////// +// +// Translation stuff +// + +const Addr PteShift = 3; +const Addr NPtePageShift = PageShift - PteShift; +const Addr NPtePage = ULL(1) << NPtePageShift; +const Addr PteMask = NPtePage - 1; + +// User Virtual +const Addr USegBase = ULL(0x0); +const Addr USegEnd = ULL(0x000003ffffffffff); + +// Kernel Direct Mapped +const Addr K0SegBase = ULL(0xfffffc0000000000); +const Addr K0SegEnd = ULL(0xfffffdffffffffff); + +// Kernel Virtual +const Addr K1SegBase = ULL(0xfffffe0000000000); +const Addr K1SegEnd = ULL(0xffffffffffffffff); + +// For loading... XXX This maybe could be USegEnd?? --ali +const Addr LoadAddrMask = ULL(0xffffffffff); + +//////////////////////////////////////////////////////////////////////// +// +// Interrupt levels +// +enum InterruptLevels { - using namespace LittleEndianGuest; - using AlphaISAInst::MaxInstSrcRegs; - using AlphaISAInst::MaxInstDestRegs; - - // These enumerate all the registers for dependence tracking. - enum DependenceTags { - // 0..31 are the integer regs 0..31 - // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag) - FP_Base_DepTag = 40, - Ctrl_Base_DepTag = 72 - }; - - StaticInstPtr decodeInst(ExtMachInst); - - // Alpha Does NOT have a delay slot - #define ISA_HAS_DELAY_SLOT 0 - - const Addr PageShift = 13; - const Addr PageBytes = ULL(1) << PageShift; - const Addr PageMask = ~(PageBytes - 1); - const Addr PageOffset = PageBytes - 1; - - - //////////////////////////////////////////////////////////////////////// - // - // Translation stuff - // - - const Addr PteShift = 3; - const Addr NPtePageShift = PageShift - PteShift; - const Addr NPtePage = ULL(1) << NPtePageShift; - const Addr PteMask = NPtePage - 1; - - // User Virtual - const Addr USegBase = ULL(0x0); - const Addr USegEnd = ULL(0x000003ffffffffff); - - // Kernel Direct Mapped - const Addr K0SegBase = ULL(0xfffffc0000000000); - const Addr K0SegEnd = ULL(0xfffffdffffffffff); - - // Kernel Virtual - const Addr K1SegBase = ULL(0xfffffe0000000000); - const Addr K1SegEnd = ULL(0xffffffffffffffff); - - // For loading... XXX This maybe could be USegEnd?? --ali - const Addr LoadAddrMask = ULL(0xffffffffff); - -#if FULL_SYSTEM - - //////////////////////////////////////////////////////////////////////// - // - // Interrupt levels - // - enum InterruptLevels - { - INTLEVEL_SOFTWARE_MIN = 4, - INTLEVEL_SOFTWARE_MAX = 19, - - INTLEVEL_EXTERNAL_MIN = 20, - INTLEVEL_EXTERNAL_MAX = 34, - - INTLEVEL_IRQ0 = 20, - INTLEVEL_IRQ1 = 21, - INTINDEX_ETHERNET = 0, - INTINDEX_SCSI = 1, - INTLEVEL_IRQ2 = 22, - INTLEVEL_IRQ3 = 23, - - INTLEVEL_SERIAL = 33, - - NumInterruptLevels = INTLEVEL_EXTERNAL_MAX - }; - -#endif - - // EV5 modes - enum mode_type - { - mode_kernel = 0, // kernel - mode_executive = 1, // executive (unused by unix) - mode_supervisor = 2, // supervisor (unused by unix) - mode_user = 3, // user mode - mode_number // number of modes - }; - - // Constants Related to the number of registers - - const int NumIntArchRegs = 32; - const int NumPALShadowRegs = 8; - const int NumFloatArchRegs = 32; - // @todo: Figure out what this number really should be. - const int NumMiscArchRegs = 77; - - const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs; - const int NumFloatRegs = NumFloatArchRegs; - const int NumMiscRegs = NumMiscArchRegs; - - const int TotalNumRegs = NumIntRegs + NumFloatRegs + - NumMiscRegs + NumInternalProcRegs; - - const int TotalDataRegs = NumIntRegs + NumFloatRegs; - - // semantically meaningful register indices - const int ZeroReg = 31; // architecturally meaningful - // the rest of these depend on the ABI - const int StackPointerReg = 30; - const int GlobalPointerReg = 29; - const int ProcedureValueReg = 27; - const int ReturnAddressReg = 26; - const int ReturnValueReg = 0; - const int FramePointerReg = 15; + INTLEVEL_SOFTWARE_MIN = 4, + INTLEVEL_SOFTWARE_MAX = 19, + + INTLEVEL_EXTERNAL_MIN = 20, + INTLEVEL_EXTERNAL_MAX = 34, - const int ArgumentReg[] = {16, 17, 18, 19, 20, 21}; - const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); + INTLEVEL_IRQ0 = 20, + INTLEVEL_IRQ1 = 21, + INTINDEX_ETHERNET = 0, + INTINDEX_SCSI = 1, + INTLEVEL_IRQ2 = 22, + INTLEVEL_IRQ3 = 23, - const int SyscallNumReg = ReturnValueReg; - const int SyscallPseudoReturnReg = ArgumentReg[4]; - const int SyscallSuccessReg = 19; + INTLEVEL_SERIAL = 33, - const int LogVMPageSize = 13; // 8K bytes - const int VMPageSize = (1 << LogVMPageSize); - - const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned - - const int MachineBytes = 8; - const int WordBytes = 4; - const int HalfwordBytes = 2; - const int ByteBytes = 1; - - // return a no-op instruction... used for instruction fetch faults - // Alpha UNOP (ldq_u r31,0(r0)) - const ExtMachInst NoopMachInst = 0x2ffe0000; + NumInterruptLevels = INTLEVEL_EXTERNAL_MAX +}; +// EV5 modes +enum mode_type +{ + mode_kernel = 0, // kernel + mode_executive = 1, // executive (unused by unix) + mode_supervisor = 2, // supervisor (unused by unix) + mode_user = 3, // user mode + mode_number // number of modes }; +// Constants Related to the number of registers + +const int NumIntArchRegs = 32; +const int NumPALShadowRegs = 8; +const int NumFloatArchRegs = 32; +// @todo: Figure out what this number really should be. +const int NumMiscArchRegs = 77; + +const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs; +const int NumFloatRegs = NumFloatArchRegs; +const int NumMiscRegs = NumMiscArchRegs; + +const int TotalNumRegs = + NumIntRegs + NumFloatRegs + NumMiscRegs + NumInternalProcRegs; + +const int TotalDataRegs = NumIntRegs + NumFloatRegs; + +// semantically meaningful register indices +const int ZeroReg = 31; // architecturally meaningful +// the rest of these depend on the ABI +const int StackPointerReg = 30; +const int GlobalPointerReg = 29; +const int ProcedureValueReg = 27; +const int ReturnAddressReg = 26; +const int ReturnValueReg = 0; +const int FramePointerReg = 15; + +const int SyscallNumReg = 0; +const int FirstArgumentReg = 16; +const int SyscallPseudoReturnReg = 20; + +const int LogVMPageSize = 13; // 8K bytes +const int VMPageSize = (1 << LogVMPageSize); + +const int BranchPredAddrShiftAmt = 2; // instructions are 4-byte aligned + +const int MachineBytes = 8; +const int WordBytes = 4; +const int HalfwordBytes = 2; +const int ByteBytes = 1; + +// return a no-op instruction... used for instruction fetch faults +// Alpha UNOP (ldq_u r31,0(r0)) +const ExtMachInst NoopMachInst = 0x2ffe0000; + +} // namespace AlphaISA + #endif // __ARCH_ALPHA_ISA_TRAITS_HH__ diff --git a/src/arch/alpha/kernel_stats.cc b/src/arch/alpha/kernel_stats.cc index a004d5f25..6e9dc1611 100644 --- a/src/arch/alpha/kernel_stats.cc +++ b/src/arch/alpha/kernel_stats.cc @@ -152,7 +152,7 @@ Statistics::changeMode(cpu_mode newmode, ThreadContext *tc) void Statistics::mode(cpu_mode newmode, ThreadContext *tc) { - Addr pcbb = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23); + Addr pcbb = tc->readMiscRegNoEffect(IPR_PALtemp23); if (newmode == kernel && pcbb == idleProcess) newmode = idle; @@ -213,5 +213,5 @@ Statistics::unserialize(Checkpoint *cp, const string §ion) themode = (cpu_mode)exemode; } -} /* end namespace AlphaISA::Kernel */ -} /* end namespace AlphaISA */ +} // namespace Kernel +} // namespace AlphaISA diff --git a/src/arch/alpha/kernel_stats.hh b/src/arch/alpha/kernel_stats.hh index 7b8640ad7..837269309 100644 --- a/src/arch/alpha/kernel_stats.hh +++ b/src/arch/alpha/kernel_stats.hh @@ -62,15 +62,15 @@ class Statistics : public ::Kernel::Statistics void changeMode(cpu_mode newmode, ThreadContext *tc); private: - Stats::Vector<> _callpal; -// Stats::Vector<> _faults; + Stats::Vector _callpal; +// Stats::Vector _faults; - Stats::Vector<> _mode; - Stats::Vector<> _modeGood; + Stats::Vector _mode; + Stats::Vector _modeGood; Stats::Formula _modeFraction; - Stats::Vector<> _modeTicks; + Stats::Vector _modeTicks; - Stats::Scalar<> _swap_context; + Stats::Scalar _swap_context; public: Statistics(System *system); @@ -90,7 +90,7 @@ class Statistics : public ::Kernel::Statistics void unserialize(Checkpoint *cp, const std::string §ion); }; -} /* end namespace AlphaISA::Kernel */ -} /* end namespace AlphaISA */ +} // namespace Kernel +} // namespace AlphaISA #endif // __ARCH_ALPHA_KERNEL_STATS_HH__ diff --git a/src/arch/alpha/linux/linux.cc b/src/arch/alpha/linux/linux.cc index e6908a572..ad8388096 100644 --- a/src/arch/alpha/linux/linux.cc +++ b/src/arch/alpha/linux/linux.cc @@ -28,47 +28,44 @@ * Authors: Korey Sewell */ -#include "arch/alpha/linux/linux.hh" - #include <fcntl.h> +#include "arch/alpha/linux/linux.hh" + // open(2) flags translation table OpenFlagTransTable AlphaLinux::openFlagTable[] = { #ifdef _MSC_VER - { AlphaLinux::TGT_O_RDONLY, _O_RDONLY }, - { AlphaLinux::TGT_O_WRONLY, _O_WRONLY }, - { AlphaLinux::TGT_O_RDWR, _O_RDWR }, - { AlphaLinux::TGT_O_APPEND, _O_APPEND }, - { AlphaLinux::TGT_O_CREAT, _O_CREAT }, - { AlphaLinux::TGT_O_TRUNC, _O_TRUNC }, - { AlphaLinux::TGT_O_EXCL, _O_EXCL }, + { AlphaLinux::TGT_O_RDONLY, _O_RDONLY }, + { AlphaLinux::TGT_O_WRONLY, _O_WRONLY }, + { AlphaLinux::TGT_O_RDWR, _O_RDWR }, + { AlphaLinux::TGT_O_APPEND, _O_APPEND }, + { AlphaLinux::TGT_O_CREAT, _O_CREAT }, + { AlphaLinux::TGT_O_TRUNC, _O_TRUNC }, + { AlphaLinux::TGT_O_EXCL, _O_EXCL }, #ifdef _O_NONBLOCK - { AlphaLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, + { AlphaLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, #endif #ifdef _O_NOCTTY - { AlphaLinux::TGT_O_NOCTTY, _O_NOCTTY }, + { AlphaLinux::TGT_O_NOCTTY, _O_NOCTTY }, #endif #ifdef _O_SYNC - { AlphaLinux::TGT_O_SYNC, _O_SYNC }, + { AlphaLinux::TGT_O_SYNC, _O_SYNC }, #endif #else /* !_MSC_VER */ - { AlphaLinux::TGT_O_RDONLY, O_RDONLY }, - { AlphaLinux::TGT_O_WRONLY, O_WRONLY }, - { AlphaLinux::TGT_O_RDWR, O_RDWR }, - { AlphaLinux::TGT_O_APPEND, O_APPEND }, - { AlphaLinux::TGT_O_CREAT, O_CREAT }, - { AlphaLinux::TGT_O_TRUNC, O_TRUNC }, - { AlphaLinux::TGT_O_EXCL, O_EXCL }, - { AlphaLinux::TGT_O_NONBLOCK, O_NONBLOCK }, - { AlphaLinux::TGT_O_NOCTTY, O_NOCTTY }, + { AlphaLinux::TGT_O_RDONLY, O_RDONLY }, + { AlphaLinux::TGT_O_WRONLY, O_WRONLY }, + { AlphaLinux::TGT_O_RDWR, O_RDWR }, + { AlphaLinux::TGT_O_APPEND, O_APPEND }, + { AlphaLinux::TGT_O_CREAT, O_CREAT }, + { AlphaLinux::TGT_O_TRUNC, O_TRUNC }, + { AlphaLinux::TGT_O_EXCL, O_EXCL }, + { AlphaLinux::TGT_O_NONBLOCK, O_NONBLOCK }, + { AlphaLinux::TGT_O_NOCTTY, O_NOCTTY }, #ifdef O_SYNC - { AlphaLinux::TGT_O_SYNC, O_SYNC }, + { AlphaLinux::TGT_O_SYNC, O_SYNC }, #endif #endif /* _MSC_VER */ }; const int AlphaLinux::NUM_OPEN_FLAGS = - (sizeof(AlphaLinux::openFlagTable)/sizeof(AlphaLinux::openFlagTable[0])); - - - + (sizeof(AlphaLinux::openFlagTable)/sizeof(AlphaLinux::openFlagTable[0])); diff --git a/src/arch/alpha/linux/linux.hh b/src/arch/alpha/linux/linux.hh index 84c04ebc3..c622c5ef1 100644 --- a/src/arch/alpha/linux/linux.hh +++ b/src/arch/alpha/linux/linux.hh @@ -28,8 +28,8 @@ * Authors: Korey Sewell */ -#ifndef __ALPHA_ALPHA_LINUX_HH -#define __ALPHA_ALPHA_LINUX_HH +#ifndef __ALPHA_ALPHA_LINUX_LINUX_HH__ +#define __ALPHA_ALPHA_LINUX_LINUX_HH__ #include "kern/linux/linux.hh" @@ -50,21 +50,21 @@ class AlphaLinux : public Linux //@{ /// open(2) flag values. - static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY - static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY - static const int TGT_O_RDWR = 00000002; //!< O_RDWR - static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK - static const int TGT_O_APPEND = 00000010; //!< O_APPEND - static const int TGT_O_CREAT = 00001000; //!< O_CREAT - static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC - static const int TGT_O_EXCL = 00004000; //!< O_EXCL - static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY - static const int TGT_O_SYNC = 00040000; //!< O_SYNC - static const int TGT_O_DRD = 00100000; //!< O_DRD - static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO - static const int TGT_O_CACHE = 00400000; //!< O_CACHE - static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC - static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC + static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 00000002; //!< O_RDWR + static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK + static const int TGT_O_APPEND = 00000010; //!< O_APPEND + static const int TGT_O_CREAT = 00001000; //!< O_CREAT + static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC + static const int TGT_O_EXCL = 00004000; //!< O_EXCL + static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY + static const int TGT_O_SYNC = 00040000; //!< O_SYNC + static const int TGT_O_DRD = 00100000; //!< O_DRD + static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO + static const int TGT_O_CACHE = 00400000; //!< O_CACHE + static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC + static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC //@} /// For mmap(). @@ -72,13 +72,13 @@ class AlphaLinux : public Linux //@{ /// For getsysinfo(). - static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string - static const unsigned GSI_CPU_INFO = 59; //!< CPU information - static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type - static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine - static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system - static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB - static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz + static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string + static const unsigned GSI_CPU_INFO = 59; //!< CPU information + static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type + static const unsigned GSI_MAX_CPU = 30; //!< max # CPUs on machine + static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system + static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB + static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz static const unsigned GSI_IEEE_FP_CONTROL = 45; //@} @@ -127,4 +127,4 @@ class AlphaLinux : public Linux }; }; -#endif +#endif // __ALPHA_ALPHA_LINUX_LINUX_HH__ diff --git a/src/arch/alpha/linux/process.cc b/src/arch/alpha/linux/process.cc index ec47992bd..aeff9fbed 100644 --- a/src/arch/alpha/linux/process.cc +++ b/src/arch/alpha/linux/process.cc @@ -43,18 +43,16 @@ using namespace std; using namespace AlphaISA; - - /// Target uname() handler. static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0)); + TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); - strcpy(name->release, "2.4.20"); + strcpy(name->release, "2.6.26"); strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003"); strcpy(name->machine, "alpha"); @@ -69,13 +67,13 @@ static SyscallReturn osf_getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); - // unsigned nbytes = tc->getSyscallArg(2); + unsigned op = process->getSyscallArg(tc, 0); + // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 45: { // GSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1)); + TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1)); // I don't think this exactly matches the HW FPCR *fpcr = 0; fpcr.copyOut(tc->getMemPort()); @@ -96,13 +94,13 @@ static SyscallReturn osf_setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); - // unsigned nbytes = tc->getSyscallArg(2); + unsigned op = process->getSyscallArg(tc, 0); + // unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case 14: { // SSI_IEEE_FP_CONTROL - TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1)); + TypedBufferArg<uint64_t> fpcr(process->getSyscallArg(tc, 1)); // I don't think this exactly matches the HW FPCR fpcr.copyIn(tc->getMemPort()); DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): " @@ -138,7 +136,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", chmodFunc<AlphaLinux>), /* 16 */ SyscallDesc("chown", chownFunc), - /* 17 */ SyscallDesc("brk", obreakFunc), + /* 17 */ SyscallDesc("brk", brkFunc), /* 18 */ SyscallDesc("osf_getfsstat", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getxpid", getpidPseudoFunc), @@ -179,9 +177,9 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 55 */ SyscallDesc("osf_reboot", unimplementedFunc), /* 56 */ SyscallDesc("osf_revoke", unimplementedFunc), /* 57 */ SyscallDesc("symlink", unimplementedFunc), - /* 58 */ SyscallDesc("readlink", unimplementedFunc), + /* 58 */ SyscallDesc("readlink", readlinkFunc), /* 59 */ SyscallDesc("execve", unimplementedFunc), - /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), /* 62 */ SyscallDesc("osf_old_fstat", unimplementedFunc), /* 63 */ SyscallDesc("getpgrp", unimplementedFunc), @@ -250,14 +248,14 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 126 */ SyscallDesc("setreuid", unimplementedFunc), /* 127 */ SyscallDesc("setregid", unimplementedFunc), /* 128 */ SyscallDesc("rename", renameFunc), - /* 129 */ SyscallDesc("truncate", unimplementedFunc), - /* 130 */ SyscallDesc("ftruncate", unimplementedFunc), + /* 129 */ SyscallDesc("truncate", truncateFunc), + /* 130 */ SyscallDesc("ftruncate", ftruncateFunc), /* 131 */ SyscallDesc("flock", unimplementedFunc), /* 132 */ SyscallDesc("setgid", unimplementedFunc), /* 133 */ SyscallDesc("sendto", unimplementedFunc), /* 134 */ SyscallDesc("shutdown", unimplementedFunc), /* 135 */ SyscallDesc("socketpair", unimplementedFunc), - /* 136 */ SyscallDesc("mkdir", unimplementedFunc), + /* 136 */ SyscallDesc("mkdir", mkdirFunc), /* 137 */ SyscallDesc("rmdir", unimplementedFunc), /* 138 */ SyscallDesc("osf_utimes", unimplementedFunc), /* 139 */ SyscallDesc("osf_old_sigreturn", unimplementedFunc), @@ -465,7 +463,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 338 */ SyscallDesc("afs_syscall", unimplementedFunc), /* 339 */ SyscallDesc("uname", unameFunc), /* 340 */ SyscallDesc("nanosleep", unimplementedFunc), - /* 341 */ SyscallDesc("mremap", unimplementedFunc), + /* 341 */ SyscallDesc("mremap", mremapFunc<AlphaLinux>), /* 342 */ SyscallDesc("nfsservctl", unimplementedFunc), /* 343 */ SyscallDesc("setresuid", unimplementedFunc), /* 344 */ SyscallDesc("getresuid", unimplementedFunc), @@ -491,7 +489,7 @@ SyscallDesc AlphaLinuxProcess::syscallDescs[] = { /* 364 */ SyscallDesc("getrusage", getrusageFunc<AlphaLinux>), /* 365 */ SyscallDesc("wait4", unimplementedFunc), /* 366 */ SyscallDesc("adjtimex", unimplementedFunc), - /* 367 */ SyscallDesc("getcwd", unimplementedFunc), + /* 367 */ SyscallDesc("getcwd", getcwdFunc), /* 368 */ SyscallDesc("capget", unimplementedFunc), /* 369 */ SyscallDesc("capset", unimplementedFunc), /* 370 */ SyscallDesc("sendfile", unimplementedFunc), @@ -581,7 +579,7 @@ AlphaLinuxProcess::AlphaLinuxProcess(LiveProcessParams * params, SyscallDesc* AlphaLinuxProcess::getDesc(int callnum) { - if (callnum < 0 || callnum > Num_Syscall_Descs) + if (callnum < 0 || callnum >= Num_Syscall_Descs) return NULL; return &syscallDescs[callnum]; } diff --git a/src/arch/alpha/linux/process.hh b/src/arch/alpha/linux/process.hh index 8d7c24e37..9ab7b0501 100644 --- a/src/arch/alpha/linux/process.hh +++ b/src/arch/alpha/linux/process.hh @@ -51,4 +51,5 @@ class AlphaLinuxProcess : public AlphaLiveProcess }; } // namespace AlphaISA + #endif // __ALPHA_LINUX_PROCESS_HH__ diff --git a/src/arch/alpha/linux/system.cc b/src/arch/alpha/linux/system.cc index 102598716..1d9332a58 100644 --- a/src/arch/alpha/linux/system.cc +++ b/src/arch/alpha/linux/system.cc @@ -157,7 +157,6 @@ LinuxAlphaSystem::~LinuxAlphaSystem() delete printThreadEvent; } - void LinuxAlphaSystem::setDelayLoop(ThreadContext *tc) { @@ -169,11 +168,9 @@ LinuxAlphaSystem::setDelayLoop(ThreadContext *tc) vp = tc->getVirtPort(); vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988)); - tc->delVirtPort(vp); } } - void LinuxAlphaSystem::SkipDelayLoopEvent::process(ThreadContext *tc) { diff --git a/src/arch/alpha/linux/system.hh b/src/arch/alpha/linux/system.hh index 00cde826a..3e4de7b2a 100644 --- a/src/arch/alpha/linux/system.hh +++ b/src/arch/alpha/linux/system.hh @@ -43,9 +43,6 @@ class IdleStartEvent; #include "kern/linux/events.hh" #include "params/LinuxAlphaSystem.hh" -using namespace AlphaISA; -using namespace Linux; - /** * This class contains linux specific system code (Loading, Events). * It points to objects that are the system binaries to load and patches them @@ -54,23 +51,20 @@ using namespace Linux; class LinuxAlphaSystem : public AlphaSystem { private: - class SkipDelayLoopEvent : public SkipFuncEvent + struct SkipDelayLoopEvent : public SkipFuncEvent { - public: SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr) : SkipFuncEvent(q, desc, addr) {} virtual void process(ThreadContext *tc); }; - class PrintThreadInfo : public PCEvent + struct PrintThreadInfo : public PCEvent { - public: PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr) : PCEvent(q, desc, addr) {} virtual void process(ThreadContext *tc); }; - /** * Addresses defining where the kernel bootloader places various * elements. Details found in include/asm-alpha/system.h @@ -112,7 +106,7 @@ class LinuxAlphaSystem : public AlphaSystem * PC based event to skip the dprink() call and emulate its * functionality */ - DebugPrintkEvent *debugPrintkEvent; + Linux::DebugPrintkEvent *debugPrintkEvent; /** * Skip calculate_delay_loop() rather than waiting for this to be diff --git a/src/arch/alpha/linux/threadinfo.hh b/src/arch/alpha/linux/threadinfo.hh index b0c8284be..db723bed3 100644 --- a/src/arch/alpha/linux/threadinfo.hh +++ b/src/arch/alpha/linux/threadinfo.hh @@ -55,7 +55,7 @@ class ThreadInfo CopyOut(tc, &data, addr, sizeof(T)); - data = TheISA::gtoh(data); + data = AlphaISA::gtoh(data); return true; } @@ -76,7 +76,7 @@ class ThreadInfo Addr sp; if (!addr) - addr = tc->readMiscRegNoEffect(TheISA::IPR_PALtemp23); + addr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp23); FunctionalPort *p = tc->getPhysPort(); p->readBlob(addr, (uint8_t *)&sp, sizeof(Addr)); @@ -147,6 +147,6 @@ class ThreadInfo } }; -/* namespace Linux */ } +} // namespace Linux #endif // __ARCH_ALPHA_LINUX_LINUX_THREADINFO_HH__ diff --git a/src/arch/alpha/locked_mem.hh b/src/arch/alpha/locked_mem.hh index df66b92bc..e8928ba08 100644 --- a/src/arch/alpha/locked_mem.hh +++ b/src/arch/alpha/locked_mem.hh @@ -49,9 +49,8 @@ #include "base/misc.hh" #include "mem/request.hh" +namespace AlphaISA { -namespace AlphaISA -{ template <class XC> inline void handleLockedRead(XC *xc, Request *req) @@ -86,9 +85,9 @@ handleLockedWrite(XC *xc, Request *req) stCondFailures++; xc->setStCondFailures(stCondFailures); if (stCondFailures % 100000 == 0) { - warn("cpu %d: %d consecutive " + warn("context %d: %d consecutive " "store conditional failures\n", - xc->readCpuId(), stCondFailures); + xc->contextId(), stCondFailures); } // store conditional failed already, so don't issue it to mem @@ -99,7 +98,6 @@ handleLockedWrite(XC *xc, Request *req) return true; } - } // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_LOCKED_MEM_HH__ diff --git a/src/arch/alpha/syscallreturn.hh b/src/arch/alpha/microcode_rom.hh index 47b4ac8c7..ef0602580 100644 --- a/src/arch/alpha/syscallreturn.hh +++ b/src/arch/alpha/microcode_rom.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2008 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,34 +25,17 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Steve Reinhardt - * Gabe Black + * Authors: Gabe Black */ -#ifndef __ARCH_ALPHA_SYSCALLRETURN_HH__ -#define __ARCH_ALPHA_SYSCALLRETURN_HH__ +#ifndef __ARCH_ALPHA_MICROCODE_ROM_HH__ +#define __ARCH_ALPHA_MICROCODE_ROM_HH__ -#include "cpu/thread_context.hh" -#include "sim/syscallreturn.hh" +#include "sim/microcode_rom.hh" namespace AlphaISA { - static inline void setSyscallReturn(SyscallReturn return_value, - ThreadContext * tc) - { - // check for error condition. Alpha syscall convention is to - // indicate success/failure in reg a3 (r19) and put the - // return value itself in the standard return value reg (v0). - if (return_value.successful()) { - // no error - tc->setIntReg(SyscallSuccessReg, 0); - tc->setIntReg(ReturnValueReg, return_value.value()); - } else { - // got an error, return details - tc->setIntReg(SyscallSuccessReg, (IntReg)-1); - tc->setIntReg(ReturnValueReg, -return_value.value()); - } - } + using ::MicrocodeRom; } -#endif +#endif // __ARCH_ALPHA_MICROCODE_ROM_HH__ diff --git a/src/arch/alpha/miscregfile.cc b/src/arch/alpha/miscregfile.cc index cb5875349..61a86f1fb 100644 --- a/src/arch/alpha/miscregfile.cc +++ b/src/arch/alpha/miscregfile.cc @@ -30,121 +30,121 @@ * Kevin Lim */ +#include <cassert> + #include "arch/alpha/miscregfile.hh" #include "base/misc.hh" -namespace AlphaISA -{ +namespace AlphaISA { - void - MiscRegFile::serialize(std::ostream &os) - { - SERIALIZE_SCALAR(fpcr); - SERIALIZE_SCALAR(uniq); - SERIALIZE_SCALAR(lock_flag); - SERIALIZE_SCALAR(lock_addr); - SERIALIZE_ARRAY(ipr, NumInternalProcRegs); - } +void +MiscRegFile::serialize(std::ostream &os) +{ + SERIALIZE_SCALAR(fpcr); + SERIALIZE_SCALAR(uniq); + SERIALIZE_SCALAR(lock_flag); + SERIALIZE_SCALAR(lock_addr); + SERIALIZE_ARRAY(ipr, NumInternalProcRegs); +} - void - MiscRegFile::unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_SCALAR(fpcr); - UNSERIALIZE_SCALAR(uniq); - UNSERIALIZE_SCALAR(lock_flag); - UNSERIALIZE_SCALAR(lock_addr); - UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs); - } +void +MiscRegFile::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(fpcr); + UNSERIALIZE_SCALAR(uniq); + UNSERIALIZE_SCALAR(lock_flag); + UNSERIALIZE_SCALAR(lock_addr); + UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs); +} - MiscReg - MiscRegFile::readRegNoEffect(int misc_reg) - { - switch(misc_reg) { - case MISCREG_FPCR: - return fpcr; - case MISCREG_UNIQ: - return uniq; - case MISCREG_LOCKFLAG: - return lock_flag; - case MISCREG_LOCKADDR: - return lock_addr; - case MISCREG_INTR: - return intr_flag; - default: - assert(misc_reg < NumInternalProcRegs); - return ipr[misc_reg]; - } +MiscReg +MiscRegFile::readRegNoEffect(int misc_reg) +{ + switch (misc_reg) { + case MISCREG_FPCR: + return fpcr; + case MISCREG_UNIQ: + return uniq; + case MISCREG_LOCKFLAG: + return lock_flag; + case MISCREG_LOCKADDR: + return lock_addr; + case MISCREG_INTR: + return intr_flag; + default: + assert(misc_reg < NumInternalProcRegs); + return ipr[misc_reg]; } +} - MiscReg - MiscRegFile::readReg(int misc_reg, ThreadContext *tc) - { - switch(misc_reg) { - case MISCREG_FPCR: - return fpcr; - case MISCREG_UNIQ: - return uniq; - case MISCREG_LOCKFLAG: - return lock_flag; - case MISCREG_LOCKADDR: - return lock_addr; - case MISCREG_INTR: - return intr_flag; - default: - return readIpr(misc_reg, tc); - } +MiscReg +MiscRegFile::readReg(int misc_reg, ThreadContext *tc) +{ + switch (misc_reg) { + case MISCREG_FPCR: + return fpcr; + case MISCREG_UNIQ: + return uniq; + case MISCREG_LOCKFLAG: + return lock_flag; + case MISCREG_LOCKADDR: + return lock_addr; + case MISCREG_INTR: + return intr_flag; + default: + return readIpr(misc_reg, tc); } +} - void - MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val) - { - switch(misc_reg) { - case MISCREG_FPCR: - fpcr = val; - return; - case MISCREG_UNIQ: - uniq = val; - return; - case MISCREG_LOCKFLAG: - lock_flag = val; - return; - case MISCREG_LOCKADDR: - lock_addr = val; - return; - case MISCREG_INTR: - intr_flag = val; - return; - default: - assert(misc_reg < NumInternalProcRegs); - ipr[misc_reg] = val; - return; - } +void +MiscRegFile::setRegNoEffect(int misc_reg, const MiscReg &val) +{ + switch (misc_reg) { + case MISCREG_FPCR: + fpcr = val; + return; + case MISCREG_UNIQ: + uniq = val; + return; + case MISCREG_LOCKFLAG: + lock_flag = val; + return; + case MISCREG_LOCKADDR: + lock_addr = val; + return; + case MISCREG_INTR: + intr_flag = val; + return; + default: + assert(misc_reg < NumInternalProcRegs); + ipr[misc_reg] = val; + return; } +} - void - MiscRegFile::setReg(int misc_reg, const MiscReg &val, - ThreadContext *tc) - { - switch(misc_reg) { - case MISCREG_FPCR: - fpcr = val; - return; - case MISCREG_UNIQ: - uniq = val; - return; - case MISCREG_LOCKFLAG: - lock_flag = val; - return; - case MISCREG_LOCKADDR: - lock_addr = val; - return; - case MISCREG_INTR: - intr_flag = val; - return; - default: - setIpr(misc_reg, val, tc); - return; - } +void +MiscRegFile::setReg(int misc_reg, const MiscReg &val, ThreadContext *tc) +{ + switch (misc_reg) { + case MISCREG_FPCR: + fpcr = val; + return; + case MISCREG_UNIQ: + uniq = val; + return; + case MISCREG_LOCKFLAG: + lock_flag = val; + return; + case MISCREG_LOCKADDR: + lock_addr = val; + return; + case MISCREG_INTR: + intr_flag = val; + return; + default: + setIpr(misc_reg, val, tc); + return; } - } + +} // namespace AlphaISA diff --git a/src/arch/alpha/miscregfile.hh b/src/arch/alpha/miscregfile.hh index 022b6404a..6105ce683 100644 --- a/src/arch/alpha/miscregfile.hh +++ b/src/arch/alpha/miscregfile.hh @@ -32,85 +32,79 @@ #ifndef __ARCH_ALPHA_MISCREGFILE_HH__ #define __ARCH_ALPHA_MISCREGFILE_HH__ +#include <iosfwd> + #include "arch/alpha/ipr.hh" #include "arch/alpha/types.hh" #include "sim/host.hh" #include "sim/serialize.hh" -#include <iostream> - class Checkpoint; class ThreadContext; -namespace AlphaISA -{ - enum MiscRegIndex - { - MISCREG_FPCR = NumInternalProcRegs, - MISCREG_UNIQ, - MISCREG_LOCKFLAG, - MISCREG_LOCKADDR, - MISCREG_INTR - }; - - static inline std::string getMiscRegName(RegIndex) - { - return ""; - } - - 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 - int intr_flag; - - public: - MiscRegFile() - { - initializeIprTable(); - } +namespace AlphaISA { - MiscReg readRegNoEffect(int misc_reg); - - MiscReg readReg(int misc_reg, ThreadContext *tc); +enum MiscRegIndex +{ + MISCREG_FPCR = NumInternalProcRegs, + MISCREG_UNIQ, + MISCREG_LOCKFLAG, + MISCREG_LOCKADDR, + MISCREG_INTR +}; + +class MiscRegFile +{ + public: + friend class RegFile; + typedef uint64_t InternalProcReg; - //These functions should be removed once the simplescalar cpu model - //has been replaced. - int getInstAsid(); - int getDataAsid(); + 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 + int intr_flag; - void setRegNoEffect(int misc_reg, const MiscReg &val); + InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs - void setReg(int misc_reg, const MiscReg &val, - ThreadContext *tc); + protected: + InternalProcReg readIpr(int idx, ThreadContext *tc); + void setIpr(int idx, InternalProcReg val, ThreadContext *tc); - void clear() - { - fpcr = uniq = 0; - lock_flag = 0; - lock_addr = 0; - intr_flag = 0; - } + public: + MiscRegFile() + { + initializeIprTable(); + } - void serialize(std::ostream &os); + // These functions should be removed once the simplescalar cpu + // model has been replaced. + int getInstAsid(); + int getDataAsid(); - void unserialize(Checkpoint *cp, const std::string §ion); - protected: - typedef uint64_t InternalProcReg; + MiscReg readRegNoEffect(int misc_reg); + MiscReg readReg(int misc_reg, ThreadContext *tc); - InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs + void setRegNoEffect(int misc_reg, const MiscReg &val); + void setReg(int misc_reg, const MiscReg &val, ThreadContext *tc); - private: - InternalProcReg readIpr(int idx, ThreadContext *tc); + void + clear() + { + fpcr = 0; + uniq = 0; + lock_flag = 0; + lock_addr = 0; + intr_flag = 0; + } - void setIpr(int idx, InternalProcReg val, ThreadContext *tc); - friend class RegFile; - }; + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); +}; - void copyIprs(ThreadContext *src, ThreadContext *dest); +void copyIprs(ThreadContext *src, ThreadContext *dest); -} +} // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_MISCREGFILE_HH__ diff --git a/src/arch/alpha/mmaped_ipr.hh b/src/arch/alpha/mmaped_ipr.hh index 2b4ba8745..af2469ca7 100644 --- a/src/arch/alpha/mmaped_ipr.hh +++ b/src/arch/alpha/mmaped_ipr.hh @@ -39,9 +39,8 @@ #include "mem/packet.hh" +namespace AlphaISA { -namespace AlphaISA -{ inline Tick handleIprRead(ThreadContext *xc, Packet *pkt) { @@ -58,4 +57,4 @@ handleIprWrite(ThreadContext *xc, Packet *pkt) } // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_MMAPED_IPR_HH__ diff --git a/src/arch/alpha/osfpal.cc b/src/arch/alpha/osfpal.cc index ed1d255a6..58a3d31eb 100644 --- a/src/arch/alpha/osfpal.cc +++ b/src/arch/alpha/osfpal.cc @@ -30,275 +30,273 @@ #include "arch/alpha/osfpal.hh" -namespace { - const char *strings[PAL::NumCodes] = { +const char * +PAL::name(int index) +{ + static const char *strings[PAL::NumCodes] = { // Priviledged PAL instructions - "halt", // 0x00 - "cflush", // 0x01 - "draina", // 0x02 - 0, // 0x03 - 0, // 0x04 - 0, // 0x05 - 0, // 0x06 - 0, // 0x07 - 0, // 0x08 - "cserve", // 0x09 - "swppal", // 0x0a - 0, // 0x0b - 0, // 0x0c - "wripir", // 0x0d - 0, // 0x0e - 0, // 0x0f - "rdmces", // 0x10 - "wrmces", // 0x11 - 0, // 0x12 - 0, // 0x13 - 0, // 0x14 - 0, // 0x15 - 0, // 0x16 - 0, // 0x17 - 0, // 0x18 - 0, // 0x19 - 0, // 0x1a - 0, // 0x1b - 0, // 0x1c - 0, // 0x1d - 0, // 0x1e - 0, // 0x1f - 0, // 0x20 - 0, // 0x21 - 0, // 0x22 - 0, // 0x23 - 0, // 0x24 - 0, // 0x25 - 0, // 0x26 - 0, // 0x27 - 0, // 0x28 - 0, // 0x29 - 0, // 0x2a - "wrfen", // 0x2b - 0, // 0x2c - "wrvptptr", // 0x2d - 0, // 0x2e - 0, // 0x2f - "swpctx", // 0x30 - "wrval", // 0x31 - "rdval", // 0x32 - "tbi", // 0x33 - "wrent", // 0x34 - "swpipl", // 0x35 - "rdps", // 0x36 - "wrkgp", // 0x37 - "wrusp", // 0x38 - "wrperfmon", // 0x39 - "rdusp", // 0x3a - 0, // 0x3b - "whami", // 0x3c - "retsys", // 0x3d - "wtint", // 0x3e - "rti", // 0x3f - 0, // 0x40 - 0, // 0x41 - 0, // 0x42 - 0, // 0x43 - 0, // 0x44 - 0, // 0x45 - 0, // 0x46 - 0, // 0x47 - 0, // 0x48 - 0, // 0x49 - 0, // 0x4a - 0, // 0x4b - 0, // 0x4c - 0, // 0x4d - 0, // 0x4e - 0, // 0x4f - 0, // 0x50 - 0, // 0x51 - 0, // 0x52 - 0, // 0x53 - 0, // 0x54 - 0, // 0x55 - 0, // 0x56 - 0, // 0x57 - 0, // 0x58 - 0, // 0x59 - 0, // 0x5a - 0, // 0x5b - 0, // 0x5c - 0, // 0x5d - 0, // 0x5e - 0, // 0x5f - 0, // 0x60 - 0, // 0x61 - 0, // 0x62 - 0, // 0x63 - 0, // 0x64 - 0, // 0x65 - 0, // 0x66 - 0, // 0x67 - 0, // 0x68 - 0, // 0x69 - 0, // 0x6a - 0, // 0x6b - 0, // 0x6c - 0, // 0x6d - 0, // 0x6e - 0, // 0x6f - 0, // 0x70 - 0, // 0x71 - 0, // 0x72 - 0, // 0x73 - 0, // 0x74 - 0, // 0x75 - 0, // 0x76 - 0, // 0x77 - 0, // 0x78 - 0, // 0x79 - 0, // 0x7a - 0, // 0x7b - 0, // 0x7c - 0, // 0x7d - 0, // 0x7e - 0, // 0x7f + "halt", // 0x00 + "cflush", // 0x01 + "draina", // 0x02 + 0, // 0x03 + 0, // 0x04 + 0, // 0x05 + 0, // 0x06 + 0, // 0x07 + 0, // 0x08 + "cserve", // 0x09 + "swppal", // 0x0a + 0, // 0x0b + 0, // 0x0c + "wripir", // 0x0d + 0, // 0x0e + 0, // 0x0f + "rdmces", // 0x10 + "wrmces", // 0x11 + 0, // 0x12 + 0, // 0x13 + 0, // 0x14 + 0, // 0x15 + 0, // 0x16 + 0, // 0x17 + 0, // 0x18 + 0, // 0x19 + 0, // 0x1a + 0, // 0x1b + 0, // 0x1c + 0, // 0x1d + 0, // 0x1e + 0, // 0x1f + 0, // 0x20 + 0, // 0x21 + 0, // 0x22 + 0, // 0x23 + 0, // 0x24 + 0, // 0x25 + 0, // 0x26 + 0, // 0x27 + 0, // 0x28 + 0, // 0x29 + 0, // 0x2a + "wrfen", // 0x2b + 0, // 0x2c + "wrvptptr", // 0x2d + 0, // 0x2e + 0, // 0x2f + "swpctx", // 0x30 + "wrval", // 0x31 + "rdval", // 0x32 + "tbi", // 0x33 + "wrent", // 0x34 + "swpipl", // 0x35 + "rdps", // 0x36 + "wrkgp", // 0x37 + "wrusp", // 0x38 + "wrperfmon", // 0x39 + "rdusp", // 0x3a + 0, // 0x3b + "whami", // 0x3c + "retsys", // 0x3d + "wtint", // 0x3e + "rti", // 0x3f + 0, // 0x40 + 0, // 0x41 + 0, // 0x42 + 0, // 0x43 + 0, // 0x44 + 0, // 0x45 + 0, // 0x46 + 0, // 0x47 + 0, // 0x48 + 0, // 0x49 + 0, // 0x4a + 0, // 0x4b + 0, // 0x4c + 0, // 0x4d + 0, // 0x4e + 0, // 0x4f + 0, // 0x50 + 0, // 0x51 + 0, // 0x52 + 0, // 0x53 + 0, // 0x54 + 0, // 0x55 + 0, // 0x56 + 0, // 0x57 + 0, // 0x58 + 0, // 0x59 + 0, // 0x5a + 0, // 0x5b + 0, // 0x5c + 0, // 0x5d + 0, // 0x5e + 0, // 0x5f + 0, // 0x60 + 0, // 0x61 + 0, // 0x62 + 0, // 0x63 + 0, // 0x64 + 0, // 0x65 + 0, // 0x66 + 0, // 0x67 + 0, // 0x68 + 0, // 0x69 + 0, // 0x6a + 0, // 0x6b + 0, // 0x6c + 0, // 0x6d + 0, // 0x6e + 0, // 0x6f + 0, // 0x70 + 0, // 0x71 + 0, // 0x72 + 0, // 0x73 + 0, // 0x74 + 0, // 0x75 + 0, // 0x76 + 0, // 0x77 + 0, // 0x78 + 0, // 0x79 + 0, // 0x7a + 0, // 0x7b + 0, // 0x7c + 0, // 0x7d + 0, // 0x7e + 0, // 0x7f // Unpriviledged PAL instructions - "bpt", // 0x80 - "bugchk", // 0x81 - 0, // 0x82 - "callsys", // 0x83 - 0, // 0x84 - 0, // 0x85 - "imb", // 0x86 - 0, // 0x87 - 0, // 0x88 - 0, // 0x89 - 0, // 0x8a - 0, // 0x8b - 0, // 0x8c - 0, // 0x8d - 0, // 0x8e - 0, // 0x8f - 0, // 0x90 - 0, // 0x91 - "urti", // 0x92 - 0, // 0x93 - 0, // 0x94 - 0, // 0x95 - 0, // 0x96 - 0, // 0x97 - 0, // 0x98 - 0, // 0x99 - 0, // 0x9a - 0, // 0x9b - 0, // 0x9c - 0, // 0x9d - "rdunique", // 0x9e - "wrunique", // 0x9f - 0, // 0xa0 - 0, // 0xa1 - 0, // 0xa2 - 0, // 0xa3 - 0, // 0xa4 - 0, // 0xa5 - 0, // 0xa6 - 0, // 0xa7 - 0, // 0xa8 - 0, // 0xa9 - "gentrap", // 0xaa - 0, // 0xab - 0, // 0xac - 0, // 0xad - "clrfen", // 0xae - 0, // 0xaf - 0, // 0xb0 - 0, // 0xb1 - 0, // 0xb2 - 0, // 0xb3 - 0, // 0xb4 - 0, // 0xb5 - 0, // 0xb6 - 0, // 0xb7 - 0, // 0xb8 - 0, // 0xb9 - 0, // 0xba - 0, // 0xbb - 0, // 0xbc - 0, // 0xbd - "nphalt", // 0xbe - "copypal", // 0xbf + "bpt", // 0x80 + "bugchk", // 0x81 + 0, // 0x82 + "callsys", // 0x83 + 0, // 0x84 + 0, // 0x85 + "imb", // 0x86 + 0, // 0x87 + 0, // 0x88 + 0, // 0x89 + 0, // 0x8a + 0, // 0x8b + 0, // 0x8c + 0, // 0x8d + 0, // 0x8e + 0, // 0x8f + 0, // 0x90 + 0, // 0x91 + "urti", // 0x92 + 0, // 0x93 + 0, // 0x94 + 0, // 0x95 + 0, // 0x96 + 0, // 0x97 + 0, // 0x98 + 0, // 0x99 + 0, // 0x9a + 0, // 0x9b + 0, // 0x9c + 0, // 0x9d + "rdunique", // 0x9e + "wrunique", // 0x9f + 0, // 0xa0 + 0, // 0xa1 + 0, // 0xa2 + 0, // 0xa3 + 0, // 0xa4 + 0, // 0xa5 + 0, // 0xa6 + 0, // 0xa7 + 0, // 0xa8 + 0, // 0xa9 + "gentrap", // 0xaa + 0, // 0xab + 0, // 0xac + 0, // 0xad + "clrfen", // 0xae + 0, // 0xaf + 0, // 0xb0 + 0, // 0xb1 + 0, // 0xb2 + 0, // 0xb3 + 0, // 0xb4 + 0, // 0xb5 + 0, // 0xb6 + 0, // 0xb7 + 0, // 0xb8 + 0, // 0xb9 + 0, // 0xba + 0, // 0xbb + 0, // 0xbc + 0, // 0xbd + "nphalt", // 0xbe + "copypal", // 0xbf #if 0 - 0, // 0xc0 - 0, // 0xc1 - 0, // 0xc2 - 0, // 0xc3 - 0, // 0xc4 - 0, // 0xc5 - 0, // 0xc6 - 0, // 0xc7 - 0, // 0xc8 - 0, // 0xc9 - 0, // 0xca - 0, // 0xcb - 0, // 0xcc - 0, // 0xcd - 0, // 0xce - 0, // 0xcf - 0, // 0xd0 - 0, // 0xd1 - 0, // 0xd2 - 0, // 0xd3 - 0, // 0xd4 - 0, // 0xd5 - 0, // 0xd6 - 0, // 0xd7 - 0, // 0xd8 - 0, // 0xd9 - 0, // 0xda - 0, // 0xdb - 0, // 0xdc - 0, // 0xdd - 0, // 0xde - 0, // 0xdf - 0, // 0xe0 - 0, // 0xe1 - 0, // 0xe2 - 0, // 0xe3 - 0, // 0xe4 - 0, // 0xe5 - 0, // 0xe6 - 0, // 0xe7 - 0, // 0xe8 - 0, // 0xe9 - 0, // 0xea - 0, // 0xeb - 0, // 0xec - 0, // 0xed - 0, // 0xee - 0, // 0xef - 0, // 0xf0 - 0, // 0xf1 - 0, // 0xf2 - 0, // 0xf3 - 0, // 0xf4 - 0, // 0xf5 - 0, // 0xf6 - 0, // 0xf7 - 0, // 0xf8 - 0, // 0xf9 - 0, // 0xfa - 0, // 0xfb - 0, // 0xfc - 0, // 0xfd - 0, // 0xfe - 0 // 0xff + 0, // 0xc0 + 0, // 0xc1 + 0, // 0xc2 + 0, // 0xc3 + 0, // 0xc4 + 0, // 0xc5 + 0, // 0xc6 + 0, // 0xc7 + 0, // 0xc8 + 0, // 0xc9 + 0, // 0xca + 0, // 0xcb + 0, // 0xcc + 0, // 0xcd + 0, // 0xce + 0, // 0xcf + 0, // 0xd0 + 0, // 0xd1 + 0, // 0xd2 + 0, // 0xd3 + 0, // 0xd4 + 0, // 0xd5 + 0, // 0xd6 + 0, // 0xd7 + 0, // 0xd8 + 0, // 0xd9 + 0, // 0xda + 0, // 0xdb + 0, // 0xdc + 0, // 0xdd + 0, // 0xde + 0, // 0xdf + 0, // 0xe0 + 0, // 0xe1 + 0, // 0xe2 + 0, // 0xe3 + 0, // 0xe4 + 0, // 0xe5 + 0, // 0xe6 + 0, // 0xe7 + 0, // 0xe8 + 0, // 0xe9 + 0, // 0xea + 0, // 0xeb + 0, // 0xec + 0, // 0xed + 0, // 0xee + 0, // 0xef + 0, // 0xf0 + 0, // 0xf1 + 0, // 0xf2 + 0, // 0xf3 + 0, // 0xf4 + 0, // 0xf5 + 0, // 0xf6 + 0, // 0xf7 + 0, // 0xf8 + 0, // 0xf9 + 0, // 0xfa + 0, // 0xfb + 0, // 0xfc + 0, // 0xfd + 0, // 0xfe + 0 // 0xff #endif }; -} -const char * -PAL::name(int index) -{ if (index > NumCodes || index < 0) return 0; diff --git a/src/arch/alpha/osfpal.hh b/src/arch/alpha/osfpal.hh index cf3940b85..2618e9dbd 100644 --- a/src/arch/alpha/osfpal.hh +++ b/src/arch/alpha/osfpal.hh @@ -28,8 +28,8 @@ * Authors: Nathan Binkert */ -#ifndef __OSFPAL_HH__ -#define __OSFPAL_HH__ +#ifndef __ARCH_ALPHA_OSFPAL_HH__ +#define __ARCH_ALPHA_OSFPAL_HH__ struct PAL { @@ -79,4 +79,4 @@ struct PAL static const char *name(int index); }; -#endif // __OSFPAL_HH__ +#endif // __ARCH_ALPHA_OSFPAL_HH__ diff --git a/src/arch/alpha/pagetable.cc b/src/arch/alpha/pagetable.cc index 3f9537834..6640e72e2 100644 --- a/src/arch/alpha/pagetable.cc +++ b/src/arch/alpha/pagetable.cc @@ -31,33 +31,34 @@ #include "arch/alpha/pagetable.hh" #include "sim/serialize.hh" -namespace AlphaISA +namespace AlphaISA { + +void +TlbEntry::serialize(std::ostream &os) { - void - TlbEntry::serialize(std::ostream &os) - { - SERIALIZE_SCALAR(tag); - SERIALIZE_SCALAR(ppn); - SERIALIZE_SCALAR(xre); - SERIALIZE_SCALAR(xwe); - SERIALIZE_SCALAR(asn); - SERIALIZE_SCALAR(asma); - SERIALIZE_SCALAR(fonr); - SERIALIZE_SCALAR(fonw); - SERIALIZE_SCALAR(valid); - } + SERIALIZE_SCALAR(tag); + SERIALIZE_SCALAR(ppn); + SERIALIZE_SCALAR(xre); + SERIALIZE_SCALAR(xwe); + SERIALIZE_SCALAR(asn); + SERIALIZE_SCALAR(asma); + SERIALIZE_SCALAR(fonr); + SERIALIZE_SCALAR(fonw); + SERIALIZE_SCALAR(valid); +} - void - TlbEntry::unserialize(Checkpoint *cp, const std::string §ion) - { - UNSERIALIZE_SCALAR(tag); - UNSERIALIZE_SCALAR(ppn); - UNSERIALIZE_SCALAR(xre); - UNSERIALIZE_SCALAR(xwe); - UNSERIALIZE_SCALAR(asn); - UNSERIALIZE_SCALAR(asma); - UNSERIALIZE_SCALAR(fonr); - UNSERIALIZE_SCALAR(fonw); - UNSERIALIZE_SCALAR(valid); - } +void +TlbEntry::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_SCALAR(tag); + UNSERIALIZE_SCALAR(ppn); + UNSERIALIZE_SCALAR(xre); + UNSERIALIZE_SCALAR(xwe); + UNSERIALIZE_SCALAR(asn); + UNSERIALIZE_SCALAR(asma); + UNSERIALIZE_SCALAR(fonr); + UNSERIALIZE_SCALAR(fonw); + UNSERIALIZE_SCALAR(valid); } + +} //namespace AlphaISA diff --git a/src/arch/alpha/pagetable.hh b/src/arch/alpha/pagetable.hh index 8ce5b4e5d..59df93bef 100644 --- a/src/arch/alpha/pagetable.hh +++ b/src/arch/alpha/pagetable.hh @@ -38,97 +38,109 @@ namespace AlphaISA { - struct VAddr +struct VAddr +{ + static const int ImplBits = 43; + static const Addr ImplMask = (ULL(1) << ImplBits) - 1; + static const Addr UnImplMask = ~ImplMask; + + Addr addr; + + VAddr(Addr a) : addr(a) {} + operator Addr() const { return addr; } + const VAddr &operator=(Addr a) { addr = a; return *this; } + + Addr vpn() const { return (addr & ImplMask) >> PageShift; } + Addr page() const { return addr & PageMask; } + Addr offset() const { return addr & PageOffset; } + + Addr level3() const + { return PteAddr(addr >> PageShift); } + Addr level2() const + { return PteAddr(addr >> (NPtePageShift + PageShift)); } + Addr level1() const + { return PteAddr(addr >> (2 * NPtePageShift + PageShift)); } +}; + +struct PageTableEntry +{ + PageTableEntry(uint64_t e) : entry(e) {} + uint64_t entry; + operator uint64_t() const { return entry; } + const PageTableEntry &operator=(uint64_t e) { entry = e; return *this; } + const PageTableEntry &operator=(const PageTableEntry &e) + { entry = e.entry; return *this; } + + Addr _pfn() const { return (entry >> 32) & 0xffffffff; } + Addr _sw() const { return (entry >> 16) & 0xffff; } + int _rsv0() const { return (entry >> 14) & 0x3; } + bool _uwe() const { return (entry >> 13) & 0x1; } + bool _kwe() const { return (entry >> 12) & 0x1; } + int _rsv1() const { return (entry >> 10) & 0x3; } + bool _ure() const { return (entry >> 9) & 0x1; } + bool _kre() const { return (entry >> 8) & 0x1; } + bool _nomb() const { return (entry >> 7) & 0x1; } + int _gh() const { return (entry >> 5) & 0x3; } + bool _asm_() const { return (entry >> 4) & 0x1; } + bool _foe() const { return (entry >> 3) & 0x1; } + bool _fow() const { return (entry >> 2) & 0x1; } + bool _for() const { return (entry >> 1) & 0x1; } + bool valid() const { return (entry >> 0) & 0x1; } + + Addr paddr() const { return _pfn() << PageShift; } +}; + +// ITB/DTB table entry +struct TlbEntry +{ + Addr tag; // virtual page number tag + Addr ppn; // physical page number + uint8_t xre; // read permissions - VMEM_PERM_* mask + uint8_t xwe; // write permissions - VMEM_PERM_* mask + uint8_t asn; // address space number + bool asma; // address space match + bool fonr; // fault on read + bool fonw; // fault on write + bool valid; // valid page table entry + + + //Construct an entry that maps to physical address addr. + TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr) { - static const int ImplBits = 43; - static const Addr ImplMask = (ULL(1) << ImplBits) - 1; - static const Addr UnImplMask = ~ImplMask; - - VAddr(Addr a) : addr(a) {} - Addr addr; - operator Addr() const { return addr; } - const VAddr &operator=(Addr a) { addr = a; return *this; } - - Addr vpn() const { return (addr & ImplMask) >> PageShift; } - Addr page() const { return addr & PageMask; } - Addr offset() const { return addr & PageOffset; } - - Addr level3() const - { return AlphaISA::PteAddr(addr >> PageShift); } - Addr level2() const - { return AlphaISA::PteAddr(addr >> NPtePageShift + PageShift); } - Addr level1() const - { return AlphaISA::PteAddr(addr >> 2 * NPtePageShift + PageShift); } - }; - - struct PageTableEntry + VAddr vaddr(_vaddr); + VAddr paddr(_paddr); + tag = vaddr.vpn(); + ppn = paddr.vpn(); + xre = 15; + xwe = 15; + asn = _asn; + asma = false; + fonr = false; + fonw = false; + valid = true; + } + + TlbEntry() + {} + + void + updateVaddr(Addr new_vaddr) { - PageTableEntry(uint64_t e) : entry(e) {} - uint64_t entry; - operator uint64_t() const { return entry; } - const PageTableEntry &operator=(uint64_t e) { entry = e; return *this; } - const PageTableEntry &operator=(const PageTableEntry &e) - { entry = e.entry; return *this; } - - Addr _pfn() const { return (entry >> 32) & 0xffffffff; } - Addr _sw() const { return (entry >> 16) & 0xffff; } - int _rsv0() const { return (entry >> 14) & 0x3; } - bool _uwe() const { return (entry >> 13) & 0x1; } - bool _kwe() const { return (entry >> 12) & 0x1; } - int _rsv1() const { return (entry >> 10) & 0x3; } - bool _ure() const { return (entry >> 9) & 0x1; } - bool _kre() const { return (entry >> 8) & 0x1; } - bool _nomb() const { return (entry >> 7) & 0x1; } - int _gh() const { return (entry >> 5) & 0x3; } - bool _asm_() const { return (entry >> 4) & 0x1; } - bool _foe() const { return (entry >> 3) & 0x1; } - bool _fow() const { return (entry >> 2) & 0x1; } - bool _for() const { return (entry >> 1) & 0x1; } - bool valid() const { return (entry >> 0) & 0x1; } - - Addr paddr() const { return _pfn() << PageShift; } - }; - - // ITB/DTB table entry - struct TlbEntry + VAddr vaddr(new_vaddr); + tag = vaddr.vpn(); + } + + Addr + pageStart() { - //Construct an entry that maps to physical address addr. - TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr) - { - VAddr vaddr(_vaddr); - VAddr paddr(_paddr); - tag = vaddr.vpn(); - ppn = paddr.vpn(); - xre = 15; - xwe = 15; - asn = _asn; - asma = false; - fonr = false; - fonw = false; - valid = true; - } - TlbEntry() - {} - - Addr tag; // virtual page number tag - Addr ppn; // physical page number - uint8_t xre; // read permissions - VMEM_PERM_* mask - uint8_t xwe; // write permissions - VMEM_PERM_* mask - uint8_t asn; // address space number - bool asma; // address space match - bool fonr; // fault on read - bool fonw; // fault on write - bool valid; // valid page table entry - - Addr pageStart() - { - return ppn << PageShift; - } - - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); - }; + return ppn << PageShift; + } + void serialize(std::ostream &os); + void unserialize(Checkpoint *cp, const std::string §ion); }; + +} // namespace AlphaISA + #endif // __ARCH_ALPHA_PAGETABLE_H__ diff --git a/src/arch/alpha/predecoder.hh b/src/arch/alpha/predecoder.hh index 725b35b9d..5502342e1 100644 --- a/src/arch/alpha/predecoder.hh +++ b/src/arch/alpha/predecoder.hh @@ -38,62 +38,72 @@ class ThreadContext; -namespace AlphaISA +namespace AlphaISA { + +class Predecoder { - class Predecoder + protected: + ThreadContext *tc; + + // The extended machine instruction being generated + ExtMachInst ext_inst; + + public: + Predecoder(ThreadContext * _tc) + : tc(_tc) + {} + + ThreadContext * + getTC() { - protected: - ThreadContext * tc; - //The extended machine instruction being generated - ExtMachInst ext_inst; - - public: - Predecoder(ThreadContext * _tc) : tc(_tc) - {} - - ThreadContext * getTC() - { - return tc; - } - - void setTC(ThreadContext * _tc) - { - tc = _tc; - } - - void process() - { - } - - void reset() - {} - - //Use this to give data to the predecoder. This should be used - //when there is control flow. - void moreBytes(Addr pc, Addr fetchPC, MachInst inst) - { - ext_inst = inst; + return tc; + } + + void + setTC(ThreadContext * _tc) + { + tc = _tc; + } + + void + process() + { } + + void + reset() + { } + + // Use this to give data to the predecoder. This should be used + // when there is control flow. + void + moreBytes(Addr pc, Addr fetchPC, MachInst inst) + { + ext_inst = inst; #if FULL_SYSTEM - ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32); + ext_inst |= (static_cast<ExtMachInst>(pc & 0x1) << 32); #endif - } - - bool needMoreBytes() - { - return true; - } - - bool extMachInstReady() - { - return true; - } - - //This returns a constant reference to the ExtMachInst to avoid a copy - const ExtMachInst & getExtMachInst() - { - return ext_inst; - } - }; + } + + bool + needMoreBytes() + { + return true; + } + + bool + extMachInstReady() + { + return true; + } + + // This returns a constant reference to the ExtMachInst to avoid a copy + const ExtMachInst & + getExtMachInst() + { + return ext_inst; + } }; +} // namespace AlphaISA + #endif // __ARCH_ALPHA_PREDECODER_HH__ diff --git a/src/arch/alpha/process.cc b/src/arch/alpha/process.cc index c2d23ecdd..9c6e62815 100644 --- a/src/arch/alpha/process.cc +++ b/src/arch/alpha/process.cc @@ -32,16 +32,20 @@ #include "arch/alpha/isa_traits.hh" #include "arch/alpha/process.hh" #include "base/loader/object_file.hh" +#include "base/loader/elf_object.hh" #include "base/misc.hh" #include "cpu/thread_context.hh" +#include "mem/page_table.hh" +#include "sim/process_impl.hh" #include "sim/system.hh" - using namespace AlphaISA; using namespace std; -AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams * params, - ObjectFile *objFile) +static const int SyscallSuccessReg = 19; + +AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams *params, + ObjectFile *objFile) : LiveProcess(params, objFile) { brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize(); @@ -61,20 +65,165 @@ AlphaLiveProcess::AlphaLiveProcess(LiveProcessParams * params, } void +AlphaLiveProcess::argsInit(int intSize, int pageSize) +{ + objFile->loadSections(initVirtMem); + + typedef AuxVector<uint64_t> auxv_t; + std::vector<auxv_t> auxv; + + ElfObject * elfObject = dynamic_cast<ElfObject *>(objFile); + if(elfObject) + { + // modern glibc uses a bunch of auxiliary vectors to set up + // TLS as well as do a bunch of other stuff + // these vectors go on the bottom of the stack, below argc/argv/envp + // pointers but above actual arg strings + // I don't have all the ones glibc looks at here, but so far it doesn't + // seem to be a problem. + // check out _dl_aux_init() in glibc/elf/dl-support.c for details + // --Lisa + auxv.push_back(auxv_t(M5_AT_PAGESZ, AlphaISA::VMPageSize)); + auxv.push_back(auxv_t(M5_AT_CLKTCK, 100)); + auxv.push_back(auxv_t(M5_AT_PHDR, elfObject->programHeaderTable())); + DPRINTF(Loader, "auxv at PHDR %08p\n", elfObject->programHeaderTable()); + auxv.push_back(auxv_t(M5_AT_PHNUM, elfObject->programHeaderCount())); + auxv.push_back(auxv_t(M5_AT_ENTRY, objFile->entryPoint())); + auxv.push_back(auxv_t(M5_AT_UID, uid())); + auxv.push_back(auxv_t(M5_AT_EUID, euid())); + auxv.push_back(auxv_t(M5_AT_GID, gid())); + auxv.push_back(auxv_t(M5_AT_EGID, egid())); + + } + + // Calculate how much space we need for arg & env & auxv arrays. + int argv_array_size = intSize * (argv.size() + 1); + int envp_array_size = intSize * (envp.size() + 1); + int auxv_array_size = intSize * 2 * (auxv.size() + 1); + + int arg_data_size = 0; + for (int i = 0; i < argv.size(); ++i) { + arg_data_size += argv[i].size() + 1; + } + int env_data_size = 0; + for (int i = 0; i < envp.size(); ++i) { + env_data_size += envp[i].size() + 1; + } + + int space_needed = + argv_array_size + + envp_array_size + + auxv_array_size + + arg_data_size + + env_data_size; + + if (space_needed < 32*1024) + space_needed = 32*1024; + + // set bottom of stack + stack_min = stack_base - space_needed; + // align it + stack_min = roundDown(stack_min, pageSize); + stack_size = stack_base - stack_min; + // map memory + pTable->allocate(stack_min, roundUp(stack_size, pageSize)); + + // map out initial stack contents + Addr argv_array_base = stack_min + intSize; // room for argc + Addr envp_array_base = argv_array_base + argv_array_size; + Addr auxv_array_base = envp_array_base + envp_array_size; + Addr arg_data_base = auxv_array_base + auxv_array_size; + Addr env_data_base = arg_data_base + arg_data_size; + + // write contents to stack + uint64_t argc = argv.size(); + if (intSize == 8) + argc = htog((uint64_t)argc); + else if (intSize == 4) + argc = htog((uint32_t)argc); + else + panic("Unknown int size"); + + initVirtMem->writeBlob(stack_min, (uint8_t*)&argc, intSize); + + copyStringArray(argv, argv_array_base, arg_data_base, initVirtMem); + copyStringArray(envp, envp_array_base, env_data_base, initVirtMem); + + //Copy the aux stuff + for(int x = 0; x < auxv.size(); x++) + { + initVirtMem->writeBlob(auxv_array_base + x * 2 * intSize, + (uint8_t*)&(auxv[x].a_type), intSize); + initVirtMem->writeBlob(auxv_array_base + (x * 2 + 1) * intSize, + (uint8_t*)&(auxv[x].a_val), intSize); + } + + ThreadContext *tc = system->getThreadContext(contextIds[0]); + + setSyscallArg(tc, 0, argc); + setSyscallArg(tc, 1, argv_array_base); + tc->setIntReg(StackPointerReg, stack_min); + + Addr prog_entry = objFile->entryPoint(); + tc->setPC(prog_entry); + tc->setNextPC(prog_entry + sizeof(MachInst)); + +#if THE_ISA != ALPHA_ISA //e.g. MIPS or Sparc + tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); +#endif + + +} + +void AlphaLiveProcess::startup() { if (checkpointRestored) return; + Process::startup(); + argsInit(MachineBytes, VMPageSize); - threadContexts[0]->setIntReg(GlobalPointerReg, objFile->globalPointer()); - //Opperate in user mode - threadContexts[0]->setMiscRegNoEffect(IPR_ICM, 0x18); + ThreadContext *tc = system->getThreadContext(contextIds[0]); + tc->setIntReg(GlobalPointerReg, objFile->globalPointer()); + //Operate in user mode + tc->setMiscRegNoEffect(IPR_ICM, 0x18); //No super page mapping - threadContexts[0]->setMiscRegNoEffect(IPR_MCSR, 0); + tc->setMiscRegNoEffect(IPR_MCSR, 0); //Set this to 0 for now, but it should be unique for each process - threadContexts[0]->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57); + tc->setMiscRegNoEffect(IPR_DTB_ASN, M5_pid << 57); } +AlphaISA::IntReg +AlphaLiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + assert(i < 6); + return tc->readIntReg(FirstArgumentReg + i); +} + +void +AlphaLiveProcess::setSyscallArg(ThreadContext *tc, + int i, AlphaISA::IntReg val) +{ + assert(i < 6); + tc->setIntReg(FirstArgumentReg + i, val); +} +void +AlphaLiveProcess::setSyscallReturn(ThreadContext *tc, + SyscallReturn return_value) +{ + // check for error condition. Alpha syscall convention is to + // indicate success/failure in reg a3 (r19) and put the + // return value itself in the standard return value reg (v0). + if (return_value.successful()) { + // no error + tc->setIntReg(SyscallSuccessReg, 0); + tc->setIntReg(ReturnValueReg, return_value.value()); + } else { + // got an error, return details + tc->setIntReg(SyscallSuccessReg, (IntReg)-1); + tc->setIntReg(ReturnValueReg, -return_value.value()); + } +} diff --git a/src/arch/alpha/process.hh b/src/arch/alpha/process.hh index c66b97d23..6d083c5ac 100644 --- a/src/arch/alpha/process.hh +++ b/src/arch/alpha/process.hh @@ -29,24 +29,24 @@ * Ali Saidi */ -#ifndef __ALPHA_PROCESS_HH__ -#define __ALPHA_PROCESS_HH__ +#ifndef __ARCH_ALPHA_PROCESS_HH__ +#define __ARCH_ALPHA_PROCESS_HH__ -#include <string> -#include <vector> #include "sim/process.hh" -class ObjectFile; -class System; - - class AlphaLiveProcess : public LiveProcess { protected: - AlphaLiveProcess(LiveProcessParams * params, ObjectFile *objFile); + AlphaLiveProcess(LiveProcessParams *params, ObjectFile *objFile); void startup(); -}; + void argsInit(int intSize, int pageSize); + + public: + AlphaISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, AlphaISA::IntReg val); + void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); +}; -#endif // __ALPHA_PROCESS_HH__ +#endif // __ARCH_ALPHA_PROCESS_HH__ diff --git a/src/arch/alpha/regfile.cc b/src/arch/alpha/regfile.cc index 2653310d7..b3aa55b19 100644 --- a/src/arch/alpha/regfile.cc +++ b/src/arch/alpha/regfile.cc @@ -33,67 +33,68 @@ #include "arch/alpha/regfile.hh" #include "cpu/thread_context.hh" -namespace AlphaISA +using namespace std; + +namespace AlphaISA { + +void +RegFile::serialize(EventManager *em, ostream &os) { - void - RegFile::serialize(std::ostream &os) - { - intRegFile.serialize(os); - floatRegFile.serialize(os); - miscRegFile.serialize(os); - SERIALIZE_SCALAR(pc); - SERIALIZE_SCALAR(npc); + intRegFile.serialize(os); + floatRegFile.serialize(os); + miscRegFile.serialize(os); + SERIALIZE_SCALAR(pc); + SERIALIZE_SCALAR(npc); #if FULL_SYSTEM - SERIALIZE_SCALAR(intrflag); + SERIALIZE_SCALAR(intrflag); #endif - } +} - void - RegFile::unserialize(Checkpoint *cp, const std::string §ion) - { - intRegFile.unserialize(cp, section); - floatRegFile.unserialize(cp, section); - miscRegFile.unserialize(cp, section); - UNSERIALIZE_SCALAR(pc); - UNSERIALIZE_SCALAR(npc); +void +RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion) +{ + intRegFile.unserialize(cp, section); + floatRegFile.unserialize(cp, section); + miscRegFile.unserialize(cp, section); + UNSERIALIZE_SCALAR(pc); + UNSERIALIZE_SCALAR(npc); #if FULL_SYSTEM - UNSERIALIZE_SCALAR(intrflag); + UNSERIALIZE_SCALAR(intrflag); #endif - } +} - void - copyRegs(ThreadContext *src, ThreadContext *dest) - { - // First loop through the integer registers. - for (int i = 0; i < NumIntRegs; ++i) { - dest->setIntReg(i, src->readIntReg(i)); - } +void +copyRegs(ThreadContext *src, ThreadContext *dest) +{ + // First loop through the integer registers. + for (int i = 0; i < NumIntRegs; ++i) + dest->setIntReg(i, src->readIntReg(i)); - // Then loop through the floating point registers. - for (int i = 0; i < TheISA::NumFloatRegs; ++i) { - dest->setFloatRegBits(i, src->readFloatRegBits(i)); - } + // Then loop through the floating point registers. + for (int i = 0; i < NumFloatRegs; ++i) + dest->setFloatRegBits(i, src->readFloatRegBits(i)); - // Copy misc. registers - copyMiscRegs(src, dest); + // Copy misc. registers + copyMiscRegs(src, dest); - // Lastly copy PC/NPC - dest->setPC(src->readPC()); - dest->setNextPC(src->readNextPC()); - } + // Lastly copy PC/NPC + dest->setPC(src->readPC()); + dest->setNextPC(src->readNextPC()); +} - void - copyMiscRegs(ThreadContext *src, ThreadContext *dest) - { - dest->setMiscRegNoEffect(AlphaISA::MISCREG_FPCR, - src->readMiscRegNoEffect(AlphaISA::MISCREG_FPCR)); - dest->setMiscRegNoEffect(AlphaISA::MISCREG_UNIQ, - src->readMiscRegNoEffect(AlphaISA::MISCREG_UNIQ)); - dest->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG, - src->readMiscRegNoEffect(AlphaISA::MISCREG_LOCKFLAG)); - dest->setMiscRegNoEffect(AlphaISA::MISCREG_LOCKADDR, - src->readMiscRegNoEffect(AlphaISA::MISCREG_LOCKADDR)); +void +copyMiscRegs(ThreadContext *src, ThreadContext *dest) +{ + dest->setMiscRegNoEffect(MISCREG_FPCR, + src->readMiscRegNoEffect(MISCREG_FPCR)); + dest->setMiscRegNoEffect(MISCREG_UNIQ, + src->readMiscRegNoEffect(MISCREG_UNIQ)); + dest->setMiscRegNoEffect(MISCREG_LOCKFLAG, + src->readMiscRegNoEffect(MISCREG_LOCKFLAG)); + dest->setMiscRegNoEffect(MISCREG_LOCKADDR, + src->readMiscRegNoEffect(MISCREG_LOCKADDR)); - copyIprs(src, dest); - } + copyIprs(src, dest); } + +} // namespace AlphaISA diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index 792a518fb..e431e7570 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -43,163 +43,187 @@ //XXX These should be implemented by someone who knows the alpha stuff better class Checkpoint; +class EventManager; class ThreadContext; -namespace AlphaISA -{ - - class RegFile { +namespace AlphaISA { - protected: - Addr pc; // program counter - Addr npc; // next-cycle program counter - Addr nnpc; +class RegFile { + protected: + Addr pc; // program counter + Addr npc; // next-cycle program counter + Addr nnpc; // next next-cycle program counter - public: - Addr readPC() - { - return pc; - } - - void setPC(Addr val) - { - pc = val; - } + public: + Addr + readPC() + { + return pc; + } - Addr readNextPC() - { - return npc; - } + void + setPC(Addr val) + { + pc = val; + } - void setNextPC(Addr val) - { - npc = val; - } + Addr + readNextPC() + { + return npc; + } - Addr readNextNPC() - { - return npc + sizeof(MachInst); - } + void + setNextPC(Addr val) + { + npc = val; + } - void setNextNPC(Addr val) - { } + Addr + readNextNPC() + { + return npc + sizeof(MachInst); + } - protected: - IntRegFile intRegFile; // (signed) integer register file - FloatRegFile floatRegFile; // floating point register file - MiscRegFile miscRegFile; // control register file + void + setNextNPC(Addr val) + { } - public: + protected: + IntRegFile intRegFile; // (signed) integer register file + FloatRegFile floatRegFile; // floating point register file + MiscRegFile miscRegFile; // control register file + public: #if FULL_SYSTEM - int intrflag; // interrupt flag - inline int instAsid() - { return miscRegFile.getInstAsid(); } - inline int dataAsid() - { return miscRegFile.getDataAsid(); } -#endif // FULL_SYSTEM + int intrflag; // interrupt flag - void clear() - { - intRegFile.clear(); - floatRegFile.clear(); - miscRegFile.clear(); - } - - MiscReg readMiscRegNoEffect(int miscReg) - { - return miscRegFile.readRegNoEffect(miscReg); - } - - MiscReg readMiscReg(int miscReg, ThreadContext *tc) - { - return miscRegFile.readReg(miscReg, tc); - } + int + instAsid() + { + return miscRegFile.getInstAsid(); + } - void setMiscRegNoEffect(int miscReg, const MiscReg &val) - { - miscRegFile.setRegNoEffect(miscReg, val); - } + int + dataAsid() + { + return miscRegFile.getDataAsid(); + } +#endif // FULL_SYSTEM - void setMiscReg(int miscReg, const MiscReg &val, - ThreadContext * tc) - { - miscRegFile.setReg(miscReg, val, tc); - } + void + clear() + { + intRegFile.clear(); + floatRegFile.clear(); + miscRegFile.clear(); + } - FloatReg readFloatReg(int floatReg) - { - return floatRegFile.d[floatReg]; - } + MiscReg + readMiscRegNoEffect(int miscReg) + { + return miscRegFile.readRegNoEffect(miscReg); + } - FloatReg readFloatReg(int floatReg, int width) - { - return readFloatReg(floatReg); - } + MiscReg + readMiscReg(int miscReg, ThreadContext *tc) + { + return miscRegFile.readReg(miscReg, tc); + } - FloatRegBits readFloatRegBits(int floatReg) - { - return floatRegFile.q[floatReg]; - } + void + setMiscRegNoEffect(int miscReg, const MiscReg &val) + { + miscRegFile.setRegNoEffect(miscReg, val); + } - FloatRegBits readFloatRegBits(int floatReg, int width) - { - return readFloatRegBits(floatReg); - } + void + setMiscReg(int miscReg, const MiscReg &val, ThreadContext *tc) + { + miscRegFile.setReg(miscReg, val, tc); + } - void setFloatReg(int floatReg, const FloatReg &val) - { - floatRegFile.d[floatReg] = val; - } + FloatReg + readFloatReg(int floatReg) + { + return floatRegFile.d[floatReg]; + } - void setFloatReg(int floatReg, const FloatReg &val, int width) - { - setFloatReg(floatReg, val); - } + FloatReg + readFloatReg(int floatReg, int width) + { + return readFloatReg(floatReg); + } - void setFloatRegBits(int floatReg, const FloatRegBits &val) - { - floatRegFile.q[floatReg] = val; - } + FloatRegBits + readFloatRegBits(int floatReg) + { + return floatRegFile.q[floatReg]; + } - void setFloatRegBits(int floatReg, const FloatRegBits &val, int width) - { - setFloatRegBits(floatReg, val); - } + FloatRegBits + readFloatRegBits(int floatReg, int width) + { + return readFloatRegBits(floatReg); + } - IntReg readIntReg(int intReg) - { - return intRegFile.readReg(intReg); - } + void + setFloatReg(int floatReg, const FloatReg &val) + { + floatRegFile.d[floatReg] = val; + } - void setIntReg(int intReg, const IntReg &val) - { - intRegFile.setReg(intReg, val); - } + void + setFloatReg(int floatReg, const FloatReg &val, int width) + { + setFloatReg(floatReg, val); + } - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void + setFloatRegBits(int floatReg, const FloatRegBits &val) + { + floatRegFile.q[floatReg] = val; + } - void changeContext(RegContextParam param, RegContextVal val) - { - //This would be an alternative place to call/implement - //the swapPALShadow function - } - }; + void + setFloatRegBits(int floatReg, const FloatRegBits &val, int width) + { + setFloatRegBits(floatReg, val); + } - static inline int flattenIntIndex(ThreadContext * tc, int reg) + IntReg + readIntReg(int intReg) { - return reg; + return intRegFile.readReg(intReg); } - static inline int flattenFloatIndex(ThreadContext * tc, int reg) + void + setIntReg(int intReg, const IntReg &val) { - return reg; + intRegFile.setReg(intReg, val); } - void copyRegs(ThreadContext *src, ThreadContext *dest); + void serialize(EventManager *em, std::ostream &os); + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion); +}; + +static inline int +flattenIntIndex(ThreadContext * tc, int reg) +{ + return reg; +} + +static inline int +flattenFloatIndex(ThreadContext * tc, int reg) +{ + return reg; +} + +void copyRegs(ThreadContext *src, ThreadContext *dest); + +void copyMiscRegs(ThreadContext *src, ThreadContext *dest); - void copyMiscRegs(ThreadContext *src, ThreadContext *dest); } // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_REGFILE_HH__ diff --git a/src/arch/alpha/remote_gdb.cc b/src/arch/alpha/remote_gdb.cc index ea5db36f4..c47293b98 100644 --- a/src/arch/alpha/remote_gdb.cc +++ b/src/arch/alpha/remote_gdb.cc @@ -30,7 +30,7 @@ /* * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and @@ -38,8 +38,8 @@ * * All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Lawrence Berkeley Laboratories. + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratories. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -51,8 +51,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * This product includes software developed by the University of + * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -69,7 +69,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 + * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 */ /*- @@ -89,8 +89,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. @@ -117,9 +117,9 @@ */ #include <sys/signal.h> +#include <unistd.h> #include <string> -#include <unistd.h> #include "config/full_system.hh" #if FULL_SYSTEM @@ -140,19 +140,17 @@ #include "sim/system.hh" using namespace std; -using namespace TheISA; +using namespace AlphaISA; -RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) - : BaseRemoteGDB(_system, c, KGDB_NUMREGS) +RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc) + : BaseRemoteGDB(_system, tc, KGDB_NUMREGS) { memset(gdbregs.regs, 0, gdbregs.bytes()); } -/////////////////////////////////////////////////////////// -// RemoteGDB::acc -// -// Determine if the mapping at va..(va+len) is valid. -// +/* + * Determine if the mapping at va..(va+len) is valid. + */ bool RemoteGDB::acc(Addr va, size_t len) { @@ -161,12 +159,12 @@ RemoteGDB::acc(Addr va, size_t len) #else Addr last_va; - va = TheISA::TruncPage(va); - last_va = TheISA::RoundPage(va + len); + va = TruncPage(va); + last_va = RoundPage(va + len); do { - if (TheISA::IsK0Seg(va)) { - if (va < (TheISA::K0SegBase + pmem->size())) { + if (IsK0Seg(va)) { + if (va < (K0SegBase + pmem->size())) { DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= " "%#x < K0SEG + size\n", va); return true; @@ -177,23 +175,25 @@ RemoteGDB::acc(Addr va, size_t len) } } - /** - * This code says that all accesses to palcode (instruction and data) - * are valid since there isn't a va->pa mapping because palcode is - * accessed physically. At some point this should probably be cleaned up - * but there is no easy way to do it. - */ + /** + * This code says that all accesses to palcode (instruction + * and data) are valid since there isn't a va->pa mapping + * because palcode is accessed physically. At some point this + * should probably be cleaned up but there is no easy way to + * do it. + */ - if (AlphaISA::PcPAL(va) || va < 0x10000) + if (PcPAL(va) || va < 0x10000) return true; - Addr ptbr = context->readMiscRegNoEffect(AlphaISA::IPR_PALtemp20); - TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va); + Addr ptbr = context->readMiscRegNoEffect(IPR_PALtemp20); + PageTableEntry pte = + kernel_pte_lookup(context->getPhysPort(), ptbr, va); if (!pte.valid()) { DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va); return false; } - va += TheISA::PageBytes; + va += PageBytes; } while (va < last_va); DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va); @@ -201,11 +201,10 @@ RemoteGDB::acc(Addr va, size_t len) #endif } -/////////////////////////////////////////////////////////// -// RemoteGDB::getregs -// -// Translate the kernel debugger register format into -// the GDB register format. +/* + * Translate the kernel debugger register format into the GDB register + * format. + */ void RemoteGDB::getregs() { @@ -214,45 +213,43 @@ RemoteGDB::getregs() gdbregs.regs[KGDB_REG_PC] = context->readPC(); // @todo: Currently this is very Alpha specific. - if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - gdbregs.regs[i] = context->readIntReg(AlphaISA::reg_redir[i]); + if (PcPAL(gdbregs.regs[KGDB_REG_PC])) { + for (int i = 0; i < NumIntArchRegs; ++i) { + gdbregs.regs[i] = context->readIntReg(reg_redir[i]); } } else { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + for (int i = 0; i < NumIntArchRegs; ++i) { gdbregs.regs[i] = context->readIntReg(i); } } #ifdef KGDB_FP_REGS - for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { + for (int i = 0; i < NumFloatArchRegs; ++i) { gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i); } #endif } -/////////////////////////////////////////////////////////// -// RemoteGDB::setregs -// -// Translate the GDB register format into the kernel -// debugger register format. -// +/* + * Translate the GDB register format into the kernel debugger register + * format. + */ void RemoteGDB::setregs() { // @todo: Currently this is very Alpha specific. - if (AlphaISA::PcPAL(gdbregs.regs[KGDB_REG_PC])) { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { - context->setIntReg(AlphaISA::reg_redir[i], gdbregs.regs[i]); + if (PcPAL(gdbregs.regs[KGDB_REG_PC])) { + for (int i = 0; i < NumIntArchRegs; ++i) { + context->setIntReg(reg_redir[i], gdbregs.regs[i]); } } else { - for (int i = 0; i < TheISA::NumIntArchRegs; ++i) { + for (int i = 0; i < NumIntArchRegs; ++i) { context->setIntReg(i, gdbregs.regs[i]); } } #ifdef KGDB_FP_REGS - for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) { + for (int i = 0; i < NumFloatArchRegs; ++i) { context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]); } #endif diff --git a/src/arch/alpha/remote_gdb.hh b/src/arch/alpha/remote_gdb.hh index 7bef183c3..43d0580d8 100644 --- a/src/arch/alpha/remote_gdb.hh +++ b/src/arch/alpha/remote_gdb.hh @@ -44,31 +44,29 @@ class System; class ThreadContext; class PhysicalMemory; -namespace AlphaISA -{ - class RemoteGDB : public BaseRemoteGDB - { - protected: - // Machine memory - bool write(Addr addr, size_t size, const char *data); +namespace AlphaISA { - public: - RemoteGDB(System *system, ThreadContext *context); +class RemoteGDB : public BaseRemoteGDB +{ + protected: + Addr notTakenBkpt; + Addr takenBkpt; - bool acc(Addr addr, size_t len); + protected: + void getregs(); + void setregs(); - protected: - void getregs(); - void setregs(); + void clearSingleStep(); + void setSingleStep(); - void clearSingleStep(); - void setSingleStep(); + // Machine memory + bool acc(Addr addr, size_t len); + bool write(Addr addr, size_t size, const char *data); - protected: + public: + RemoteGDB(System *system, ThreadContext *context); +}; - Addr notTakenBkpt; - Addr takenBkpt; - }; -} +} // namespace AlphaISA -#endif /* __ARCH_ALPHA_REMOTE_GDB_H__ */ +#endif // __ARCH_ALPHA_REMOTE_GDB_HH__ diff --git a/src/arch/alpha/stacktrace.cc b/src/arch/alpha/stacktrace.cc index c16498e72..1b5a9be34 100644 --- a/src/arch/alpha/stacktrace.cc +++ b/src/arch/alpha/stacktrace.cc @@ -41,330 +41,326 @@ using namespace std; -namespace AlphaISA +namespace AlphaISA { + +ProcessInfo::ProcessInfo(ThreadContext *_tc) + : tc(_tc) { - ProcessInfo::ProcessInfo(ThreadContext *_tc) - : tc(_tc) - { - Addr addr = 0; + Addr addr = 0; + VirtualPort *vp = tc->getVirtPort(); + SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - VirtualPort *vp; + if (!symtab->findAddress("thread_info_size", addr)) + panic("thread info not compiled into kernel\n"); + thread_info_size = vp->readGtoH<int32_t>(addr); - vp = tc->getVirtPort(); + if (!symtab->findAddress("task_struct_size", addr)) + panic("thread info not compiled into kernel\n"); + task_struct_size = vp->readGtoH<int32_t>(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr)) - panic("thread info not compiled into kernel\n"); - thread_info_size = vp->readGtoH<int32_t>(addr); + if (!symtab->findAddress("thread_info_task", addr)) + panic("thread info not compiled into kernel\n"); + task_off = vp->readGtoH<int32_t>(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr)) - panic("thread info not compiled into kernel\n"); - task_struct_size = vp->readGtoH<int32_t>(addr); + if (!symtab->findAddress("task_struct_pid", addr)) + panic("thread info not compiled into kernel\n"); + pid_off = vp->readGtoH<int32_t>(addr); - if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr)) - panic("thread info not compiled into kernel\n"); - task_off = vp->readGtoH<int32_t>(addr); + if (!symtab->findAddress("task_struct_comm", addr)) + panic("thread info not compiled into kernel\n"); + name_off = vp->readGtoH<int32_t>(addr); +} - if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr)) - panic("thread info not compiled into kernel\n"); - pid_off = vp->readGtoH<int32_t>(addr); +Addr +ProcessInfo::task(Addr ksp) const +{ + Addr base = ksp & ~0x3fff; + if (base == ULL(0xfffffc0000000000)) + return 0; - if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) - panic("thread info not compiled into kernel\n"); - name_off = vp->readGtoH<int32_t>(addr); + Addr tsk; - tc->delVirtPort(vp); - } + VirtualPort *vp; - Addr - ProcessInfo::task(Addr ksp) const - { - Addr base = ksp & ~0x3fff; - if (base == ULL(0xfffffc0000000000)) - return 0; + vp = tc->getVirtPort(); + tsk = vp->readGtoH<Addr>(base + task_off); - Addr tsk; + return tsk; +} - VirtualPort *vp; +int +ProcessInfo::pid(Addr ksp) const +{ + Addr task = this->task(ksp); + if (!task) + return -1; - vp = tc->getVirtPort(); - tsk = vp->readGtoH<Addr>(base + task_off); - tc->delVirtPort(vp); + uint16_t pd; - return tsk; - } + VirtualPort *vp; - int - ProcessInfo::pid(Addr ksp) const - { - Addr task = this->task(ksp); - if (!task) - return -1; + vp = tc->getVirtPort(); + pd = vp->readGtoH<uint16_t>(task + pid_off); - uint16_t pd; + return pd; +} - VirtualPort *vp; +string +ProcessInfo::name(Addr ksp) const +{ + Addr task = this->task(ksp); + if (!task) + return "console"; - vp = tc->getVirtPort(); - pd = vp->readGtoH<uint16_t>(task + pid_off); - tc->delVirtPort(vp); + char comm[256]; + CopyStringOut(tc, comm, task + name_off, sizeof(comm)); + if (!comm[0]) + return "startup"; - return pd; - } + return comm; +} - string - ProcessInfo::name(Addr ksp) const - { - Addr task = this->task(ksp); - if (!task) - return "console"; +StackTrace::StackTrace() + : tc(0), stack(64) +{ +} - char comm[256]; - CopyStringOut(tc, comm, task + name_off, sizeof(comm)); - if (!comm[0]) - return "startup"; +StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) + : tc(0), stack(64) +{ + trace(_tc, inst); +} - return comm; - } +StackTrace::~StackTrace() +{ +} - StackTrace::StackTrace() - : tc(0), stack(64) - { - } +void +StackTrace::trace(ThreadContext *_tc, bool is_call) +{ + tc = _tc; - StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst) - : tc(0), stack(64) - { - trace(_tc, inst); - } + System *sys = tc->getSystemPtr(); - StackTrace::~StackTrace() - { - } + bool usermode = + (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0; - void - StackTrace::trace(ThreadContext *_tc, bool is_call) - { - tc = _tc; + Addr pc = tc->readNextPC(); + bool kernel = sys->kernelStart <= pc && pc <= sys->kernelEnd; - bool usermode = (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0; + if (usermode) { + stack.push_back(user); + return; + } - Addr pc = tc->readNextPC(); - bool kernel = tc->getSystemPtr()->kernelStart <= pc && - pc <= tc->getSystemPtr()->kernelEnd; + if (!kernel) { + stack.push_back(console); + return; + } - if (usermode) { - stack.push_back(user); - return; - } + SymbolTable *symtab = sys->kernelSymtab; + Addr ksp = tc->readIntReg(StackPointerReg); + Addr bottom = ksp & ~0x3fff; - if (!kernel) { - stack.push_back(console); - return; - } + if (is_call) { + Addr addr; + if (!symtab->findNearestAddr(pc, addr)) + panic("could not find address %#x", pc); + + stack.push_back(addr); + pc = tc->readPC(); + } - SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - Addr ksp = tc->readIntReg(TheISA::StackPointerReg); - Addr bottom = ksp & ~0x3fff; + while (ksp > bottom) { Addr addr; + if (!symtab->findNearestAddr(pc, addr)) + panic("could not find symbol for pc=%#x", pc); + assert(pc >= addr && "symbol botch: callpc < func"); - if (is_call) { - if (!symtab->findNearestAddr(pc, addr)) - panic("could not find address %#x", pc); + stack.push_back(addr); - stack.push_back(addr); - pc = tc->readPC(); - } + if (isEntry(addr)) + return; Addr ra; int size; - - while (ksp > bottom) { - if (!symtab->findNearestAddr(pc, addr)) - panic("could not find symbol for pc=%#x", pc); - assert(pc >= addr && "symbol botch: callpc < func"); - - stack.push_back(addr); - - if (isEntry(addr)) + if (decodePrologue(ksp, pc, addr, size, ra)) { + if (!ra) return; - if (decodePrologue(ksp, pc, addr, size, ra)) { - if (!ra) - return; - - if (size <= 0) { - stack.push_back(unknown); - return; - } - - pc = ra; - ksp += size; - } else { + if (size <= 0) { stack.push_back(unknown); return; } - bool kernel = tc->getSystemPtr()->kernelStart <= pc && - pc <= tc->getSystemPtr()->kernelEnd; - if (!kernel) - return; - - if (stack.size() >= 1000) - panic("unwinding too far"); + pc = ra; + ksp += size; + } else { + stack.push_back(unknown); + return; } - panic("unwinding too far"); + bool kernel = sys->kernelStart <= pc && pc <= sys->kernelEnd; + if (!kernel) + return; + + if (stack.size() >= 1000) + panic("unwinding too far"); } - bool - StackTrace::isEntry(Addr addr) - { - if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp12)) - return true; + panic("unwinding too far"); +} - if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp7)) - return true; +bool +StackTrace::isEntry(Addr addr) +{ + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp12)) + return true; - if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp11)) - return true; + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp7)) + return true; - if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp21)) - return true; + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp11)) + return true; - if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp9)) - return true; + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp21)) + return true; - if (addr == tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp2)) - return true; + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp9)) + return true; - return false; - } + if (addr == tc->readMiscRegNoEffect(IPR_PALtemp2)) + return true; - bool - StackTrace::decodeStack(MachInst inst, int &disp) - { - // lda $sp, -disp($sp) - // - // Opcode<31:26> == 0x08 - // RA<25:21> == 30 - // RB<20:16> == 30 - // Disp<15:0> - const MachInst mem_mask = 0xffff0000; - const MachInst lda_pattern = 0x23de0000; - const MachInst lda_disp_mask = 0x0000ffff; - - // subq $sp, disp, $sp - // addq $sp, disp, $sp - // - // Opcode<31:26> == 0x10 - // RA<25:21> == 30 - // Lit<20:13> - // One<12> = 1 - // Func<11:5> == 0x20 (addq) - // Func<11:5> == 0x29 (subq) - // RC<4:0> == 30 - const MachInst intop_mask = 0xffe01fff; - const MachInst addq_pattern = 0x43c0141e; - const MachInst subq_pattern = 0x43c0153e; - const MachInst intop_disp_mask = 0x001fe000; - const int intop_disp_shift = 13; - - if ((inst & mem_mask) == lda_pattern) - disp = -sext<16>(inst & lda_disp_mask); - else if ((inst & intop_mask) == addq_pattern) - disp = -int((inst & intop_disp_mask) >> intop_disp_shift); - else if ((inst & intop_mask) == subq_pattern) - disp = int((inst & intop_disp_mask) >> intop_disp_shift); - else - return false; + return false; +} - return true; - } +bool +StackTrace::decodeStack(MachInst inst, int &disp) +{ + // lda $sp, -disp($sp) + // + // Opcode<31:26> == 0x08 + // RA<25:21> == 30 + // RB<20:16> == 30 + // Disp<15:0> + const MachInst mem_mask = 0xffff0000; + const MachInst lda_pattern = 0x23de0000; + const MachInst lda_disp_mask = 0x0000ffff; + + // subq $sp, disp, $sp + // addq $sp, disp, $sp + // + // Opcode<31:26> == 0x10 + // RA<25:21> == 30 + // Lit<20:13> + // One<12> = 1 + // Func<11:5> == 0x20 (addq) + // Func<11:5> == 0x29 (subq) + // RC<4:0> == 30 + const MachInst intop_mask = 0xffe01fff; + const MachInst addq_pattern = 0x43c0141e; + const MachInst subq_pattern = 0x43c0153e; + const MachInst intop_disp_mask = 0x001fe000; + const int intop_disp_shift = 13; + + if ((inst & mem_mask) == lda_pattern) + disp = -sext<16>(inst & lda_disp_mask); + else if ((inst & intop_mask) == addq_pattern) + disp = -int((inst & intop_disp_mask) >> intop_disp_shift); + else if ((inst & intop_mask) == subq_pattern) + disp = int((inst & intop_disp_mask) >> intop_disp_shift); + else + return false; - bool - StackTrace::decodeSave(MachInst inst, int ®, int &disp) - { - // lda $stq, disp($sp) - // - // Opcode<31:26> == 0x08 - // RA<25:21> == ? - // RB<20:16> == 30 - // Disp<15:0> - const MachInst stq_mask = 0xfc1f0000; - const MachInst stq_pattern = 0xb41e0000; - const MachInst stq_disp_mask = 0x0000ffff; - const MachInst reg_mask = 0x03e00000; - const int reg_shift = 21; - - if ((inst & stq_mask) == stq_pattern) { - reg = (inst & reg_mask) >> reg_shift; - disp = sext<16>(inst & stq_disp_mask); - } else { - return false; - } + return true; +} - return true; +bool +StackTrace::decodeSave(MachInst inst, int ®, int &disp) +{ + // lda $stq, disp($sp) + // + // Opcode<31:26> == 0x08 + // RA<25:21> == ? + // RB<20:16> == 30 + // Disp<15:0> + const MachInst stq_mask = 0xfc1f0000; + const MachInst stq_pattern = 0xb41e0000; + const MachInst stq_disp_mask = 0x0000ffff; + const MachInst reg_mask = 0x03e00000; + const int reg_shift = 21; + + if ((inst & stq_mask) == stq_pattern) { + reg = (inst & reg_mask) >> reg_shift; + disp = sext<16>(inst & stq_disp_mask); + } else { + return false; } - /* - * Decode the function prologue for the function we're in, and note - * which registers are stored where, and how large the stack frame is. - */ - bool - StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, - int &size, Addr &ra) - { - size = 0; - ra = 0; - - for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { - MachInst inst; - CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst)); - - int reg, disp; - if (decodeStack(inst, disp)) { - if (size) { - // panic("decoding frame size again"); - return true; - } - size += disp; - } else if (decodeSave(inst, reg, disp)) { - if (!ra && reg == ReturnAddressReg) { - CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); - if (!ra) { - // panic("no return address value pc=%#x\n", pc); - return false; - } + return true; +} + +/* + * Decode the function prologue for the function we're in, and note + * which registers are stored where, and how large the stack frame is. + */ +bool +StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func, int &size, + Addr &ra) +{ + size = 0; + ra = 0; + + for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) { + MachInst inst; + CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst)); + + int reg, disp; + if (decodeStack(inst, disp)) { + if (size) { + // panic("decoding frame size again"); + return true; + } + size += disp; + } else if (decodeSave(inst, reg, disp)) { + if (!ra && reg == ReturnAddressReg) { + CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr)); + if (!ra) { + // panic("no return address value pc=%#x\n", pc); + return false; } } } - - return true; } + return true; +} + #if TRACING_ON - void - StackTrace::dump() - { - StringWrap name(tc->getCpuPtr()->name()); - SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - - DPRINTFN("------ Stack ------\n"); - - string symbol; - for (int i = 0, size = stack.size(); i < size; ++i) { - Addr addr = stack[size - i - 1]; - if (addr == user) - symbol = "user"; - else if (addr == console) - symbol = "console"; - else if (addr == unknown) - symbol = "unknown"; - else - symtab->findSymbol(addr, symbol); - - DPRINTFN("%#x: %s\n", addr, symbol); - } +void +StackTrace::dump() +{ + StringWrap name(tc->getCpuPtr()->name()); + SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; + + DPRINTFN("------ Stack ------\n"); + + string symbol; + for (int i = 0, size = stack.size(); i < size; ++i) { + Addr addr = stack[size - i - 1]; + if (addr == user) + symbol = "user"; + else if (addr == console) + symbol = "console"; + else if (addr == unknown) + symbol = "unknown"; + else + symtab->findSymbol(addr, symbol); + + DPRINTFN("%#x: %s\n", addr, symbol); } -#endif } +#endif + +} // namespace AlphaISA diff --git a/src/arch/alpha/stacktrace.hh b/src/arch/alpha/stacktrace.hh index 834abbc2f..db42c4399 100644 --- a/src/arch/alpha/stacktrace.hh +++ b/src/arch/alpha/stacktrace.hh @@ -36,90 +36,90 @@ class ThreadContext; -namespace AlphaISA -{ - class StackTrace; +namespace AlphaISA { - class ProcessInfo - { - private: - ThreadContext *tc; +class StackTrace; + +class ProcessInfo +{ + private: + ThreadContext *tc; - int thread_info_size; - int task_struct_size; - int task_off; - int pid_off; - int name_off; + int thread_info_size; + int task_struct_size; + int task_off; + int pid_off; + int name_off; - public: - ProcessInfo(ThreadContext *_tc); + public: + ProcessInfo(ThreadContext *_tc); - Addr task(Addr ksp) const; - int pid(Addr ksp) const; - std::string name(Addr ksp) const; - }; + Addr task(Addr ksp) const; + int pid(Addr ksp) const; + std::string name(Addr ksp) const; +}; - class StackTrace - { - protected: - typedef TheISA::MachInst MachInst; - private: - ThreadContext *tc; - std::vector<Addr> stack; +class StackTrace +{ + private: + ThreadContext *tc; + std::vector<Addr> stack; - private: - bool isEntry(Addr addr); - bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); - bool decodeSave(MachInst inst, int ®, int &disp); - bool decodeStack(MachInst inst, int &disp); + private: + bool isEntry(Addr addr); + bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra); + bool decodeSave(MachInst inst, int ®, int &disp); + bool decodeStack(MachInst inst, int &disp); - void trace(ThreadContext *tc, bool is_call); + void trace(ThreadContext *tc, bool is_call); - public: - StackTrace(); - StackTrace(ThreadContext *tc, StaticInstPtr inst); - ~StackTrace(); + public: + StackTrace(); + StackTrace(ThreadContext *tc, StaticInstPtr inst); + ~StackTrace(); - void clear() - { - tc = 0; - stack.clear(); - } + void + clear() + { + tc = 0; + stack.clear(); + } - bool valid() const { return tc != NULL; } - bool trace(ThreadContext *tc, StaticInstPtr inst); + bool valid() const { return tc != NULL; } + bool trace(ThreadContext *tc, StaticInstPtr inst); - public: - const std::vector<Addr> &getstack() const { return stack; } + public: + const std::vector<Addr> &getstack() const { return stack; } - static const int user = 1; - static const int console = 2; - static const int unknown = 3; + static const int user = 1; + static const int console = 2; + static const int unknown = 3; #if TRACING_ON - private: - void dump(); + private: + void dump(); - public: - void dprintf() { if (DTRACE(Stack)) dump(); } + public: + void dprintf() { if (DTRACE(Stack)) dump(); } #else - public: - void dprintf() {} + public: + void dprintf() {} #endif - }; +}; - inline bool - StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) - { - if (!inst->isCall() && !inst->isReturn()) - return false; +inline bool +StackTrace::trace(ThreadContext *tc, StaticInstPtr inst) +{ + if (!inst->isCall() && !inst->isReturn()) + return false; - if (valid()) - clear(); + if (valid()) + clear(); - trace(tc, !inst->isReturn()); - return true; - } + trace(tc, !inst->isReturn()); + return true; } +} // namespace AlphaISA + #endif // __ARCH_ALPHA_STACKTRACE_HH__ diff --git a/src/arch/alpha/system.cc b/src/arch/alpha/system.cc index 2af62ceea..72d918870 100644 --- a/src/arch/alpha/system.cc +++ b/src/arch/alpha/system.cc @@ -42,8 +42,7 @@ #include "params/AlphaSystem.hh" #include "sim/byteswap.hh" - -using namespace LittleEndianGuest; +using namespace AlphaISA; AlphaSystem::AlphaSystem(Params *p) : System(p) @@ -67,8 +66,8 @@ AlphaSystem::AlphaSystem(Params *p) // Load program sections into memory - pal->loadSections(&functionalPort, AlphaISA::LoadAddrMask); - console->loadSections(&functionalPort, AlphaISA::LoadAddrMask); + pal->loadSections(&functionalPort, LoadAddrMask); + console->loadSections(&functionalPort, LoadAddrMask); // load symbols if (!console->loadGlobalSymbols(consoleSymtab)) @@ -117,7 +116,6 @@ AlphaSystem::AlphaSystem(Params *p) virtPort.write(addr+0x58, data); } else panic("could not find hwrpb\n"); - } AlphaSystem::~AlphaSystem() @@ -142,9 +140,9 @@ AlphaSystem::~AlphaSystem() * in the procedure value register (pv aka t12 == r27). This sequence * looks like the following: * - * opcode Ra Rb offset - * ldah gp,X(pv) 09 29 27 X - * lda gp,Y(gp) 08 29 29 Y + * opcode Ra Rb offset + * ldah gp,X(pv) 09 29 27 X + * lda gp,Y(gp) 08 29 29 Y * * for some constant offsets X and Y. The catch is that the linker * (or maybe even the compiler, I'm not sure) may recognize that the @@ -172,11 +170,11 @@ AlphaSystem::fixFuncEventAddr(Addr addr) const uint32_t gp_lda_pattern = (8 << 26) | (29 << 21) | (29 << 16); uint32_t i1 = virtPort.read<uint32_t>(addr); - uint32_t i2 = virtPort.read<uint32_t>(addr + sizeof(AlphaISA::MachInst)); + uint32_t i2 = virtPort.read<uint32_t>(addr + sizeof(MachInst)); if ((i1 & inst_mask) == gp_ldah_pattern && (i2 & inst_mask) == gp_lda_pattern) { - Addr new_addr = addr + 2* sizeof(AlphaISA::MachInst); + Addr new_addr = addr + 2 * sizeof(MachInst); DPRINTF(Loader, "fixFuncEventAddr: %p -> %p", addr, new_addr); return new_addr; } else { @@ -184,15 +182,15 @@ AlphaSystem::fixFuncEventAddr(Addr addr) } } - void AlphaSystem::setAlphaAccess(Addr access) { Addr addr = 0; if (consoleSymtab->findAddress("m5AlphaAccess", addr)) { - virtPort.write(addr, htog(EV5::Phys2K0Seg(access))); - } else + virtPort.write(addr, htog(Phys2K0Seg(access))); + } else { panic("could not find m5AlphaAccess\n"); + } } void @@ -203,7 +201,6 @@ AlphaSystem::serialize(std::ostream &os) palSymtab->serialize("pal_symtab", os); } - void AlphaSystem::unserialize(Checkpoint *cp, const std::string §ion) { diff --git a/src/arch/alpha/system.hh b/src/arch/alpha/system.hh index a934550b7..da42ab263 100644 --- a/src/arch/alpha/system.hh +++ b/src/arch/alpha/system.hh @@ -49,10 +49,10 @@ class AlphaSystem : public System AlphaSystem(Params *p); ~AlphaSystem(); -/** - * Serialization stuff - */ public: + /** + * Serialization stuff + */ virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); @@ -77,26 +77,28 @@ class AlphaSystem : public System /** Event to halt the simulator if the console calls panic() */ BreakPCEvent *consolePanicEvent; #endif + protected: const Params *params() const { return (const Params *)_params; } /** Add a function-based event to PALcode. */ template <class T> - T *addPalFuncEvent(const char *lbl) + T * + addPalFuncEvent(const char *lbl) { return addFuncEvent<T>(palSymtab, lbl); } /** Add a function-based event to the console code. */ template <class T> - T *addConsoleFuncEvent(const char *lbl) + T * + addConsoleFuncEvent(const char *lbl) { return addFuncEvent<T>(consoleSymtab, lbl); } virtual Addr fixFuncEventAddr(Addr addr); - }; -#endif +#endif // __ARCH_ALPHA_SYSTEM_HH__ diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 77bf5e285..2b0afacfe 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -43,19 +43,20 @@ #include "cpu/thread_context.hh" using namespace std; -using namespace EV5; namespace AlphaISA { + /////////////////////////////////////////////////////////////////////// // // Alpha TLB // + #ifdef DEBUG bool uncacheBit39 = false; bool uncacheBit40 = false; #endif -#define MODE2MASK(X) (1 << (X)) +#define MODE2MASK(X) (1 << (X)) TLB::TLB(const Params *p) : BaseTLB(p), size(p->size), nlu(0) @@ -114,20 +115,20 @@ TLB::lookup(Addr vpn, uint8_t asn) return retval; } - Fault -TLB::checkCacheability(RequestPtr &req) +TLB::checkCacheability(RequestPtr &req, bool itb) { -// in Alpha, cacheability is controlled by upper-level bits of the -// physical address - -/* - * We support having the uncacheable bit in either bit 39 or bit 40. - * The Turbolaser platform (and EV5) support having the bit in 39, but - * Tsunami (which Linux assumes uses an EV6) generates accesses with - * the bit in 40. So we must check for both, but we have debug flags - * to catch a weird case where both are used, which shouldn't happen. - */ + // in Alpha, cacheability is controlled by upper-level bits of the + // physical address + + /* + * We support having the uncacheable bit in either bit 39 or bit + * 40. The Turbolaser platform (and EV5) support having the bit + * in 39, but Tsunami (which Linux assumes uses an EV6) generates + * accesses with the bit in 40. So we must check for both, but we + * have debug flags to catch a weird case where both are used, + * which shouldn't happen. + */ #if ALPHA_TLASER @@ -141,13 +142,20 @@ TLB::checkCacheability(RequestPtr &req) return new UnimpFault("IPR memory space not implemented!"); } else { // mark request as uncacheable - req->setFlags(req->getFlags() | UNCACHEABLE); + req->setFlags(Request::UNCACHEABLE); #if !ALPHA_TLASER - // Clear bits 42:35 of the physical address (10-2 in Tsunami manual) + // Clear bits 42:35 of the physical address (10-2 in + // Tsunami manual) req->setPaddr(req->getPaddr() & PAddrUncachedMask); #endif } + // We shouldn't be able to read from an uncachable address in Alpha as + // we don't have a ROM and we don't want to try to fetch from a device + // register as we destroy any data that is clear-on-read. + if (req->isUncacheable() && itb) + return new UnimpFault("CPU trying to fetch from uncached I/O"); + } return NoFault; } @@ -216,7 +224,8 @@ TLB::flushProcesses() ++i; if (!entry->asma) { - DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, entry->tag, entry->ppn); + DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, + entry->tag, entry->ppn); entry->valid = false; lookupTable.erase(cur); } @@ -279,7 +288,6 @@ TLB::unserialize(Checkpoint *cp, const string §ion) } } - /////////////////////////////////////////////////////////////////////// // // Alpha ITB @@ -308,13 +316,12 @@ ITB::regStats() accesses = hits + misses; } - Fault -ITB::translate(RequestPtr &req, ThreadContext *tc) +ITB::translateAtomic(RequestPtr req, ThreadContext *tc) { //If this is a pal pc, then set PHYSICAL - if(FULL_SYSTEM && PcPAL(req->getPC())) - req->setFlags(req->getFlags() | PHYSICAL); + if (FULL_SYSTEM && PcPAL(req->getPC())) + req->setFlags(Request::PHYSICAL); if (PcPAL(req->getPC())) { // strip off PAL PC marker (lsb is 1) @@ -323,7 +330,7 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) return NoFault; } - if (req->getFlags() & PHYSICAL) { + if (req->getFlags() & Request::PHYSICAL) { req->setPaddr(req->getVaddr()); } else { // verify that this is a good virtual address @@ -390,15 +397,23 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) if (req->getPaddr() & ~PAddrImplMask) return genMachineCheckFault(); - return checkCacheability(req); + return checkCacheability(req, true); } +void +ITB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation) +{ + assert(translation); + translation->finish(translateAtomic(req, tc), req, tc, false); +} + /////////////////////////////////////////////////////////////////////// // // Alpha DTB // - DTB::DTB(const Params *p) +DTB::DTB(const Params *p) : TLB(p) {} @@ -472,14 +487,13 @@ DTB::regStats() } Fault -DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) +DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write) { Addr pc = tc->readPC(); mode_type mode = (mode_type)DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)); - /** * Check for alignment faults */ @@ -491,13 +505,13 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) } if (PcPAL(pc)) { - mode = (req->getFlags() & ALTMODE) ? + mode = (req->getFlags() & Request::ALTMODE) ? (mode_type)ALT_MODE_AM( tc->readMiscRegNoEffect(IPR_ALT_MODE)) : mode_kernel; } - if (req->getFlags() & PHYSICAL) { + if (req->getFlags() & Request::PHYSICAL) { req->setPaddr(req->getVaddr()); } else { // verify that this is a good virtual address @@ -517,14 +531,15 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) #endif { - // only valid in kernel mode if (DTB_CM_CM(tc->readMiscRegNoEffect(IPR_DTB_CM)) != mode_kernel) { if (write) { write_acv++; } else { read_acv++; } uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK); - return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); + + return new DtbAcvFault(req->getVaddr(), req->getFlags(), + flags); } req->setPaddr(req->getVaddr() & PAddrImplMask); @@ -553,7 +568,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (write) { write_misses++; } else { read_misses++; } uint64_t flags = (write ? MM_STAT_WR_MASK : 0) | MM_STAT_DTB_MISS_MASK; - return (req->getFlags() & VPTE) ? + return (req->getFlags() & Request::VPTE) ? (Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(), flags)) : (Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(), @@ -570,25 +585,28 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) uint64_t flags = MM_STAT_WR_MASK | MM_STAT_ACV_MASK | (entry->fonw ? MM_STAT_FONW_MASK : 0); - return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); + return new DtbPageFault(req->getVaddr(), req->getFlags(), + flags); } if (entry->fonw) { write_acv++; - uint64_t flags = MM_STAT_WR_MASK | - MM_STAT_FONW_MASK; - return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); + uint64_t flags = MM_STAT_WR_MASK | MM_STAT_FONW_MASK; + return new DtbPageFault(req->getVaddr(), req->getFlags(), + flags); } } else { if (!(entry->xre & MODE2MASK(mode))) { read_acv++; uint64_t flags = MM_STAT_ACV_MASK | (entry->fonr ? MM_STAT_FONR_MASK : 0); - return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); + return new DtbAcvFault(req->getVaddr(), req->getFlags(), + flags); } if (entry->fonr) { read_acv++; uint64_t flags = MM_STAT_FONR_MASK; - return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); + return new DtbPageFault(req->getVaddr(), req->getFlags(), + flags); } } } @@ -606,6 +624,14 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) return checkCacheability(req); } +void +DTB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write) +{ + assert(translation); + translation->finish(translateAtomic(req, tc, write), req, tc, write); +} + TlbEntry & TLB::index(bool advance) { diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index e61ae5c6d..643889534 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -29,8 +29,8 @@ * Steve Reinhardt */ -#ifndef __ALPHA_MEMORY_HH__ -#define __ALPHA_MEMORY_HH__ +#ifndef __ARCH_ALPHA_TLB_HH__ +#define __ARCH_ALPHA_TLB_HH__ #include <map> @@ -48,110 +48,120 @@ class ThreadContext; -namespace AlphaISA +namespace AlphaISA { + +class TlbEntry; + +class TLB : public BaseTLB { - class TlbEntry; + protected: + typedef std::multimap<Addr, int> PageTable; + PageTable lookupTable; // Quick lookup into page table + + TlbEntry *table; // the Page Table + int size; // TLB Size + int nlu; // not last used entry (for replacement) + + void nextnlu() { if (++nlu >= size) nlu = 0; } + TlbEntry *lookup(Addr vpn, uint8_t asn); + + public: + typedef AlphaTLBParams Params; + TLB(const Params *p); + virtual ~TLB(); + + int getsize() const { return size; } - class TLB : public BaseTLB + TlbEntry &index(bool advance = true); + void insert(Addr vaddr, TlbEntry &entry); + + void flushAll(); + void flushProcesses(); + void flushAddr(Addr addr, uint8_t asn); + + void + demapPage(Addr vaddr, uint64_t asn) { - protected: - typedef std::multimap<Addr, int> PageTable; - PageTable lookupTable; // Quick lookup into page table - - TlbEntry *table; // the Page Table - int size; // TLB Size - int nlu; // not last used entry (for replacement) - - void nextnlu() { if (++nlu >= size) nlu = 0; } - TlbEntry *lookup(Addr vpn, uint8_t asn); - - public: - typedef AlphaTLBParams Params; - TLB(const Params *p); - virtual ~TLB(); - - int getsize() const { return size; } - - TlbEntry &index(bool advance = true); - void insert(Addr vaddr, TlbEntry &entry); - - void flushAll(); - void flushProcesses(); - void flushAddr(Addr addr, uint8_t asn); - - void demapPage(Addr vaddr, uint64_t asn) - { - assert(asn < (1 << 8)); - flushAddr(vaddr, asn); - } - - // static helper functions... really EV5 VM traits - static bool validVirtualAddress(Addr vaddr) { - // unimplemented bits must be all 0 or all 1 - Addr unimplBits = vaddr & EV5::VAddrUnImplMask; - return (unimplBits == 0) || (unimplBits == EV5::VAddrUnImplMask); - } - - static Fault checkCacheability(RequestPtr &req); - - // Checkpointing - virtual void serialize(std::ostream &os); - virtual void unserialize(Checkpoint *cp, const std::string §ion); - - // Most recently used page table entries - TlbEntry *EntryCache[3]; - inline void flushCache() - { - memset(EntryCache, 0, 3 * sizeof(TlbEntry*)); - } - - inline TlbEntry* updateCache(TlbEntry *entry) { - EntryCache[2] = EntryCache[1]; - EntryCache[1] = EntryCache[0]; - EntryCache[0] = entry; - return entry; - } - }; - - class ITB : public TLB + assert(asn < (1 << 8)); + flushAddr(vaddr, asn); + } + + // static helper functions... really EV5 VM traits + static bool + validVirtualAddress(Addr vaddr) { - protected: - mutable Stats::Scalar<> hits; - mutable Stats::Scalar<> misses; - mutable Stats::Scalar<> acv; - mutable Stats::Formula accesses; + // unimplemented bits must be all 0 or all 1 + Addr unimplBits = vaddr & VAddrUnImplMask; + return unimplBits == 0 || unimplBits == VAddrUnImplMask; + } - public: - typedef AlphaITBParams Params; - ITB(const Params *p); - virtual void regStats(); + static Fault checkCacheability(RequestPtr &req, bool itb = false); - Fault translate(RequestPtr &req, ThreadContext *tc); - }; + // Checkpointing + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); - class DTB : public TLB + // Most recently used page table entries + TlbEntry *EntryCache[3]; + inline void + flushCache() { - protected: - mutable Stats::Scalar<> read_hits; - mutable Stats::Scalar<> read_misses; - mutable Stats::Scalar<> read_acv; - mutable Stats::Scalar<> read_accesses; - mutable Stats::Scalar<> write_hits; - mutable Stats::Scalar<> write_misses; - mutable Stats::Scalar<> write_acv; - mutable Stats::Scalar<> write_accesses; - Stats::Formula hits; - Stats::Formula misses; - Stats::Formula acv; - Stats::Formula accesses; - - public: - typedef AlphaDTBParams Params; - DTB(const Params *p); - virtual void regStats(); - - Fault translate(RequestPtr &req, ThreadContext *tc, bool write); - }; -} - -#endif // __ALPHA_MEMORY_HH__ + memset(EntryCache, 0, 3 * sizeof(TlbEntry*)); + } + + inline TlbEntry * + updateCache(TlbEntry *entry) { + EntryCache[2] = EntryCache[1]; + EntryCache[1] = EntryCache[0]; + EntryCache[0] = entry; + return entry; + } +}; + +class ITB : public TLB +{ + protected: + mutable Stats::Scalar hits; + mutable Stats::Scalar misses; + mutable Stats::Scalar acv; + mutable Stats::Formula accesses; + + public: + typedef AlphaITBParams Params; + ITB(const Params *p); + virtual void regStats(); + + Fault translateAtomic(RequestPtr req, ThreadContext *tc); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation); +}; + +class DTB : public TLB +{ + protected: + mutable Stats::Scalar read_hits; + mutable Stats::Scalar read_misses; + mutable Stats::Scalar read_acv; + mutable Stats::Scalar read_accesses; + mutable Stats::Scalar write_hits; + mutable Stats::Scalar write_misses; + mutable Stats::Scalar write_acv; + mutable Stats::Scalar write_accesses; + Stats::Formula hits; + Stats::Formula misses; + Stats::Formula acv; + Stats::Formula accesses; + + public: + typedef AlphaDTBParams Params; + DTB(const Params *p); + virtual void regStats(); + + Fault translateAtomic(RequestPtr req, ThreadContext *tc, bool write); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write); +}; + +} // namespace AlphaISA + +#endif // __ARCH_ALPHA_TLB_HH__ diff --git a/src/arch/alpha/tru64/process.cc b/src/arch/alpha/tru64/process.cc index 6823d820a..8fa3cdeda 100644 --- a/src/arch/alpha/tru64/process.cc +++ b/src/arch/alpha/tru64/process.cc @@ -32,10 +32,8 @@ #include "arch/alpha/tru64/tru64.hh" #include "arch/alpha/isa_traits.hh" #include "arch/alpha/tru64/process.hh" - #include "cpu/thread_context.hh" #include "kern/tru64/tru64.hh" - #include "sim/process.hh" #include "sim/syscall_emul.hh" @@ -47,7 +45,7 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<AlphaTru64::utsname> name(tc->getSyscallArg(0)); + TypedBufferArg<AlphaTru64::utsname> name(process->getSyscallArg(tc, 0)); strcpy(name->sysname, "OSF1"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -64,34 +62,35 @@ static SyscallReturn getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); - unsigned nbytes = tc->getSyscallArg(2); + unsigned op = process->getSyscallArg(tc, 0); + unsigned nbytes = process->getSyscallArg(tc, 2); switch (op) { case AlphaTru64::GSI_MAX_CPU: { - TypedBufferArg<uint32_t> max_cpu(tc->getSyscallArg(1)); + TypedBufferArg<uint32_t> max_cpu(process->getSyscallArg(tc, 1)); *max_cpu = htog((uint32_t)process->numCpus()); max_cpu.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPUS_IN_BOX: { - TypedBufferArg<uint32_t> cpus_in_box(tc->getSyscallArg(1)); + TypedBufferArg<uint32_t> cpus_in_box(process->getSyscallArg(tc, 1)); *cpus_in_box = htog((uint32_t)process->numCpus()); cpus_in_box.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PHYSMEM: { - TypedBufferArg<uint64_t> physmem(tc->getSyscallArg(1)); - *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB + TypedBufferArg<uint64_t> physmem(process->getSyscallArg(tc, 1)); + *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB physmem.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_CPU_INFO: { - TypedBufferArg<AlphaTru64::cpu_info> infop(tc->getSyscallArg(1)); + TypedBufferArg<AlphaTru64::cpu_info> + infop(process->getSyscallArg(tc, 1)); infop->current_cpu = htog(0); infop->cpus_in_box = htog(process->numCpus()); @@ -108,14 +107,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } case AlphaTru64::GSI_PROC_TYPE: { - TypedBufferArg<uint64_t> proc_type(tc->getSyscallArg(1)); + TypedBufferArg<uint64_t> proc_type(process->getSyscallArg(tc, 1)); *proc_type = htog((uint64_t)11); proc_type.copyOut(tc->getMemPort()); return 1; } case AlphaTru64::GSI_PLATFORM_NAME: { - BufferArg bufArg(tc->getSyscallArg(1), nbytes); + BufferArg bufArg(process->getSyscallArg(tc, 1), nbytes); strncpy((char *)bufArg.bufferPtr(), "COMPAQ Professional Workstation XP1000", nbytes); @@ -124,7 +123,7 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, } case AlphaTru64::GSI_CLK_TCK: { - TypedBufferArg<uint64_t> clk_hz(tc->getSyscallArg(1)); + TypedBufferArg<uint64_t> clk_hz(process->getSyscallArg(tc, 1)); *clk_hz = htog((uint64_t)1024); clk_hz.copyOut(tc->getMemPort()); return 1; @@ -143,12 +142,12 @@ static SyscallReturn setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - unsigned op = tc->getSyscallArg(0); + unsigned op = process->getSyscallArg(tc, 0); switch (op) { case AlphaTru64::SSI_IEEE_FP_CONTROL: warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n", - tc->getSyscallArg(1)); + process->getSyscallArg(tc, 1)); break; default: @@ -159,26 +158,24 @@ setsysinfoFunc(SyscallDesc *desc, int callnum, LiveProcess *process, return 0; } - /// Target table() handler. -static -SyscallReturn tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process, - ThreadContext *tc) +static SyscallReturn +tableFunc(SyscallDesc *desc, int callnum, LiveProcess *process, + ThreadContext *tc) { using namespace std; - using namespace TheISA; - int id = tc->getSyscallArg(0); // table ID - int index = tc->getSyscallArg(1); // index into table + int id = process->getSyscallArg(tc, 0); // table ID + int index = process->getSyscallArg(tc, 1); // index into table // arg 2 is buffer pointer; type depends on table ID - int nel = tc->getSyscallArg(3); // number of elements - int lel = tc->getSyscallArg(4); // expected element size + int nel = process->getSyscallArg(tc, 3); // number of elements + int lel = process->getSyscallArg(tc, 4); // expected element size switch (id) { case AlphaTru64::TBL_SYSINFO: { if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo)) return -EINVAL; - TypedBufferArg<Tru64::tbl_sysinfo> elp(tc->getSyscallArg(2)); + TypedBufferArg<Tru64::tbl_sysinfo> elp(process->getSyscallArg(tc, 2)); const int clk_hz = one_million; elp->si_user = htog(curTick / (Clock::Frequency / clk_hz)); @@ -219,7 +216,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", unimplementedFunc), /* 16 */ SyscallDesc("chown", unimplementedFunc), - /* 17 */ SyscallDesc("obreak", obreakFunc), + /* 17 */ SyscallDesc("obreak", brkFunc), /* 18 */ SyscallDesc("pre_F64_getfsstat", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getpid", getpidPseudoFunc), @@ -260,9 +257,9 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 55 */ SyscallDesc("reboot", unimplementedFunc), /* 56 */ SyscallDesc("revoke", unimplementedFunc), /* 57 */ SyscallDesc("symlink", unimplementedFunc), - /* 58 */ SyscallDesc("readlink", unimplementedFunc), + /* 58 */ SyscallDesc("readlink", readlinkFunc), /* 59 */ SyscallDesc("execve", unimplementedFunc), - /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), /* 62 */ SyscallDesc("old_fstat", unimplementedFunc), /* 63 */ SyscallDesc("getpgrp", unimplementedFunc), @@ -339,7 +336,7 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 133 */ SyscallDesc("sendto", unimplementedFunc), /* 134 */ SyscallDesc("shutdown", unimplementedFunc), /* 135 */ SyscallDesc("socketpair", unimplementedFunc), - /* 136 */ SyscallDesc("mkdir", unimplementedFunc), + /* 136 */ SyscallDesc("mkdir", mkdirFunc), /* 137 */ SyscallDesc("rmdir", unimplementedFunc), /* 138 */ SyscallDesc("utimes", unimplementedFunc), /* 139 */ SyscallDesc("obsolete 4.2 sigreturn", unimplementedFunc), @@ -472,15 +469,14 @@ SyscallDesc AlphaTru64Process::syscallDescs[] = { /* 266 */ SyscallDesc("sendfile", unimplementedFunc), }; - - SyscallDesc AlphaTru64Process::machSyscallDescs[] = { /* 0 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 1 */ SyscallDesc("m5_mutex_lock", AlphaTru64::m5_mutex_lockFunc), /* 2 */ SyscallDesc("m5_mutex_trylock", AlphaTru64::m5_mutex_trylockFunc), /* 3 */ SyscallDesc("m5_mutex_unlock", AlphaTru64::m5_mutex_unlockFunc), /* 4 */ SyscallDesc("m5_cond_signal", AlphaTru64::m5_cond_signalFunc), - /* 5 */ SyscallDesc("m5_cond_broadcast", AlphaTru64::m5_cond_broadcastFunc), + /* 5 */ SyscallDesc("m5_cond_broadcast", + AlphaTru64::m5_cond_broadcastFunc), /* 6 */ SyscallDesc("m5_cond_wait", AlphaTru64::m5_cond_waitFunc), /* 7 */ SyscallDesc("m5_thread_exit", AlphaTru64::m5_thread_exitFunc), /* 8 */ SyscallDesc("kern_invalid", unimplementedFunc), @@ -507,7 +503,8 @@ SyscallDesc AlphaTru64Process::machSyscallDescs[] = { /* 29 */ SyscallDesc("nxm_thread_destroy", unimplementedFunc), /* 30 */ SyscallDesc("lw_wire", unimplementedFunc), /* 31 */ SyscallDesc("lw_unwire", unimplementedFunc), - /* 32 */ SyscallDesc("nxm_thread_create", AlphaTru64::nxm_thread_createFunc), + /* 32 */ SyscallDesc("nxm_thread_create", + AlphaTru64::nxm_thread_createFunc), /* 33 */ SyscallDesc("nxm_task_init", AlphaTru64::nxm_task_initFunc), /* 34 */ SyscallDesc("kern_invalid", unimplementedFunc), /* 35 */ SyscallDesc("nxm_idle", AlphaTru64::nxm_idleFunc), @@ -572,9 +569,8 @@ AlphaTru64Process::getDesc(int callnum) return &syscallDescs[callnum]; } - -AlphaTru64Process::AlphaTru64Process(LiveProcessParams * params, - ObjectFile *objFile) +AlphaTru64Process::AlphaTru64Process(LiveProcessParams *params, + ObjectFile *objFile) : AlphaLiveProcess(params, objFile), Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)), Num_Mach_Syscall_Descs(sizeof(machSyscallDescs) / sizeof(SyscallDesc)) diff --git a/src/arch/alpha/tru64/process.hh b/src/arch/alpha/tru64/process.hh index 16bc499c6..6d7a76555 100644 --- a/src/arch/alpha/tru64/process.hh +++ b/src/arch/alpha/tru64/process.hh @@ -28,12 +28,13 @@ * Authors: Steve Reinhardt */ -#ifndef __ALPHA_TRU64_PROCESS_HH__ -#define __ALPHA_TRU64_PROCESS_HH__ +#ifndef __ARCH_ALPHA_TRU64_PROCESS_HH__ +#define __ARCH_ALPHA_TRU64_PROCESS_HH__ #include "arch/alpha/process.hh" namespace AlphaISA { + /// A process with emulated Alpha Tru64 syscalls. class AlphaTru64Process : public AlphaLiveProcess { @@ -51,9 +52,9 @@ class AlphaTru64Process : public AlphaLiveProcess const int Num_Syscall_Descs; const int Num_Mach_Syscall_Descs; - virtual SyscallDesc* getDesc(int callnum); + virtual SyscallDesc *getDesc(int callnum); }; } // namespace AlphaISA -#endif // __ALPHA_TRU64_PROCESS_HH__ +#endif // __ARCH_ALPHA_TRU64_PROCESS_HH__ diff --git a/src/arch/alpha/tru64/tru64.cc b/src/arch/alpha/tru64/tru64.cc index 56b04846f..c72e975f0 100644 --- a/src/arch/alpha/tru64/tru64.cc +++ b/src/arch/alpha/tru64/tru64.cc @@ -33,34 +33,34 @@ // open(2) flags translation table OpenFlagTransTable AlphaTru64::openFlagTable[] = { #ifdef _MSC_VER - { AlphaTru64::TGT_O_RDONLY, _O_RDONLY }, - { AlphaTru64::TGT_O_WRONLY, _O_WRONLY }, - { AlphaTru64::TGT_O_RDWR, _O_RDWR }, - { AlphaTru64::TGT_O_APPEND, _O_APPEND }, - { AlphaTru64::TGT_O_CREAT, _O_CREAT }, - { AlphaTru64::TGT_O_TRUNC, _O_TRUNC }, - { AlphaTru64::TGT_O_EXCL, _O_EXCL }, + { AlphaTru64::TGT_O_RDONLY, _O_RDONLY }, + { AlphaTru64::TGT_O_WRONLY, _O_WRONLY }, + { AlphaTru64::TGT_O_RDWR, _O_RDWR }, + { AlphaTru64::TGT_O_APPEND, _O_APPEND }, + { AlphaTru64::TGT_O_CREAT, _O_CREAT }, + { AlphaTru64::TGT_O_TRUNC, _O_TRUNC }, + { AlphaTru64::TGT_O_EXCL, _O_EXCL }, #ifdef _O_NONBLOCK - { AlphaTru64::TGT_O_NONBLOCK, _O_NONBLOCK }, + { AlphaTru64::TGT_O_NONBLOCK, _O_NONBLOCK }, #endif #ifdef _O_NOCTTY - { AlphaTru64::TGT_O_NOCTTY, _O_NOCTTY }, + { AlphaTru64::TGT_O_NOCTTY, _O_NOCTTY }, #endif #ifdef _O_SYNC - { AlphaTru64::TGT_O_SYNC, _O_SYNC }, + { AlphaTru64::TGT_O_SYNC, _O_SYNC }, #endif #else /* !_MSC_VER */ - { AlphaTru64::TGT_O_RDONLY, O_RDONLY }, - { AlphaTru64::TGT_O_WRONLY, O_WRONLY }, - { AlphaTru64::TGT_O_RDWR, O_RDWR }, - { AlphaTru64::TGT_O_APPEND, O_APPEND }, - { AlphaTru64::TGT_O_CREAT, O_CREAT }, - { AlphaTru64::TGT_O_TRUNC, O_TRUNC }, - { AlphaTru64::TGT_O_EXCL, O_EXCL }, - { AlphaTru64::TGT_O_NONBLOCK, O_NONBLOCK }, - { AlphaTru64::TGT_O_NOCTTY, O_NOCTTY }, + { AlphaTru64::TGT_O_RDONLY, O_RDONLY }, + { AlphaTru64::TGT_O_WRONLY, O_WRONLY }, + { AlphaTru64::TGT_O_RDWR, O_RDWR }, + { AlphaTru64::TGT_O_APPEND, O_APPEND }, + { AlphaTru64::TGT_O_CREAT, O_CREAT }, + { AlphaTru64::TGT_O_TRUNC, O_TRUNC }, + { AlphaTru64::TGT_O_EXCL, O_EXCL }, + { AlphaTru64::TGT_O_NONBLOCK, O_NONBLOCK }, + { AlphaTru64::TGT_O_NOCTTY, O_NOCTTY }, #ifdef O_SYNC - { AlphaTru64::TGT_O_SYNC, O_SYNC }, + { AlphaTru64::TGT_O_SYNC, O_SYNC }, #endif #endif /* _MSC_VER */ }; diff --git a/src/arch/alpha/tru64/tru64.hh b/src/arch/alpha/tru64/tru64.hh index 90e5f12dc..4ba35fc50 100644 --- a/src/arch/alpha/tru64/tru64.hh +++ b/src/arch/alpha/tru64/tru64.hh @@ -28,14 +28,13 @@ * Authors: Korey Sewell */ -#ifndef __ALPHA_ALPHA_TRU64_HH -#define __ALPHA_ALPHA_TRU64_HH +#ifndef __ALPHA_ALPHA_TRU64_TRU64_HH__ +#define __ALPHA_ALPHA_TRU64_TRU64_HH__ #include "kern/tru64/tru64.hh" class AlphaTru64 : public Tru64 { - public: /// This table maps the target open() flags to the corresponding /// host open() flags. @@ -46,21 +45,21 @@ class AlphaTru64 : public Tru64 //@{ /// open(2) flag values. - static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY - static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY - static const int TGT_O_RDWR = 00000002; //!< O_RDWR - static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK - static const int TGT_O_APPEND = 00000010; //!< O_APPEND - static const int TGT_O_CREAT = 00001000; //!< O_CREAT - static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC - static const int TGT_O_EXCL = 00004000; //!< O_EXCL - static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY - static const int TGT_O_SYNC = 00040000; //!< O_SYNC - static const int TGT_O_DRD = 00100000; //!< O_DRD - static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO - static const int TGT_O_CACHE = 00400000; //!< O_CACHE - static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC - static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC + static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 00000002; //!< O_RDWR + static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK + static const int TGT_O_APPEND = 00000010; //!< O_APPEND + static const int TGT_O_CREAT = 00001000; //!< O_CREAT + static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC + static const int TGT_O_EXCL = 00004000; //!< O_EXCL + static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY + static const int TGT_O_SYNC = 00040000; //!< O_SYNC + static const int TGT_O_DRD = 00100000; //!< O_DRD + static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO + static const int TGT_O_CACHE = 00400000; //!< O_CACHE + static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC + static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC //@} /// For mmap(). @@ -68,13 +67,13 @@ class AlphaTru64 : public Tru64 //@{ /// For getsysinfo(). - static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string - static const unsigned GSI_CPU_INFO = 59; //!< CPU information - static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type - static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine - static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system - static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB - static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz + static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name string + static const unsigned GSI_CPU_INFO = 59; //!< CPU information + static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type + static const unsigned GSI_MAX_CPU = 30; //!< max # CPUs on machine + static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system + static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB + static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz //@} //@{ @@ -124,6 +123,4 @@ class AlphaTru64 : public Tru64 }; }; - - -#endif +#endif // __ALPHA_ALPHA_TRU64_TRU64_HH__ diff --git a/src/arch/alpha/types.hh b/src/arch/alpha/types.hh index f6648b776..7905114b8 100644 --- a/src/arch/alpha/types.hh +++ b/src/arch/alpha/types.hh @@ -32,47 +32,43 @@ #ifndef __ARCH_ALPHA_TYPES_HH__ #define __ARCH_ALPHA_TYPES_HH__ -#include <inttypes.h> +#include "sim/host.hh" -namespace AlphaISA -{ - - typedef uint32_t MachInst; - typedef uint64_t ExtMachInst; - typedef uint8_t RegIndex; +namespace AlphaISA { - typedef uint64_t IntReg; - typedef uint64_t LargestRead; +typedef uint32_t MachInst; +typedef uint64_t ExtMachInst; +typedef uint8_t RegIndex; - // floating point register file entry type - typedef double FloatReg; - typedef uint64_t FloatRegBits; +typedef uint64_t IntReg; +typedef uint64_t LargestRead; - // control register file contents - typedef uint64_t MiscReg; +// floating point register file entry type +typedef double FloatReg; +typedef uint64_t FloatRegBits; - typedef union { - IntReg intreg; - FloatReg fpreg; - MiscReg ctrlreg; - } AnyReg; +// control register file contents +typedef uint64_t MiscReg; - enum RegContextParam - { - CONTEXT_PALMODE - }; +union AnyReg +{ + IntReg intreg; + FloatReg fpreg; + MiscReg ctrlreg; +}; - typedef bool RegContextVal; +enum annotes +{ + ANNOTE_NONE = 0, + // An impossible number for instruction annotations + ITOUCH_ANNOTE = 0xffffffff, +}; - enum annotes { - ANNOTE_NONE = 0, - // An impossible number for instruction annotations - ITOUCH_ANNOTE = 0xffffffff, - }; +struct CoreSpecific +{ + int core_type; +}; - struct CoreSpecific { - int core_type; - }; } // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_TYPES_HH__ diff --git a/src/arch/alpha/utility.cc b/src/arch/alpha/utility.cc index f1864203b..763da0d4f 100644 --- a/src/arch/alpha/utility.cc +++ b/src/arch/alpha/utility.cc @@ -36,28 +36,28 @@ #include "mem/vport.hh" #endif -namespace AlphaISA -{ +namespace AlphaISA { -uint64_t getArgument(ThreadContext *tc, int number, bool fp) +uint64_t +getArgument(ThreadContext *tc, int number, bool fp) { #if FULL_SYSTEM + const int NumArgumentRegs = 6; if (number < NumArgumentRegs) { if (fp) - return tc->readFloatRegBits(ArgumentReg[number]); + return tc->readFloatRegBits(16 + number); else - return tc->readIntReg(ArgumentReg[number]); + return tc->readIntReg(16 + number); } else { Addr sp = tc->readIntReg(StackPointerReg); - VirtualPort *vp = tc->getVirtPort(tc); + VirtualPort *vp = tc->getVirtPort(); uint64_t arg = vp->read<uint64_t>(sp + (number-NumArgumentRegs) * sizeof(uint64_t)); - tc->delVirtPort(vp); return arg; } #else panic("getArgument() is Full system only\n"); - M5_DUMMY_RETURN + M5_DUMMY_RETURN; #endif } diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh index 11357bc44..76c6c5726 100644 --- a/src/arch/alpha/utility.hh +++ b/src/arch/alpha/utility.hh @@ -32,127 +32,137 @@ #ifndef __ARCH_ALPHA_UTILITY_HH__ #define __ARCH_ALPHA_UTILITY_HH__ -#include "config/full_system.hh" #include "arch/alpha/types.hh" #include "arch/alpha/isa_traits.hh" #include "arch/alpha/regfile.hh" #include "base/misc.hh" +#include "config/full_system.hh" #include "cpu/thread_context.hh" -namespace AlphaISA +namespace AlphaISA { + +uint64_t getArgument(ThreadContext *tc, int number, bool fp); + +inline bool +inUserMode(ThreadContext *tc) +{ + return (tc->readMiscRegNoEffect(IPR_DTB_CM) & 0x18) != 0; +} + +inline bool +isCallerSaveIntegerRegister(unsigned int reg) +{ + panic("register classification not implemented"); + return (reg >= 1 && reg <= 8) || (reg >= 22 && reg <= 25) || reg == 27; +} + +inline bool +isCalleeSaveIntegerRegister(unsigned int reg) +{ + panic("register classification not implemented"); + return reg >= 9 && reg <= 15; +} + +inline bool +isCallerSaveFloatRegister(unsigned int reg) +{ + panic("register classification not implemented"); + return false; +} + +inline bool +isCalleeSaveFloatRegister(unsigned int reg) +{ + panic("register classification not implemented"); + return false; +} + +inline Addr +alignAddress(const Addr &addr, unsigned int nbytes) +{ + return (addr & ~(nbytes - 1)); +} + +// Instruction address compression hooks +inline Addr +realPCToFetchPC(const Addr &addr) +{ + return addr; +} + +inline Addr +fetchPCToRealPC(const Addr &addr) { + return addr; +} - uint64_t getArgument(ThreadContext *tc, int number, bool fp); - - static inline bool - inUserMode(ThreadContext *tc) - { - return (tc->readMiscRegNoEffect(AlphaISA::IPR_DTB_CM) & 0x18) != 0; - } - - inline bool isCallerSaveIntegerRegister(unsigned int reg) { - panic("register classification not implemented"); - return (reg >= 1 && reg <= 8 || reg >= 22 && reg <= 25 || reg == 27); - } - - inline bool isCalleeSaveIntegerRegister(unsigned int reg) { - panic("register classification not implemented"); - return (reg >= 9 && reg <= 15); - } - - inline bool isCallerSaveFloatRegister(unsigned int reg) { - panic("register classification not implemented"); - return false; - } - - inline bool isCalleeSaveFloatRegister(unsigned int reg) { - panic("register classification not implemented"); - return false; - } - - inline Addr alignAddress(const Addr &addr, - unsigned int nbytes) { - return (addr & ~(nbytes - 1)); - } - - // Instruction address compression hooks - inline Addr realPCToFetchPC(const Addr &addr) { - return addr; - } - - inline Addr fetchPCToRealPC(const Addr &addr) { - return addr; - } - - // the size of "fetched" instructions (not necessarily the size - // of real instructions for PISA) - inline size_t fetchInstSize() { - return sizeof(MachInst); - } - - inline MachInst makeRegisterCopy(int dest, int src) { - panic("makeRegisterCopy not implemented"); - return 0; - } - - // Machine operations - - void saveMachineReg(AnyReg &savereg, const RegFile ®_file, - int regnum); - - void restoreMachineReg(RegFile ®s, const AnyReg ®, - int regnum); - - /** - * Function to insure ISA semantics about 0 registers. - * @param tc The thread context. - */ - template <class TC> - void zeroRegisters(TC *tc); - - // Alpha IPR register accessors - inline bool PcPAL(Addr addr) { return addr & 0x3; } - inline void startupCPU(ThreadContext *tc, int cpuId) { - tc->activate(0); - } - - //////////////////////////////////////////////////////////////////////// - // - // Translation stuff - // - - inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; } - - // User Virtual - inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; } - - // Kernel Direct Mapped - inline bool IsK0Seg(Addr a) { return K0SegBase <= a && a <= K0SegEnd; } - inline Addr K0Seg2Phys(Addr addr) { return addr & ~K0SegBase; } - - // Kernel Virtual - inline bool IsK1Seg(Addr a) { return K1SegBase <= a && a <= K1SegEnd; } - - inline Addr - TruncPage(Addr addr) - { return addr & ~(PageBytes - 1); } - - inline Addr - RoundPage(Addr addr) - { return (addr + PageBytes - 1) & ~(PageBytes - 1); } - - void initIPRs(ThreadContext *tc, int cpuId); +// the size of "fetched" instructions (not necessarily the size +// of real instructions for PISA) +inline size_t +fetchInstSize() +{ + return sizeof(MachInst); +} + +inline MachInst +makeRegisterCopy(int dest, int src) +{ + panic("makeRegisterCopy not implemented"); + return 0; +} + +// Machine operations +void saveMachineReg(AnyReg &savereg, const RegFile ®_file, int regnum); +void restoreMachineReg(RegFile ®s, const AnyReg ®, int regnum); + +/** + * Function to insure ISA semantics about 0 registers. + * @param tc The thread context. + */ +template <class TC> +void zeroRegisters(TC *tc); + +// Alpha IPR register accessors +inline bool PcPAL(Addr addr) { return addr & 0x3; } +inline void startupCPU(ThreadContext *tc, int cpuId) { tc->activate(0); } + +//////////////////////////////////////////////////////////////////////// +// +// Translation stuff +// + +inline Addr PteAddr(Addr a) { return (a & PteMask) << PteShift; } + +// User Virtual +inline bool IsUSeg(Addr a) { return USegBase <= a && a <= USegEnd; } + +// Kernel Direct Mapped +inline bool IsK0Seg(Addr a) { return K0SegBase <= a && a <= K0SegEnd; } +inline Addr K0Seg2Phys(Addr addr) { return addr & ~K0SegBase; } + +// Kernel Virtual +inline bool IsK1Seg(Addr a) { return K1SegBase <= a && a <= K1SegEnd; } + +inline Addr +TruncPage(Addr addr) +{ return addr & ~(PageBytes - 1); } + +inline Addr +RoundPage(Addr addr) +{ return (addr + PageBytes - 1) & ~(PageBytes - 1); } + +void initIPRs(ThreadContext *tc, int cpuId); #if FULL_SYSTEM - void initCPU(ThreadContext *tc, int cpuId); - - /** - * Function to check for and process any interrupts. - * @param tc The thread context. - */ - template <class TC> - void processInterrupts(TC *tc); +void initCPU(ThreadContext *tc, int cpuId); + +/** + * Function to check for and process any interrupts. + * @param tc The thread context. + */ +template <class TC> +void processInterrupts(TC *tc); #endif } // namespace AlphaISA -#endif +#endif // __ARCH_ALPHA_UTILITY_HH__ diff --git a/src/arch/alpha/vtophys.cc b/src/arch/alpha/vtophys.cc index 6ffbea181..4a043d8d1 100644 --- a/src/arch/alpha/vtophys.cc +++ b/src/arch/alpha/vtophys.cc @@ -40,27 +40,28 @@ #include "mem/vport.hh" using namespace std; -using namespace AlphaISA; -AlphaISA::PageTableEntry -AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr) +namespace AlphaISA { + +PageTableEntry +kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, VAddr vaddr) { Addr level1_pte = ptbr + vaddr.level1(); - AlphaISA::PageTableEntry level1 = mem->read<uint64_t>(level1_pte); + PageTableEntry level1 = mem->read<uint64_t>(level1_pte); if (!level1.valid()) { DPRINTF(VtoPhys, "level 1 PTE not valid, va = %#\n", vaddr); return 0; } Addr level2_pte = level1.paddr() + vaddr.level2(); - AlphaISA::PageTableEntry level2 = mem->read<uint64_t>(level2_pte); + PageTableEntry level2 = mem->read<uint64_t>(level2_pte); if (!level2.valid()) { DPRINTF(VtoPhys, "level 2 PTE not valid, va = %#x\n", vaddr); return 0; } Addr level3_pte = level2.paddr() + vaddr.level3(); - AlphaISA::PageTableEntry level3 = mem->read<uint64_t>(level3_pte); + PageTableEntry level3 = mem->read<uint64_t>(level3_pte); if (!level3.valid()) { DPRINTF(VtoPhys, "level 3 PTE not valid, va = %#x\n", vaddr); return 0; @@ -69,13 +70,13 @@ AlphaISA::kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vadd } Addr -AlphaISA::vtophys(Addr vaddr) +vtophys(Addr vaddr) { Addr paddr = 0; - if (AlphaISA::IsUSeg(vaddr)) + if (IsUSeg(vaddr)) DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr); - else if (AlphaISA::IsK0Seg(vaddr)) - paddr = AlphaISA::K0Seg2Phys(vaddr); + else if (IsK0Seg(vaddr)) + paddr = K0Seg2Phys(vaddr); else panic("vtophys: ptbr is not set on virtual lookup"); @@ -85,22 +86,22 @@ AlphaISA::vtophys(Addr vaddr) } Addr -AlphaISA::vtophys(ThreadContext *tc, Addr addr) +vtophys(ThreadContext *tc, Addr addr) { - AlphaISA::VAddr vaddr = addr; - Addr ptbr = tc->readMiscRegNoEffect(AlphaISA::IPR_PALtemp20); + VAddr vaddr = addr; + Addr ptbr = tc->readMiscRegNoEffect(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? - if (AlphaISA::PcPAL(vaddr) && (vaddr < EV5::PalMax)) { + if (PcPAL(vaddr) && (vaddr < PalMax)) { paddr = vaddr & ~ULL(1); } else { - if (AlphaISA::IsK0Seg(vaddr)) { - paddr = AlphaISA::K0Seg2Phys(vaddr); + if (IsK0Seg(vaddr)) { + paddr = K0Seg2Phys(vaddr); } else if (!ptbr) { paddr = vaddr; } else { - AlphaISA::PageTableEntry pte = + PageTableEntry pte = kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr); if (pte.valid()) paddr = pte.paddr() | vaddr.offset(); @@ -113,3 +114,4 @@ AlphaISA::vtophys(ThreadContext *tc, Addr addr) return paddr; } +} // namespace AlphaISA diff --git a/src/arch/alpha/vtophys.hh b/src/arch/alpha/vtophys.hh index bd2ee8468..b13afd090 100644 --- a/src/arch/alpha/vtophys.hh +++ b/src/arch/alpha/vtophys.hh @@ -41,12 +41,13 @@ class FunctionalPort; namespace AlphaISA { - PageTableEntry - kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr); +PageTableEntry kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, + VAddr vaddr); - Addr vtophys(Addr vaddr); - Addr vtophys(ThreadContext *tc, Addr vaddr); +Addr vtophys(Addr vaddr); +Addr vtophys(ThreadContext *tc, Addr vaddr); + +} // namespace AlphaISA -}; #endif // __ARCH_ALPHA_VTOPHYS_H__ |