diff options
Diffstat (limited to 'src/arch/alpha')
-rw-r--r-- | src/arch/alpha/SConscript | 1 | ||||
-rw-r--r-- | src/arch/alpha/ev5.cc | 17 | ||||
-rw-r--r-- | src/arch/alpha/ipr.cc | 140 | ||||
-rw-r--r-- | src/arch/alpha/ipr.hh | 237 | ||||
-rw-r--r-- | src/arch/alpha/isa/decoder.isa | 30 | ||||
-rw-r--r-- | src/arch/alpha/isa/fp.isa | 2 | ||||
-rw-r--r-- | src/arch/alpha/isa/main.isa | 6 | ||||
-rw-r--r-- | src/arch/alpha/isa_traits.hh | 98 | ||||
-rw-r--r-- | src/arch/alpha/regfile.hh | 55 | ||||
-rw-r--r-- | src/arch/alpha/tlb.cc | 926 | ||||
-rw-r--r-- | src/arch/alpha/tlb.hh | 158 |
11 files changed, 991 insertions, 679 deletions
diff --git a/src/arch/alpha/SConscript b/src/arch/alpha/SConscript index 216c88cc7..9a5680649 100644 --- a/src/arch/alpha/SConscript +++ b/src/arch/alpha/SConscript @@ -56,6 +56,7 @@ full_system_sources = Split(''' tlb.cc arguments.cc ev5.cc + ipr.cc osfpal.cc stacktrace.cc vtophys.cc diff --git a/src/arch/alpha/ev5.cc b/src/arch/alpha/ev5.cc index 7595423c3..314b445e0 100644 --- a/src/arch/alpha/ev5.cc +++ b/src/arch/alpha/ev5.cc @@ -60,7 +60,7 @@ AlphaISA::initCPU(ThreadContext *tc, int cpuId) tc->setIntReg(16, cpuId); tc->setIntReg(0, cpuId); - AlphaFault *reset = new ResetFault; + AlphaISA::AlphaFault *reset = new AlphaISA::ResetFault; tc->setPC(tc->readMiscReg(IPR_PAL_BASE) + reset->vect()); tc->setNextPC(tc->readPC() + sizeof(MachInst)); @@ -176,7 +176,7 @@ AlphaISA::MiscRegFile::getDataAsid() } AlphaISA::MiscReg -AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc) +AlphaISA::MiscRegFile::readIpr(int idx, ThreadContext *tc) { uint64_t retval = 0; // return value, default 0 @@ -269,12 +269,12 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc) case AlphaISA::IPR_DTB_IAP: case AlphaISA::IPR_ITB_IA: case AlphaISA::IPR_ITB_IAP: - fault = new UnimplementedOpcodeFault; + panic("Tried to read write only register %d\n", idx); break; default: // invalid IPR - fault = new UnimplementedOpcodeFault; + panic("Tried to read from invalid ipr %d\n", idx); break; } @@ -286,13 +286,13 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc) int break_ipl = -1; #endif -Fault +void AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) { uint64_t old; if (tc->misspeculating()) - return NoFault; + return; switch (idx) { case AlphaISA::IPR_PALtemp0: @@ -443,7 +443,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) case AlphaISA::IPR_ITB_PTE_TEMP: case AlphaISA::IPR_DTB_PTE_TEMP: // read-only registers - return new UnimplementedOpcodeFault; + panic("Tried to write read only ipr %d\n", idx); case AlphaISA::IPR_HWINT_CLR: case AlphaISA::IPR_SL_XMIT: @@ -547,11 +547,10 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc) default: // invalid IPR - return new UnimplementedOpcodeFault; + panic("Tried to write to invalid ipr %d\n", idx); } // no error... - return NoFault; } diff --git a/src/arch/alpha/ipr.cc b/src/arch/alpha/ipr.cc new file mode 100644 index 000000000..8e83102eb --- /dev/null +++ b/src/arch/alpha/ipr.cc @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2003-2005 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 <assert.h> +#include <string.h> + +#include "arch/alpha/ipr.hh" + +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() + { + static bool initialized = false; + if(initialized) + return; + + memset(IprToMiscRegIndex, -1, MaxInternalProcRegs * sizeof(int)); + + for(int x = 0; x < NumInternalProcRegs; x++) + IprToMiscRegIndex[MiscRegIndexToIpr[x]] = x; + } +} + diff --git a/src/arch/alpha/ipr.hh b/src/arch/alpha/ipr.hh new file mode 100644 index 000000000..b55154764 --- /dev/null +++ b/src/arch/alpha/ipr.hh @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2003-2005 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: Steve Reinhardt + * Gabe Black + */ + +#ifndef __ARCH_ALPHA_IPR_HH__ +#define __ARCH_ALPHA_IPR_HH__ + +namespace AlphaISA +{ + //////////////////////////////////////////////////////////////////////// + // + // 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(); +} + +#endif diff --git a/src/arch/alpha/isa/decoder.isa b/src/arch/alpha/isa/decoder.isa index 5bd19b677..be6f574a9 100644 --- a/src/arch/alpha/isa/decoder.isa +++ b/src/arch/alpha/isa/decoder.isa @@ -629,7 +629,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->readMiscRegWithEffect(AlphaISA::IPR_CC, fault) + (Rb & 0); + Ra = xc->readMiscRegWithEffect(AlphaISA::IPR_CC) + (Rb & 0); #else Ra = curTick; @@ -661,12 +661,12 @@ decode OPCODE default Unknown::unknown() { #if FULL_SYSTEM format BasicOperate { 0xe000: rc({{ - Ra = xc->readIntrFlag(); - xc->setIntrFlag(0); + Ra = IntrFlag; + IntrFlag = 0; }}, IsNonSpeculative, IsUnverifiable); 0xf000: rs({{ - Ra = xc->readIntrFlag(); - xc->setIntrFlag(1); + Ra = IntrFlag; + IntrFlag = 1; }}, IsNonSpeculative, IsUnverifiable); } #else @@ -681,7 +681,7 @@ decode OPCODE default Unknown::unknown() { 0x00: CallPal::call_pal({{ if (!palValid || (palPriv - && xc->readMiscRegWithEffect(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { + && xc->readMiscRegWithEffect(AlphaISA::IPR_ICM) != AlphaISA::mode_kernel)) { // invalid pal function code, or attempt to do privileged // PAL call in non-kernel mode fault = new UnimplementedOpcodeFault; @@ -693,7 +693,7 @@ decode OPCODE default Unknown::unknown() { if (dopal) { xc->setMiscRegWithEffect(AlphaISA::IPR_EXC_ADDR, NPC); - NPC = xc->readMiscRegWithEffect(AlphaISA::IPR_PAL_BASE, fault) + palOffset; + NPC = xc->readMiscRegWithEffect(AlphaISA::IPR_PAL_BASE) + palOffset; } } }}, IsNonSpeculative); @@ -745,7 +745,13 @@ decode OPCODE default Unknown::unknown() { 0: OpcdecFault::hw_mfpr(); format HwMoveIPR { 1: hw_mfpr({{ - Ra = xc->readMiscRegWithEffect(ipr_index, fault); + int miscRegIndex = (ipr_index < MaxInternalProcRegs) ? + IprToMiscRegIndex[ipr_index] : -1; + if(miscRegIndex < 0 || !IprIsReadable(miscRegIndex) || + miscRegIndex >= NumInternalProcRegs) + fault = new UnimplementedOpcodeFault; + else + Ra = xc->readMiscRegWithEffect(miscRegIndex); }}, IsIprAccess); } } @@ -754,7 +760,13 @@ decode OPCODE default Unknown::unknown() { 0: OpcdecFault::hw_mtpr(); format HwMoveIPR { 1: hw_mtpr({{ - xc->setMiscRegWithEffect(ipr_index, Ra); + int miscRegIndex = (ipr_index < MaxInternalProcRegs) ? + IprToMiscRegIndex[ipr_index] : -1; + if(miscRegIndex < 0 || !IprIsWritable(miscRegIndex) || + miscRegIndex >= NumInternalProcRegs) + fault = new UnimplementedOpcodeFault; + else + xc->setMiscRegWithEffect(miscRegIndex, Ra); if (traceData) { traceData->setData(Ra); } }}, IsIprAccess); } diff --git a/src/arch/alpha/isa/fp.isa b/src/arch/alpha/isa/fp.isa index b4339a1b7..103f85775 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->readMiscRegWithEffect(AlphaISA::IPR_ICSR, fault))) { + if (!EV5::ICSR_FPE(xc->readMiscRegWithEffect(AlphaISA::IPR_ICSR))) { fault = new FloatEnableFault; } return fault; diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa index 2024b1117..06d3e8243 100644 --- a/src/arch/alpha/isa/main.isa +++ b/src/arch/alpha/isa/main.isa @@ -71,6 +71,7 @@ output exec {{ #if FULL_SYSTEM #include "sim/pseudo_inst.hh" #endif +#include "arch/alpha/ipr.hh" #include "base/fenv.hh" #include "config/ss_compatible_fp.hh" #include "cpu/base.hh" @@ -183,8 +184,9 @@ def operands {{ 'Fc': ('FloatReg', 'df', 'FC', 'IsFloating', 3), 'Mem': ('Mem', 'uq', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4), 'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4), - 'Runiq': ('ControlReg', 'uq', 'TheISA::Uniq_DepTag', None, 1), - 'FPCR': (' ControlReg', 'uq', 'TheISA::Fpcr_DepTag', None, 1), + 'Runiq': ('ControlReg', 'uq', 'AlphaISA::Uniq_DepTag', None, 1), + 'FPCR': ('ControlReg', 'uq', 'AlphaISA::Fpcr_DepTag', None, 1), + 'IntrFlag': ('ControlReg', 'uq', 'AlphaISA::Intr_Flag_DepTag', None, 1), # The next two are hacks for non-full-system call-pal emulation 'R0': ('IntReg', 'uq', '0', None, 1), 'R16': ('IntReg', 'uq', '16', None, 1), diff --git a/src/arch/alpha/isa_traits.hh b/src/arch/alpha/isa_traits.hh index 4f439b8df..a919a4a1f 100644 --- a/src/arch/alpha/isa_traits.hh +++ b/src/arch/alpha/isa_traits.hh @@ -34,6 +34,7 @@ namespace LittleEndianGuest {} +#include "arch/alpha/ipr.hh" #include "arch/alpha/types.hh" #include "config/full_system.hh" #include "sim/host.hh" @@ -54,7 +55,8 @@ namespace AlphaISA Uniq_DepTag = 73, Lock_Flag_DepTag = 74, Lock_Addr_DepTag = 75, - IPR_Base_DepTag = 76 + Intr_Flag_DepTag = 76, + IPR_Base_DepTag = 77 }; StaticInstPtr decodeInst(ExtMachInst); @@ -131,100 +133,6 @@ namespace AlphaISA #endif -#if FULL_SYSTEM - //////////////////////////////////////////////////////////////////////// - // - // Internal Processor Reigsters - // - enum md_ipr_names - { - IPR_ISR = 0x100, // interrupt summary register - IPR_ITB_TAG = 0x101, // ITLB tag register - IPR_ITB_PTE = 0x102, // ITLB page table entry register - IPR_ITB_ASN = 0x103, // ITLB address space register - IPR_ITB_PTE_TEMP = 0x104, // ITLB page table entry temp register - IPR_ITB_IA = 0x105, // ITLB invalidate all register - IPR_ITB_IAP = 0x106, // ITLB invalidate all process register - IPR_ITB_IS = 0x107, // ITLB invalidate select register - IPR_SIRR = 0x108, // software interrupt request register - IPR_ASTRR = 0x109, // asynchronous system trap request register - IPR_ASTER = 0x10a, // asynchronous system trap enable register - IPR_EXC_ADDR = 0x10b, // exception address register - IPR_EXC_SUM = 0x10c, // exception summary register - IPR_EXC_MASK = 0x10d, // exception mask register - IPR_PAL_BASE = 0x10e, // PAL base address register - IPR_ICM = 0x10f, // instruction current mode - IPR_IPLR = 0x110, // interrupt priority level register - IPR_INTID = 0x111, // interrupt ID register - IPR_IFAULT_VA_FORM = 0x112, // formatted faulting virtual addr register - IPR_IVPTBR = 0x113, // virtual page table base register - IPR_HWINT_CLR = 0x115, // H/W interrupt clear register - IPR_SL_XMIT = 0x116, // serial line transmit register - IPR_SL_RCV = 0x117, // serial line receive register - IPR_ICSR = 0x118, // instruction control and status register - IPR_IC_FLUSH = 0x119, // instruction cache flush control - IPR_IC_PERR_STAT = 0x11a, // inst cache parity error status register - IPR_PMCTR = 0x11c, // performance counter register - - // PAL temporary registers... - // register meanings gleaned from osfpal.s source code - IPR_PALtemp0 = 0x140, // local scratch - IPR_PALtemp1 = 0x141, // local scratch - IPR_PALtemp2 = 0x142, // entUna - IPR_PALtemp3 = 0x143, // CPU specific impure area pointer - IPR_PALtemp4 = 0x144, // memory management temp - IPR_PALtemp5 = 0x145, // memory management temp - IPR_PALtemp6 = 0x146, // memory management temp - IPR_PALtemp7 = 0x147, // entIF - IPR_PALtemp8 = 0x148, // intmask - IPR_PALtemp9 = 0x149, // entSys - IPR_PALtemp10 = 0x14a, // ?? - IPR_PALtemp11 = 0x14b, // entInt - IPR_PALtemp12 = 0x14c, // entArith - IPR_PALtemp13 = 0x14d, // reserved for platform specific PAL - IPR_PALtemp14 = 0x14e, // reserved for platform specific PAL - IPR_PALtemp15 = 0x14f, // reserved for platform specific PAL - IPR_PALtemp16 = 0x150, // scratch / whami<7:0> / mces<4:0> - IPR_PALtemp17 = 0x151, // sysval - IPR_PALtemp18 = 0x152, // usp - IPR_PALtemp19 = 0x153, // ksp - IPR_PALtemp20 = 0x154, // PTBR - IPR_PALtemp21 = 0x155, // entMM - IPR_PALtemp22 = 0x156, // kgp - IPR_PALtemp23 = 0x157, // PCBB - - IPR_DTB_ASN = 0x200, // DTLB address space number register - IPR_DTB_CM = 0x201, // DTLB current mode register - IPR_DTB_TAG = 0x202, // DTLB tag register - IPR_DTB_PTE = 0x203, // DTLB page table entry register - IPR_DTB_PTE_TEMP = 0x204, // DTLB page table entry temporary register - - IPR_MM_STAT = 0x205, // data MMU fault status register - IPR_VA = 0x206, // fault virtual address register - IPR_VA_FORM = 0x207, // formatted virtual address register - IPR_MVPTBR = 0x208, // MTU virtual page table base register - IPR_DTB_IAP = 0x209, // DTLB invalidate all process register - IPR_DTB_IA = 0x20a, // DTLB invalidate all register - IPR_DTB_IS = 0x20b, // DTLB invalidate single register - IPR_ALT_MODE = 0x20c, // alternate mode register - IPR_CC = 0x20d, // cycle counter register - IPR_CC_CTL = 0x20e, // cycle counter control register - IPR_MCSR = 0x20f, // MTU control register - - IPR_DC_FLUSH = 0x210, - IPR_DC_PERR_STAT = 0x212, // Dcache parity error status register - IPR_DC_TEST_CTL = 0x213, // Dcache test tag control register - IPR_DC_TEST_TAG = 0x214, // Dcache test tag register - IPR_DC_TEST_TAG_TEMP = 0x215, // Dcache test tag temporary register - IPR_DC_MODE = 0x216, // Dcache mode register - IPR_MAF_MODE = 0x217, // miss address file mode register - - NumInternalProcRegs // number of IPR registers - }; -#else - const int NumInternalProcRegs = 0; -#endif - // Constants Related to the number of registers const int NumIntArchRegs = 32; diff --git a/src/arch/alpha/regfile.hh b/src/arch/alpha/regfile.hh index 43b48a0ab..e806adbcb 100644 --- a/src/arch/alpha/regfile.hh +++ b/src/arch/alpha/regfile.hh @@ -31,8 +31,9 @@ #ifndef __ARCH_ALPHA_REGFILE_HH__ #define __ARCH_ALPHA_REGFILE_HH__ -#include "arch/alpha/types.hh" #include "arch/alpha/isa_traits.hh" +#include "arch/alpha/ipr.hh" +#include "arch/alpha/types.hh" #include "sim/faults.hh" #include <string> @@ -109,21 +110,28 @@ namespace AlphaISA 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() + { +#if FULL_SYSTEM + initializeIprTable(); +#endif + } + MiscReg readReg(int misc_reg); - MiscReg readRegWithEffect(int misc_reg, Fault &fault, - ThreadContext *tc); + MiscReg readRegWithEffect(int misc_reg, ThreadContext *tc); //These functions should be removed once the simplescalar cpu model //has been replaced. int getInstAsid(); int getDataAsid(); - Fault setReg(int misc_reg, const MiscReg &val); + void setReg(int misc_reg, const MiscReg &val); - Fault setRegWithEffect(int misc_reg, const MiscReg &val, + void setRegWithEffect(int misc_reg, const MiscReg &val, ThreadContext *tc); void clear() @@ -131,6 +139,7 @@ namespace AlphaISA fpcr = uniq = 0; lock_flag = 0; lock_addr = 0; + intr_flag = 0; } void serialize(std::ostream &os); @@ -143,9 +152,9 @@ namespace AlphaISA InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs private: - InternalProcReg readIpr(int idx, Fault &fault, ThreadContext *tc); + InternalProcReg readIpr(int idx, ThreadContext *tc); - Fault setIpr(int idx, InternalProcReg val, ThreadContext *tc); + void setIpr(int idx, InternalProcReg val, ThreadContext *tc); #endif friend class RegFile; }; @@ -215,22 +224,20 @@ namespace AlphaISA return miscRegFile.readReg(miscReg); } - MiscReg readMiscRegWithEffect(int miscReg, - Fault &fault, ThreadContext *tc) + MiscReg readMiscRegWithEffect(int miscReg, ThreadContext *tc) { - fault = NoFault; - return miscRegFile.readRegWithEffect(miscReg, fault, tc); + return miscRegFile.readRegWithEffect(miscReg, tc); } - Fault setMiscReg(int miscReg, const MiscReg &val) + void setMiscReg(int miscReg, const MiscReg &val) { - return miscRegFile.setReg(miscReg, val); + miscRegFile.setReg(miscReg, val); } - Fault setMiscRegWithEffect(int miscReg, const MiscReg &val, + void setMiscRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc) { - return miscRegFile.setRegWithEffect(miscReg, val, tc); + miscRegFile.setRegWithEffect(miscReg, val, tc); } FloatReg readFloatReg(int floatReg) @@ -253,26 +260,24 @@ namespace AlphaISA return readFloatRegBits(floatReg); } - Fault setFloatReg(int floatReg, const FloatReg &val) + void setFloatReg(int floatReg, const FloatReg &val) { floatRegFile.d[floatReg] = val; - return NoFault; } - Fault setFloatReg(int floatReg, const FloatReg &val, int width) + void setFloatReg(int floatReg, const FloatReg &val, int width) { - return setFloatReg(floatReg, val); + setFloatReg(floatReg, val); } - Fault setFloatRegBits(int floatReg, const FloatRegBits &val) + void setFloatRegBits(int floatReg, const FloatRegBits &val) { floatRegFile.q[floatReg] = val; - return NoFault; } - Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width) + void setFloatRegBits(int floatReg, const FloatRegBits &val, int width) { - return setFloatRegBits(floatReg, val); + setFloatRegBits(floatReg, val); } IntReg readIntReg(int intReg) @@ -280,9 +285,9 @@ namespace AlphaISA return intRegFile.readReg(intReg); } - Fault setIntReg(int intReg, const IntReg &val) + void setIntReg(int intReg, const IntReg &val) { - return intRegFile.setReg(intReg, val); + intRegFile.setReg(intReg, val); } void serialize(std::ostream &os); diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index bab44c434..ae302e686 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -46,589 +46,591 @@ using namespace std; using namespace EV5; -/////////////////////////////////////////////////////////////////////// -// -// Alpha TLB -// +namespace AlphaISA +{ + /////////////////////////////////////////////////////////////////////// + // + // Alpha TLB + // #ifdef DEBUG -bool uncacheBit39 = false; -bool uncacheBit40 = false; + bool uncacheBit39 = false; + bool uncacheBit40 = false; #endif #define MODE2MASK(X) (1 << (X)) -AlphaTLB::AlphaTLB(const string &name, int s) - : SimObject(name), size(s), nlu(0) -{ - table = new AlphaISA::PTE[size]; - memset(table, 0, sizeof(AlphaISA::PTE[size])); -} + TLB::TLB(const string &name, int s) + : SimObject(name), size(s), nlu(0) + { + table = new PTE[size]; + memset(table, 0, sizeof(PTE[size])); + } -AlphaTLB::~AlphaTLB() -{ - if (table) - delete [] table; -} + TLB::~TLB() + { + if (table) + delete [] table; + } -// look up an entry in the TLB -AlphaISA::PTE * -AlphaTLB::lookup(Addr vpn, uint8_t asn) const -{ - // assume not found... - AlphaISA::PTE *retval = NULL; + // look up an entry in the TLB + PTE * + TLB::lookup(Addr vpn, uint8_t asn) const + { + // assume not found... + PTE *retval = NULL; + + PageTable::const_iterator i = lookupTable.find(vpn); + if (i != lookupTable.end()) { + while (i->first == vpn) { + int index = i->second; + PTE *pte = &table[index]; + assert(pte->valid); + if (vpn == pte->tag && (pte->asma || pte->asn == asn)) { + retval = pte; + break; + } - PageTable::const_iterator i = lookupTable.find(vpn); - if (i != lookupTable.end()) { - while (i->first == vpn) { - int index = i->second; - AlphaISA::PTE *pte = &table[index]; - assert(pte->valid); - if (vpn == pte->tag && (pte->asma || pte->asn == asn)) { - retval = pte; - break; + ++i; } - - ++i; } - } - DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, - retval ? "hit" : "miss", retval ? retval->ppn : 0); - return retval; -} + DPRINTF(TLB, "lookup %#x, asn %#x -> %s ppn %#x\n", vpn, (int)asn, + retval ? "hit" : "miss", retval ? retval->ppn : 0); + return retval; + } -Fault -AlphaTLB::checkCacheability(RequestPtr &req) -{ - // in Alpha, cacheability is controlled by upper-level bits of the - // physical address + Fault + TLB::checkCacheability(RequestPtr &req) + { + // 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. - */ + /* + * 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 - if (req->getPaddr() & PAddrUncachedBit39) { + if (req->getPaddr() & PAddrUncachedBit39) { #else - if (req->getPaddr() & PAddrUncachedBit43) { + if (req->getPaddr() & PAddrUncachedBit43) { #endif - // IPR memory space not implemented - if (PAddrIprSpace(req->getPaddr())) { - return new UnimpFault("IPR memory space not implemented!"); - } else { - // mark request as uncacheable - req->setFlags(req->getFlags() | UNCACHEABLE); + // IPR memory space not implemented + if (PAddrIprSpace(req->getPaddr())) { + return new UnimpFault("IPR memory space not implemented!"); + } else { + // mark request as uncacheable + req->setFlags(req->getFlags() | UNCACHEABLE); #if !ALPHA_TLASER - // Clear bits 42:35 of the physical address (10-2 in Tsunami manual) - req->setPaddr(req->getPaddr() & PAddrUncachedMask); + // Clear bits 42:35 of the physical address (10-2 in Tsunami manual) + req->setPaddr(req->getPaddr() & PAddrUncachedMask); #endif + } } + return NoFault; } - return NoFault; -} -// insert a new TLB entry -void -AlphaTLB::insert(Addr addr, AlphaISA::PTE &pte) -{ - AlphaISA::VAddr vaddr = addr; - if (table[nlu].valid) { - Addr oldvpn = table[nlu].tag; - PageTable::iterator i = lookupTable.find(oldvpn); + // insert a new TLB entry + void + TLB::insert(Addr addr, PTE &pte) + { + VAddr vaddr = addr; + if (table[nlu].valid) { + Addr oldvpn = table[nlu].tag; + PageTable::iterator i = lookupTable.find(oldvpn); - if (i == lookupTable.end()) - panic("TLB entry not found in lookupTable"); - - int index; - while ((index = i->second) != nlu) { - if (table[index].tag != oldvpn) + if (i == lookupTable.end()) panic("TLB entry not found in lookupTable"); - ++i; + int index; + while ((index = i->second) != nlu) { + if (table[index].tag != oldvpn) + panic("TLB entry not found in lookupTable"); + + ++i; + } + + DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); + + lookupTable.erase(i); } - DPRINTF(TLB, "remove @%d: %#x -> %#x\n", nlu, oldvpn, table[nlu].ppn); + DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn); - lookupTable.erase(i); - } + table[nlu] = pte; + table[nlu].tag = vaddr.vpn(); + table[nlu].valid = true; - DPRINTF(TLB, "insert @%d: %#x -> %#x\n", nlu, vaddr.vpn(), pte.ppn); + lookupTable.insert(make_pair(vaddr.vpn(), nlu)); + nextnlu(); + } - table[nlu] = pte; - table[nlu].tag = vaddr.vpn(); - table[nlu].valid = true; + void + TLB::flushAll() + { + DPRINTF(TLB, "flushAll\n"); + memset(table, 0, sizeof(PTE[size])); + lookupTable.clear(); + nlu = 0; + } - lookupTable.insert(make_pair(vaddr.vpn(), nlu)); - nextnlu(); -} + void + TLB::flushProcesses() + { + PageTable::iterator i = lookupTable.begin(); + PageTable::iterator end = lookupTable.end(); + while (i != end) { + int index = i->second; + PTE *pte = &table[index]; + assert(pte->valid); -void -AlphaTLB::flushAll() -{ - DPRINTF(TLB, "flushAll\n"); - memset(table, 0, sizeof(AlphaISA::PTE[size])); - lookupTable.clear(); - nlu = 0; -} + // we can't increment i after we erase it, so save a copy and + // increment it to get the next entry now + PageTable::iterator cur = i; + ++i; -void -AlphaTLB::flushProcesses() -{ - PageTable::iterator i = lookupTable.begin(); - PageTable::iterator end = lookupTable.end(); - while (i != end) { - int index = i->second; - AlphaISA::PTE *pte = &table[index]; - assert(pte->valid); - - // we can't increment i after we erase it, so save a copy and - // increment it to get the next entry now - PageTable::iterator cur = i; - ++i; - - if (!pte->asma) { - DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); - pte->valid = false; - lookupTable.erase(cur); + if (!pte->asma) { + DPRINTF(TLB, "flush @%d: %#x -> %#x\n", index, pte->tag, pte->ppn); + pte->valid = false; + lookupTable.erase(cur); + } } } -} -void -AlphaTLB::flushAddr(Addr addr, uint8_t asn) -{ - AlphaISA::VAddr vaddr = addr; + void + TLB::flushAddr(Addr addr, uint8_t asn) + { + VAddr vaddr = addr; - PageTable::iterator i = lookupTable.find(vaddr.vpn()); - if (i == lookupTable.end()) - return; + PageTable::iterator i = lookupTable.find(vaddr.vpn()); + if (i == lookupTable.end()) + return; - while (i->first == vaddr.vpn()) { - int index = i->second; - AlphaISA::PTE *pte = &table[index]; - assert(pte->valid); + while (i->first == vaddr.vpn()) { + int index = i->second; + PTE *pte = &table[index]; + assert(pte->valid); - if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) { - DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(), - pte->ppn); + if (vaddr.vpn() == pte->tag && (pte->asma || pte->asn == asn)) { + DPRINTF(TLB, "flushaddr @%d: %#x -> %#x\n", index, vaddr.vpn(), + pte->ppn); - // invalidate this entry - pte->valid = false; + // invalidate this entry + pte->valid = false; - lookupTable.erase(i); - } + lookupTable.erase(i); + } - ++i; + ++i; + } } -} -void -AlphaTLB::serialize(ostream &os) -{ - SERIALIZE_SCALAR(size); - SERIALIZE_SCALAR(nlu); + void + TLB::serialize(ostream &os) + { + SERIALIZE_SCALAR(size); + SERIALIZE_SCALAR(nlu); - for (int i = 0; i < size; i++) { - nameOut(os, csprintf("%s.PTE%d", name(), i)); - table[i].serialize(os); + for (int i = 0; i < size; i++) { + nameOut(os, csprintf("%s.PTE%d", name(), i)); + table[i].serialize(os); + } } -} -void -AlphaTLB::unserialize(Checkpoint *cp, const string §ion) -{ - UNSERIALIZE_SCALAR(size); - UNSERIALIZE_SCALAR(nlu); + void + TLB::unserialize(Checkpoint *cp, const string §ion) + { + UNSERIALIZE_SCALAR(size); + UNSERIALIZE_SCALAR(nlu); - for (int i = 0; i < size; i++) { - table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); - if (table[i].valid) { - lookupTable.insert(make_pair(table[i].tag, i)); + for (int i = 0; i < size; i++) { + table[i].unserialize(cp, csprintf("%s.PTE%d", section, i)); + if (table[i].valid) { + lookupTable.insert(make_pair(table[i].tag, i)); + } } } -} - -/////////////////////////////////////////////////////////////////////// -// -// Alpha ITB -// -AlphaITB::AlphaITB(const std::string &name, int size) - : AlphaTLB(name, size) -{} - -void -AlphaITB::regStats() -{ - hits - .name(name() + ".hits") - .desc("ITB hits"); - misses - .name(name() + ".misses") - .desc("ITB misses"); - acv - .name(name() + ".acv") - .desc("ITB acv"); - accesses - .name(name() + ".accesses") - .desc("ITB accesses"); - - accesses = hits + misses; -} - - -Fault -AlphaITB::translate(RequestPtr &req, ThreadContext *tc) const -{ - if (AlphaISA::PcPAL(req->getVaddr())) { - // strip off PAL PC marker (lsb is 1) - req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask); - hits++; - return NoFault; + /////////////////////////////////////////////////////////////////////// + // + // Alpha ITB + // + ITB::ITB(const std::string &name, int size) + : TLB(name, size) + {} + + + void + ITB::regStats() + { + hits + .name(name() + ".hits") + .desc("ITB hits"); + misses + .name(name() + ".misses") + .desc("ITB misses"); + acv + .name(name() + ".acv") + .desc("ITB acv"); + accesses + .name(name() + ".accesses") + .desc("ITB accesses"); + + accesses = hits + misses; } - if (req->getFlags() & PHYSICAL) { - req->setPaddr(req->getVaddr()); - } else { - // verify that this is a good virtual address - if (!validVirtualAddress(req->getVaddr())) { - acv++; - return new ItbAcvFault(req->getVaddr()); + + Fault + ITB::translate(RequestPtr &req, ThreadContext *tc) const + { + if (PcPAL(req->getVaddr())) { + // strip off PAL PC marker (lsb is 1) + req->setPaddr((req->getVaddr() & ~3) & PAddrImplMask); + hits++; + return NoFault; } + if (req->getFlags() & PHYSICAL) { + req->setPaddr(req->getVaddr()); + } else { + // verify that this is a good virtual address + if (!validVirtualAddress(req->getVaddr())) { + acv++; + return new ItbAcvFault(req->getVaddr()); + } + - // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5 - // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6 + // VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5 + // VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6 #if ALPHA_TLASER - if ((MCSR_SP(tc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && - VAddrSpaceEV5(req->getVaddr()) == 2) { + if ((MCSR_SP(tc->readMiscReg(IPR_MCSR)) & 2) && + VAddrSpaceEV5(req->getVaddr()) == 2) { #else - if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { + if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { #endif - // only valid in kernel mode - if (ICM_CM(tc->readMiscReg(AlphaISA::IPR_ICM)) != - AlphaISA::mode_kernel) { - acv++; - return new ItbAcvFault(req->getVaddr()); - } + // only valid in kernel mode + if (ICM_CM(tc->readMiscReg(IPR_ICM)) != + mode_kernel) { + acv++; + return new ItbAcvFault(req->getVaddr()); + } - req->setPaddr(req->getVaddr() & PAddrImplMask); + req->setPaddr(req->getVaddr() & PAddrImplMask); #if !ALPHA_TLASER - // sign extend the physical address properly - if (req->getPaddr() & PAddrUncachedBit40) - req->setPaddr(req->getPaddr() | ULL(0xf0000000000)); - else - req->setPaddr(req->getPaddr() & ULL(0xffffffffff)); + // sign extend the physical address properly + if (req->getPaddr() & PAddrUncachedBit40) + req->setPaddr(req->getPaddr() | ULL(0xf0000000000)); + else + req->setPaddr(req->getPaddr() & ULL(0xffffffffff)); #endif - } else { - // not a physical address: need to look up pte - int asn = DTB_ASN_ASN(tc->readMiscReg(AlphaISA::IPR_DTB_ASN)); - AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(), - asn); - - if (!pte) { - misses++; - return new ItbPageFault(req->getVaddr()); - } + } else { + // not a physical address: need to look up pte + int asn = DTB_ASN_ASN(tc->readMiscReg(IPR_DTB_ASN)); + PTE *pte = lookup(VAddr(req->getVaddr()).vpn(), + asn); + + if (!pte) { + misses++; + return new ItbPageFault(req->getVaddr()); + } - req->setPaddr((pte->ppn << AlphaISA::PageShift) + - (AlphaISA::VAddr(req->getVaddr()).offset() - & ~3)); + req->setPaddr((pte->ppn << PageShift) + + (VAddr(req->getVaddr()).offset() + & ~3)); - // check permissions for this access - if (!(pte->xre & - (1 << ICM_CM(tc->readMiscReg(AlphaISA::IPR_ICM))))) { - // instruction access fault - acv++; - return new ItbAcvFault(req->getVaddr()); - } + // check permissions for this access + if (!(pte->xre & + (1 << ICM_CM(tc->readMiscReg(IPR_ICM))))) { + // instruction access fault + acv++; + return new ItbAcvFault(req->getVaddr()); + } - hits++; + hits++; + } } - } - - // check that the physical address is ok (catch bad physical addresses) - if (req->getPaddr() & ~PAddrImplMask) - return genMachineCheckFault(); - return checkCacheability(req); - -} + // check that the physical address is ok (catch bad physical addresses) + if (req->getPaddr() & ~PAddrImplMask) + return genMachineCheckFault(); -/////////////////////////////////////////////////////////////////////// -// -// Alpha DTB -// -AlphaDTB::AlphaDTB(const std::string &name, int size) - : AlphaTLB(name, size) -{} + return checkCacheability(req); -void -AlphaDTB::regStats() -{ - read_hits - .name(name() + ".read_hits") - .desc("DTB read hits") - ; - - read_misses - .name(name() + ".read_misses") - .desc("DTB read misses") - ; - - read_acv - .name(name() + ".read_acv") - .desc("DTB read access violations") - ; - - read_accesses - .name(name() + ".read_accesses") - .desc("DTB read accesses") - ; - - write_hits - .name(name() + ".write_hits") - .desc("DTB write hits") - ; - - write_misses - .name(name() + ".write_misses") - .desc("DTB write misses") - ; - - write_acv - .name(name() + ".write_acv") - .desc("DTB write access violations") - ; - - write_accesses - .name(name() + ".write_accesses") - .desc("DTB write accesses") - ; - - hits - .name(name() + ".hits") - .desc("DTB hits") - ; - - misses - .name(name() + ".misses") - .desc("DTB misses") - ; - - acv - .name(name() + ".acv") - .desc("DTB access violations") - ; - - accesses - .name(name() + ".accesses") - .desc("DTB accesses") - ; - - hits = read_hits + write_hits; - misses = read_misses + write_misses; - acv = read_acv + write_acv; - accesses = read_accesses + write_accesses; -} + } -Fault -AlphaDTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const -{ - Addr pc = tc->readPC(); + /////////////////////////////////////////////////////////////////////// + // + // Alpha DTB + // + DTB::DTB(const std::string &name, int size) + : TLB(name, size) + {} + + void + DTB::regStats() + { + read_hits + .name(name() + ".read_hits") + .desc("DTB read hits") + ; + + read_misses + .name(name() + ".read_misses") + .desc("DTB read misses") + ; + + read_acv + .name(name() + ".read_acv") + .desc("DTB read access violations") + ; + + read_accesses + .name(name() + ".read_accesses") + .desc("DTB read accesses") + ; + + write_hits + .name(name() + ".write_hits") + .desc("DTB write hits") + ; + + write_misses + .name(name() + ".write_misses") + .desc("DTB write misses") + ; + + write_acv + .name(name() + ".write_acv") + .desc("DTB write access violations") + ; + + write_accesses + .name(name() + ".write_accesses") + .desc("DTB write accesses") + ; + + hits + .name(name() + ".hits") + .desc("DTB hits") + ; + + misses + .name(name() + ".misses") + .desc("DTB misses") + ; + + acv + .name(name() + ".acv") + .desc("DTB access violations") + ; + + accesses + .name(name() + ".accesses") + .desc("DTB accesses") + ; + + hits = read_hits + write_hits; + misses = read_misses + write_misses; + acv = read_acv + write_acv; + accesses = read_accesses + write_accesses; + } - AlphaISA::mode_type mode = - (AlphaISA::mode_type)DTB_CM_CM(tc->readMiscReg(AlphaISA::IPR_DTB_CM)); + Fault + DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const + { + Addr pc = tc->readPC(); + mode_type mode = + (mode_type)DTB_CM_CM(tc->readMiscReg(IPR_DTB_CM)); - /** - * Check for alignment faults - */ - if (req->getVaddr() & (req->getSize() - 1)) { - DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(), - req->getSize()); - uint64_t flags = write ? MM_STAT_WR_MASK : 0; - return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags); - } - if (pc & 0x1) { - mode = (req->getFlags() & ALTMODE) ? - (AlphaISA::mode_type)ALT_MODE_AM( - tc->readMiscReg(AlphaISA::IPR_ALT_MODE)) - : AlphaISA::mode_kernel; - } + /** + * Check for alignment faults + */ + if (req->getVaddr() & (req->getSize() - 1)) { + DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->getVaddr(), + req->getSize()); + uint64_t flags = write ? MM_STAT_WR_MASK : 0; + return new DtbAlignmentFault(req->getVaddr(), req->getFlags(), flags); + } - if (req->getFlags() & PHYSICAL) { - req->setPaddr(req->getVaddr()); - } else { - // verify that this is a good virtual address - if (!validVirtualAddress(req->getVaddr())) { - if (write) { write_acv++; } else { read_acv++; } - uint64_t flags = (write ? MM_STAT_WR_MASK : 0) | - MM_STAT_BAD_VA_MASK | - MM_STAT_ACV_MASK; - return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); + if (pc & 0x1) { + mode = (req->getFlags() & ALTMODE) ? + (mode_type)ALT_MODE_AM( + tc->readMiscReg(IPR_ALT_MODE)) + : mode_kernel; } - // Check for "superpage" mapping + if (req->getFlags() & PHYSICAL) { + req->setPaddr(req->getVaddr()); + } else { + // verify that this is a good virtual address + if (!validVirtualAddress(req->getVaddr())) { + if (write) { write_acv++; } else { read_acv++; } + uint64_t flags = (write ? MM_STAT_WR_MASK : 0) | + MM_STAT_BAD_VA_MASK | + MM_STAT_ACV_MASK; + return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); + } + + // Check for "superpage" mapping #if ALPHA_TLASER - if ((MCSR_SP(tc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) && - VAddrSpaceEV5(req->getVaddr()) == 2) { + if ((MCSR_SP(tc->readMiscReg(IPR_MCSR)) & 2) && + VAddrSpaceEV5(req->getVaddr()) == 2) { #else - if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { + if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) { #endif - // only valid in kernel mode - if (DTB_CM_CM(tc->readMiscReg(AlphaISA::IPR_DTB_CM)) != - AlphaISA::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); - } + // only valid in kernel mode + if (DTB_CM_CM(tc->readMiscReg(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); + } - req->setPaddr(req->getVaddr() & PAddrImplMask); + req->setPaddr(req->getVaddr() & PAddrImplMask); #if !ALPHA_TLASER - // sign extend the physical address properly - if (req->getPaddr() & PAddrUncachedBit40) - req->setPaddr(req->getPaddr() | ULL(0xf0000000000)); - else - req->setPaddr(req->getPaddr() & ULL(0xffffffffff)); + // sign extend the physical address properly + if (req->getPaddr() & PAddrUncachedBit40) + req->setPaddr(req->getPaddr() | ULL(0xf0000000000)); + else + req->setPaddr(req->getPaddr() & ULL(0xffffffffff)); #endif - } else { - if (write) - write_accesses++; - else - read_accesses++; - - int asn = DTB_ASN_ASN(tc->readMiscReg(AlphaISA::IPR_DTB_ASN)); - - // not a physical address: need to look up pte - AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(), - asn); - - if (!pte) { - // page fault - 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) ? - (Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(), - flags)) : - (Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(), - flags)); - } - - req->setPaddr((pte->ppn << AlphaISA::PageShift) + - AlphaISA::VAddr(req->getVaddr()).offset()); - - if (write) { - if (!(pte->xwe & MODE2MASK(mode))) { - // declare the instruction access fault - write_acv++; - uint64_t flags = MM_STAT_WR_MASK | - MM_STAT_ACV_MASK | - (pte->fonw ? MM_STAT_FONW_MASK : 0); - return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); - } - if (pte->fonw) { - write_acv++; - uint64_t flags = MM_STAT_WR_MASK | - MM_STAT_FONW_MASK; - return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); - } } else { - if (!(pte->xre & MODE2MASK(mode))) { - read_acv++; - uint64_t flags = MM_STAT_ACV_MASK | - (pte->fonr ? MM_STAT_FONR_MASK : 0); - return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); + if (write) + write_accesses++; + else + read_accesses++; + + int asn = DTB_ASN_ASN(tc->readMiscReg(IPR_DTB_ASN)); + + // not a physical address: need to look up pte + PTE *pte = lookup(VAddr(req->getVaddr()).vpn(), + asn); + + if (!pte) { + // page fault + 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) ? + (Fault)(new PDtbMissFault(req->getVaddr(), req->getFlags(), + flags)) : + (Fault)(new NDtbMissFault(req->getVaddr(), req->getFlags(), + flags)); } - if (pte->fonr) { - read_acv++; - uint64_t flags = MM_STAT_FONR_MASK; - return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); + + req->setPaddr((pte->ppn << PageShift) + + VAddr(req->getVaddr()).offset()); + + if (write) { + if (!(pte->xwe & MODE2MASK(mode))) { + // declare the instruction access fault + write_acv++; + uint64_t flags = MM_STAT_WR_MASK | + MM_STAT_ACV_MASK | + (pte->fonw ? MM_STAT_FONW_MASK : 0); + return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); + } + if (pte->fonw) { + write_acv++; + uint64_t flags = MM_STAT_WR_MASK | + MM_STAT_FONW_MASK; + return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); + } + } else { + if (!(pte->xre & MODE2MASK(mode))) { + read_acv++; + uint64_t flags = MM_STAT_ACV_MASK | + (pte->fonr ? MM_STAT_FONR_MASK : 0); + return new DtbAcvFault(req->getVaddr(), req->getFlags(), flags); + } + if (pte->fonr) { + read_acv++; + uint64_t flags = MM_STAT_FONR_MASK; + return new DtbPageFault(req->getVaddr(), req->getFlags(), flags); + } } } + + if (write) + write_hits++; + else + read_hits++; } - if (write) - write_hits++; - else - read_hits++; + // check that the physical address is ok (catch bad physical addresses) + if (req->getPaddr() & ~PAddrImplMask) + return genMachineCheckFault(); + + return checkCacheability(req); } - // check that the physical address is ok (catch bad physical addresses) - if (req->getPaddr() & ~PAddrImplMask) - return genMachineCheckFault(); + PTE & + TLB::index(bool advance) + { + PTE *pte = &table[nlu]; - return checkCacheability(req); -} + if (advance) + nextnlu(); -AlphaISA::PTE & -AlphaTLB::index(bool advance) -{ - AlphaISA::PTE *pte = &table[nlu]; + return *pte; + } - if (advance) - nextnlu(); + DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", TLB) - return *pte; -} + BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB) -DEFINE_SIM_OBJECT_CLASS_NAME("AlphaTLB", AlphaTLB) + Param<int> size; -BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaITB) + END_DECLARE_SIM_OBJECT_PARAMS(ITB) - Param<int> size; + BEGIN_INIT_SIM_OBJECT_PARAMS(ITB) -END_DECLARE_SIM_OBJECT_PARAMS(AlphaITB) + INIT_PARAM_DFLT(size, "TLB size", 48) -BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaITB) + END_INIT_SIM_OBJECT_PARAMS(ITB) - INIT_PARAM_DFLT(size, "TLB size", 48) - -END_INIT_SIM_OBJECT_PARAMS(AlphaITB) + CREATE_SIM_OBJECT(ITB) + { + return new ITB(getInstanceName(), size); + } -CREATE_SIM_OBJECT(AlphaITB) -{ - return new AlphaITB(getInstanceName(), size); -} + REGISTER_SIM_OBJECT("AlphaITB", ITB) -REGISTER_SIM_OBJECT("AlphaITB", AlphaITB) + BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB) -BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB) + Param<int> size; - Param<int> size; + END_DECLARE_SIM_OBJECT_PARAMS(DTB) -END_DECLARE_SIM_OBJECT_PARAMS(AlphaDTB) + BEGIN_INIT_SIM_OBJECT_PARAMS(DTB) -BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaDTB) + INIT_PARAM_DFLT(size, "TLB size", 64) - INIT_PARAM_DFLT(size, "TLB size", 64) + END_INIT_SIM_OBJECT_PARAMS(DTB) -END_INIT_SIM_OBJECT_PARAMS(AlphaDTB) + CREATE_SIM_OBJECT(DTB) + { + return new DTB(getInstanceName(), size); + } -CREATE_SIM_OBJECT(AlphaDTB) -{ - return new AlphaDTB(getInstanceName(), size); + REGISTER_SIM_OBJECT("AlphaDTB", DTB) } - -REGISTER_SIM_OBJECT("AlphaDTB", AlphaDTB) - diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index 955460649..ea5ba5539 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -36,6 +36,7 @@ #include "arch/alpha/ev5.hh" #include "arch/alpha/isa_traits.hh" +#include "arch/alpha/pagetable.hh" #include "arch/alpha/utility.hh" #include "arch/alpha/vtophys.hh" #include "base/statistics.hh" @@ -45,82 +46,87 @@ class ThreadContext; -class AlphaTLB : public SimObject +namespace AlphaISA { - protected: - typedef std::multimap<Addr, int> PageTable; - PageTable lookupTable; // Quick lookup into page table - - AlphaISA::PTE *table; // the Page Table - int size; // TLB Size - int nlu; // not last used entry (for replacement) - - void nextnlu() { if (++nlu >= size) nlu = 0; } - AlphaISA::PTE *lookup(Addr vpn, uint8_t asn) const; - - public: - AlphaTLB(const std::string &name, int size); - virtual ~AlphaTLB(); - - int getsize() const { return size; } - - AlphaISA::PTE &index(bool advance = true); - void insert(Addr vaddr, AlphaISA::PTE &pte); - - void flushAll(); - void flushProcesses(); - void flushAddr(Addr addr, uint8_t 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); -}; - -class AlphaITB : public AlphaTLB -{ - protected: - mutable Stats::Scalar<> hits; - mutable Stats::Scalar<> misses; - mutable Stats::Scalar<> acv; - mutable Stats::Formula accesses; - - public: - AlphaITB(const std::string &name, int size); - virtual void regStats(); - - Fault translate(RequestPtr &req, ThreadContext *tc) const; -}; - -class AlphaDTB : public AlphaTLB -{ - 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: - AlphaDTB(const std::string &name, int size); - virtual void regStats(); - - Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const; -}; + class PTE; + + class TLB : public SimObject + { + protected: + typedef std::multimap<Addr, int> PageTable; + PageTable lookupTable; // Quick lookup into page table + + PTE *table; // the Page Table + int size; // TLB Size + int nlu; // not last used entry (for replacement) + + void nextnlu() { if (++nlu >= size) nlu = 0; } + PTE *lookup(Addr vpn, uint8_t asn) const; + + public: + TLB(const std::string &name, int size); + virtual ~TLB(); + + int getsize() const { return size; } + + PTE &index(bool advance = true); + void insert(Addr vaddr, PTE &pte); + + void flushAll(); + void flushProcesses(); + void flushAddr(Addr addr, uint8_t 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); + }; + + class ITB : public TLB + { + protected: + mutable Stats::Scalar<> hits; + mutable Stats::Scalar<> misses; + mutable Stats::Scalar<> acv; + mutable Stats::Formula accesses; + + public: + ITB(const std::string &name, int size); + virtual void regStats(); + + Fault translate(RequestPtr &req, ThreadContext *tc) const; + }; + + 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: + DTB(const std::string &name, int size); + virtual void regStats(); + + Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const; + }; +} #endif // __ALPHA_MEMORY_HH__ |