Merge zizzer:/bk/newmem
into zeep.pool:/z/saidi/work/m5.newmem --HG-- extra : convert_revision : c358d5e3211756bbf905eef2a62b65a2e56a86f3
This commit is contained in:
commit
544f4b4d81
22 changed files with 1926 additions and 213 deletions
|
@ -53,6 +53,7 @@ isa_switch_hdrs = Split('''
|
|||
isa_traits.hh
|
||||
kernel_stats.hh
|
||||
locked_mem.hh
|
||||
mmaped_ipr.hh
|
||||
process.hh
|
||||
regfile.hh
|
||||
remote_gdb.hh
|
||||
|
|
61
src/arch/alpha/mmaped_ipr.hh
Normal file
61
src/arch/alpha/mmaped_ipr.hh
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2006 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: Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ALPHA_MMAPED_IPR_HH__
|
||||
#define __ARCH_ALPHA_MMAPED_IPR_HH__
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* ISA-specific helper functions for memory mapped IPR accesses.
|
||||
*/
|
||||
|
||||
#include "mem/packet.hh"
|
||||
|
||||
|
||||
namespace AlphaISA
|
||||
{
|
||||
inline Tick
|
||||
handleIprRead(ThreadContext *xc, Packet *pkt)
|
||||
{
|
||||
panic("No handleIprRead implementation in Alpha\n");
|
||||
}
|
||||
|
||||
|
||||
inline Tick
|
||||
handleIprWrite(ThreadContext *xc, Packet *pkt)
|
||||
{
|
||||
panic("No handleIprWrite implementation in Alpha\n");
|
||||
}
|
||||
|
||||
|
||||
} // namespace AlphaISA
|
||||
|
||||
#endif
|
61
src/arch/mips/mmaped_ipr.hh
Normal file
61
src/arch/mips/mmaped_ipr.hh
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2006 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: Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_MIPS_MMAPED_IPR_HH__
|
||||
#define __ARCH_MIPS_MMAPED_IPR_HH__
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* ISA-specific helper functions for memory mapped IPR accesses.
|
||||
*/
|
||||
|
||||
#include "mem/packet.hh"
|
||||
|
||||
|
||||
namespace MipsISA
|
||||
{
|
||||
inline Tick
|
||||
handleIprRead(ThreadContext *xc, Packet *pkt)
|
||||
{
|
||||
panic("No implementation for handleIprRead in MIPS\n");
|
||||
}
|
||||
|
||||
|
||||
inline Tick
|
||||
handleIprWrite(ThreadContext *xc, Packet *pkt)
|
||||
{
|
||||
panic("No implementation for handleIprWrite in MIPS\n");
|
||||
}
|
||||
|
||||
|
||||
} // namespace MipsISA
|
||||
|
||||
#endif
|
|
@ -56,6 +56,7 @@ base_sources = Split('''
|
|||
full_system_sources = Split('''
|
||||
arguments.cc
|
||||
remote_gdb.cc
|
||||
pagetable.cc
|
||||
stacktrace.cc
|
||||
system.cc
|
||||
tlb.cc
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
* Ali Saidi
|
||||
*/
|
||||
|
||||
#include "arch/sparc/asi.hh"
|
||||
|
@ -37,8 +38,8 @@ namespace SparcISA
|
|||
return
|
||||
(asi == ASI_BLK_AIUP) ||
|
||||
(asi == ASI_BLK_AIUS) ||
|
||||
(asi == ASI_BLK_AIUPL) ||
|
||||
(asi == ASI_BLK_AIUSL) ||
|
||||
(asi == ASI_BLK_AIUP_L) ||
|
||||
(asi == ASI_BLK_AIUS_L) ||
|
||||
(asi == ASI_BLK_P) ||
|
||||
(asi == ASI_BLK_S) ||
|
||||
(asi == ASI_BLK_PL) ||
|
||||
|
@ -50,10 +51,10 @@ namespace SparcISA
|
|||
return
|
||||
(asi == ASI_AIUP) ||
|
||||
(asi == ASI_BLK_AIUP) ||
|
||||
(asi == ASI_AIUPL) ||
|
||||
(asi == ASI_BLK_AIUPL) ||
|
||||
(asi == ASI_AIUP_L) ||
|
||||
(asi == ASI_BLK_AIUP_L) ||
|
||||
(asi == ASI_LDTX_AIUP) ||
|
||||
(asi == ASI_LDTX_AIUPL) ||
|
||||
(asi == ASI_LDTX_AIUP_L) ||
|
||||
(asi == ASI_P) ||
|
||||
(asi == ASI_PNF) ||
|
||||
(asi == ASI_PL) ||
|
||||
|
@ -79,10 +80,10 @@ namespace SparcISA
|
|||
return
|
||||
(asi == ASI_AIUS) ||
|
||||
(asi == ASI_BLK_AIUS) ||
|
||||
(asi == ASI_AIUSL) ||
|
||||
(asi == ASI_BLK_AIUSL) ||
|
||||
(asi == ASI_AIUS_L) ||
|
||||
(asi == ASI_BLK_AIUS_L) ||
|
||||
(asi == ASI_LDTX_AIUS) ||
|
||||
(asi == ASI_LDTX_AIUSL) ||
|
||||
(asi == ASI_LDTX_AIUS_L) ||
|
||||
(asi == ASI_S) ||
|
||||
(asi == ASI_SNF) ||
|
||||
(asi == ASI_SL) ||
|
||||
|
@ -119,14 +120,14 @@ namespace SparcISA
|
|||
(asi == ASI_AIUS) ||
|
||||
(asi == ASI_BLK_AIUP) ||
|
||||
(asi == ASI_BLK_AIUS) ||
|
||||
(asi == ASI_AIUPL) ||
|
||||
(asi == ASI_AIUSL) ||
|
||||
(asi == ASI_BLK_AIUPL) ||
|
||||
(asi == ASI_BLK_AIUSL) ||
|
||||
(asi == ASI_AIUP_L) ||
|
||||
(asi == ASI_AIUS_L) ||
|
||||
(asi == ASI_BLK_AIUP_L) ||
|
||||
(asi == ASI_BLK_AIUS_L) ||
|
||||
(asi == ASI_LDTX_AIUP) ||
|
||||
(asi == ASI_LDTX_AIUS) ||
|
||||
(asi == ASI_LDTX_AIUPL) ||
|
||||
(asi == ASI_LDTX_AIUSL);
|
||||
(asi == ASI_LDTX_AIUP_L) ||
|
||||
(asi == ASI_LDTX_AIUS_L);
|
||||
}
|
||||
|
||||
bool AsiIsIO(ASI asi)
|
||||
|
@ -144,22 +145,21 @@ namespace SparcISA
|
|||
(asi == ASI_REAL_L) ||
|
||||
(asi == ASI_REAL_IO_L) ||
|
||||
(asi == ASI_LDTX_REAL) ||
|
||||
(asi == ASI_LDTX_REAL_L) ||
|
||||
(asi == ASI_MMU_REAL);
|
||||
(asi == ASI_LDTX_REAL_L);
|
||||
}
|
||||
|
||||
bool AsiIsLittle(ASI asi)
|
||||
{
|
||||
return
|
||||
(asi == ASI_NL) ||
|
||||
(asi == ASI_AIUPL) ||
|
||||
(asi == ASI_AIUSL) ||
|
||||
(asi == ASI_AIUP_L) ||
|
||||
(asi == ASI_AIUS_L) ||
|
||||
(asi == ASI_REAL_L) ||
|
||||
(asi == ASI_REAL_IO_L) ||
|
||||
(asi == ASI_BLK_AIUPL) ||
|
||||
(asi == ASI_BLK_AIUSL) ||
|
||||
(asi == ASI_LDTX_AIUPL) ||
|
||||
(asi == ASI_LDTX_AIUSL) ||
|
||||
(asi == ASI_BLK_AIUP_L) ||
|
||||
(asi == ASI_BLK_AIUS_L) ||
|
||||
(asi == ASI_LDTX_AIUP_L) ||
|
||||
(asi == ASI_LDTX_AIUS_L) ||
|
||||
(asi == ASI_LDTX_REAL_L) ||
|
||||
(asi == ASI_LDTX_NL) ||
|
||||
(asi == ASI_PL) ||
|
||||
|
@ -189,8 +189,8 @@ namespace SparcISA
|
|||
(asi == ASI_LDTX_AIUS) ||
|
||||
(asi == ASI_LDTX_REAL) ||
|
||||
(asi == ASI_LDTX_N) ||
|
||||
(asi == ASI_LDTX_AIUPL) ||
|
||||
(asi == ASI_LDTX_AIUSL) ||
|
||||
(asi == ASI_LDTX_AIUP_L) ||
|
||||
(asi == ASI_LDTX_AIUS_L) ||
|
||||
(asi == ASI_LDTX_REAL_L) ||
|
||||
(asi == ASI_LDTX_NL) ||
|
||||
(asi == ASI_LDTX_P) ||
|
||||
|
@ -248,8 +248,7 @@ namespace SparcISA
|
|||
bool AsiIsCmt(ASI asi)
|
||||
{
|
||||
return
|
||||
(asi == ASI_CMT_PER_STRAND) ||
|
||||
(asi == ASI_CMT_SHARED);
|
||||
(asi == ASI_CMT_PER_STRAND);
|
||||
}
|
||||
|
||||
bool AsiIsQueue(ASI asi)
|
||||
|
@ -257,23 +256,38 @@ namespace SparcISA
|
|||
return asi == ASI_QUEUE;
|
||||
}
|
||||
|
||||
bool AsiIsDtlb(ASI asi)
|
||||
{
|
||||
return
|
||||
(asi == ASI_DTLB_DATA_IN_REG) ||
|
||||
(asi == ASI_DTLB_DATA_ACCESS_REG) ||
|
||||
(asi == ASI_DTLB_TAG_READ_REG);
|
||||
}
|
||||
|
||||
bool AsiIsMmu(ASI asi)
|
||||
{
|
||||
return
|
||||
(asi == ASI_MMU_CONTEXTID) ||
|
||||
(asi == ASI_IMMU) ||
|
||||
(asi == ASI_MMU_REAL) ||
|
||||
(asi == ASI_MMU) ||
|
||||
(asi == ASI_DMMU) ||
|
||||
(asi == ASI_UMMU) ||
|
||||
(asi == ASI_DMMU_DEMAP);
|
||||
return asi == ASI_MMU ||
|
||||
(asi >= ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0 &&
|
||||
asi <= ASI_IMMU_CTXT_ZERO_CONFIG) ||
|
||||
(asi >= ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0 &&
|
||||
asi <= ASI_IMMU_CTXT_NONZERO_CONFIG) ||
|
||||
(asi >= ASI_IMMU &&
|
||||
asi <= ASI_IMMU_TSB_PS1_PTR_REG) ||
|
||||
(asi >= ASI_ITLB_DATA_IN_REG &&
|
||||
asi <= ASI_TLB_INVALIDATE_ALL);
|
||||
}
|
||||
|
||||
bool AsiIsUnPriv(ASI asi)
|
||||
{
|
||||
return asi >= 0x80;
|
||||
}
|
||||
|
||||
bool AsiIsPriv(ASI asi)
|
||||
{
|
||||
return asi <= 0x2f;
|
||||
}
|
||||
|
||||
|
||||
bool AsiIsHPriv(ASI asi)
|
||||
{
|
||||
return asi >= 0x30 && asi <= 0x7f;
|
||||
}
|
||||
|
||||
bool AsiIsReg(ASI asi)
|
||||
{
|
||||
return AsiIsMmu(asi) || AsiIsScratchPad(asi);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
* Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SPARC_ASI_HH__
|
||||
|
@ -34,6 +35,7 @@
|
|||
namespace SparcISA
|
||||
{
|
||||
enum ASI {
|
||||
ASI_IMPLICIT = 0x00,
|
||||
/* Priveleged ASIs */
|
||||
//0x00-0x03 implementation dependent
|
||||
ASI_NUCLEUS = 0x4,
|
||||
|
@ -53,64 +55,110 @@ namespace SparcISA
|
|||
ASI_BLOCK_AS_IF_USER_PRIMARY = ASI_BLK_AIUP,
|
||||
ASI_BLK_AIUS = 0x17,
|
||||
ASI_BLOCK_AS_IF_USER_SECONDARY = ASI_BLK_AIUS,
|
||||
ASI_AIUPL = 0x18,
|
||||
ASI_AS_IF_USER_PRIMARY_LITTLE = ASI_AIUPL,
|
||||
ASI_AIUSL = 0x19,
|
||||
ASI_AS_IF_USER_SECONDARY_LITTLE = ASI_AIUSL,
|
||||
ASI_AIUP_L = 0x18,
|
||||
ASI_AS_IF_USER_PRIMARY_LITTLE = ASI_AIUP_L,
|
||||
ASI_AIUS_L = 0x19,
|
||||
ASI_AS_IF_USER_SECONDARY_LITTLE = ASI_AIUS_L,
|
||||
//0x1A-0x1B implementation dependent
|
||||
ASI_REAL_L = 0x1C,
|
||||
ASI_REAL_LITTLE = ASI_REAL_L,
|
||||
ASI_REAL_IO_L = 0x1D,
|
||||
ASI_REAL_IO_LITTLE = ASI_REAL_IO_L,
|
||||
ASI_BLK_AIUPL = 0x1E,
|
||||
ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE = ASI_BLK_AIUPL,
|
||||
ASI_BLK_AIUSL = 0x1F,
|
||||
ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE = ASI_BLK_AIUSL,
|
||||
ASI_BLK_AIUP_L = 0x1E,
|
||||
ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE = ASI_BLK_AIUP_L,
|
||||
ASI_BLK_AIUS_L = 0x1F,
|
||||
ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE = ASI_BLK_AIUS_L,
|
||||
ASI_SCRATCHPAD = 0x20,
|
||||
ASI_MMU_CONTEXTID = 0x21,
|
||||
ASI_MMU = 0x21,
|
||||
ASI_LDTX_AIUP = 0x22,
|
||||
ASI_LD_TWINX_AS_IF_USER_PRIMARY = ASI_LDTX_AIUP,
|
||||
ASI_LDTX_AIUS = 0x23,
|
||||
ASI_LD_TWINX_AS_IF_USER_SECONDARY = ASI_LDTX_AIUS,
|
||||
//0x24 implementation dependent
|
||||
ASI_QUAD_LDD = 0x24,
|
||||
ASI_QUEUE = 0x25,
|
||||
ASI_LDTX_REAL = 0x26,
|
||||
ASI_LD_TWINX_REAL = ASI_LDTX_REAL,
|
||||
ASI_QUAD_LDD_REAL = 0x26,
|
||||
ASI_LDTX_REAL = ASI_QUAD_LDD_REAL,
|
||||
ASI_LDTX_N = 0x27,
|
||||
ASI_LD_TWINX_NUCLEUS = ASI_LDTX_N,
|
||||
ASI_ST_BLKINIT_NUCLEUS = ASI_LDTX_N,
|
||||
ASI_STBI_N = ASI_LDTX_N,
|
||||
//0x28-0x29 implementation dependent
|
||||
ASI_LDTX_AIUPL = 0x2A,
|
||||
ASI_LD_TWINX_AS_IF_USER_PRIMARY_LITTLE = ASI_LDTX_AIUPL,
|
||||
ASI_LDTX_AIUSL = 0x2B,
|
||||
ASI_LD_TWINX_AS_IF_USER_SECONDARY_LITTLE = ASI_LDTX_AIUSL,
|
||||
//0x2C-0x2D implementation dependent
|
||||
ASI_LDTX_AIUP_L = 0x2A,
|
||||
ASI_TWINX_AS_IF_USER_PRIMARY_LITTLE = ASI_LDTX_AIUP_L,
|
||||
ASI_ST_BLKINIT_AS_IF_USER_PRIMARY_LITTLE = ASI_LDTX_AIUP_L,
|
||||
ASI_STBI_AIUP_L = ASI_LDTX_AIUP_L,
|
||||
ASI_LDTX_AIUS_L = 0x2B,
|
||||
ASI_LD_TWINX_AS_IF_USER_SECONDARY_LITTLE = ASI_LDTX_AIUS_L,
|
||||
ASI_ST_BLKINIT_AS_IF_USER_SECONDARY_LITTLE = ASI_LDTX_AIUS_L,
|
||||
ASI_STBI_AIUS_L = ASI_LDTX_AIUS_L,
|
||||
ASI_LTX_L = 0x2C,
|
||||
ASI_TWINX_LITTLE = ASI_LTX_L,
|
||||
//0x2D implementation dependent
|
||||
ASI_LDTX_REAL_L = 0x2E,
|
||||
ASI_LD_TWINX_REAL_LITTLE = ASI_LDTX_REAL_L,
|
||||
ASI_LDTX_NL = 0x2F,
|
||||
ASI_LD_TWINX_NUCLEUS_LITTLE = ASI_LDTX_NL,
|
||||
//0x30-0x40 implementation dependent
|
||||
ASI_CMT_SHARED = 0x41,
|
||||
//0x42-0x4F implementation dependent
|
||||
//0x20 implementation dependent
|
||||
ASI_DMMU_CTXT_ZERO_TSB_BASE_PS0 = 0x31,
|
||||
ASI_DMMU_CTXT_ZERO_TSB_BASE_PS1 = 0x32,
|
||||
ASI_DMMU_CTXT_ZERO_CONFIG = 0x33,
|
||||
//0x34 implementation dependent
|
||||
ASI_IMMU_CTXT_ZERO_TSB_BASE_PS0 = 0x35,
|
||||
ASI_IMMU_CTXT_ZERO_TSB_BASE_PS1 = 0x36,
|
||||
ASI_IMMU_CTXT_ZERO_CONFIG = 0x37,
|
||||
//0x38 implementation dependent
|
||||
ASI_DMMU_CTXT_NONZERO_TSB_BASE_PS0 = 0x39,
|
||||
ASI_DMMU_CTXT_NONZERO_USB_BASE_PS1 = 0x3A,
|
||||
ASI_DMMU_CTXT_NONZERO_CONFIG = 0x3B,
|
||||
//0x3C implementation dependent
|
||||
ASI_IMMU_CTXT_NONZERO_TSB_BASE_PS0 = 0x3D,
|
||||
ASI_IMMU_CTXT_NONZERO_USB_BASE_PS1 = 0x3E,
|
||||
ASI_IMMU_CTXT_NONZERO_CONFIG = 0x3F,
|
||||
ASI_STREAM_MA = 0x40,
|
||||
//0x41 implementation dependent
|
||||
ASI_SPARC_BIST_CONTROL = 0x42,
|
||||
ASI_INST_MASK_REG = 0x42,
|
||||
ASI_LSU_DIAG_REG = 0x42,
|
||||
//0x43 implementation dependent
|
||||
ASI_STM_CTL_REG = 0x44,
|
||||
ASI_LSU_CONTROL_REG = 0x45,
|
||||
ASI_DCACHE_DATA = 0x46,
|
||||
ASI_DCACHE_TAG = 0x47,
|
||||
ASI_INTR_DISPATCH_STATUS = 0x48,
|
||||
ASI_INTR_RECEIVE = 0x49,
|
||||
ASI_UPA_CONFIG_REGISTER = 0x4A,
|
||||
ASI_SPARC_ERROR_EN_REG = 0x4B,
|
||||
ASI_SPARC_ERROR_STATUS_REG = 0x4C,
|
||||
ASI_SPARC_ERROR_ADDRESS_REG = 0x4D,
|
||||
ASI_ECACHE_TAG_DATA = 0x4E,
|
||||
ASI_HYP_SCRATCHPAD = 0x4F,
|
||||
ASI_IMMU = 0x50,
|
||||
ASI_MMU_REAL = 0x52,
|
||||
ASI_IMMU_TSB_PS0_PTR_REG = 0x51,
|
||||
ASI_IMMU_TSB_PS1_PTR_REG = 0x52,
|
||||
//0x53 implementation dependent
|
||||
ASI_MMU = 0x54,
|
||||
ASI_ITLB_DATA_IN_REG = 0x54,
|
||||
ASI_ITLB_DATA_ACCESS_REG = 0x55,
|
||||
ASI_ITLB_TAG_READ_REG = 0x56,
|
||||
ASI_IMMU_DEMAP = 0x57,
|
||||
ASI_DMMU = 0x58,
|
||||
ASI_UMMU = 0x58,
|
||||
//0x59-0x5B reserved
|
||||
ASI_DMMU_TSB_PS0_PTR_REG = 0x59,
|
||||
ASI_DMMU_TSB_PS1_PTR_REG = 0x5A,
|
||||
ASI_DMMU_TSB_DIRECT_PTR_REG = 0x5B,
|
||||
ASI_DTLB_DATA_IN_REG = 0x5C,
|
||||
ASI_DTLB_DATA_ACCESS_REG = 0x5D,
|
||||
ASI_DTLB_TAG_READ_REG = 0x5E,
|
||||
ASI_DMMU_DEMAP = 0x5F,
|
||||
//0x60-62 implementation dependent
|
||||
ASI_TLB_INVALIDATE_ALL = 0x60,
|
||||
//0x61-0x62 implementation dependent
|
||||
ASI_CMT_PER_STRAND = 0x63,
|
||||
//0x64-0x67 implementation dependent
|
||||
//0x68-0x7F reserved
|
||||
|
||||
//0x64-0x65 implementation dependent
|
||||
ASI_ICACHE_INSTR = 0x66,
|
||||
ASI_ICACHE_TAG = 0x67,
|
||||
//0x68-0x71 implementation dependent
|
||||
ASI_SWVR_INTR_RECEIVE = 0x72,
|
||||
ASI_SWVR_UDB_INTR_W = 0x73,
|
||||
ASI_SWVR_UDB_INTR_R = 0x74,
|
||||
//0x74-0x7F reserved
|
||||
/* Unpriveleged ASIs */
|
||||
ASI_P = 0x80,
|
||||
ASI_PRIMARY = ASI_P,
|
||||
|
@ -216,6 +264,10 @@ namespace SparcISA
|
|||
bool AsiIsQueue(ASI);
|
||||
bool AsiIsDtlb(ASI);
|
||||
bool AsiIsMmu(ASI);
|
||||
bool AsiIsUnPriv(ASI);
|
||||
bool AsiIsPriv(ASI);
|
||||
bool AsiIsHPriv(ASI);
|
||||
bool AsiIsReg(ASI);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
* Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SPARC_ISA_TRAITS_HH__
|
||||
|
@ -46,10 +47,6 @@ class StaticInstPtr;
|
|||
|
||||
namespace BigEndianGuest {}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
#include "arch/sparc/isa_fullsys_traits.hh"
|
||||
#endif
|
||||
|
||||
namespace SparcISA
|
||||
{
|
||||
class RegFile;
|
||||
|
@ -133,6 +130,30 @@ namespace SparcISA
|
|||
|
||||
// return a no-op instruction... used for instruction fetch faults
|
||||
extern const MachInst NoopMachInst;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
////////// Interrupt Stuff ///////////
|
||||
enum InterruptLevels
|
||||
{
|
||||
INTLEVEL_MIN = 1,
|
||||
INTLEVEL_MAX = 15,
|
||||
|
||||
NumInterruptLevels = INTLEVEL_MAX - INTLEVEL_MIN
|
||||
};
|
||||
|
||||
// I don't know what it's for, so I don't
|
||||
// know what SPARC's value should be
|
||||
// For loading... XXX This maybe could be USegEnd?? --ali
|
||||
const Addr LoadAddrMask = ULL(0xffffffffff);
|
||||
|
||||
/////////// TLB Stuff ////////////
|
||||
const Addr StartVAddrHole = ULL(0x0000800000000000);
|
||||
const Addr EndVAddrHole = ULL(0xFFFF7FFFFFFFFFFF);
|
||||
const Addr VAddrAMask = ULL(0xFFFFFFFF);
|
||||
const Addr PAddrImplMask = ULL(0x000000FFFFFFFFFF);
|
||||
const Addr BytesInPageMask = ULL(0x1FFF);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // __ARCH_SPARC_ISA_TRAITS_HH__
|
||||
|
|
|
@ -95,8 +95,32 @@ void MiscRegFile::reset()
|
|||
hstick_cmpr = 0;
|
||||
strandStatusReg = 0;
|
||||
fsr = 0;
|
||||
implicitInstAsi = ASI_PRIMARY;
|
||||
implicitDataAsi = ASI_PRIMARY;
|
||||
|
||||
priContext = 0;
|
||||
secContext = 0;
|
||||
partId = 0;
|
||||
lsuCtrlReg = 0;
|
||||
|
||||
iTlbC0TsbPs0 = 0;
|
||||
iTlbC0TsbPs1 = 0;
|
||||
iTlbC0Config = 0;
|
||||
iTlbCXTsbPs0 = 0;
|
||||
iTlbCXTsbPs1 = 0;
|
||||
iTlbCXConfig = 0;
|
||||
iTlbSfsr = 0;
|
||||
iTlbTagAccess = 0;
|
||||
|
||||
dTlbC0TsbPs0 = 0;
|
||||
dTlbC0TsbPs1 = 0;
|
||||
dTlbC0Config = 0;
|
||||
dTlbCXTsbPs0 = 0;
|
||||
dTlbCXTsbPs1 = 0;
|
||||
dTlbCXConfig = 0;
|
||||
dTlbSfsr = 0;
|
||||
dTlbSfar = 0;
|
||||
dTlbTagAccess = 0;
|
||||
|
||||
memset(scratchPad, 0, sizeof(scratchPad));
|
||||
}
|
||||
|
||||
MiscReg MiscRegFile::readReg(int miscReg)
|
||||
|
@ -180,6 +204,69 @@ MiscReg MiscRegFile::readReg(int miscReg)
|
|||
/** Floating Point Status Register */
|
||||
case MISCREG_FSR:
|
||||
return fsr;
|
||||
|
||||
case MISCREG_MMU_P_CONTEXT:
|
||||
return priContext;
|
||||
case MISCREG_MMU_S_CONTEXT:
|
||||
return secContext;
|
||||
case MISCREG_MMU_PART_ID:
|
||||
return partId;
|
||||
case MISCREG_MMU_LSU_CTRL:
|
||||
return lsuCtrlReg;
|
||||
|
||||
case MISCREG_MMU_ITLB_C0_TSB_PS0:
|
||||
return iTlbC0TsbPs0;
|
||||
case MISCREG_MMU_ITLB_C0_TSB_PS1:
|
||||
return iTlbC0TsbPs1;
|
||||
case MISCREG_MMU_ITLB_C0_CONFIG:
|
||||
return iTlbC0Config;
|
||||
case MISCREG_MMU_ITLB_CX_TSB_PS0:
|
||||
return iTlbCXTsbPs0;
|
||||
case MISCREG_MMU_ITLB_CX_TSB_PS1:
|
||||
return iTlbCXTsbPs1;
|
||||
case MISCREG_MMU_ITLB_CX_CONFIG:
|
||||
return iTlbCXConfig;
|
||||
case MISCREG_MMU_ITLB_SFSR:
|
||||
return iTlbSfsr;
|
||||
case MISCREG_MMU_ITLB_TAG_ACCESS:
|
||||
return iTlbTagAccess;
|
||||
|
||||
case MISCREG_MMU_DTLB_C0_TSB_PS0:
|
||||
return dTlbC0TsbPs0;
|
||||
case MISCREG_MMU_DTLB_C0_TSB_PS1:
|
||||
return dTlbC0TsbPs1;
|
||||
case MISCREG_MMU_DTLB_C0_CONFIG:
|
||||
return dTlbC0Config;
|
||||
case MISCREG_MMU_DTLB_CX_TSB_PS0:
|
||||
return dTlbCXTsbPs0;
|
||||
case MISCREG_MMU_DTLB_CX_TSB_PS1:
|
||||
return dTlbCXTsbPs1;
|
||||
case MISCREG_MMU_DTLB_CX_CONFIG:
|
||||
return dTlbCXConfig;
|
||||
case MISCREG_MMU_DTLB_SFSR:
|
||||
return dTlbSfsr;
|
||||
case MISCREG_MMU_DTLB_SFAR:
|
||||
return dTlbSfar;
|
||||
case MISCREG_MMU_DTLB_TAG_ACCESS:
|
||||
return dTlbTagAccess;
|
||||
|
||||
case MISCREG_SCRATCHPAD_R0:
|
||||
return scratchPad[0];
|
||||
case MISCREG_SCRATCHPAD_R1:
|
||||
return scratchPad[1];
|
||||
case MISCREG_SCRATCHPAD_R2:
|
||||
return scratchPad[2];
|
||||
case MISCREG_SCRATCHPAD_R3:
|
||||
return scratchPad[3];
|
||||
case MISCREG_SCRATCHPAD_R4:
|
||||
return scratchPad[4];
|
||||
case MISCREG_SCRATCHPAD_R5:
|
||||
return scratchPad[5];
|
||||
case MISCREG_SCRATCHPAD_R6:
|
||||
return scratchPad[6];
|
||||
case MISCREG_SCRATCHPAD_R7:
|
||||
return scratchPad[7];
|
||||
|
||||
default:
|
||||
panic("Miscellaneous register %d not implemented\n", miscReg);
|
||||
}
|
||||
|
@ -326,35 +413,95 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val)
|
|||
case MISCREG_FSR:
|
||||
fsr = val;
|
||||
break;
|
||||
|
||||
case MISCREG_MMU_P_CONTEXT:
|
||||
priContext = val;
|
||||
break;
|
||||
case MISCREG_MMU_S_CONTEXT:
|
||||
secContext = val;
|
||||
break;
|
||||
case MISCREG_MMU_PART_ID:
|
||||
partId = val;
|
||||
break;
|
||||
case MISCREG_MMU_LSU_CTRL:
|
||||
lsuCtrlReg = val;
|
||||
break;
|
||||
|
||||
case MISCREG_MMU_ITLB_C0_TSB_PS0:
|
||||
iTlbC0TsbPs0 = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_C0_TSB_PS1:
|
||||
iTlbC0TsbPs1 = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_C0_CONFIG:
|
||||
iTlbC0Config = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_CX_TSB_PS0:
|
||||
iTlbCXTsbPs0 = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_CX_TSB_PS1:
|
||||
iTlbCXTsbPs1 = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_CX_CONFIG:
|
||||
iTlbCXConfig = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_SFSR:
|
||||
iTlbSfsr = val;
|
||||
break;
|
||||
case MISCREG_MMU_ITLB_TAG_ACCESS:
|
||||
iTlbTagAccess = val;
|
||||
break;
|
||||
|
||||
case MISCREG_MMU_DTLB_C0_TSB_PS0:
|
||||
dTlbC0TsbPs0 = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_C0_TSB_PS1:
|
||||
dTlbC0TsbPs1 = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_C0_CONFIG:
|
||||
dTlbC0Config = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_CX_TSB_PS0:
|
||||
dTlbCXTsbPs0 = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_CX_TSB_PS1:
|
||||
dTlbCXTsbPs1 = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_CX_CONFIG:
|
||||
dTlbCXConfig = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_SFSR:
|
||||
dTlbSfsr = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_SFAR:
|
||||
dTlbSfar = val;
|
||||
break;
|
||||
case MISCREG_MMU_DTLB_TAG_ACCESS:
|
||||
dTlbTagAccess = val;
|
||||
break;
|
||||
|
||||
case MISCREG_SCRATCHPAD_R0:
|
||||
scratchPad[0] = val;
|
||||
case MISCREG_SCRATCHPAD_R1:
|
||||
scratchPad[1] = val;
|
||||
case MISCREG_SCRATCHPAD_R2:
|
||||
scratchPad[2] = val;
|
||||
case MISCREG_SCRATCHPAD_R3:
|
||||
scratchPad[3] = val;
|
||||
case MISCREG_SCRATCHPAD_R4:
|
||||
scratchPad[4] = val;
|
||||
case MISCREG_SCRATCHPAD_R5:
|
||||
scratchPad[5] = val;
|
||||
case MISCREG_SCRATCHPAD_R6:
|
||||
scratchPad[6] = val;
|
||||
case MISCREG_SCRATCHPAD_R7:
|
||||
scratchPad[7] = val;
|
||||
|
||||
default:
|
||||
panic("Miscellaneous register %d not implemented\n", miscReg);
|
||||
}
|
||||
}
|
||||
|
||||
inline void MiscRegFile::setImplicitAsis()
|
||||
{
|
||||
//The spec seems to use trap level to indicate the privilege level of the
|
||||
//processor. It's unclear whether the implicit ASIs should directly depend
|
||||
//on the trap level, or if they should really be based on the privelege
|
||||
//bits
|
||||
if(tl == 0)
|
||||
{
|
||||
implicitInstAsi = implicitDataAsi =
|
||||
(pstate & (1 << 9)) ? ASI_PRIMARY_LITTLE : ASI_PRIMARY;
|
||||
}
|
||||
else if(tl <= MaxPTL)
|
||||
{
|
||||
implicitInstAsi = ASI_NUCLEUS;
|
||||
implicitDataAsi = (pstate & (1 << 9)) ? ASI_NUCLEUS_LITTLE : ASI_NUCLEUS;
|
||||
}
|
||||
else
|
||||
{
|
||||
//This is supposed to force physical addresses to match the spec.
|
||||
//It might not because of context values and partition values.
|
||||
implicitInstAsi = implicitDataAsi = ASI_REAL;
|
||||
}
|
||||
}
|
||||
|
||||
void MiscRegFile::setRegWithEffect(int miscReg,
|
||||
const MiscReg &val, ThreadContext * tc)
|
||||
{
|
||||
|
@ -376,11 +523,9 @@ void MiscRegFile::setRegWithEffect(int miscReg,
|
|||
break;
|
||||
case MISCREG_PSTATE:
|
||||
pstate = val;
|
||||
setImplicitAsis();
|
||||
return;
|
||||
case MISCREG_TL:
|
||||
tl = val;
|
||||
setImplicitAsis();
|
||||
return;
|
||||
case MISCREG_CWP:
|
||||
tc->changeRegFileContext(CONTEXT_CWP, val);
|
||||
|
@ -483,8 +628,28 @@ void MiscRegFile::serialize(std::ostream & os)
|
|||
SERIALIZE_ARRAY(htstate, MaxTL);
|
||||
SERIALIZE_SCALAR(htba);
|
||||
SERIALIZE_SCALAR(hstick_cmpr);
|
||||
SERIALIZE_SCALAR((int)implicitInstAsi);
|
||||
SERIALIZE_SCALAR((int)implicitDataAsi);
|
||||
SERIALIZE_SCALAR(strandStatusReg);
|
||||
SERIALIZE_SCALAR(priContext);
|
||||
SERIALIZE_SCALAR(secContext);
|
||||
SERIALIZE_SCALAR(partId);
|
||||
SERIALIZE_SCALAR(lsuCtrlReg);
|
||||
SERIALIZE_SCALAR(iTlbC0TsbPs0);
|
||||
SERIALIZE_SCALAR(iTlbC0TsbPs1);
|
||||
SERIALIZE_SCALAR(iTlbC0Config);
|
||||
SERIALIZE_SCALAR(iTlbCXTsbPs0);
|
||||
SERIALIZE_SCALAR(iTlbCXTsbPs1);
|
||||
SERIALIZE_SCALAR(iTlbCXConfig);
|
||||
SERIALIZE_SCALAR(iTlbSfsr);
|
||||
SERIALIZE_SCALAR(iTlbTagAccess);
|
||||
SERIALIZE_SCALAR(dTlbC0TsbPs0);
|
||||
SERIALIZE_SCALAR(dTlbC0TsbPs1);
|
||||
SERIALIZE_SCALAR(dTlbC0Config);
|
||||
SERIALIZE_SCALAR(dTlbCXTsbPs0);
|
||||
SERIALIZE_SCALAR(dTlbCXTsbPs1);
|
||||
SERIALIZE_SCALAR(dTlbSfsr);
|
||||
SERIALIZE_SCALAR(dTlbSfar);
|
||||
SERIALIZE_SCALAR(dTlbTagAccess);
|
||||
SERIALIZE_ARRAY(scratchPad,8);
|
||||
}
|
||||
|
||||
void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
|
||||
|
@ -514,12 +679,28 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section)
|
|||
UNSERIALIZE_ARRAY(htstate, MaxTL);
|
||||
UNSERIALIZE_SCALAR(htba);
|
||||
UNSERIALIZE_SCALAR(hstick_cmpr);
|
||||
int temp;
|
||||
UNSERIALIZE_SCALAR(temp);
|
||||
implicitInstAsi = (ASI)temp;
|
||||
UNSERIALIZE_SCALAR(temp);
|
||||
implicitDataAsi = (ASI)temp;
|
||||
}
|
||||
UNSERIALIZE_SCALAR(strandStatusReg);
|
||||
UNSERIALIZE_SCALAR(priContext);
|
||||
UNSERIALIZE_SCALAR(secContext);
|
||||
UNSERIALIZE_SCALAR(partId);
|
||||
UNSERIALIZE_SCALAR(lsuCtrlReg);
|
||||
UNSERIALIZE_SCALAR(iTlbC0TsbPs0);
|
||||
UNSERIALIZE_SCALAR(iTlbC0TsbPs1);
|
||||
UNSERIALIZE_SCALAR(iTlbC0Config);
|
||||
UNSERIALIZE_SCALAR(iTlbCXTsbPs0);
|
||||
UNSERIALIZE_SCALAR(iTlbCXTsbPs1);
|
||||
UNSERIALIZE_SCALAR(iTlbCXConfig);
|
||||
UNSERIALIZE_SCALAR(iTlbSfsr);
|
||||
UNSERIALIZE_SCALAR(iTlbTagAccess);
|
||||
UNSERIALIZE_SCALAR(dTlbC0TsbPs0);
|
||||
UNSERIALIZE_SCALAR(dTlbC0TsbPs1);
|
||||
UNSERIALIZE_SCALAR(dTlbC0Config);
|
||||
UNSERIALIZE_SCALAR(dTlbCXTsbPs0);
|
||||
UNSERIALIZE_SCALAR(dTlbCXTsbPs1);
|
||||
UNSERIALIZE_SCALAR(dTlbSfsr);
|
||||
UNSERIALIZE_SCALAR(dTlbSfar);
|
||||
UNSERIALIZE_SCALAR(dTlbTagAccess);
|
||||
UNSERIALIZE_ARRAY(scratchPad,8);}
|
||||
|
||||
#if FULL_SYSTEM
|
||||
void
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#ifndef __ARCH_SPARC_MISCREGFILE_HH__
|
||||
#define __ARCH_SPARC_MISCREGFILE_HH__
|
||||
|
||||
#include "arch/sparc/asi.hh"
|
||||
#include "arch/sparc/faults.hh"
|
||||
#include "arch/sparc/isa_traits.hh"
|
||||
#include "arch/sparc/types.hh"
|
||||
|
@ -92,7 +91,42 @@ namespace SparcISA
|
|||
MISCREG_HSTICK_CMPR,
|
||||
|
||||
/** Floating Point Status Register */
|
||||
MISCREG_FSR
|
||||
MISCREG_FSR,
|
||||
|
||||
/** MMU Internal Registers */
|
||||
MISCREG_MMU_P_CONTEXT,
|
||||
MISCREG_MMU_S_CONTEXT,
|
||||
MISCREG_MMU_PART_ID,
|
||||
MISCREG_MMU_LSU_CTRL,
|
||||
|
||||
MISCREG_MMU_ITLB_C0_TSB_PS0,
|
||||
MISCREG_MMU_ITLB_C0_TSB_PS1,
|
||||
MISCREG_MMU_ITLB_C0_CONFIG,
|
||||
MISCREG_MMU_ITLB_CX_TSB_PS0,
|
||||
MISCREG_MMU_ITLB_CX_TSB_PS1,
|
||||
MISCREG_MMU_ITLB_CX_CONFIG,
|
||||
MISCREG_MMU_ITLB_SFSR,
|
||||
MISCREG_MMU_ITLB_TAG_ACCESS,
|
||||
|
||||
MISCREG_MMU_DTLB_C0_TSB_PS0,
|
||||
MISCREG_MMU_DTLB_C0_TSB_PS1,
|
||||
MISCREG_MMU_DTLB_C0_CONFIG,
|
||||
MISCREG_MMU_DTLB_CX_TSB_PS0,
|
||||
MISCREG_MMU_DTLB_CX_TSB_PS1,
|
||||
MISCREG_MMU_DTLB_CX_CONFIG,
|
||||
MISCREG_MMU_DTLB_SFSR,
|
||||
MISCREG_MMU_DTLB_SFAR,
|
||||
MISCREG_MMU_DTLB_TAG_ACCESS,
|
||||
|
||||
/** Scratchpad regiscers **/
|
||||
MISCREG_SCRATCHPAD_R0,
|
||||
MISCREG_SCRATCHPAD_R1,
|
||||
MISCREG_SCRATCHPAD_R2,
|
||||
MISCREG_SCRATCHPAD_R3,
|
||||
MISCREG_SCRATCHPAD_R4,
|
||||
MISCREG_SCRATCHPAD_R5,
|
||||
MISCREG_SCRATCHPAD_R6,
|
||||
MISCREG_SCRATCHPAD_R7
|
||||
};
|
||||
|
||||
// The control registers, broken out into fields
|
||||
|
@ -146,8 +180,32 @@ namespace SparcISA
|
|||
/** Floating point misc registers. */
|
||||
uint64_t fsr; // Floating-Point State Register
|
||||
|
||||
ASI implicitInstAsi;
|
||||
ASI implicitDataAsi;
|
||||
/** MMU Internal Registers */
|
||||
uint16_t priContext;
|
||||
uint16_t secContext;
|
||||
uint16_t partId;
|
||||
uint64_t lsuCtrlReg;
|
||||
|
||||
uint64_t iTlbC0TsbPs0;
|
||||
uint64_t iTlbC0TsbPs1;
|
||||
uint64_t iTlbC0Config;
|
||||
uint64_t iTlbCXTsbPs0;
|
||||
uint64_t iTlbCXTsbPs1;
|
||||
uint64_t iTlbCXConfig;
|
||||
uint64_t iTlbSfsr;
|
||||
uint64_t iTlbTagAccess;
|
||||
|
||||
uint64_t dTlbC0TsbPs0;
|
||||
uint64_t dTlbC0TsbPs1;
|
||||
uint64_t dTlbC0Config;
|
||||
uint64_t dTlbCXTsbPs0;
|
||||
uint64_t dTlbCXTsbPs1;
|
||||
uint64_t dTlbCXConfig;
|
||||
uint64_t dTlbSfsr;
|
||||
uint64_t dTlbSfar;
|
||||
uint64_t dTlbTagAccess;
|
||||
|
||||
uint64_t scratchPad[8];
|
||||
|
||||
// These need to check the int_dis field and if 0 then
|
||||
// set appropriate bit in softint and checkinterrutps on the cpu
|
||||
|
@ -188,14 +246,14 @@ namespace SparcISA
|
|||
void setRegWithEffect(int miscReg,
|
||||
const MiscReg &val, ThreadContext * tc);
|
||||
|
||||
ASI getInstAsid()
|
||||
int getInstAsid()
|
||||
{
|
||||
return implicitInstAsi;
|
||||
return priContext | (uint32_t)partId << 13;
|
||||
}
|
||||
|
||||
ASI getDataAsid()
|
||||
int getDataAsid()
|
||||
{
|
||||
return implicitDataAsi;
|
||||
return priContext | (uint32_t)partId << 13;
|
||||
}
|
||||
|
||||
void serialize(std::ostream & os);
|
||||
|
@ -209,7 +267,6 @@ namespace SparcISA
|
|||
bool isHyperPriv() { return (hpstate & (1 << 2)); }
|
||||
bool isPriv() { return (hpstate & (1 << 2)) || (pstate & (1 << 2)); }
|
||||
bool isNonPriv() { return !isPriv(); }
|
||||
inline void setImplicitAsis();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
63
src/arch/sparc/mmaped_ipr.hh
Normal file
63
src/arch/sparc/mmaped_ipr.hh
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2006 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: Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SPARC_MMAPED_IPR_HH__
|
||||
#define __ARCH_SPARC_MMAPED_IPR_HH__
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* ISA-specific helper functions for memory mapped IPR accesses.
|
||||
*/
|
||||
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "mem/packet.hh"
|
||||
#include "arch/sparc/tlb.hh"
|
||||
|
||||
|
||||
namespace SparcISA
|
||||
{
|
||||
inline Tick
|
||||
handleIprRead(ThreadContext *xc, Packet *pkt)
|
||||
{
|
||||
return xc->getDTBPtr()->doMmuRegRead(xc, pkt);
|
||||
}
|
||||
|
||||
|
||||
inline Tick
|
||||
handleIprWrite(ThreadContext *xc, Packet *pkt)
|
||||
{
|
||||
return xc->getDTBPtr()->doMmuRegWrite(xc, pkt);
|
||||
}
|
||||
|
||||
|
||||
} // namespace SparcISA
|
||||
|
||||
#endif
|
69
src/arch/sparc/pagetable.cc
Normal file
69
src/arch/sparc/pagetable.cc
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2006 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: Ali Saidi
|
||||
*/
|
||||
|
||||
#include "arch/sparc/pagetable.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
namespace SparcISA
|
||||
{
|
||||
void
|
||||
TlbEntry::serialize(std::ostream &os)
|
||||
{
|
||||
SERIALIZE_SCALAR(range.va);
|
||||
SERIALIZE_SCALAR(range.size);
|
||||
SERIALIZE_SCALAR(range.contextId);
|
||||
SERIALIZE_SCALAR(range.partitionId);
|
||||
SERIALIZE_SCALAR(range.real);
|
||||
uint64_t entry4u = pte();
|
||||
SERIALIZE_SCALAR(entry4u);
|
||||
SERIALIZE_SCALAR(used);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TlbEntry::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
UNSERIALIZE_SCALAR(range.va);
|
||||
UNSERIALIZE_SCALAR(range.size);
|
||||
UNSERIALIZE_SCALAR(range.contextId);
|
||||
UNSERIALIZE_SCALAR(range.partitionId);
|
||||
UNSERIALIZE_SCALAR(range.real);
|
||||
uint64_t entry4u;
|
||||
UNSERIALIZE_SCALAR(entry4u);
|
||||
pte.populate(entry4u);
|
||||
UNSERIALIZE_SCALAR(used);
|
||||
}
|
||||
|
||||
|
||||
int PageTableEntry::pageSizes[] = {8*1024, 64*1024, 0, 4*1024*1024, 0,
|
||||
256*1024*1024L};
|
||||
|
||||
|
||||
}
|
194
src/arch/sparc/pagetable.hh
Normal file
194
src/arch/sparc/pagetable.hh
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* Copyright (c) 2006 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: Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SPARC_PAGETABLE_HH__
|
||||
#define __ARCH_SPARC_PAGETABLE_HH__
|
||||
|
||||
#include "arch/sparc/isa_traits.hh"
|
||||
#include "config/full_system.hh"
|
||||
|
||||
namespace SparcISA
|
||||
{
|
||||
struct VAddr
|
||||
{
|
||||
VAddr(Addr a) { panic("not implemented yet."); }
|
||||
};
|
||||
|
||||
class PageTableEntry
|
||||
{
|
||||
public:
|
||||
enum EntryType {
|
||||
sun4v,
|
||||
sun4u,
|
||||
invalid
|
||||
};
|
||||
|
||||
private:
|
||||
uint64_t entry;
|
||||
EntryType type;
|
||||
uint64_t entry4u;
|
||||
bool populated;
|
||||
|
||||
|
||||
public:
|
||||
PageTableEntry() : entry(0), type(invalid), populated(false) {}
|
||||
|
||||
PageTableEntry(uint64_t e, EntryType t = sun4u)
|
||||
: entry(e), type(t), populated(true)
|
||||
|
||||
{
|
||||
populate(entry, type);
|
||||
}
|
||||
|
||||
void populate(uint64_t e, EntryType t = sun4u)
|
||||
{
|
||||
entry = e;
|
||||
type = t;
|
||||
populated = true;
|
||||
|
||||
// If we get a sun4v format TTE, turn it into a sun4u
|
||||
if (type == sun4u)
|
||||
entry4u = entry;
|
||||
else {
|
||||
uint64_t entry4u = 0;
|
||||
entry4u |= entry & ULL(0x8000000000000000); //valid
|
||||
entry4u |= (entry & 0x3) << 61; //size[1:0]
|
||||
entry4u |= (entry & ULL(0x4000000000000000)) >> 2; //nfo
|
||||
entry4u |= (entry & 0x1000) << 47; //ie
|
||||
//entry4u |= (entry & 0x3F00000000000000) >> 7; //soft2
|
||||
entry4u |= (entry & 0x4) << 48; //size[2]
|
||||
//diag?
|
||||
entry4u |= (entry & ULL(0x0000FFFFFFFFE000)); //paddr
|
||||
entry4u |= (entry & 0x400) >> 5; //cp
|
||||
entry4u |= (entry & 0x200) >> 5; //cv
|
||||
entry4u |= (entry & 0x800) >> 8; //e
|
||||
entry4u |= (entry & 0x100) >> 6; //p
|
||||
entry4u |= (entry & 0x40) >> 5; //w
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
populated = false;
|
||||
}
|
||||
|
||||
static int pageSizes[6];
|
||||
|
||||
|
||||
uint64_t operator()() const { assert(populated); return entry4u; }
|
||||
const PageTableEntry &operator=(uint64_t e) { populated = true;
|
||||
entry4u = e; return *this; }
|
||||
|
||||
const PageTableEntry &operator=(const PageTableEntry &e)
|
||||
{ populated = true; entry4u = e.entry4u; return *this; }
|
||||
|
||||
bool valid() const { return entry4u & ULL(0x8000000000000000) && populated; }
|
||||
uint8_t _size() const { assert(populated);
|
||||
return ((entry4u & 0x6) >> 61) |
|
||||
((entry4u & ULL(0x000080000000000)) >> 46); }
|
||||
Addr size() const { return pageSizes[_size()]; }
|
||||
bool ie() const { return entry4u >> 59 & 0x1; }
|
||||
Addr pfn() const { assert(populated);
|
||||
return entry4u >> 13 & ULL(0xFFFFFFFFFF); }
|
||||
Addr paddr() const { assert(populated);
|
||||
return entry4u & ULL(0x0000FFFFFFFFE000); }
|
||||
bool locked() const { assert(populated);
|
||||
return entry4u & 0x40; }
|
||||
bool cv() const { assert(populated);
|
||||
return entry4u & 0x10; }
|
||||
bool cp() const { assert(populated);
|
||||
return entry4u & 0x20; }
|
||||
bool priv() const { assert(populated);
|
||||
return entry4u & 0x4; }
|
||||
bool writable() const { assert(populated);
|
||||
return entry4u & 0x2; }
|
||||
bool nofault() const { assert(populated);
|
||||
return entry4u & ULL(0x1000000000000000); }
|
||||
bool sideffect() const { assert(populated);
|
||||
return entry4u & 0x8; }
|
||||
};
|
||||
|
||||
struct TlbRange {
|
||||
Addr va;
|
||||
Addr size;
|
||||
int contextId;
|
||||
int partitionId;
|
||||
bool real;
|
||||
|
||||
inline bool operator<(const TlbRange &r2) const
|
||||
{
|
||||
if (real && !r2.real)
|
||||
return true;
|
||||
if (!real && r2.real)
|
||||
return false;
|
||||
|
||||
if (!real && !r2.real) {
|
||||
if (contextId < r2.contextId)
|
||||
return true;
|
||||
else if (contextId > r2.contextId)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (partitionId < r2.partitionId)
|
||||
return true;
|
||||
else if (partitionId > r2.partitionId)
|
||||
return false;
|
||||
|
||||
if (va < r2.va)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
inline bool operator==(const TlbRange &r2) const
|
||||
{
|
||||
return va == r2.va &&
|
||||
size == r2.size &&
|
||||
contextId == r2.contextId &&
|
||||
partitionId == r2.partitionId &&
|
||||
real == r2.real;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct TlbEntry {
|
||||
TlbRange range;
|
||||
PageTableEntry pte;
|
||||
bool used;
|
||||
bool valid;
|
||||
|
||||
void serialize(std::ostream &os);
|
||||
void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
|
||||
};
|
||||
|
||||
|
||||
}; // namespace SparcISA
|
||||
|
||||
#endif // __ARCH_SPARC_PAGE_TABLE_HH__
|
||||
|
|
@ -82,12 +82,12 @@ namespace SparcISA
|
|||
void setMiscRegWithEffect(int miscReg, const MiscReg &val,
|
||||
ThreadContext * tc);
|
||||
|
||||
ASI instAsid()
|
||||
int instAsid()
|
||||
{
|
||||
return miscRegFile.getInstAsid();
|
||||
}
|
||||
|
||||
ASI dataAsid()
|
||||
int dataAsid()
|
||||
{
|
||||
return miscRegFile.getDataAsid();
|
||||
}
|
||||
|
|
|
@ -25,55 +25,566 @@
|
|||
* (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: Nathan Binkert
|
||||
* Steve Reinhardt
|
||||
* Andrew Schultz
|
||||
* Authors: Ali Saidi
|
||||
*/
|
||||
|
||||
#include "arch/sparc/asi.hh"
|
||||
#include "arch/sparc/tlb.hh"
|
||||
#include "sim/builder.hh"
|
||||
#include "arch/sparc/miscregfile.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
|
||||
/* @todo remove some of the magic constants. -- ali
|
||||
* */
|
||||
namespace SparcISA
|
||||
{
|
||||
DEFINE_SIM_OBJECT_CLASS_NAME("SparcTLB", TLB)
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB)
|
||||
TLB::TLB(const std::string &name, int s)
|
||||
: SimObject(name), size(s)
|
||||
{
|
||||
// To make this work you'll have to change the hypervisor and OS
|
||||
if (size > 64)
|
||||
fatal("SPARC T1 TLB registers don't support more than 64 TLB entries.");
|
||||
|
||||
Param<int> size;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(ITB)
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(ITB)
|
||||
|
||||
INIT_PARAM_DFLT(size, "TLB size", 48)
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(ITB)
|
||||
|
||||
|
||||
CREATE_SIM_OBJECT(ITB)
|
||||
{
|
||||
return new ITB(getInstanceName(), size);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("SparcITB", ITB)
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB)
|
||||
|
||||
Param<int> size;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(DTB)
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(DTB)
|
||||
|
||||
INIT_PARAM_DFLT(size, "TLB size", 64)
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(DTB)
|
||||
|
||||
|
||||
CREATE_SIM_OBJECT(DTB)
|
||||
{
|
||||
return new DTB(getInstanceName(), size);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("SparcDTB", DTB)
|
||||
tlb = new TlbEntry[size];
|
||||
memset(tlb, 0, sizeof(TlbEntry) * size);
|
||||
}
|
||||
|
||||
void
|
||||
TLB::clearUsedBits()
|
||||
{
|
||||
MapIter i;
|
||||
for (i = lookupTable.begin(); i != lookupTable.end();) {
|
||||
TlbEntry *t = i->second;
|
||||
if (!t->pte.locked()) {
|
||||
t->used = false;
|
||||
usedEntries--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TLB::insert(Addr va, int partition_id, int context_id, bool real,
|
||||
const PageTableEntry& PTE)
|
||||
{
|
||||
|
||||
|
||||
MapIter i;
|
||||
TlbEntry *new_entry;
|
||||
int x = -1;
|
||||
for (x = 0; x < size; x++) {
|
||||
if (!tlb[x].valid || !tlb[x].used) {
|
||||
new_entry = &tlb[x];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the last ently if their all locked
|
||||
if (x == -1)
|
||||
x = size - 1;
|
||||
|
||||
assert(PTE.valid());
|
||||
new_entry->range.va = va;
|
||||
new_entry->range.size = PTE.size();
|
||||
new_entry->range.partitionId = partition_id;
|
||||
new_entry->range.contextId = context_id;
|
||||
new_entry->range.real = real;
|
||||
new_entry->pte = PTE;
|
||||
new_entry->used = true;;
|
||||
new_entry->valid = true;
|
||||
usedEntries++;
|
||||
|
||||
|
||||
// Demap any entry that conflicts
|
||||
i = lookupTable.find(new_entry->range);
|
||||
if (i != lookupTable.end()) {
|
||||
i->second->valid = false;
|
||||
if (i->second->used) {
|
||||
i->second->used = false;
|
||||
usedEntries--;
|
||||
}
|
||||
lookupTable.erase(i);
|
||||
}
|
||||
|
||||
lookupTable.insert(new_entry->range, new_entry);;
|
||||
|
||||
// If all entries have there used bit set, clear it on them all, but the
|
||||
// one we just inserted
|
||||
if (usedEntries == size) {
|
||||
clearUsedBits();
|
||||
new_entry->used = true;
|
||||
usedEntries++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
TlbEntry*
|
||||
TLB::lookup(Addr va, int partition_id, bool real, int context_id)
|
||||
{
|
||||
MapIter i;
|
||||
TlbRange tr;
|
||||
TlbEntry *t;
|
||||
|
||||
// Assemble full address structure
|
||||
tr.va = va;
|
||||
tr.size = va + MachineBytes;
|
||||
tr.contextId = context_id;
|
||||
tr.partitionId = partition_id;
|
||||
tr.real = real;
|
||||
|
||||
// Try to find the entry
|
||||
i = lookupTable.find(tr);
|
||||
if (i == lookupTable.end()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Mark the entries used bit and clear other used bits in needed
|
||||
t = i->second;
|
||||
if (!t->used) {
|
||||
t->used = true;
|
||||
usedEntries++;
|
||||
if (usedEntries == size) {
|
||||
clearUsedBits();
|
||||
t->used = true;
|
||||
usedEntries++;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TLB::demapPage(Addr va, int partition_id, bool real, int context_id)
|
||||
{
|
||||
TlbRange tr;
|
||||
MapIter i;
|
||||
|
||||
// Assemble full address structure
|
||||
tr.va = va;
|
||||
tr.size = va + MachineBytes;
|
||||
tr.contextId = context_id;
|
||||
tr.partitionId = partition_id;
|
||||
tr.real = real;
|
||||
|
||||
// Demap any entry that conflicts
|
||||
i = lookupTable.find(tr);
|
||||
if (i != lookupTable.end()) {
|
||||
i->second->valid = false;
|
||||
if (i->second->used) {
|
||||
i->second->used = false;
|
||||
usedEntries--;
|
||||
}
|
||||
lookupTable.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TLB::demapContext(int partition_id, int context_id)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < size; x++) {
|
||||
if (tlb[x].range.contextId == context_id &&
|
||||
tlb[x].range.partitionId == partition_id) {
|
||||
tlb[x].valid = false;
|
||||
if (tlb[x].used) {
|
||||
tlb[x].used = false;
|
||||
usedEntries--;
|
||||
}
|
||||
lookupTable.erase(tlb[x].range);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TLB::demapAll(int partition_id)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < size; x++) {
|
||||
if (!tlb[x].pte.locked() && tlb[x].range.partitionId == partition_id) {
|
||||
tlb[x].valid = false;
|
||||
if (tlb[x].used) {
|
||||
tlb[x].used = false;
|
||||
usedEntries--;
|
||||
}
|
||||
lookupTable.erase(tlb[x].range);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TLB::invalidateAll()
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < size; x++) {
|
||||
tlb[x].valid = false;
|
||||
}
|
||||
usedEntries = 0;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
TLB::TteRead(int entry) {
|
||||
assert(entry < size);
|
||||
return tlb[entry].pte();
|
||||
}
|
||||
|
||||
uint64_t
|
||||
TLB::TagRead(int entry) {
|
||||
assert(entry < size);
|
||||
uint64_t tag;
|
||||
|
||||
tag = tlb[entry].range.contextId | tlb[entry].range.va |
|
||||
(uint64_t)tlb[entry].range.partitionId << 61;
|
||||
tag |= tlb[entry].range.real ? ULL(1) << 60 : 0;
|
||||
tag |= (uint64_t)~tlb[entry].pte._size() << 56;
|
||||
return tag;
|
||||
}
|
||||
|
||||
bool
|
||||
TLB::validVirtualAddress(Addr va, bool am)
|
||||
{
|
||||
if (am)
|
||||
return true;
|
||||
if (va >= StartVAddrHole && va <= EndVAddrHole)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TLB::writeSfsr(ThreadContext *tc, int reg, bool write, ContextType ct,
|
||||
bool se, FaultTypes ft, int asi)
|
||||
{
|
||||
uint64_t sfsr;
|
||||
sfsr = tc->readMiscReg(reg);
|
||||
|
||||
if (sfsr & 0x1)
|
||||
sfsr = 0x3;
|
||||
else
|
||||
sfsr = 1;
|
||||
|
||||
if (write)
|
||||
sfsr |= 1 << 2;
|
||||
sfsr |= ct << 4;
|
||||
if (se)
|
||||
sfsr |= 1 << 6;
|
||||
sfsr |= ft << 7;
|
||||
sfsr |= asi << 16;
|
||||
tc->setMiscReg(reg, sfsr);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ITB::writeSfsr(ThreadContext *tc, bool write, ContextType ct,
|
||||
bool se, FaultTypes ft, int asi)
|
||||
{
|
||||
TLB::writeSfsr(tc, MISCREG_MMU_ITLB_SFSR, write, ct, se, ft, asi);
|
||||
}
|
||||
|
||||
void
|
||||
DTB::writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct,
|
||||
bool se, FaultTypes ft, int asi)
|
||||
{
|
||||
TLB::writeSfsr(tc, MISCREG_MMU_DTLB_SFSR, write, ct, se, ft, asi);
|
||||
tc->setMiscReg(MISCREG_MMU_DTLB_SFAR, a);
|
||||
}
|
||||
|
||||
|
||||
Fault
|
||||
ITB::translate(RequestPtr &req, ThreadContext *tc)
|
||||
{
|
||||
uint64_t hpstate = tc->readMiscReg(MISCREG_HPSTATE);
|
||||
uint64_t pstate = tc->readMiscReg(MISCREG_PSTATE);
|
||||
bool lsuIm = tc->readMiscReg(MISCREG_MMU_LSU_CTRL) >> 2 & 0x1;
|
||||
uint64_t tl = tc->readMiscReg(MISCREG_TL);
|
||||
uint64_t part_id = tc->readMiscReg(MISCREG_MMU_PART_ID);
|
||||
bool addr_mask = pstate >> 3 & 0x1;
|
||||
bool priv = pstate >> 2 & 0x1;
|
||||
Addr vaddr = req->getVaddr();
|
||||
int context;
|
||||
ContextType ct;
|
||||
int asi;
|
||||
bool real = false;
|
||||
TlbEntry *e;
|
||||
|
||||
assert(req->getAsi() == ASI_IMPLICIT);
|
||||
|
||||
if (tl > 0) {
|
||||
asi = ASI_N;
|
||||
ct = Nucleus;
|
||||
context = 0;
|
||||
} else {
|
||||
asi = ASI_P;
|
||||
ct = Primary;
|
||||
context = tc->readMiscReg(MISCREG_MMU_P_CONTEXT);
|
||||
}
|
||||
|
||||
if ( hpstate >> 2 & 0x1 || hpstate >> 5 & 0x1 ) {
|
||||
req->setPaddr(req->getVaddr() & PAddrImplMask);
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
// If the asi is unaligned trap
|
||||
if (vaddr & 0x7) {
|
||||
writeSfsr(tc, false, ct, false, OtherFault, asi);
|
||||
return new MemAddressNotAligned;
|
||||
}
|
||||
|
||||
if (addr_mask)
|
||||
vaddr = vaddr & VAddrAMask;
|
||||
|
||||
if (!validVirtualAddress(vaddr, addr_mask)) {
|
||||
writeSfsr(tc, false, ct, false, VaOutOfRange, asi);
|
||||
return new InstructionAccessException;
|
||||
}
|
||||
|
||||
if (lsuIm) {
|
||||
e = lookup(req->getVaddr(), part_id, true);
|
||||
real = true;
|
||||
context = 0;
|
||||
} else {
|
||||
e = lookup(vaddr, part_id, false, context);
|
||||
}
|
||||
|
||||
if (e == NULL || !e->valid) {
|
||||
tc->setMiscReg(MISCREG_MMU_ITLB_TAG_ACCESS,
|
||||
vaddr & ~BytesInPageMask | context);
|
||||
if (real)
|
||||
return new InstructionRealTranslationMiss;
|
||||
else
|
||||
return new FastInstructionAccessMMUMiss;
|
||||
}
|
||||
|
||||
// were not priviledged accesing priv page
|
||||
if (!priv && e->pte.priv()) {
|
||||
writeSfsr(tc, false, ct, false, PrivViolation, asi);
|
||||
return new InstructionAccessException;
|
||||
}
|
||||
|
||||
req->setPaddr(e->pte.paddr() & ~e->pte.size() |
|
||||
req->getVaddr() & e->pte.size());
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Fault
|
||||
DTB::translate(RequestPtr &req, ThreadContext *tc, bool write)
|
||||
{
|
||||
/* @todo this could really use some profiling and fixing to make it faster! */
|
||||
uint64_t hpstate = tc->readMiscReg(MISCREG_HPSTATE);
|
||||
uint64_t pstate = tc->readMiscReg(MISCREG_PSTATE);
|
||||
bool lsuDm = tc->readMiscReg(MISCREG_MMU_LSU_CTRL) >> 3 & 0x1;
|
||||
uint64_t tl = tc->readMiscReg(MISCREG_TL);
|
||||
uint64_t part_id = tc->readMiscReg(MISCREG_MMU_PART_ID);
|
||||
bool hpriv = hpstate >> 2 & 0x1;
|
||||
bool red = hpstate >> 5 >> 0x1;
|
||||
bool addr_mask = pstate >> 3 & 0x1;
|
||||
bool priv = pstate >> 2 & 0x1;
|
||||
bool implicit = false;
|
||||
bool real = false;
|
||||
Addr vaddr = req->getVaddr();
|
||||
ContextType ct;
|
||||
int context;
|
||||
ASI asi;
|
||||
|
||||
TlbEntry *e;
|
||||
|
||||
|
||||
asi = (ASI)req->getAsi();
|
||||
if (asi == ASI_IMPLICIT)
|
||||
implicit = true;
|
||||
|
||||
if (implicit) {
|
||||
if (tl > 0) {
|
||||
asi = ASI_N;
|
||||
ct = Nucleus;
|
||||
context = 0;
|
||||
} else {
|
||||
asi = ASI_P;
|
||||
ct = Primary;
|
||||
context = tc->readMiscReg(MISCREG_MMU_P_CONTEXT);
|
||||
}
|
||||
} else if (!hpriv && !red) {
|
||||
if (tl > 0) {
|
||||
ct = Nucleus;
|
||||
context = 0;
|
||||
} else if (AsiIsSecondary(asi)) {
|
||||
ct = Secondary;
|
||||
context = tc->readMiscReg(MISCREG_MMU_S_CONTEXT);
|
||||
} else {
|
||||
context = tc->readMiscReg(MISCREG_MMU_P_CONTEXT);
|
||||
ct = Primary; //???
|
||||
}
|
||||
|
||||
// We need to check for priv level/asi priv
|
||||
if (!priv && !AsiIsUnPriv(asi)) {
|
||||
// It appears that context should be Nucleus in these cases?
|
||||
writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi);
|
||||
return new PrivilegedAction;
|
||||
}
|
||||
if (priv && AsiIsHPriv(asi)) {
|
||||
writeSfr(tc, vaddr, write, Nucleus, false, IllegalAsi, asi);
|
||||
return new DataAccessException;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If the asi is unaligned trap
|
||||
if (AsiIsBlock(asi) && vaddr & 0x3f || vaddr & 0x7) {
|
||||
writeSfr(tc, vaddr, false, ct, false, OtherFault, asi);
|
||||
return new MemAddressNotAligned;
|
||||
}
|
||||
|
||||
if (addr_mask)
|
||||
vaddr = vaddr & VAddrAMask;
|
||||
|
||||
if (!validVirtualAddress(vaddr, addr_mask)) {
|
||||
writeSfr(tc, vaddr, false, ct, true, VaOutOfRange, asi);
|
||||
return new DataAccessException;
|
||||
}
|
||||
|
||||
if (!implicit) {
|
||||
if (AsiIsLittle(asi))
|
||||
panic("Little Endian ASIs not supported\n");
|
||||
if (AsiIsBlock(asi))
|
||||
panic("Block ASIs not supported\n");
|
||||
if (AsiIsNoFault(asi))
|
||||
panic("No Fault ASIs not supported\n");
|
||||
if (AsiIsTwin(asi))
|
||||
panic("Twin ASIs not supported\n");
|
||||
if (AsiIsPartialStore(asi))
|
||||
panic("Partial Store ASIs not supported\n");
|
||||
if (AsiIsMmu(asi))
|
||||
goto handleMmuRegAccess;
|
||||
|
||||
if (AsiIsScratchPad(asi))
|
||||
goto handleScratchRegAccess;
|
||||
}
|
||||
|
||||
if ((!lsuDm && !hpriv) || AsiIsReal(asi)) {
|
||||
real = true;
|
||||
context = 0;
|
||||
};
|
||||
|
||||
if (hpriv && (implicit || (!AsiIsAsIfUser(asi) && !AsiIsReal(asi)))) {
|
||||
req->setPaddr(req->getVaddr() & PAddrImplMask);
|
||||
return NoFault;
|
||||
}
|
||||
|
||||
e = lookup(req->getVaddr(), part_id, real, context);
|
||||
|
||||
if (e == NULL || !e->valid) {
|
||||
tc->setMiscReg(MISCREG_MMU_DTLB_TAG_ACCESS,
|
||||
vaddr & ~BytesInPageMask | context);
|
||||
if (real)
|
||||
return new DataRealTranslationMiss;
|
||||
else
|
||||
return new FastDataAccessMMUMiss;
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (write && !e->pte.writable()) {
|
||||
writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), OtherFault, asi);
|
||||
return new FastDataAccessProtection;
|
||||
}
|
||||
|
||||
if (e->pte.nofault() && !AsiIsNoFault(asi)) {
|
||||
writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), LoadFromNfo, asi);
|
||||
return new DataAccessException;
|
||||
}
|
||||
|
||||
if (e->pte.sideffect())
|
||||
req->setFlags(req->getFlags() | UNCACHEABLE);
|
||||
|
||||
|
||||
if (!priv && e->pte.priv()) {
|
||||
writeSfr(tc, vaddr, write, ct, e->pte.sideffect(), PrivViolation, asi);
|
||||
return new DataAccessException;
|
||||
}
|
||||
|
||||
req->setPaddr(e->pte.paddr() & ~e->pte.size() |
|
||||
req->getVaddr() & e->pte.size());
|
||||
return NoFault;
|
||||
/** Normal flow ends here. */
|
||||
|
||||
handleScratchRegAccess:
|
||||
if (vaddr > 0x38 || (vaddr >= 0x20 && vaddr < 0x30 && !hpriv)) {
|
||||
writeSfr(tc, vaddr, write, Primary, true, IllegalAsi, asi);
|
||||
return new DataAccessException;
|
||||
}
|
||||
handleMmuRegAccess:
|
||||
req->setMmapedIpr(true);
|
||||
req->setPaddr(req->getVaddr());
|
||||
return NoFault;
|
||||
};
|
||||
|
||||
Tick
|
||||
DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt)
|
||||
{
|
||||
panic("need to implement DTB::doMmuRegRead()\n");
|
||||
}
|
||||
|
||||
Tick
|
||||
DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt)
|
||||
{
|
||||
panic("need to implement DTB::doMmuRegWrite()\n");
|
||||
}
|
||||
|
||||
void
|
||||
TLB::serialize(std::ostream &os)
|
||||
{
|
||||
panic("Need to implement serialize tlb for SPARC\n");
|
||||
}
|
||||
|
||||
void
|
||||
TLB::unserialize(Checkpoint *cp, const std::string §ion)
|
||||
{
|
||||
panic("Need to implement unserialize tlb for SPARC\n");
|
||||
}
|
||||
|
||||
|
||||
DEFINE_SIM_OBJECT_CLASS_NAME("SparcTLB", TLB)
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(ITB)
|
||||
|
||||
Param<int> size;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(ITB)
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(ITB)
|
||||
|
||||
INIT_PARAM_DFLT(size, "TLB size", 48)
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(ITB)
|
||||
|
||||
|
||||
CREATE_SIM_OBJECT(ITB)
|
||||
{
|
||||
return new ITB(getInstanceName(), size);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("SparcITB", ITB)
|
||||
|
||||
BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB)
|
||||
|
||||
Param<int> size;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(DTB)
|
||||
|
||||
BEGIN_INIT_SIM_OBJECT_PARAMS(DTB)
|
||||
|
||||
INIT_PARAM_DFLT(size, "TLB size", 64)
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(DTB)
|
||||
|
||||
|
||||
CREATE_SIM_OBJECT(DTB)
|
||||
{
|
||||
return new DTB(getInstanceName(), size);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("SparcDTB", DTB)
|
||||
}
|
||||
|
|
|
@ -31,57 +31,127 @@
|
|||
#ifndef __ARCH_SPARC_TLB_HH__
|
||||
#define __ARCH_SPARC_TLB_HH__
|
||||
|
||||
#include "arch/sparc/tlb_map.hh"
|
||||
#include "base/misc.hh"
|
||||
#include "mem/request.hh"
|
||||
#include "sim/faults.hh"
|
||||
#include "sim/sim_object.hh"
|
||||
|
||||
class ThreadContext;
|
||||
class Packet;
|
||||
|
||||
namespace SparcISA
|
||||
{
|
||||
const int PAddrImplBits = 40;
|
||||
const Addr PAddrImplMask = (ULL(1) << PAddrImplBits) - 1;
|
||||
|
||||
class TLB : public SimObject
|
||||
{
|
||||
public:
|
||||
TLB(const std::string &name, int size) : SimObject(name)
|
||||
{
|
||||
}
|
||||
class TLB : public SimObject
|
||||
{
|
||||
protected:
|
||||
TlbMap lookupTable;;
|
||||
typedef TlbMap::iterator MapIter;
|
||||
|
||||
TlbEntry *tlb;
|
||||
|
||||
int size;
|
||||
int usedEntries;
|
||||
|
||||
enum FaultTypes {
|
||||
OtherFault = 0,
|
||||
PrivViolation = 0x1,
|
||||
SideEffect = 0x2,
|
||||
AtomicToIo = 0x4,
|
||||
IllegalAsi = 0x8,
|
||||
LoadFromNfo = 0x10,
|
||||
VaOutOfRange = 0x20,
|
||||
VaOutOfRangeJmp = 0x40
|
||||
};
|
||||
|
||||
class ITB : public TLB
|
||||
{
|
||||
public:
|
||||
ITB(const std::string &name, int size) : TLB(name, size)
|
||||
{
|
||||
}
|
||||
|
||||
Fault translate(RequestPtr &req, ThreadContext *tc) const
|
||||
{
|
||||
//For now, always assume the address is already physical.
|
||||
//Also assume that there are 40 bits of physical address space.
|
||||
req->setPaddr(req->getVaddr() & PAddrImplMask);
|
||||
return NoFault;
|
||||
}
|
||||
enum ContextType {
|
||||
Primary = 0,
|
||||
Secondary = 1,
|
||||
Nucleus = 2
|
||||
};
|
||||
|
||||
class DTB : public TLB
|
||||
{
|
||||
public:
|
||||
DTB(const std::string &name, int size) : TLB(name, size)
|
||||
{
|
||||
}
|
||||
|
||||
Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const
|
||||
{
|
||||
//For now, always assume the address is already physical.
|
||||
//Also assume that there are 40 bits of physical address space.
|
||||
req->setPaddr(req->getVaddr() & ((1ULL << 40) - 1));
|
||||
return NoFault;
|
||||
}
|
||||
};
|
||||
/** lookup an entry in the TLB based on the partition id, and real bit if
|
||||
* real is true or the partition id, and context id if real is false.
|
||||
* @param va the virtual address not shifted (e.g. bottom 13 bits are 0)
|
||||
* @param paritition_id partition this entry is for
|
||||
* @param real is this a real->phys or virt->phys translation
|
||||
* @param context_id if this is virt->phys what context
|
||||
* @return A pointer to a tlb entry
|
||||
*/
|
||||
TlbEntry *lookup(Addr va, int partition_id, bool real, int context_id = 0);
|
||||
|
||||
/** Insert a PTE into the TLB. */
|
||||
void insert(Addr vpn, int partition_id, int context_id, bool real,
|
||||
const PageTableEntry& PTE);
|
||||
|
||||
/** Given an entry id, read that tlb entries' tag. */
|
||||
uint64_t TagRead(int entry);
|
||||
|
||||
/** Give an entry id, read that tlb entries' tte */
|
||||
uint64_t TteRead(int entry);
|
||||
|
||||
/** Remove all entries from the TLB */
|
||||
void invalidateAll();
|
||||
|
||||
/** Remove all non-locked entries from the tlb that match partition id. */
|
||||
void demapAll(int partition_id);
|
||||
|
||||
/** Remove all entries that match a given context/partition id. */
|
||||
void demapContext(int partition_id, int context_id);
|
||||
|
||||
/** Remve all entries that match a certain partition id, (contextid), and
|
||||
* va). */
|
||||
void demapPage(Addr va, int partition_id, bool real, int context_id);
|
||||
|
||||
/** Checks if the virtual address provided is a valid one. */
|
||||
bool validVirtualAddress(Addr va, bool am);
|
||||
|
||||
void writeSfsr(ThreadContext *tc, int reg, bool write, ContextType ct,
|
||||
bool se, FaultTypes ft, int asi);
|
||||
|
||||
void TLB::clearUsedBits();
|
||||
|
||||
|
||||
public:
|
||||
TLB(const std::string &name, int size);
|
||||
|
||||
// Checkpointing
|
||||
virtual void serialize(std::ostream &os);
|
||||
virtual void unserialize(Checkpoint *cp, const std::string §ion);
|
||||
};
|
||||
|
||||
class ITB : public TLB
|
||||
{
|
||||
public:
|
||||
ITB(const std::string &name, int size) : TLB(name, size)
|
||||
{
|
||||
}
|
||||
|
||||
Fault translate(RequestPtr &req, ThreadContext *tc);
|
||||
private:
|
||||
void writeSfsr(ThreadContext *tc, bool write, ContextType ct,
|
||||
bool se, FaultTypes ft, int asi);
|
||||
};
|
||||
|
||||
class DTB : public TLB
|
||||
{
|
||||
public:
|
||||
DTB(const std::string &name, int size) : TLB(name, size)
|
||||
{
|
||||
}
|
||||
|
||||
Fault translate(RequestPtr &req, ThreadContext *tc, bool write);
|
||||
Tick doMmuRegRead(ThreadContext *tc, Packet *pkt);
|
||||
Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt);
|
||||
|
||||
private:
|
||||
void writeSfr(ThreadContext *tc, Addr a, bool write, ContextType ct,
|
||||
bool se, FaultTypes ft, int asi);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __ARCH_SPARC_TLB_HH__
|
||||
|
|
135
src/arch/sparc/tlb_map.hh
Normal file
135
src/arch/sparc/tlb_map.hh
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (c) 2006 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: Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_SPARC_TLB_MAP_HH__
|
||||
#define __ARCH_SPARC_TLB_MAP_HH__
|
||||
|
||||
#include "arch/sparc/pagetable.hh"
|
||||
#include <map>
|
||||
|
||||
namespace SparcISA
|
||||
{
|
||||
|
||||
class TlbMap
|
||||
{
|
||||
private:
|
||||
typedef std::map<TlbRange, TlbEntry*> RangeMap;
|
||||
RangeMap tree;
|
||||
|
||||
public:
|
||||
typedef RangeMap::iterator iterator;
|
||||
|
||||
iterator find(const TlbRange &r)
|
||||
{
|
||||
iterator i;
|
||||
|
||||
i = tree.upper_bound(r);
|
||||
|
||||
if (i == tree.begin())
|
||||
// Nothing could match, so return end()
|
||||
return tree.end();
|
||||
|
||||
i--;
|
||||
|
||||
if (r.real != i->first.real)
|
||||
return tree.end();
|
||||
if (!r.real && r.contextId != i->first.contextId)
|
||||
return tree.end();
|
||||
if (r.partitionId != i->first.partitionId)
|
||||
return tree.end();
|
||||
if (i->first.va <= r.va+r.size &&
|
||||
i->first.va+i->first.size >= r.va)
|
||||
return i;
|
||||
|
||||
return tree.end();
|
||||
}
|
||||
|
||||
bool intersect(const TlbRange &r)
|
||||
{
|
||||
iterator i;
|
||||
i = find(r);
|
||||
if (i != tree.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
iterator insert(TlbRange &r, TlbEntry *d)
|
||||
{
|
||||
if (intersect(r))
|
||||
return tree.end();
|
||||
|
||||
return tree.insert(std::make_pair<TlbRange,TlbEntry*>(r, d)).first;
|
||||
}
|
||||
|
||||
size_t erase(TlbRange k)
|
||||
{
|
||||
return tree.erase(k);
|
||||
}
|
||||
|
||||
void erase(iterator p)
|
||||
{
|
||||
tree.erase(p);
|
||||
}
|
||||
|
||||
void erase(iterator p, iterator q)
|
||||
{
|
||||
tree.erase(p,q);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
tree.erase(tree.begin(), tree.end());
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return tree.begin();
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return tree.end();
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return tree.size();
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
return tree.empty();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif // __ARCH_SPARC_TLB_MAP_HH__
|
|
@ -33,6 +33,7 @@
|
|||
#define __ARCH_SPARC_VTOPHYS_H__
|
||||
|
||||
#include "arch/sparc/isa_traits.hh"
|
||||
#include "arch/sparc/pagetable.hh"
|
||||
|
||||
class ThreadContext;
|
||||
class FunctionalPort;
|
||||
|
|
129
src/base/range_map.hh
Normal file
129
src/base/range_map.hh
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright (c) 2006 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: Ali Saidi
|
||||
*/
|
||||
|
||||
#ifndef __BASE_RANGE_MAP_HH__
|
||||
#define __BASE_RANGE_MAP_HH__
|
||||
|
||||
#include "base/range.hh"
|
||||
|
||||
#include <map>
|
||||
|
||||
template <class T,class V>
|
||||
class range_map
|
||||
{
|
||||
private:
|
||||
typedef std::map<Range<T>,V> RangeMap;
|
||||
RangeMap tree;
|
||||
|
||||
public:
|
||||
typedef typename RangeMap::iterator iterator;
|
||||
|
||||
template <class U>
|
||||
const iterator find(const Range<U> &r)
|
||||
{
|
||||
iterator i;
|
||||
|
||||
i = tree.upper_bound(r);
|
||||
|
||||
if (i == tree.begin())
|
||||
// Nothing could match, so return end()
|
||||
return tree.end();
|
||||
|
||||
i--;
|
||||
|
||||
if (i->first.start <= r.end && i->first.end >= r.start)
|
||||
return i;
|
||||
|
||||
return tree.end();
|
||||
}
|
||||
|
||||
template <class U>
|
||||
bool intersect(const Range<U> &r)
|
||||
{
|
||||
iterator i;
|
||||
i = find(r);
|
||||
if (i != tree.end())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
template <class U,class W>
|
||||
iterator insert(const Range<U> &r, const W d)
|
||||
{
|
||||
if (intersect(r))
|
||||
return tree.end();
|
||||
|
||||
return tree.insert(std::make_pair<Range<T>,V>(r, d)).first;
|
||||
}
|
||||
|
||||
size_t erase(T k)
|
||||
{
|
||||
return tree.erase(k);
|
||||
}
|
||||
|
||||
void erase(iterator p)
|
||||
{
|
||||
tree.erase(p);
|
||||
}
|
||||
|
||||
void erase(iterator p, iterator q)
|
||||
{
|
||||
tree.erase(p,q);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
tree.erase(tree.begin(), tree.end());
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return tree.begin();
|
||||
}
|
||||
|
||||
iterator end()
|
||||
{
|
||||
return tree.end();
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return tree.size();
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
return tree.empty();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif //__BASE_RANGE_MAP_HH__
|
|
@ -29,6 +29,7 @@
|
|||
*/
|
||||
|
||||
#include "arch/locked_mem.hh"
|
||||
#include "arch/mmaped_ipr.hh"
|
||||
#include "arch/utility.hh"
|
||||
#include "cpu/exetrace.hh"
|
||||
#include "cpu/simple/atomic.hh"
|
||||
|
@ -289,7 +290,10 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
|
|||
if (fault == NoFault) {
|
||||
pkt->reinitFromRequest();
|
||||
|
||||
dcache_latency = dcachePort.sendAtomic(pkt);
|
||||
if (req->isMmapedIpr())
|
||||
dcache_latency = TheISA::handleIprRead(thread->getTC(),pkt);
|
||||
else
|
||||
dcache_latency = dcachePort.sendAtomic(pkt);
|
||||
dcache_access = true;
|
||||
|
||||
assert(pkt->result == Packet::Success);
|
||||
|
@ -376,11 +380,15 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
|
|||
}
|
||||
|
||||
if (do_access) {
|
||||
data = htog(data);
|
||||
pkt->reinitFromRequest();
|
||||
pkt->dataStatic(&data);
|
||||
|
||||
dcache_latency = dcachePort.sendAtomic(pkt);
|
||||
if (req->isMmapedIpr()) {
|
||||
dcache_latency = TheISA::handleIprWrite(thread->getTC(), pkt);
|
||||
} else {
|
||||
data = htog(data);
|
||||
dcache_latency = dcachePort.sendAtomic(pkt);
|
||||
}
|
||||
dcache_access = true;
|
||||
|
||||
assert(pkt->result == Packet::Success);
|
||||
|
|
|
@ -49,26 +49,28 @@ class Request;
|
|||
typedef Request* RequestPtr;
|
||||
|
||||
|
||||
/** ASI information for this request if it exsits. */
|
||||
const uint32_t ASI_BITS = 0x000FF;
|
||||
/** The request is a Load locked/store conditional. */
|
||||
const unsigned LOCKED = 0x001;
|
||||
const uint32_t LOCKED = 0x00100;
|
||||
/** The virtual address is also the physical address. */
|
||||
const unsigned PHYSICAL = 0x002;
|
||||
const uint32_t PHYSICAL = 0x00200;
|
||||
/** The request is an ALPHA VPTE pal access (hw_ld). */
|
||||
const unsigned VPTE = 0x004;
|
||||
const uint32_t VPTE = 0x00400;
|
||||
/** Use the alternate mode bits in ALPHA. */
|
||||
const unsigned ALTMODE = 0x008;
|
||||
const uint32_t ALTMODE = 0x00800;
|
||||
/** The request is to an uncacheable address. */
|
||||
const unsigned UNCACHEABLE = 0x010;
|
||||
const uint32_t UNCACHEABLE = 0x01000;
|
||||
/** The request should not cause a page fault. */
|
||||
const unsigned NO_FAULT = 0x020;
|
||||
const uint32_t NO_FAULT = 0x02000;
|
||||
/** The request should be prefetched into the exclusive state. */
|
||||
const unsigned PF_EXCLUSIVE = 0x100;
|
||||
const uint32_t PF_EXCLUSIVE = 0x10000;
|
||||
/** The request should be marked as LRU. */
|
||||
const unsigned EVICT_NEXT = 0x200;
|
||||
const uint32_t EVICT_NEXT = 0x20000;
|
||||
/** The request should ignore unaligned access faults */
|
||||
const unsigned NO_ALIGN_FAULT = 0x400;
|
||||
const uint32_t NO_ALIGN_FAULT = 0x40000;
|
||||
/** The request was an instruction read. */
|
||||
const unsigned INST_READ = 0x800;
|
||||
const uint32_t INST_READ = 0x80000;
|
||||
|
||||
class Request
|
||||
{
|
||||
|
@ -95,6 +97,10 @@ class Request
|
|||
|
||||
/** The address space ID. */
|
||||
int asid;
|
||||
|
||||
/** This request is to a memory mapped register. */
|
||||
bool mmapedIpr;
|
||||
|
||||
/** The virtual address of the request. */
|
||||
Addr vaddr;
|
||||
|
||||
|
@ -164,6 +170,7 @@ class Request
|
|||
validAsidVaddr = false;
|
||||
validPC = false;
|
||||
validScResult = false;
|
||||
mmapedIpr = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -181,6 +188,7 @@ class Request
|
|||
validAsidVaddr = true;
|
||||
validPC = true;
|
||||
validScResult = false;
|
||||
mmapedIpr = false;
|
||||
}
|
||||
|
||||
/** Set just the physical address. This should only be used to
|
||||
|
@ -215,6 +223,19 @@ class Request
|
|||
/** Accessor function for asid.*/
|
||||
int getAsid() { assert(validAsidVaddr); return asid; }
|
||||
|
||||
/** Accessor function for asi.*/
|
||||
uint8_t getAsi() { assert(validAsidVaddr); return flags & ASI_BITS; }
|
||||
|
||||
/** Accessor function for asi.*/
|
||||
void setAsi(uint8_t a)
|
||||
{ assert(validAsidVaddr); flags = (flags & ~ASI_BITS) | a; }
|
||||
|
||||
/** Accessor function for asi.*/
|
||||
bool isMmapedIpr() { assert(validPaddr); return mmapedIpr; }
|
||||
|
||||
/** Accessor function for asi.*/
|
||||
void setMmapedIpr(bool r) { assert(validPaddr); mmapedIpr = r; }
|
||||
|
||||
/** Accessor function to check if sc result is valid. */
|
||||
bool scResultValid() { return validScResult; }
|
||||
/** Accessor function for store conditional return value.*/
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
/** uint64_t constant */
|
||||
#define ULL(N) ((uint64_t)N##ULL)
|
||||
/** int64_t constant */
|
||||
#define LL(N) (((int64_t)N##LL)
|
||||
#define LL(N) ((int64_t)N##LL)
|
||||
|
||||
/** Statistics counter type. Not much excuse for not using a 64-bit
|
||||
* integer here, but if you're desperate and only run short
|
||||
|
|
63
src/unittest/rangemaptest.cc
Normal file
63
src/unittest/rangemaptest.cc
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2006 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: Ali Saidi
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include "sim/host.hh"
|
||||
#include "base/range_map.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
range_map<Addr,int> r;
|
||||
|
||||
range_map<Addr,int>::iterator i;
|
||||
|
||||
i = r.insert(RangeIn<Addr>(0,40),5);
|
||||
assert(i != r.end());
|
||||
i = r.insert(RangeIn<Addr>(60,90),3);
|
||||
assert(i != r.end());
|
||||
|
||||
i = r.find(RangeIn(20,30));
|
||||
assert(i != r.end());
|
||||
cout << i->first << " " << i->second << endl;
|
||||
|
||||
i = r.find(RangeIn(55,55));
|
||||
assert(i == r.end());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue