summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2006-11-29 17:34:20 -0500
committerGabe Black <gblack@eecs.umich.edu>2006-11-29 17:34:20 -0500
commit5bdf4400b223056d296ae27f4a7ee2f707a4d1bd (patch)
treeff29e4424fe411d28b82ab653baa86a7f86ed18b
parentf2daf210f1cac2dd0a102b9d796fb700d4be92d1 (diff)
parent544f4b4d8156c1b7f779a2dd974cbff6a5b67c20 (diff)
downloadgem5-5bdf4400b223056d296ae27f4a7ee2f707a4d1bd.tar.xz
Merge zizzer:/bk/sparcfs
into zower.eecs.umich.edu:/eecshome/m5/newmemmid src/arch/sparc/isa_traits.hh: src/arch/sparc/miscregfile.hh: hand merge --HG-- extra : convert_revision : 34f50dc5e6e22096cb2c08b5888f2b0fcd418f3e
-rw-r--r--RELEASE_NOTES16
-rw-r--r--SConstruct2
-rw-r--r--configs/common/Simulation.py3
-rw-r--r--src/SConscript1
-rw-r--r--src/arch/SConscript1
-rw-r--r--src/arch/alpha/mmaped_ipr.hh61
-rw-r--r--src/arch/mips/mmaped_ipr.hh61
-rw-r--r--src/arch/sparc/SConscript1
-rw-r--r--src/arch/sparc/asi.cc94
-rw-r--r--src/arch/sparc/asi.hh108
-rw-r--r--src/arch/sparc/isa_traits.hh29
-rw-r--r--src/arch/sparc/miscregfile.cc253
-rw-r--r--src/arch/sparc/miscregfile.hh72
-rw-r--r--src/arch/sparc/mmaped_ipr.hh63
-rw-r--r--src/arch/sparc/pagetable.cc69
-rw-r--r--src/arch/sparc/pagetable.hh194
-rw-r--r--src/arch/sparc/regfile.hh4
-rw-r--r--src/arch/sparc/tlb.cc559
-rw-r--r--src/arch/sparc/tlb.hh142
-rw-r--r--src/arch/sparc/tlb_map.hh135
-rw-r--r--src/arch/sparc/vtophys.hh1
-rw-r--r--src/base/range_map.hh129
-rw-r--r--src/cpu/o3/cpu.cc8
-rwxr-xr-xsrc/cpu/o3/thread_context.hh2
-rwxr-xr-xsrc/cpu/o3/thread_context_impl.hh6
-rw-r--r--src/cpu/simple/atomic.cc24
-rw-r--r--src/cpu/simple/timing.cc10
-rw-r--r--src/cpu/thread_context.hh4
-rw-r--r--src/cpu/thread_state.cc16
-rw-r--r--src/cpu/thread_state.hh6
-rw-r--r--src/mem/cache/coherence/uni_coherence.cc4
-rw-r--r--src/mem/request.hh41
-rw-r--r--src/sim/host.hh2
-rw-r--r--src/unittest/rangemaptest.cc63
34 files changed, 1966 insertions, 218 deletions
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
index 39086de89..03eec3aab 100644
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -1,3 +1,19 @@
+Nov. 28, 2006: m5_2.0_beta2
+--------------------
+Bug fixes since beta 1:
+1. Many cache issues resolved
+2. Uni-coherence fixes in full-system
+3. LL/SC Support
+4. Draining/Switchover
+5. Functional Accesses
+6. Bus now has real timing
+7. Single config file fro all SpecCPU2000 benchmarks
+8. Several other minor bug fixes and enhancements
+
+Outstading issues for 2.0 release:
+1. Simulator performance fixes for memory system/caches
+2. Multiprocessor linux boot using the detailed O3 CPU model
+
Aug. 25, 2006: m5_2.0_beta patch 1
--------------------
Handful of minor bug fixes for m5_2.0_beta,
diff --git a/SConstruct b/SConstruct
index d8851f091..50ca2d6e4 100644
--- a/SConstruct
+++ b/SConstruct
@@ -344,7 +344,7 @@ sticky_opts.AddOptions(
# values (more than one value) not to be able to be restored from
# a saved option file. If this causes trouble then upgrade to
# scons 0.96.90 or later.
- ListOption('CPU_MODELS', 'CPU models', 'AtomicSimpleCPU,TimingSimpleCPU',
+ ListOption('CPU_MODELS', 'CPU models', 'AtomicSimpleCPU,TimingSimpleCPU,O3CPU',
env['ALL_CPU_LIST']),
BoolOption('ALPHA_TLASER',
'Model Alpha TurboLaser platform (vs. Tsunami)', False),
diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py
index 374ff3fc2..e037d0343 100644
--- a/configs/common/Simulation.py
+++ b/configs/common/Simulation.py
@@ -39,6 +39,9 @@ def setCPUClass(options):
if options.timing:
TmpClass = TimingSimpleCPU
elif options.detailed:
+ if not options.caches:
+ print "O3 CPU must be used with caches"
+ sys.exit(1)
TmpClass = DerivO3CPU
else:
TmpClass = AtomicSimpleCPU
diff --git a/src/SConscript b/src/SConscript
index 9d54174ab..429e1bee1 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -333,6 +333,7 @@ makeEnv('fast', '.fo', strip = True,
# Profiled binary
makeEnv('prof', '.po',
CCFLAGS = Split('-O3 -g -pg'),
+ CPPDEFINES = ['NDEBUG', 'TRACING_ON=0'],
LINKFLAGS = '-pg')
Return('envList')
diff --git a/src/arch/SConscript b/src/arch/SConscript
index bbe3c4e3a..74be5f8d1 100644
--- a/src/arch/SConscript
+++ b/src/arch/SConscript
@@ -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
diff --git a/src/arch/alpha/mmaped_ipr.hh b/src/arch/alpha/mmaped_ipr.hh
new file mode 100644
index 000000000..2b4ba8745
--- /dev/null
+++ b/src/arch/alpha/mmaped_ipr.hh
@@ -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
diff --git a/src/arch/mips/mmaped_ipr.hh b/src/arch/mips/mmaped_ipr.hh
new file mode 100644
index 000000000..041c76fdc
--- /dev/null
+++ b/src/arch/mips/mmaped_ipr.hh
@@ -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
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript
index 281c166c0..a0a6112de 100644
--- a/src/arch/sparc/SConscript
+++ b/src/arch/sparc/SConscript
@@ -56,6 +56,7 @@ base_sources = Split('''
full_system_sources = Split('''
arguments.cc
remote_gdb.cc
+ pagetable.cc
stacktrace.cc
system.cc
tlb.cc
diff --git a/src/arch/sparc/asi.cc b/src/arch/sparc/asi.cc
index 00c9e041e..14e581e43 100644
--- a/src/arch/sparc/asi.cc
+++ b/src/arch/sparc/asi.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)
+ bool AsiIsMmu(ASI asi)
{
- return
- (asi == ASI_DTLB_DATA_IN_REG) ||
- (asi == ASI_DTLB_DATA_ACCESS_REG) ||
- (asi == ASI_DTLB_TAG_READ_REG);
+ 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 AsiIsMmu(ASI asi)
+ bool AsiIsUnPriv(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 >= 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);
+ }
+
}
diff --git a/src/arch/sparc/asi.hh b/src/arch/sparc/asi.hh
index 6677b23df..a0d667cf3 100644
--- a/src/arch/sparc/asi.hh
+++ b/src/arch/sparc/asi.hh
@@ -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);
};
diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh
index 287f90658..2bd7ccf3b 100644
--- a/src/arch/sparc/isa_traits.hh
+++ b/src/arch/sparc/isa_traits.hh
@@ -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__
@@ -39,10 +40,6 @@ class StaticInstPtr;
namespace BigEndianGuest {}
-#if FULL_SYSTEM
-#include "arch/sparc/isa_fullsys_traits.hh"
-#endif
-
namespace SparcISA
{
class RegFile;
@@ -94,6 +91,30 @@ namespace SparcISA
const int BranchPredAddrShiftAmt = 2;
StaticInstPtr decodeInst(ExtMachInst);
+
+#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__
diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc
index 7b0939c29..d2164155f 100644
--- a/src/arch/sparc/miscregfile.cc
+++ b/src/arch/sparc/miscregfile.cc
@@ -102,8 +102,32 @@ void MiscRegFile::clear()
//This is set this way in Legion for some reason
strandStatusReg = 0x50000;
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)
@@ -187,6 +211,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);
}
@@ -333,35 +420,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)
{
@@ -383,11 +530,9 @@ void MiscRegFile::setRegWithEffect(int miscReg,
break;
case MISCREG_PSTATE:
pstate = val & PSTATE_MASK;
- setImplicitAsis();
return;
case MISCREG_TL:
tl = val;
- setImplicitAsis();
return;
case MISCREG_CWP:
tc->changeRegFileContext(CONTEXT_CWP, val);
@@ -490,8 +635,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)
@@ -521,12 +686,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
diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh
index 6bc04b583..90d7229e0 100644
--- a/src/arch/sparc/miscregfile.hh
+++ b/src/arch/sparc/miscregfile.hh
@@ -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"
@@ -93,6 +92,40 @@ namespace SparcISA
/** Floating Point Status Register */
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
MISCREG_NUMMISCREGS
};
@@ -150,8 +183,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
@@ -192,14 +249,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);
@@ -213,7 +270,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();
};
}
diff --git a/src/arch/sparc/mmaped_ipr.hh b/src/arch/sparc/mmaped_ipr.hh
new file mode 100644
index 000000000..d87d127b0
--- /dev/null
+++ b/src/arch/sparc/mmaped_ipr.hh
@@ -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
diff --git a/src/arch/sparc/pagetable.cc b/src/arch/sparc/pagetable.cc
new file mode 100644
index 000000000..22130d41c
--- /dev/null
+++ b/src/arch/sparc/pagetable.cc
@@ -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 &section)
+{
+ 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};
+
+
+}
diff --git a/src/arch/sparc/pagetable.hh b/src/arch/sparc/pagetable.hh
new file mode 100644
index 000000000..21dbad0a3
--- /dev/null
+++ b/src/arch/sparc/pagetable.hh
@@ -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 &section);
+
+};
+
+
+}; // namespace SparcISA
+
+#endif // __ARCH_SPARC_PAGE_TABLE_HH__
+
diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh
index 9f33435f6..0a09d0f66 100644
--- a/src/arch/sparc/regfile.hh
+++ b/src/arch/sparc/regfile.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();
}
diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc
index 0b1a2ff5f..5fde4d36d 100644
--- a/src/arch/sparc/tlb.cc
+++ b/src/arch/sparc/tlb.cc
@@ -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.");
+
+ 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);
- Param<int> size;
+ 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;
+ }
- END_DECLARE_SIM_OBJECT_PARAMS(ITB)
+ // If the asi is unaligned trap
+ if (vaddr & 0x7) {
+ writeSfsr(tc, false, ct, false, OtherFault, asi);
+ return new MemAddressNotAligned;
+ }
- BEGIN_INIT_SIM_OBJECT_PARAMS(ITB)
+ if (addr_mask)
+ vaddr = vaddr & VAddrAMask;
- INIT_PARAM_DFLT(size, "TLB size", 48)
+ if (!validVirtualAddress(vaddr, addr_mask)) {
+ writeSfsr(tc, false, ct, false, VaOutOfRange, asi);
+ return new InstructionAccessException;
+ }
- END_INIT_SIM_OBJECT_PARAMS(ITB)
+ 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;
+ }
- CREATE_SIM_OBJECT(ITB)
- {
- return new ITB(getInstanceName(), size);
+ // were not priviledged accesing priv page
+ if (!priv && e->pte.priv()) {
+ writeSfsr(tc, false, ct, false, PrivViolation, asi);
+ return new InstructionAccessException;
}
- REGISTER_SIM_OBJECT("SparcITB", ITB)
+ req->setPaddr(e->pte.paddr() & ~e->pte.size() |
+ req->getVaddr() & e->pte.size());
+ return NoFault;
+}
- BEGIN_DECLARE_SIM_OBJECT_PARAMS(DTB)
- Param<int> size;
- END_DECLARE_SIM_OBJECT_PARAMS(DTB)
+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;
+ }
- BEGIN_INIT_SIM_OBJECT_PARAMS(DTB)
+ if (e->pte.sideffect())
+ req->setFlags(req->getFlags() | UNCACHEABLE);
- INIT_PARAM_DFLT(size, "TLB size", 64)
- END_INIT_SIM_OBJECT_PARAMS(DTB)
+ 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. */
- CREATE_SIM_OBJECT(DTB)
- {
- return new DTB(getInstanceName(), size);
+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 &section)
+{
+ 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)
+REGISTER_SIM_OBJECT("SparcDTB", DTB)
}
diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh
index 136103f44..2df4fe4c8 100644
--- a/src/arch/sparc/tlb.hh
+++ b/src/arch/sparc/tlb.hh
@@ -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
+
+ /** 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 &section);
+};
+
+class ITB : public TLB
+{
+ public:
+ ITB(const std::string &name, int size) : TLB(name, size)
{
- 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;
- }
- };
+ }
+
+ 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__
diff --git a/src/arch/sparc/tlb_map.hh b/src/arch/sparc/tlb_map.hh
new file mode 100644
index 000000000..226ef23a1
--- /dev/null
+++ b/src/arch/sparc/tlb_map.hh
@@ -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__
diff --git a/src/arch/sparc/vtophys.hh b/src/arch/sparc/vtophys.hh
index bf2b757d6..66679a565 100644
--- a/src/arch/sparc/vtophys.hh
+++ b/src/arch/sparc/vtophys.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;
diff --git a/src/base/range_map.hh b/src/base/range_map.hh
new file mode 100644
index 000000000..17ecb9290
--- /dev/null
+++ b/src/base/range_map.hh
@@ -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__
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index 3dc353a9f..a5a00015f 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -497,8 +497,6 @@ FullO3CPU<Impl>::init()
}
#if FULL_SYSTEM
- src_tc->init();
-
TheISA::initCPU(src_tc, src_tc->readCpuId());
#endif
}
@@ -554,6 +552,12 @@ template <class Impl>
void
FullO3CPU<Impl>::activateContext(int tid, int delay)
{
+#if FULL_SYSTEM
+ // Connect the ThreadContext's memory ports (Functional/Virtual
+ // Ports)
+ threadContexts[tid]->connectMemPorts();
+#endif
+
// Needs to set each stage to running as well.
if (delay){
DPRINTF(O3CPU, "[tid:%i]: Scheduling thread context to activate "
diff --git a/src/cpu/o3/thread_context.hh b/src/cpu/o3/thread_context.hh
index 031f36480..390569c3d 100755
--- a/src/cpu/o3/thread_context.hh
+++ b/src/cpu/o3/thread_context.hh
@@ -92,7 +92,7 @@ class O3ThreadContext : public ThreadContext
void delVirtPort(VirtualPort *vp);
- virtual void init() { thread->init(); }
+ virtual void connectMemPorts() { thread->connectMemPorts(); }
#else
virtual TranslatingPort *getMemPort() { return thread->getMemPort(); }
diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh
index 0180756e3..afebf294f 100755
--- a/src/cpu/o3/thread_context_impl.hh
+++ b/src/cpu/o3/thread_context_impl.hh
@@ -101,8 +101,10 @@ template <class Impl>
void
O3ThreadContext<Impl>::delVirtPort(VirtualPort *vp)
{
- delete vp->getPeer();
- delete vp;
+ if (vp != thread->getVirtPort()) {
+ delete vp->getPeer();
+ delete vp;
+ }
}
#endif
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index cd335e36d..67611e815 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -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"
@@ -77,9 +78,6 @@ AtomicSimpleCPU::init()
for (int i = 0; i < threadContexts.size(); ++i) {
ThreadContext *tc = threadContexts[i];
- // initialize the mem pointers
- tc->init();
-
// initialize CPU, including PC
TheISA::initCPU(tc, tc->readCpuId());
}
@@ -240,6 +238,13 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay)
assert(!tickEvent.scheduled());
notIdleFraction++;
+
+#if FULL_SYSTEM
+ // Connect the ThreadContext's memory ports (Functional/Virtual
+ // Ports)
+ tc->connectMemPorts();
+#endif
+
//Make sure ticks are still on multiples of cycles
tickEvent.schedule(nextCycle(curTick + cycles(delay)));
_status = Running;
@@ -285,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);
@@ -372,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);
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index aa23a00e8..dfffb0b1f 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -59,9 +59,6 @@ TimingSimpleCPU::init()
for (int i = 0; i < threadContexts.size(); ++i) {
ThreadContext *tc = threadContexts[i];
- // initialize the mem pointers
- tc->init();
-
// initialize CPU, including PC
TheISA::initCPU(tc, tc->readCpuId());
}
@@ -241,6 +238,13 @@ TimingSimpleCPU::activateContext(int thread_num, int delay)
notIdleFraction++;
_status = Running;
+
+#if FULL_SYSTEM
+ // Connect the ThreadContext's memory ports (Functional/Virtual
+ // Ports)
+ tc->connectMemPorts();
+#endif
+
// kick things off by initiating the fetch of the next instruction
fetchEvent =
new EventWrapper<TimingSimpleCPU, &TimingSimpleCPU::fetch>(this, false);
diff --git a/src/cpu/thread_context.hh b/src/cpu/thread_context.hh
index baeb7a8be..bb9cc9e16 100644
--- a/src/cpu/thread_context.hh
+++ b/src/cpu/thread_context.hh
@@ -134,7 +134,7 @@ class ThreadContext
virtual void delVirtPort(VirtualPort *vp) = 0;
- virtual void init() = 0;
+ virtual void connectMemPorts() = 0;
#else
virtual TranslatingPort *getMemPort() = 0;
@@ -308,7 +308,7 @@ class ProxyThreadContext : public ThreadContext
void delVirtPort(VirtualPort *vp) { return actualTC->delVirtPort(vp); }
- void init() {actualTC->init(); }
+ void connectMemPorts() { actualTC->connectMemPorts(); }
#else
TranslatingPort *getMemPort() { return actualTC->getMemPort(); }
diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc
index 9cac4fd26..93dd1e2eb 100644
--- a/src/cpu/thread_state.cc
+++ b/src/cpu/thread_state.cc
@@ -113,23 +113,29 @@ ThreadState::unserialize(Checkpoint *cp, const std::string &section)
#if FULL_SYSTEM
void
-ThreadState::init()
+ThreadState::connectMemPorts()
{
- initPhysPort();
- initVirtPort();
+ connectPhysPort();
+ connectVirtPort();
}
void
-ThreadState::initPhysPort()
+ThreadState::connectPhysPort()
{
+ // @todo: For now this disregards any older port that may have
+ // already existed. Fix this memory leak once the bus port IDs
+ // for functional ports is resolved.
physPort = new FunctionalPort(csprintf("%s-%d-funcport",
baseCpu->name(), tid));
connectToMemFunc(physPort);
}
void
-ThreadState::initVirtPort()
+ThreadState::connectVirtPort()
{
+ // @todo: For now this disregards any older port that may have
+ // already existed. Fix this memory leak once the bus port IDs
+ // for functional ports is resolved.
virtPort = new VirtualPort(csprintf("%s-%d-vport",
baseCpu->name(), tid));
connectToMemFunc(virtPort);
diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh
index 1844be8b7..4f878db1f 100644
--- a/src/cpu/thread_state.hh
+++ b/src/cpu/thread_state.hh
@@ -91,11 +91,11 @@ struct ThreadState {
Tick readLastSuspend() { return lastSuspend; }
#if FULL_SYSTEM
- void init();
+ void connectMemPorts();
- void initPhysPort();
+ void connectPhysPort();
- void initVirtPort();
+ void connectVirtPort();
void dumpFuncProfile();
diff --git a/src/mem/cache/coherence/uni_coherence.cc b/src/mem/cache/coherence/uni_coherence.cc
index 5813a0281..ea615d70a 100644
--- a/src/mem/cache/coherence/uni_coherence.cc
+++ b/src/mem/cache/coherence/uni_coherence.cc
@@ -94,10 +94,6 @@ UniCoherence::handleBusRequest(PacketPtr &pkt, CacheBlk *blk, MSHR *mshr,
bool
UniCoherence::propogateInvalidate(PacketPtr pkt, bool isTiming)
{
- //Make sure we don't snoop a write
- //we are expecting writeInvalidates on the snoop port of a uni-coherent cache
- assert(!(!pkt->isInvalidate() && pkt->isWrite()));
-
if (pkt->isInvalidate()) {
/* Temp Fix for now, forward all invalidates up as functional accesses */
if (isTiming) {
diff --git a/src/mem/request.hh b/src/mem/request.hh
index e54984fcd..b01c02441 100644
--- a/src/mem/request.hh
+++ b/src/mem/request.hh
@@ -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.*/
diff --git a/src/sim/host.hh b/src/sim/host.hh
index a2faa206b..8b1ddbfe7 100644
--- a/src/sim/host.hh
+++ b/src/sim/host.hh
@@ -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
diff --git a/src/unittest/rangemaptest.cc b/src/unittest/rangemaptest.cc
new file mode 100644
index 000000000..6fd99c927
--- /dev/null
+++ b/src/unittest/rangemaptest.cc
@@ -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());
+}
+
+
+
+
+
+
+
+