summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct16
-rw-r--r--configs/boot/mutex-test.rcS6
-rw-r--r--configs/common/Benchmarks.py2
-rw-r--r--configs/example/fs.py1
-rw-r--r--configs/example/memtest.py138
-rw-r--r--configs/splash2/run.py283
-rw-r--r--src/arch/alpha/faults.cc4
-rw-r--r--src/arch/alpha/isa/main.isa11
-rw-r--r--src/arch/alpha/isa/mem.isa10
-rw-r--r--src/arch/alpha/utility.hh7
-rwxr-xr-xsrc/arch/isa_parser.py18
-rw-r--r--src/arch/mips/isa/formats/mem.isa10
-rw-r--r--src/arch/mips/isa/includes.isa23
-rw-r--r--src/arch/mips/utility.hh7
-rw-r--r--src/arch/sparc/SConscript1
-rw-r--r--src/arch/sparc/asi.cc279
-rw-r--r--src/arch/sparc/asi.hh55
-rw-r--r--src/arch/sparc/isa/base.isa2
-rw-r--r--src/arch/sparc/isa/bitfields.isa4
-rw-r--r--src/arch/sparc/isa/decoder.isa312
-rw-r--r--src/arch/sparc/isa/formats.isa28
-rw-r--r--src/arch/sparc/isa/formats/basic.isa17
-rw-r--r--src/arch/sparc/isa/formats/branch.isa6
-rw-r--r--src/arch/sparc/isa/formats/formats.isa62
-rw-r--r--src/arch/sparc/isa/formats/integerop.isa12
-rw-r--r--src/arch/sparc/isa/formats/mem/basicmem.isa (renamed from src/arch/sparc/isa/formats/mem.isa)117
-rw-r--r--src/arch/sparc/isa/formats/mem/blockmem.isa337
-rw-r--r--src/arch/sparc/isa/formats/mem/mem.isa45
-rw-r--r--src/arch/sparc/isa/formats/mem/util.isa226
-rw-r--r--src/arch/sparc/isa/formats/micro.isa103
-rw-r--r--src/arch/sparc/isa/formats/priv.isa4
-rw-r--r--src/arch/sparc/isa/formats/unimp.isa147
-rw-r--r--src/arch/sparc/isa/includes.isa4
-rw-r--r--src/arch/sparc/isa/main.isa4
-rw-r--r--src/arch/sparc/isa/operands.isa34
-rw-r--r--src/arch/sparc/utility.hh17
-rw-r--r--src/base/bitfield.hh2
-rw-r--r--src/base/traceflags.py4
-rw-r--r--src/cpu/checker/cpu.cc8
-rw-r--r--src/cpu/checker/cpu_impl.hh6
-rw-r--r--src/cpu/exetrace.cc95
-rw-r--r--src/cpu/memtest/memtest.cc44
-rw-r--r--src/cpu/memtest/memtest.hh16
-rw-r--r--src/cpu/o3/alpha/dyn_inst.hh2
-rw-r--r--src/cpu/o3/alpha/dyn_inst_impl.hh2
-rw-r--r--src/cpu/o3/fetch.hh2
-rw-r--r--src/cpu/o3/fetch_impl.hh9
-rw-r--r--src/cpu/o3/lsq_impl.hh9
-rw-r--r--src/cpu/o3/lsq_unit.hh4
-rw-r--r--src/cpu/o3/lsq_unit_impl.hh2
-rwxr-xr-xsrc/cpu/o3/mips/dyn_inst.hh2
-rwxr-xr-xsrc/cpu/o3/mips/dyn_inst_impl.hh2
-rw-r--r--src/cpu/ozone/dyn_inst.hh2
-rw-r--r--src/cpu/ozone/dyn_inst_impl.hh2
-rw-r--r--src/cpu/ozone/front_end.hh2
-rw-r--r--src/cpu/ozone/front_end_impl.hh4
-rw-r--r--src/cpu/ozone/lw_lsq.hh4
-rw-r--r--src/cpu/ozone/lw_lsq_impl.hh2
-rw-r--r--src/cpu/quiesce_event.cc2
-rw-r--r--src/cpu/simple/atomic.cc18
-rw-r--r--src/cpu/simple/atomic.hh18
-rw-r--r--src/cpu/simple/base.cc52
-rw-r--r--src/cpu/simple/base.hh1
-rw-r--r--src/cpu/simple/timing.cc74
-rw-r--r--src/cpu/simple/timing.hh20
-rw-r--r--src/cpu/simple_thread.hh20
-rw-r--r--src/cpu/static_inst.cc7
-rw-r--r--src/cpu/static_inst.hh22
-rw-r--r--src/cpu/thread_state.cc4
-rw-r--r--src/cpu/thread_state.hh10
-rw-r--r--src/dev/alpha_console.cc6
-rw-r--r--src/dev/alpha_console.hh4
-rw-r--r--src/dev/baddev.cc4
-rw-r--r--src/dev/baddev.hh4
-rw-r--r--src/dev/i8254xGBe.cc6
-rw-r--r--src/dev/i8254xGBe.hh6
-rw-r--r--src/dev/ide_ctrl.cc9
-rw-r--r--src/dev/ide_ctrl.hh8
-rw-r--r--src/dev/io_device.cc10
-rw-r--r--src/dev/io_device.hh20
-rw-r--r--src/dev/isa_fake.cc6
-rw-r--r--src/dev/isa_fake.hh7
-rw-r--r--src/dev/ns_gige.cc7
-rw-r--r--src/dev/ns_gige.hh6
-rw-r--r--src/dev/pciconfigall.cc5
-rw-r--r--src/dev/pciconfigall.hh4
-rw-r--r--src/dev/pcidev.cc7
-rw-r--r--src/dev/pcidev.hh7
-rw-r--r--src/dev/sinic.cc5
-rw-r--r--src/dev/sinic.hh4
-rw-r--r--src/dev/tsunami_cchip.cc12
-rw-r--r--src/dev/tsunami_cchip.hh4
-rw-r--r--src/dev/tsunami_io.cc6
-rw-r--r--src/dev/tsunami_io.hh4
-rw-r--r--src/dev/tsunami_pchip.cc5
-rw-r--r--src/dev/tsunami_pchip.hh4
-rw-r--r--src/dev/uart8250.cc6
-rw-r--r--src/dev/uart8250.hh4
-rw-r--r--src/kern/linux/linux.hh4
-rw-r--r--src/kern/solaris/solaris.hh4
-rw-r--r--src/kern/tru64/tru64.hh69
-rw-r--r--src/mem/bridge.cc10
-rw-r--r--src/mem/bridge.hh14
-rw-r--r--src/mem/bus.cc17
-rw-r--r--src/mem/bus.hh18
-rw-r--r--src/mem/cache/base_cache.cc54
-rw-r--r--src/mem/cache/base_cache.hh36
-rw-r--r--src/mem/cache/cache.hh28
-rw-r--r--src/mem/cache/cache_blk.hh83
-rw-r--r--src/mem/cache/cache_impl.hh323
-rw-r--r--src/mem/cache/coherence/coherence_protocol.cc277
-rw-r--r--src/mem/cache/coherence/coherence_protocol.hh42
-rw-r--r--src/mem/cache/coherence/simple_coherence.hh14
-rw-r--r--src/mem/cache/coherence/uni_coherence.cc48
-rw-r--r--src/mem/cache/coherence/uni_coherence.hh10
-rw-r--r--src/mem/cache/miss/blocking_buffer.cc20
-rw-r--r--src/mem/cache/miss/blocking_buffer.hh18
-rw-r--r--src/mem/cache/miss/miss_queue.cc28
-rw-r--r--src/mem/cache/miss/miss_queue.hh22
-rw-r--r--src/mem/cache/miss/mshr.cc8
-rw-r--r--src/mem/cache/miss/mshr.hh14
-rw-r--r--src/mem/cache/miss/mshr_queue.cc10
-rw-r--r--src/mem/cache/miss/mshr_queue.hh10
-rw-r--r--src/mem/cache/prefetch/base_prefetcher.cc14
-rw-r--r--src/mem/cache/prefetch/base_prefetcher.hh12
-rw-r--r--src/mem/cache/prefetch/ghb_prefetcher.hh2
-rw-r--r--src/mem/cache/prefetch/stride_prefetcher.hh2
-rw-r--r--src/mem/cache/prefetch/tagged_prefetcher.hh2
-rw-r--r--src/mem/cache/prefetch/tagged_prefetcher_impl.hh2
-rw-r--r--src/mem/cache/tags/fa_lru.cc4
-rw-r--r--src/mem/cache/tags/fa_lru.hh4
-rw-r--r--src/mem/cache/tags/iic.cc8
-rw-r--r--src/mem/cache/tags/iic.hh4
-rw-r--r--src/mem/cache/tags/lru.cc5
-rw-r--r--src/mem/cache/tags/lru.hh4
-rw-r--r--src/mem/cache/tags/split.cc4
-rw-r--r--src/mem/cache/tags/split.hh4
-rw-r--r--src/mem/cache/tags/split_lifo.cc4
-rw-r--r--src/mem/cache/tags/split_lifo.hh4
-rw-r--r--src/mem/cache/tags/split_lru.cc4
-rw-r--r--src/mem/cache/tags/split_lru.hh4
-rw-r--r--src/mem/dram.cc2
-rw-r--r--src/mem/dram.hh2
-rw-r--r--src/mem/packet.cc12
-rw-r--r--src/mem/packet.hh145
-rw-r--r--src/mem/packet_access.hh62
-rw-r--r--src/mem/page_table.cc13
-rw-r--r--src/mem/physical.cc16
-rw-r--r--src/mem/physical.hh8
-rw-r--r--src/mem/port.cc1
-rw-r--r--src/mem/port.hh18
-rw-r--r--src/mem/tport.cc17
-rw-r--r--src/mem/tport.hh12
-rw-r--r--src/python/m5/objects/MemTest.py1
-rw-r--r--src/sim/eventq.hh22
-rw-r--r--src/sim/faults.cc2
-rw-r--r--src/sim/main.cc6
-rw-r--r--src/sim/pseudo_inst.cc20
-rw-r--r--src/sim/syscall_emul.hh8
-rw-r--r--tests/configs/memtest.py6
-rw-r--r--tests/quick/00.hello/ref/sparc/linux/simple-timing/config.ini236
-rw-r--r--tests/quick/00.hello/ref/sparc/linux/simple-timing/config.out227
-rw-r--r--tests/quick/00.hello/ref/sparc/linux/simple-timing/m5stats.txt214
-rw-r--r--tests/quick/00.hello/ref/sparc/linux/simple-timing/stderr3
-rw-r--r--tests/quick/00.hello/ref/sparc/linux/simple-timing/stdout12
-rw-r--r--util/statetrace/arch/tracechild_sparc.cc172
-rw-r--r--util/statetrace/arch/tracechild_sparc.hh8
-rw-r--r--util/term/term.c283
-rwxr-xr-xutil/tracediff62
169 files changed, 4323 insertions, 1540 deletions
diff --git a/SConstruct b/SConstruct
index 50089700a..dac4d137c 100644
--- a/SConstruct
+++ b/SConstruct
@@ -347,7 +347,10 @@ sticky_opts.AddOptions(
('CC', 'C compiler', os.environ.get('CC', env['CC'])),
('CXX', 'C++ compiler', os.environ.get('CXX', env['CXX'])),
BoolOption('BATCH', 'Use batch pool for build and tests', False),
- ('BATCH_CMD', 'Batch pool submission command name', 'qdo')
+ ('BATCH_CMD', 'Batch pool submission command name', 'qdo'),
+ ('PYTHONHOME',
+ 'Override the default PYTHONHOME for this system (use with caution)',
+ '%s:%s' % (sys.prefix, sys.exec_prefix))
)
# Non-sticky options only apply to the current build.
@@ -359,7 +362,7 @@ nonsticky_opts.AddOptions(
# These options get exported to #defines in config/*.hh (see src/SConscript).
env.ExportOptions = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
'USE_MYSQL', 'NO_FAST_ALLOC', 'SS_COMPATIBLE_FP', \
- 'USE_CHECKER']
+ 'USE_CHECKER', 'PYTHONHOME']
# Define a handy 'no-op' action
def no_action(target, source, env):
@@ -399,8 +402,13 @@ def config_emitter(target, source, env):
option = str(target[0])
# True target is config header file
target = os.path.join('config', option.lower() + '.hh')
- # Force value to 0/1 even if it's a Python bool
- val = int(eval(str(env[option])))
+ val = env[option]
+ if isinstance(val, bool):
+ # Force value to 0/1
+ val = int(val)
+ elif isinstance(val, str):
+ val = '"' + val + '"'
+
# Sources are option name & value (packaged in SCons Value nodes)
return ([target], [Value(option), Value(val)])
diff --git a/configs/boot/mutex-test.rcS b/configs/boot/mutex-test.rcS
new file mode 100644
index 000000000..acf875368
--- /dev/null
+++ b/configs/boot/mutex-test.rcS
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+cd /benchmarks/tests
+/sbin/m5 resetstats
+./pthread_mutex_test 4 10000
+/sbin/m5 exit
diff --git a/configs/common/Benchmarks.py b/configs/common/Benchmarks.py
index 1f272517a..eda0e80f9 100644
--- a/configs/common/Benchmarks.py
+++ b/configs/common/Benchmarks.py
@@ -97,6 +97,8 @@ Benchmarks = {
'ValStreamScale': [SysConfig('micro_streamscale.rcS', '512MB')],
'ValStreamCopy': [SysConfig('micro_streamcopy.rcS', '512MB')],
+ 'MutexTest': [SysConfig('mutex-test.rcS', '128MB')],
+
'bnAn': [SysConfig('/z/saidi/work/m5.newmem.head/configs/boot/bn-app.rcS',
'128MB', '/z/saidi/work/bottleneck/bnimg.img')]
}
diff --git a/configs/example/fs.py b/configs/example/fs.py
index 3573c47ac..11b82178b 100644
--- a/configs/example/fs.py
+++ b/configs/example/fs.py
@@ -95,6 +95,7 @@ class MyCache(BaseCache):
latency = 1
mshrs = 10
tgts_per_mshr = 5
+ protocol = CoherenceProtocol(protocol='moesi')
# driver system CPU is always simple... note this is an assignment of
# a class, not an instance.
diff --git a/configs/example/memtest.py b/configs/example/memtest.py
new file mode 100644
index 000000000..141ecfd8e
--- /dev/null
+++ b/configs/example/memtest.py
@@ -0,0 +1,138 @@
+# 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: Ron Dreslinski
+
+import m5
+from m5.objects import *
+import os, optparse, sys
+m5.AddToPath('../common')
+
+parser = optparse.OptionParser()
+
+parser.add_option("--caches", action="store_true")
+parser.add_option("-t", "--timing", action="store_true")
+parser.add_option("-m", "--maxtick", type="int")
+parser.add_option("-l", "--maxloads", default = "1000000000000", type="int")
+parser.add_option("-n", "--numtesters", default = "8", type="int")
+parser.add_option("-p", "--protocol",
+ default="moesi",
+ help="The coherence protocol to use for the L1'a (i.e. MOESI, MOSI)")
+
+(options, args) = parser.parse_args()
+
+if args:
+ print "Error: script doesn't take any positional arguments"
+ sys.exit(1)
+
+# --------------------
+# Base L1 Cache
+# ====================
+
+class L1(BaseCache):
+ latency = 1
+ block_size = 64
+ mshrs = 12
+ tgts_per_mshr = 8
+ protocol = CoherenceProtocol(protocol=options.protocol)
+
+# ----------------------
+# Base L2 Cache
+# ----------------------
+
+class L2(BaseCache):
+ block_size = 64
+ latency = 10
+ mshrs = 92
+ tgts_per_mshr = 16
+ write_buffers = 8
+
+#MAX CORES IS 8 with the false sharing method
+if options.numtesters > 8:
+ print "Error: NUmber of testers limited to 8 because of false sharing"
+ sys,exit(1)
+
+if options.timing:
+ cpus = [ MemTest(atomic=False, max_loads=options.maxloads, percent_functional=50,
+ percent_uncacheable=10, progress_interval=1000)
+ for i in xrange(options.numtesters) ]
+else:
+ cpus = [ MemTest(atomic=True, max_loads=options.maxloads, percent_functional=50,
+ percent_uncacheable=10, progress_interval=1000)
+ for i in xrange(options.numtesters) ]
+# system simulated
+system = System(cpu = cpus, funcmem = PhysicalMemory(),
+ physmem = PhysicalMemory(latency = "50ps"), membus = Bus(clock="500GHz", width=16))
+
+# l2cache & bus
+if options.caches:
+ system.toL2Bus = Bus(clock="500GHz", width=16)
+ system.l2c = L2(size='64kB', assoc=8)
+ system.l2c.cpu_side = system.toL2Bus.port
+
+ # connect l2c to membus
+ system.l2c.mem_side = system.membus.port
+
+which_port = 0
+# add L1 caches
+for cpu in cpus:
+ if options.caches:
+ cpu.l1c = L1(size = '32kB', assoc = 4)
+ cpu.test = cpu.l1c.cpu_side
+ cpu.l1c.mem_side = system.toL2Bus.port
+ else:
+ cpu.test = system.membus.port
+ if which_port == 0:
+ system.funcmem.port = cpu.functional
+ which_port = 1
+ else:
+ system.funcmem.functional = cpu.functional
+
+
+# connect memory to membus
+system.physmem.port = system.membus.port
+
+
+# -----------------------
+# run simulation
+# -----------------------
+
+root = Root( system = system )
+if options.timing:
+ root.system.mem_mode = 'timing'
+else:
+ root.system.mem_mode = 'atomic'
+
+# instantiate configuration
+m5.instantiate(root)
+
+# simulate until program terminates
+if options.maxtick:
+ exit_event = m5.simulate(options.maxtick)
+else:
+ exit_event = m5.simulate()
+
+print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause()
diff --git a/configs/splash2/run.py b/configs/splash2/run.py
index ebbe14939..93b166d77 100644
--- a/configs/splash2/run.py
+++ b/configs/splash2/run.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2005 The Regents of The University of Michigan
+# Copyright (c) 2005-2006 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -26,54 +26,243 @@
#
# Authors: Ron Dreslinski
-from m5 import *
-import Splash2
-
-if 'SYSTEM' not in env:
- panic("The SYSTEM environment variable must be set!\ne.g -ESYSTEM=Detailed\n")
-
-if env['SYSTEM'] == 'Simple':
- from SimpleConfig import *
- BaseCPU.workload = Parent.workload
- SimpleStandAlone.cpu = [ CPU() for i in xrange(int(env['NP'])) ]
- root = SimpleStandAlone()
-elif env['SYSTEM'] == 'Detailed':
- from DetailedConfig import *
- BaseCPU.workload = Parent.workload
- DetailedStandAlone.cpu = [ DetailedCPU() for i in xrange(int(env['NP'])) ]
- root = DetailedStandAlone()
+# Splash2 Run Script
+#
+
+import m5
+from m5.objects import *
+import os, optparse, sys
+m5.AddToPath('../common')
+
+# --------------------
+# Define Command Line Options
+# ====================
+
+parser = optparse.OptionParser()
+
+parser.add_option("-d", "--detailed", action="store_true")
+parser.add_option("-t", "--timing", action="store_true")
+parser.add_option("-m", "--maxtick", type="int")
+parser.add_option("-n", "--numcpus",
+ help="Number of cpus in total", type="int")
+parser.add_option("-f", "--frequency",
+ default = "1GHz",
+ help="Frequency of each CPU")
+parser.add_option("-p", "--protocol",
+ default="moesi",
+ help="The coherence protocol to use for the L1'a (i.e. MOESI, MOSI)")
+parser.add_option("--l1size",
+ default = "32kB")
+parser.add_option("--l1latency",
+ default = 1)
+parser.add_option("--l2size",
+ default = "256kB")
+parser.add_option("--l2latency",
+ default = 10)
+parser.add_option("--rootdir",
+ help="ROot directory of Splash2",
+ default="/dist/splash2/codes")
+parser.add_option("-b", "--benchmark",
+ help="Splash 2 benchmark to run")
+
+(options, args) = parser.parse_args()
+
+if args:
+ print "Error: script doesn't take any positional arguments"
+ sys.exit(1)
+
+if not options.numcpus:
+ print "Specify the number of cpus with -n"
+ sys.exit(1)
+
+# --------------------
+# Define Splash2 Benchmarks
+# ====================
+class Cholesky(LiveProcess):
+ executable = options.rootdir + '/kernels/cholesky/CHOLESKY'
+ cmd = 'CHOLESKY -p' + str(options.numcpus) + ' '\
+ + options.rootdir + '/kernels/cholesky/inputs/tk23.O'
+
+class FFT(LiveProcess):
+ executable = options.rootdir + '/kernels/fft/FFT'
+ cmd = 'FFT -p' + str(options.numcpus) + ' -m18'
+
+class LU_contig(LiveProcess):
+ executable = options.rootdir + '/kernels/lu/contiguous_blocks/LU'
+ cmd = 'LU -p' + str(options.numcpus)
+
+class LU_noncontig(LiveProcess):
+ executable = options.rootdir + '/kernels/lu/non_contiguous_blocks/LU'
+ cmd = 'LU -p' + str(options.numcpus)
+
+class Radix(LiveProcess):
+ executable = options.rootdir + '/kernels/radix/RADIX'
+ cmd = 'RADIX -n524288 -p' + str(options.numcpus)
+
+class Barnes(LiveProcess):
+ executable = options.rootdir + '/apps/barnes/BARNES'
+ cmd = 'BARNES'
+ input = options.rootdir + '/apps/barnes/input.p' + str(options.numcpus)
+
+class FMM(LiveProcess):
+ executable = options.rootdir + '/apps/fmm/FMM'
+ cmd = 'FMM'
+ input = options.rootdir + '/apps/fmm/inputs/input.2048.p' + str(options.numcpus)
+
+class Ocean_contig(LiveProcess):
+ executable = options.rootdir + '/apps/ocean/contiguous_partitions/OCEAN'
+ cmd = 'OCEAN -p' + str(options.numcpus)
+
+class Ocean_noncontig(LiveProcess):
+ executable = options.rootdir + '/apps/ocean/non_contiguous_partitions/OCEAN'
+ cmd = 'OCEAN -p' + str(options.numcpus)
+
+class Raytrace(LiveProcess):
+ executable = options.rootdir + '/apps/raytrace/RAYTRACE'
+ cmd = 'RAYTRACE -p' + str(options.numcpus) + ' ' \
+ + options.rootdir + 'apps/raytrace/inputs/teapot.env'
+
+class Water_nsquared(LiveProcess):
+ executable = options.rootdir + '/apps/water-nsquared/WATER-NSQUARED'
+ cmd = 'WATER-NSQUARED'
+ input = options.rootdir + '/apps/water-nsquared/input.p' + str(options.numcpus)
+
+class Water_spatial(LiveProcess):
+ executable = options.rootdir + '/apps/water-spatial/WATER-SPATIAL'
+ cmd = 'WATER-SPATIAL'
+ input = options.rootdir + '/apps/water-spatial/input.p' + str(options.numcpus)
+
+
+# --------------------
+# Base L1 Cache Definition
+# ====================
+
+class L1(BaseCache):
+ latency = options.l1latency
+ block_size = 64
+ mshrs = 12
+ tgts_per_mshr = 8
+ protocol = CoherenceProtocol(protocol=options.protocol)
+
+# ----------------------
+# Base L2 Cache Definition
+# ----------------------
+
+class L2(BaseCache):
+ block_size = 64
+ latency = options.l2latency
+ mshrs = 92
+ tgts_per_mshr = 16
+ write_buffers = 8
+
+# ----------------------
+# Define the cpus
+# ----------------------
+
+busFrequency = Frequency(options.frequency)
+
+if options.timing:
+ cpus = [TimingSimpleCPU(cpu_id = i,
+ clock=options.frequency)
+ for i in xrange(options.numcpus)]
+elif options.detailed:
+ cpus = [DerivO3CPU(cpu_id = i,
+ clock=options.frequency)
+ for i in xrange(options.numcpus)]
else:
- panic("The SYSTEM environment variable was set to something improper.\n Use Simple or Detailed\n")
-
-if 'BENCHMARK' not in env:
- panic("The BENCHMARK environment variable must be set!\ne.g. -EBENCHMARK=Cholesky\n")
-
-if env['BENCHMARK'] == 'Cholesky':
- root.workload = Splash2.Cholesky()
-elif env['BENCHMARK'] == 'FFT':
- root.workload = Splash2.FFT()
-elif env['BENCHMARK'] == 'LUContig':
- root.workload = Splash2.LU_contig()
-elif env['BENCHMARK'] == 'LUNoncontig':
- root.workload = Splash2.LU_noncontig()
-elif env['BENCHMARK'] == 'Radix':
- root.workload = Splash2.Radix()
-elif env['BENCHMARK'] == 'Barnes':
- root.workload = Splash2.Barnes()
-elif env['BENCHMARK'] == 'FMM':
- root.workload = Splash2.FMM()
-elif env['BENCHMARK'] == 'OceanContig':
- root.workload = Splash2.Ocean_contig()
-elif env['BENCHMARK'] == 'OceanNoncontig':
- root.workload = Splash2.Ocean_noncontig()
-elif env['BENCHMARK'] == 'Raytrace':
- root.workload = Splash2.Raytrace()
-elif env['BENCHMARK'] == 'WaterNSquared':
- root.workload = Splash2.Water_nsquared()
-elif env['BENCHMARK'] == 'WaterSpatial':
- root.workload = Splash2.Water_spatial()
+ cpus = [AtomicSimpleCPU(cpu_id = i,
+ clock=options.frequency)
+ for i in xrange(options.numcpus)]
+
+# ----------------------
+# Create a system, and add system wide objects
+# ----------------------
+system = System(cpu = cpus, physmem = PhysicalMemory(),
+ membus = Bus(clock = busFrequency))
+
+system.toL2bus = Bus(clock = busFrequency)
+system.l2 = L2(size = options.l2size, assoc = 8)
+
+# ----------------------
+# Connect the L2 cache and memory together
+# ----------------------
+
+system.physmem.port = system.membus.port
+system.l2.cpu_side = system.toL2bus.port
+system.l2.mem_side = system.membus.port
+
+# ----------------------
+# Connect the L2 cache and clusters together
+# ----------------------
+for cpu in cpus:
+ cpu.addPrivateSplitL1Caches(L1(size = options.l1size, assoc = 1),
+ L1(size = options.l1size, assoc = 4))
+ cpu.mem = cpu.dcache
+ # connect cpu level-1 caches to shared level-2 cache
+ cpu.connectMemPorts(system.toL2bus)
+
+
+# ----------------------
+# Define the root
+# ----------------------
+
+root = Root(system = system)
+
+# --------------------
+# Pick the correct Splash2 Benchmarks
+# ====================
+if options.benchmark == 'Cholesky':
+ root.workload = Cholesky()
+elif options.benchmark == 'FFT':
+ root.workload = FFT()
+elif options.benchmark == 'LUContig':
+ root.workload = LU_contig()
+elif options.benchmark == 'LUNoncontig':
+ root.workload = LU_noncontig()
+elif options.benchmark == 'Radix':
+ root.workload = Radix()
+elif options.benchmark == 'Barnes':
+ root.workload = Barnes()
+elif options.benchmark == 'FMM':
+ root.workload = FMM()
+elif options.benchmark == 'OceanContig':
+ root.workload = Ocean_contig()
+elif options.benchmark == 'OceanNoncontig':
+ root.workload = Ocean_noncontig()
+elif options.benchmark == 'Raytrace':
+ root.workload = Raytrace()
+elif options.benchmark == 'WaterNSquared':
+ root.workload = Water_nsquared()
+elif options.benchmark == 'WaterSpatial':
+ root.workload = Water_spatial()
else:
- panic("The BENCHMARK environment variable was set to something" \
+ panic("The --benchmark environment variable was set to something" \
+" improper.\nUse Cholesky, FFT, LUContig, LUNoncontig, Radix" \
+", Barnes, FMM, OceanContig,\nOceanNoncontig, Raytrace," \
+" WaterNSquared, or WaterSpatial\n")
+
+# --------------------
+# Assign the workload to the cpus
+# ====================
+
+for cpu in cpus:
+ cpu.workload = root.workload
+
+# ----------------------
+# Run the simulation
+# ----------------------
+
+if options.timing or options.detailed:
+ root.system.mem_mode = 'timing'
+
+# instantiate configuration
+m5.instantiate(root)
+
+# simulate until program terminates
+if options.maxtick:
+ exit_event = m5.simulate(options.maxtick)
+else:
+ exit_event = m5.simulate()
+
+print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause()
+
diff --git a/src/arch/alpha/faults.cc b/src/arch/alpha/faults.cc
index eef4361fd..7179bf025 100644
--- a/src/arch/alpha/faults.cc
+++ b/src/arch/alpha/faults.cc
@@ -194,7 +194,8 @@ void PageTableFault::invoke(ThreadContext *tc)
// We've accessed the next page
if (vaddr > p->stack_min - PageBytes) {
- warn("Increasing stack %#x:%#x to %#x:%#x because of access to %#x",
+ DPRINTF(Stack,
+ "Increasing stack %#x:%#x to %#x:%#x because of access to %#x",
p->stack_min, p->stack_base, p->stack_min - PageBytes,
p->stack_base, vaddr);
p->stack_min -= PageBytes;
@@ -202,6 +203,7 @@ void PageTableFault::invoke(ThreadContext *tc)
fatal("Over max stack size for one thread\n");
p->pTable->allocate(p->stack_min, PageBytes);
} else {
+ warn("Page fault on address %#x\n", vaddr);
FaultBase::invoke(tc);
}
}
diff --git a/src/arch/alpha/isa/main.isa b/src/arch/alpha/isa/main.isa
index 1270bf8d8..2024b1117 100644
--- a/src/arch/alpha/isa/main.isa
+++ b/src/arch/alpha/isa/main.isa
@@ -45,20 +45,22 @@ output header {{
#include <iostream>
#include <iomanip>
+#include "arch/alpha/faults.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/static_inst.hh"
-#include "arch/alpha/faults.hh"
#include "mem/request.hh" // some constructors use MemReq flags
+#include "mem/packet.hh"
}};
output decoder {{
+#include <cmath>
+
#include "base/cprintf.hh"
#include "base/fenv.hh"
#include "base/loader/symtab.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/thread_context.hh" // for Jump::branchTarget()
-
-#include <math.h>
+#include "mem/packet.hh"
using namespace AlphaISA;
}};
@@ -73,8 +75,9 @@ output exec {{
#include "config/ss_compatible_fp.hh"
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/sim_exit.hh"
-#include "mem/packet_impl.hh"
using namespace AlphaISA;
}};
diff --git a/src/arch/alpha/isa/mem.isa b/src/arch/alpha/isa/mem.isa
index fe69c36a5..02291ed6b 100644
--- a/src/arch/alpha/isa/mem.isa
+++ b/src/arch/alpha/isa/mem.isa
@@ -186,7 +186,7 @@ def template InitiateAccDeclare {{
def template CompleteAccDeclare {{
- Fault completeAcc(Packet *, %(CPU_exec_context)s *,
+ Fault completeAcc(PacketPtr, %(CPU_exec_context)s *,
Trace::InstRecord *) const;
}};
@@ -313,7 +313,7 @@ def template LoadInitiateAcc {{
def template LoadCompleteAcc {{
- Fault %(class_name)s::completeAcc(Packet *pkt,
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@@ -437,7 +437,7 @@ def template StoreInitiateAcc {{
def template StoreCompleteAcc {{
- Fault %(class_name)s::completeAcc(Packet *pkt,
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@@ -460,7 +460,7 @@ def template StoreCompleteAcc {{
def template StoreCondCompleteAcc {{
- Fault %(class_name)s::completeAcc(Packet *pkt,
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@@ -535,7 +535,7 @@ def template MiscInitiateAcc {{
def template MiscCompleteAcc {{
- Fault %(class_name)s::completeAcc(Packet *pkt,
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
diff --git a/src/arch/alpha/utility.hh b/src/arch/alpha/utility.hh
index d3ccc0444..0304d1c3a 100644
--- a/src/arch/alpha/utility.hh
+++ b/src/arch/alpha/utility.hh
@@ -37,16 +37,17 @@
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/regfile.hh"
#include "base/misc.hh"
+#include "cpu/thread_context.hh"
namespace AlphaISA
{
static inline ExtMachInst
- makeExtMI(MachInst inst, const uint64_t &pc) {
+ makeExtMI(MachInst inst, ThreadContext * xc) {
#if FULL_SYSTEM
ExtMachInst ext_inst = inst;
- if (pc && 0x1)
- return ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
+ if (xc->readPC() && 0x1)
+ return ext_inst|=(static_cast<ExtMachInst>(xc->readPC() & 0x1) << 32);
else
return ext_inst;
#else
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py
index 4d522e18a..b235398f1 100755
--- a/src/arch/isa_parser.py
+++ b/src/arch/isa_parser.py
@@ -1636,7 +1636,7 @@ opClassRE = re.compile(r'.*Op|No_OpClass')
class InstObjParams:
def __init__(self, mnem, class_name, base_class = '',
- code = None, opt_args = [], *extras):
+ code = None, opt_args = [], extras = {}):
self.mnemonic = mnem
self.class_name = class_name
self.base_class = base_class
@@ -1648,13 +1648,23 @@ class InstObjParams:
else:
origCode = code
codeBlock = CodeBlock(code)
- compositeCode = '\n'.join([origCode] +
- [pair[1] for pair in extras])
+ stringExtras = {}
+ otherExtras = {}
+ for (k, v) in extras.items():
+ if type(v) == str:
+ stringExtras[k] = v
+ else:
+ otherExtras[k] = v
+ compositeCode = "\n".join([origCode] + stringExtras.values())
+ # compositeCode = '\n'.join([origCode] +
+ # [pair[1] for pair in extras])
compositeBlock = CodeBlock(compositeCode)
for code_attr in compositeBlock.__dict__.keys():
setattr(self, code_attr, getattr(compositeBlock, code_attr))
- for (key, snippet) in extras:
+ for (key, snippet) in stringExtras.items():
setattr(self, key, CodeBlock(snippet).code)
+ for (key, item) in otherExtras.items():
+ setattr(self, key, item)
self.code = codeBlock.code
self.orig_code = origCode
else:
diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa
index d6b0c2938..e786cfbe2 100644
--- a/src/arch/mips/isa/formats/mem.isa
+++ b/src/arch/mips/isa/formats/mem.isa
@@ -162,7 +162,7 @@ def template InitiateAccDeclare {{
def template CompleteAccDeclare {{
- Fault completeAcc(Packet *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+ Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
@@ -288,7 +288,7 @@ def template LoadInitiateAcc {{
def template LoadCompleteAcc {{
- Fault %(class_name)s::completeAcc(Packet *pkt,
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@@ -412,7 +412,7 @@ def template StoreInitiateAcc {{
def template StoreCompleteAcc {{
- Fault %(class_name)s::completeAcc(Packet *pkt,
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@@ -434,7 +434,7 @@ def template StoreCompleteAcc {{
}};
def template StoreCondCompleteAcc {{
- Fault %(class_name)s::completeAcc(Packet *pkt,
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@@ -509,7 +509,7 @@ def template MiscInitiateAcc {{
def template MiscCompleteAcc {{
- Fault %(class_name)s::completeAcc(Packet *pkt,
+ Fault %(class_name)s::completeAcc(PacketPtr pkt,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
diff --git a/src/arch/mips/isa/includes.isa b/src/arch/mips/isa/includes.isa
index f58c8adaa..274fdcaa1 100644
--- a/src/arch/mips/isa/includes.isa
+++ b/src/arch/mips/isa/includes.isa
@@ -38,23 +38,25 @@ output header {{
#include <iostream>
#include <iomanip>
-#include "cpu/static_inst.hh"
#include "arch/mips/isa_traits.hh"
+#include "cpu/static_inst.hh"
+#include "mem/packet.hh"
}};
output decoder {{
+#include <cmath>
+#if defined(linux)
+#include <fenv.h>
+#endif
+
+#include "arch/mips/faults.hh"
+#include "arch/mips/isa_traits.hh"
+#include "arch/mips/isa_traits.hh"
#include "arch/mips/isa_traits.hh"
+#include "arch/mips/utility.hh"
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "cpu/thread_context.hh"
-#include "arch/mips/faults.hh"
-#include "arch/mips/isa_traits.hh"
-#include "arch/mips/utility.hh"
-
-#include <math.h>
-#if defined(linux)
-#include <fenv.h>
-#endif
using namespace MipsISA;
}};
@@ -74,8 +76,9 @@ output exec {{
#endif
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/sim_exit.hh"
-#include "mem/packet_impl.hh"
using namespace MipsISA;
}};
diff --git a/src/arch/mips/utility.hh b/src/arch/mips/utility.hh
index ae2fe1aea..56689ba4d 100644
--- a/src/arch/mips/utility.hh
+++ b/src/arch/mips/utility.hh
@@ -35,6 +35,7 @@
#include "arch/mips/types.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
+#include "cpu/thread_context.hh"
//XXX This is needed for size_t. We should use something other than size_t
//#include "kern/linux/linux.hh"
#include "sim/host.hh"
@@ -86,11 +87,11 @@ namespace MipsISA {
}
static inline ExtMachInst
- makeExtMI(MachInst inst, const uint64_t &pc) {
+ makeExtMI(MachInst inst, ThreadContext * xc) {
#if FULL_SYSTEM
ExtMachInst ext_inst = inst;
- if (pc && 0x1)
- return ext_inst|=(static_cast<ExtMachInst>(pc & 0x1) << 32);
+ if (xc->readPC() && 0x1)
+ return ext_inst|=(static_cast<ExtMachInst>(xc->readPC() & 0x1) << 32);
else
return ext_inst;
#else
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript
index 66f2b57e0..e317502e0 100644
--- a/src/arch/sparc/SConscript
+++ b/src/arch/sparc/SConscript
@@ -44,6 +44,7 @@ Import('env')
# Base sources used by all configurations.
base_sources = Split('''
+ asi.cc
faults.cc
floatregfile.cc
intregfile.cc
diff --git a/src/arch/sparc/asi.cc b/src/arch/sparc/asi.cc
new file mode 100644
index 000000000..00c9e041e
--- /dev/null
+++ b/src/arch/sparc/asi.cc
@@ -0,0 +1,279 @@
+/*
+ * 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: Gabe Black
+ */
+
+#include "arch/sparc/asi.hh"
+
+namespace SparcISA
+{
+ bool AsiIsBlock(ASI asi)
+ {
+ return
+ (asi == ASI_BLK_AIUP) ||
+ (asi == ASI_BLK_AIUS) ||
+ (asi == ASI_BLK_AIUPL) ||
+ (asi == ASI_BLK_AIUSL) ||
+ (asi == ASI_BLK_P) ||
+ (asi == ASI_BLK_S) ||
+ (asi == ASI_BLK_PL) ||
+ (asi == ASI_BLK_SL);
+ }
+
+ bool AsiIsPrimary(ASI asi)
+ {
+ return
+ (asi == ASI_AIUP) ||
+ (asi == ASI_BLK_AIUP) ||
+ (asi == ASI_AIUPL) ||
+ (asi == ASI_BLK_AIUPL) ||
+ (asi == ASI_LDTX_AIUP) ||
+ (asi == ASI_LDTX_AIUPL) ||
+ (asi == ASI_P) ||
+ (asi == ASI_PNF) ||
+ (asi == ASI_PL) ||
+ (asi == ASI_PNFL) ||
+ (asi == ASI_PST8_P) ||
+ (asi == ASI_PST16_P) ||
+ (asi == ASI_PST32_P) ||
+ (asi == ASI_PST8_PL) ||
+ (asi == ASI_PST16_PL) ||
+ (asi == ASI_PST32_PL) ||
+ (asi == ASI_FL8_P) ||
+ (asi == ASI_FL16_P) ||
+ (asi == ASI_FL8_PL) ||
+ (asi == ASI_FL16_PL) ||
+ (asi == ASI_LDTX_P) ||
+ (asi == ASI_LDTX_PL) ||
+ (asi == ASI_BLK_P) ||
+ (asi == ASI_BLK_PL);
+ }
+
+ bool AsiIsSecondary(ASI asi)
+ {
+ return
+ (asi == ASI_AIUS) ||
+ (asi == ASI_BLK_AIUS) ||
+ (asi == ASI_AIUSL) ||
+ (asi == ASI_BLK_AIUSL) ||
+ (asi == ASI_LDTX_AIUS) ||
+ (asi == ASI_LDTX_AIUSL) ||
+ (asi == ASI_S) ||
+ (asi == ASI_SNF) ||
+ (asi == ASI_SL) ||
+ (asi == ASI_SNFL) ||
+ (asi == ASI_PST8_S) ||
+ (asi == ASI_PST16_S) ||
+ (asi == ASI_PST32_S) ||
+ (asi == ASI_PST8_SL) ||
+ (asi == ASI_PST16_SL) ||
+ (asi == ASI_PST32_SL) ||
+ (asi == ASI_FL8_S) ||
+ (asi == ASI_FL16_S) ||
+ (asi == ASI_FL8_SL) ||
+ (asi == ASI_FL16_SL) ||
+ (asi == ASI_LDTX_S) ||
+ (asi == ASI_LDTX_SL) ||
+ (asi == ASI_BLK_S) ||
+ (asi == ASI_BLK_SL);
+ }
+
+ bool AsiNucleus(ASI asi)
+ {
+ return
+ (asi == ASI_N) ||
+ (asi == ASI_NL) ||
+ (asi == ASI_LDTX_N) ||
+ (asi == ASI_LDTX_NL);
+ }
+
+ bool AsiIsAsIfUser(ASI asi)
+ {
+ return
+ (asi == ASI_AIUP) ||
+ (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_LDTX_AIUP) ||
+ (asi == ASI_LDTX_AIUS) ||
+ (asi == ASI_LDTX_AIUPL) ||
+ (asi == ASI_LDTX_AIUSL);
+ }
+
+ bool AsiIsIO(ASI asi)
+ {
+ return
+ (asi == ASI_REAL_IO) ||
+ (asi == ASI_REAL_IO_L);
+ }
+
+ bool AsiIsReal(ASI asi)
+ {
+ return
+ (asi == ASI_REAL) ||
+ (asi == ASI_REAL_IO) ||
+ (asi == ASI_REAL_L) ||
+ (asi == ASI_REAL_IO_L) ||
+ (asi == ASI_LDTX_REAL) ||
+ (asi == ASI_LDTX_REAL_L) ||
+ (asi == ASI_MMU_REAL);
+ }
+
+ bool AsiIsLittle(ASI asi)
+ {
+ return
+ (asi == ASI_NL) ||
+ (asi == ASI_AIUPL) ||
+ (asi == ASI_AIUSL) ||
+ (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_LDTX_REAL_L) ||
+ (asi == ASI_LDTX_NL) ||
+ (asi == ASI_PL) ||
+ (asi == ASI_SL) ||
+ (asi == ASI_PNFL) ||
+ (asi == ASI_SNFL) ||
+ (asi == ASI_PST8_PL) ||
+ (asi == ASI_PST8_SL) ||
+ (asi == ASI_PST16_PL) ||
+ (asi == ASI_PST16_SL) ||
+ (asi == ASI_PST32_PL) ||
+ (asi == ASI_PST32_SL) ||
+ (asi == ASI_FL8_PL) ||
+ (asi == ASI_FL8_SL) ||
+ (asi == ASI_FL16_PL) ||
+ (asi == ASI_FL16_SL) ||
+ (asi == ASI_LDTX_PL) ||
+ (asi == ASI_LDTX_SL) ||
+ (asi == ASI_BLK_PL) ||
+ (asi == ASI_BLK_SL);
+ }
+
+ bool AsiIsTwin(ASI asi)
+ {
+ return
+ (asi == ASI_LDTX_AIUP) ||
+ (asi == ASI_LDTX_AIUS) ||
+ (asi == ASI_LDTX_REAL) ||
+ (asi == ASI_LDTX_N) ||
+ (asi == ASI_LDTX_AIUPL) ||
+ (asi == ASI_LDTX_AIUSL) ||
+ (asi == ASI_LDTX_REAL_L) ||
+ (asi == ASI_LDTX_NL) ||
+ (asi == ASI_LDTX_P) ||
+ (asi == ASI_LDTX_S) ||
+ (asi == ASI_LDTX_PL) ||
+ (asi == ASI_LDTX_SL);
+ }
+
+ bool AsiIsPartialStore(ASI asi)
+ {
+ return
+ (asi == ASI_PST8_P) ||
+ (asi == ASI_PST8_S) ||
+ (asi == ASI_PST16_P) ||
+ (asi == ASI_PST16_S) ||
+ (asi == ASI_PST32_P) ||
+ (asi == ASI_PST32_S) ||
+ (asi == ASI_PST8_PL) ||
+ (asi == ASI_PST8_SL) ||
+ (asi == ASI_PST16_PL) ||
+ (asi == ASI_PST16_SL) ||
+ (asi == ASI_PST32_PL) ||
+ (asi == ASI_PST32_SL);
+ }
+
+ bool AsiIsFloatingLoad(ASI asi)
+ {
+ return
+ (asi == ASI_FL8_P) ||
+ (asi == ASI_FL8_S) ||
+ (asi == ASI_FL16_P) ||
+ (asi == ASI_FL16_S) ||
+ (asi == ASI_FL8_PL) ||
+ (asi == ASI_FL8_SL) ||
+ (asi == ASI_FL16_PL) ||
+ (asi == ASI_FL16_SL);
+ }
+
+ bool AsiIsNoFault(ASI asi)
+ {
+ return
+ (asi == ASI_PNF) ||
+ (asi == ASI_SNF) ||
+ (asi == ASI_PNFL) ||
+ (asi == ASI_SNFL);
+ }
+
+ bool AsiIsScratchPad(ASI asi)
+ {
+ return
+ (asi == ASI_SCRATCHPAD) ||
+ (asi == ASI_HYP_SCRATCHPAD);
+ }
+
+ bool AsiIsCmt(ASI asi)
+ {
+ return
+ (asi == ASI_CMT_PER_STRAND) ||
+ (asi == ASI_CMT_SHARED);
+ }
+
+ bool AsiIsQueue(ASI asi)
+ {
+ 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);
+ }
+}
diff --git a/src/arch/sparc/asi.hh b/src/arch/sparc/asi.hh
index 482e077e0..876567225 100644
--- a/src/arch/sparc/asi.hh
+++ b/src/arch/sparc/asi.hh
@@ -156,23 +156,23 @@ namespace SparcISA
ASI_PST32_SL = 0xCD,
ASI_PST32_SECONDARY_LITTLE = ASI_PST32_SL,
//0xCE-0xCF implementation dependent
- ASI_PL8_P = 0xD0,
- ASI_PL8_PRIMARY = ASI_PL8_P,
- ASI_PL8_S = 0xD1,
- ASI_PL8_SECONDARY = ASI_PL8_S,
- ASI_PL16_P = 0xD2,
- ASI_PL16_PRIMARY = ASI_PL16_P,
- ASI_PL16_S = 0xD3,
- ASI_PL16_SECONDARY = ASI_PL16_S,
+ ASI_FL8_P = 0xD0,
+ ASI_FL8_PRIMARY = ASI_FL8_P,
+ ASI_FL8_S = 0xD1,
+ ASI_FL8_SECONDARY = ASI_FL8_S,
+ ASI_FL16_P = 0xD2,
+ ASI_FL16_PRIMARY = ASI_FL16_P,
+ ASI_FL16_S = 0xD3,
+ ASI_FL16_SECONDARY = ASI_FL16_S,
//0xD4-0xD7 implementation dependent
- ASI_PL8_PL = 0xD8,
- ASI_PL8_PRIMARY_LITTLE = ASI_PL8_PL,
- ASI_PL8_SL = 0xD9,
- ASI_PL8_SECONDARY_LITTLE = ASI_PL8_SL,
- ASI_PL16_PL = 0xDA,
- ASI_PL16_PRIMARY_LITTLE = ASI_PL16_PL,
- ASI_PL16_SL = 0xDB,
- ASI_PL16_SECONDARY_LITTLE = ASI_PL16_SL,
+ ASI_FL8_PL = 0xD8,
+ ASI_FL8_PRIMARY_LITTLE = ASI_FL8_PL,
+ ASI_FL8_SL = 0xD9,
+ ASI_FL8_SECONDARY_LITTLE = ASI_FL8_SL,
+ ASI_FL16_PL = 0xDA,
+ ASI_FL16_PRIMARY_LITTLE = ASI_FL16_PL,
+ ASI_FL16_SL = 0xDB,
+ ASI_FL16_SECONDARY_LITTLE = ASI_FL16_SL,
//0xDC-0xDF implementation dependent
//0xE0-0xE1 reserved
ASI_LDTX_P = 0xE2,
@@ -193,9 +193,30 @@ namespace SparcISA
ASI_BLK_PL = 0xF8,
ASI_BLOCK_PRIMARY_LITTLE = ASI_BLK_PL,
ASI_BLK_SL = 0xF9,
- ASI_BLOCK_SECONDARY_LITTLE = ASI_BLK_SL
+ ASI_BLOCK_SECONDARY_LITTLE = ASI_BLK_SL,
//0xFA-0xFF implementation dependent
+ MAX_ASI = 0xFF
};
+
+ //Functions that classify an asi
+ bool AsiIsBlock(ASI);
+ bool AsiIsPrimary(ASI);
+ bool AsiIsSecondary(ASI);
+ bool AsiIsNucleus(ASI);
+ bool AsiIsAsIfUser(ASI);
+ bool AsiIsIO(ASI);
+ bool AsiIsReal(ASI);
+ bool AsiIsLittle(ASI);
+ bool AsiIsTwin(ASI);
+ bool AsiIsPartialStore(ASI);
+ bool AsiIsFloatingLoad(ASI);
+ bool AsiIsNoFault(ASI);
+ bool AsiIsScratchPad(ASI);
+ bool AsiIsCmt(ASI);
+ bool AsiIsQueue(ASI);
+ bool AsiIsDtlb(ASI);
+ bool AsiIsMmu(ASI);
+
};
#endif // __ARCH_SPARC_TLB_HH__
diff --git a/src/arch/sparc/isa/base.isa b/src/arch/sparc/isa/base.isa
index b518265aa..a4c022411 100644
--- a/src/arch/sparc/isa/base.isa
+++ b/src/arch/sparc/isa/base.isa
@@ -77,7 +77,7 @@ output header {{
protected:
// Constructor.
SparcStaticInst(const char *mnem,
- MachInst _machInst, OpClass __opClass)
+ ExtMachInst _machInst, OpClass __opClass)
: StaticInst(mnem, _machInst, __opClass)
{
}
diff --git a/src/arch/sparc/isa/bitfields.isa b/src/arch/sparc/isa/bitfields.isa
index 27f52fa29..372f5c4ef 100644
--- a/src/arch/sparc/isa/bitfields.isa
+++ b/src/arch/sparc/isa/bitfields.isa
@@ -76,3 +76,7 @@ def bitfield SIMM11 <10:0>;
def bitfield SIMM13 <12:0>;
def bitfield SW_TRAP <7:0>;
def bitfield X <12>;
+
+// Extended bitfields which aren't part of the actual instruction.
+
+def bitfield EXT_ASI <39:32>;
diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa
index 1384b21a0..45d3616d9 100644
--- a/src/arch/sparc/isa/decoder.isa
+++ b/src/arch/sparc/isa/decoder.isa
@@ -441,7 +441,7 @@ decode OP default Unknown::unknown()
0x34: decode OPF{
format BasicOperate{
0x01: fmovs({{
- Frd.uw = Frs2.uw;
+ Frds.uw = Frs2s.uw;
//fsr.ftt = fsr.cexc = 0
Fsr &= ~(7 << 14);
Fsr &= ~(0x1F);
@@ -454,7 +454,7 @@ decode OP default Unknown::unknown()
}});
0x03: Trap::fmovq({{fault = new FpDisabled;}});
0x05: fnegs({{
- Frd.uw = Frs2.uw ^ (1UL << 31);
+ Frds.uw = Frs2s.uw ^ (1UL << 31);
//fsr.ftt = fsr.cexc = 0
Fsr &= ~(7 << 14);
Fsr &= ~(0x1F);
@@ -467,7 +467,7 @@ decode OP default Unknown::unknown()
}});
0x07: Trap::fnegq({{fault = new FpDisabled;}});
0x09: fabss({{
- Frd.uw = ((1UL << 31) - 1) & Frs2.uw;
+ Frds.uw = ((1UL << 31) - 1) & Frs2s.uw;
//fsr.ftt = fsr.cexc = 0
Fsr &= ~(7 << 14);
Fsr &= ~(0x1F);
@@ -479,55 +479,55 @@ decode OP default Unknown::unknown()
Fsr &= ~(0x1F);
}});
0x0B: Trap::fabsq({{fault = new FpDisabled;}});
- 0x29: fsqrts({{Frd.sf = sqrt(Frs2.sf);}});
+ 0x29: fsqrts({{Frds.sf = sqrt(Frs2s.sf);}});
0x2A: fsqrtd({{Frd.df = sqrt(Frs2.df);}});
0x2B: Trap::fsqrtq({{fault = new FpDisabled;}});
- 0x41: fadds({{Frd.sf = Frs1.sf + Frs2.sf;}});
+ 0x41: fadds({{Frds.sf = Frs1s.sf + Frs2s.sf;}});
0x42: faddd({{Frd.df = Frs1.df + Frs2.df;}});
0x43: Trap::faddq({{fault = new FpDisabled;}});
- 0x45: fsubs({{Frd.sf = Frs1.sf - Frs2.sf;}});
+ 0x45: fsubs({{Frds.sf = Frs1s.sf - Frs2s.sf;}});
0x46: fsubd({{Frd.df = Frs1.df - Frs2.df;}});
0x47: Trap::fsubq({{fault = new FpDisabled;}});
- 0x49: fmuls({{Frd.sf = Frs1.sf * Frs2.sf;}});
+ 0x49: fmuls({{Frds.sf = Frs1s.sf * Frs2s.sf;}});
0x4A: fmuld({{Frd.df = Frs1.df * Frs2.df;}});
0x4B: Trap::fmulq({{fault = new FpDisabled;}});
- 0x4D: fdivs({{Frd.sf = Frs1.sf / Frs2.sf;}});
+ 0x4D: fdivs({{Frds.sf = Frs1s.sf / Frs2s.sf;}});
0x4E: fdivd({{Frd.df = Frs1.df / Frs2.df;}});
0x4F: Trap::fdivq({{fault = new FpDisabled;}});
- 0x69: fsmuld({{Frd.df = Frs1.sf * Frs2.sf;}});
+ 0x69: fsmuld({{Frd.df = Frs1s.sf * Frs2s.sf;}});
0x6E: Trap::fdmulq({{fault = new FpDisabled;}});
0x81: fstox({{
- Frd.df = (double)static_cast<int64_t>(Frs2.sf);
+ Frd.df = (double)static_cast<int64_t>(Frs2s.sf);
}});
0x82: fdtox({{
Frd.df = (double)static_cast<int64_t>(Frs2.df);
}});
0x83: Trap::fqtox({{fault = new FpDisabled;}});
0x84: fxtos({{
- Frd.sf = static_cast<float>((int64_t)Frs2.df);
+ Frds.sf = static_cast<float>((int64_t)Frs2.df);
}});
0x88: fxtod({{
Frd.df = static_cast<double>((int64_t)Frs2.df);
}});
0x8C: Trap::fxtoq({{fault = new FpDisabled;}});
0xC4: fitos({{
- Frd.sf = static_cast<float>((int32_t)Frs2.sf);
+ Frds.sf = static_cast<float>((int32_t)Frs2s.sf);
}});
- 0xC6: fdtos({{Frd.sf = Frs2.df;}});
+ 0xC6: fdtos({{Frds.sf = Frs2.df;}});
0xC7: Trap::fqtos({{fault = new FpDisabled;}});
0xC8: fitod({{
- Frd.df = static_cast<double>((int32_t)Frs2.sf);
+ Frd.df = static_cast<double>((int32_t)Frs2s.sf);
}});
- 0xC9: fstod({{Frd.df = Frs2.sf;}});
+ 0xC9: fstod({{Frd.df = Frs2s.sf;}});
0xCB: Trap::fqtod({{fault = new FpDisabled;}});
0xCC: Trap::fitoq({{fault = new FpDisabled;}});
0xCD: Trap::fstoq({{fault = new FpDisabled;}});
0xCE: Trap::fdtoq({{fault = new FpDisabled;}});
0xD1: fstoi({{
- Frd.sf = (float)static_cast<int32_t>(Frs2.sf);
+ Frds.sf = (float)static_cast<int32_t>(Frs2s.sf);
}});
0xD2: fdtoi({{
- Frd.sf = (float)static_cast<int32_t>(Frs2.df);
+ Frds.sf = (float)static_cast<int32_t>(Frs2.df);
}});
0xD3: Trap::fqtoi({{fault = new FpDisabled;}});
default: Trap::fpop1({{fault = new FpDisabled;}});
@@ -620,7 +620,7 @@ decode OP default Unknown::unknown()
0x56: Trap::fpsub32({{fault = new IllegalInstruction;}});
0x57: Trap::fpsub32s({{fault = new IllegalInstruction;}});
0x60: BasicOperate::fzero({{Frd.df = 0;}});
- 0x61: BasicOperate::fzeros({{Frd.sf = 0;}});
+ 0x61: BasicOperate::fzeros({{Frds.sf = 0;}});
0x62: Trap::fnor({{fault = new IllegalInstruction;}});
0x63: Trap::fnors({{fault = new IllegalInstruction;}});
0x64: Trap::fandnot2({{fault = new IllegalInstruction;}});
@@ -629,7 +629,7 @@ decode OP default Unknown::unknown()
Frd.df = (double)(~((uint64_t)Frs2.df));
}});
0x67: BasicOperate::fnot2s({{
- Frd.sf = (float)(~((uint32_t)Frs2.sf));
+ Frds.sf = (float)(~((uint32_t)Frs2s.sf));
}});
0x68: Trap::fandnot1({{fault = new IllegalInstruction;}});
0x69: Trap::fandnot1s({{fault = new IllegalInstruction;}});
@@ -637,7 +637,7 @@ decode OP default Unknown::unknown()
Frd.df = (double)(~((uint64_t)Frs1.df));
}});
0x6B: BasicOperate::fnot1s({{
- Frd.sf = (float)(~((uint32_t)Frs1.sf));
+ Frds.sf = (float)(~((uint32_t)Frs1s.sf));
}});
0x6C: Trap::fxor({{fault = new IllegalInstruction;}});
0x6D: Trap::fxors({{fault = new IllegalInstruction;}});
@@ -820,92 +820,248 @@ decode OP default Unknown::unknown()
}
0x3: decode OP3 {
format Load {
- 0x00: lduw({{Rd = Mem;}}, {{32}});
- 0x01: ldub({{Rd = Mem;}}, {{8}});
- 0x02: lduh({{Rd = Mem;}}, {{16}});
+ 0x00: lduw({{Rd = Mem.uw;}});
+ 0x01: ldub({{Rd = Mem.ub;}});
+ 0x02: lduh({{Rd = Mem.uhw;}});
0x03: ldd({{
- uint64_t val = Mem;
+ uint64_t val = Mem.udw;
RdLow = val<31:0>;
RdHigh = val<63:32>;
- }}, {{64}});
+ }});
}
format Store {
- 0x04: stw({{Mem = Rd.sw;}}, {{32}});
- 0x05: stb({{Mem = Rd.sb;}}, {{8}});
- 0x06: sth({{Mem = Rd.shw;}}, {{16}});
- 0x07: std({{Mem = RdLow<31:0> | (RdHigh<31:0> << 32);}}, {{64}});
+ 0x04: stw({{Mem.uw = Rd.sw;}});
+ 0x05: stb({{Mem.ub = Rd.sb;}});
+ 0x06: sth({{Mem.uhw = Rd.shw;}});
+ 0x07: std({{Mem.udw = RdLow<31:0> | (RdHigh<31:0> << 32);}});
}
format Load {
- 0x08: ldsw({{Rd = (int32_t)Mem;}}, {{32}});
- 0x09: ldsb({{Rd = (int8_t)Mem;}}, {{8}});
- 0x0A: ldsh({{Rd = (int16_t)Mem;}}, {{16}});
- 0x0B: ldx({{Rd = (int64_t)Mem;}}, {{64}});
+ 0x08: ldsw({{Rd = (int32_t)Mem.sw;}});
+ 0x09: ldsb({{Rd = (int8_t)Mem.sb;}});
+ 0x0A: ldsh({{Rd = (int16_t)Mem.shw;}});
+ 0x0B: ldx({{Rd = (int64_t)Mem.sdw;}});
0x0D: ldstub({{
- Rd = Mem;
- Mem = 0xFF;
- }}, {{8}});
+ Rd = Mem.ub;
+ Mem.ub = 0xFF;
+ }});
}
- 0x0E: Store::stx({{Mem = Rd}}, {{64}});
- 0x0F: LoadStore::swap({{
- uint32_t temp = Rd;
- Rd = Mem;
- Mem = temp;
- }}, {{32}});
+ 0x0E: Store::stx({{Mem.udw = Rd}});
+ 0x0F: LoadStore::swap(
+ {{*temp = Rd.uw;
+ Rd.uw = Mem.uw;}},
+ {{Mem.uw = *temp;}});
format Load {
- 0x10: lduwa({{Rd = Mem;}}, {{32}});
- 0x11: lduba({{Rd = Mem;}}, {{8}});
- 0x12: lduha({{Rd = Mem;}}, {{16}});
+ 0x10: lduwa({{Rd = Mem.uw;}});
+ 0x11: lduba({{Rd = Mem.ub;}});
+ 0x12: lduha({{Rd = Mem.uhw;}});
0x13: ldda({{
- uint64_t val = Mem;
+ uint64_t val = Mem.udw;
RdLow = val<31:0>;
RdHigh = val<63:32>;
- }}, {{64}});
+ }});
}
format Store {
- 0x14: stwa({{Mem = Rd;}}, {{32}});
- 0x15: stba({{Mem = Rd;}}, {{8}});
- 0x16: stha({{Mem = Rd;}}, {{16}});
- 0x17: stda({{Mem = RdLow<31:0> | RdHigh<31:0> << 32;}}, {{64}});
+ 0x14: stwa({{Mem.uw = Rd;}});
+ 0x15: stba({{Mem.ub = Rd;}});
+ 0x16: stha({{Mem.uhw = Rd;}});
+ 0x17: stda({{Mem.udw = RdLow<31:0> | RdHigh<31:0> << 32;}});
}
format Load {
- 0x18: ldswa({{Rd = (int32_t)Mem;}}, {{32}});
- 0x19: ldsba({{Rd = (int8_t)Mem;}}, {{8}});
- 0x1A: ldsha({{Rd = (int16_t)Mem;}}, {{16}});
- 0x1B: ldxa({{Rd = (int64_t)Mem;}}, {{64}});
+ 0x18: ldswa({{Rd = (int32_t)Mem.sw;}});
+ 0x19: ldsba({{Rd = (int8_t)Mem.sb;}});
+ 0x1A: ldsha({{Rd = (int16_t)Mem.shw;}});
+ 0x1B: ldxa({{Rd = (int64_t)Mem.sdw;}});
}
- 0x1D: LoadStore::ldstuba({{
- Rd = Mem;
- Mem = 0xFF;
- }}, {{8}});
- 0x1E: Store::stxa({{Mem = Rd}}, {{64}});
- 0x1F: LoadStore::swapa({{
- uint32_t temp = Rd;
- Rd = Mem;
- Mem = temp;
- }}, {{32}});
+ 0x1D: LoadStore::ldstuba(
+ {{Rd = Mem.ub;}},
+ {{Mem.ub = 0xFF}});
+ 0x1E: Store::stxa({{Mem.udw = Rd}});
+ 0x1F: LoadStore::swapa(
+ {{*temp = Rd.uw;
+ Rd.uw = Mem.uw;}},
+ {{Mem.uw = *temp;}});
format Trap {
- 0x20: Load::ldf({{Frd.uw = Mem;}}, {{32}});
+ 0x20: Load::ldf({{Frd.uw = Mem.uw;}});
0x21: decode X {
- 0x0: Load::ldfsr({{Fsr = Mem<31:0> | Fsr<63:32>;}}, {{32}});
- 0x1: Load::ldxfsr({{Fsr = Mem;}}, {{64}});
+ 0x0: Load::ldfsr({{Fsr = Mem.uw | Fsr<63:32>;}});
+ 0x1: Load::ldxfsr({{Fsr = Mem.udw;}});
}
0x22: ldqf({{fault = new FpDisabled;}});
- 0x23: Load::lddf({{Frd.udw = Mem;}}, {{64}});
- 0x24: Store::stf({{Mem = Frd.uw;}}, {{32}});
+ 0x23: Load::lddf({{Frd.udw = Mem.udw;}});
+ 0x24: Store::stf({{Mem.uw = Frd.uw;}});
0x25: decode X {
- 0x0: Store::stfsr({{Mem = Fsr<31:0>;}}, {{32}});
- 0x1: Store::stxfsr({{Mem = Fsr;}}, {{64}});
+ 0x0: Store::stfsr({{Mem.uw = Fsr<31:0>;}});
+ 0x1: Store::stxfsr({{Mem.udw = Fsr;}});
}
0x26: stqf({{fault = new FpDisabled;}});
- 0x27: Store::stdf({{Mem = Frd.udw;}}, {{64}});
+ 0x27: Store::stdf({{Mem.udw = Frd.udw;}});
0x2D: Nop::prefetch({{ }});
- 0x30: Load::ldfa({{Frd.uw = Mem;}}, {{32}});
+ 0x30: Load::ldfa({{Frd.uw = Mem.uw;}});
0x32: ldqfa({{fault = new FpDisabled;}});
- 0x33: Load::lddfa({{Frd.udw = Mem;}}, {{64}});
- 0x34: Store::stfa({{Mem = Frd.uw;}}, {{32}});
+ format LoadAlt {
+ 0x33: decode EXT_ASI {
+ //ASI_NUCLEUS
+ 0x04: FailUnimpl::lddfa_n();
+ //ASI_NUCLEUS_LITTLE
+ 0x0C: FailUnimpl::lddfa_nl();
+ //ASI_AS_IF_USER_PRIMARY
+ 0x10: FailUnimpl::lddfa_aiup();
+ //ASI_AS_IF_USER_PRIMARY_LITTLE
+ 0x18: FailUnimpl::lddfa_aiupl();
+ //ASI_AS_IF_USER_SECONDARY
+ 0x11: FailUnimpl::lddfa_aius();
+ //ASI_AS_IF_USER_SECONDARY_LITTLE
+ 0x19: FailUnimpl::lddfa_aiusl();
+ //ASI_REAL
+ 0x14: FailUnimpl::lddfa_real();
+ //ASI_REAL_LITTLE
+ 0x1C: FailUnimpl::lddfa_real_l();
+ //ASI_REAL_IO
+ 0x15: FailUnimpl::lddfa_real_io();
+ //ASI_REAL_IO_LITTLE
+ 0x1D: FailUnimpl::lddfa_real_io_l();
+ //ASI_PRIMARY
+ 0x80: FailUnimpl::lddfa_p();
+ //ASI_PRIMARY_LITTLE
+ 0x88: FailUnimpl::lddfa_pl();
+ //ASI_SECONDARY
+ 0x81: FailUnimpl::lddfa_s();
+ //ASI_SECONDARY_LITTLE
+ 0x89: FailUnimpl::lddfa_sl();
+ //ASI_PRIMARY_NO_FAULT
+ 0x82: FailUnimpl::lddfa_pnf();
+ //ASI_PRIMARY_NO_FAULT_LITTLE
+ 0x8A: FailUnimpl::lddfa_pnfl();
+ //ASI_SECONDARY_NO_FAULT
+ 0x83: FailUnimpl::lddfa_snf();
+ //ASI_SECONDARY_NO_FAULT_LITTLE
+ 0x8B: FailUnimpl::lddfa_snfl();
+
+ format BlockLoad {
+ // LDBLOCKF
+ //ASI_BLOCK_AS_IF_USER_PRIMARY
+ 0x16: FailUnimpl::ldblockf_aiup();
+ //ASI_BLOCK_AS_IF_USER_SECONDARY
+ 0x17: FailUnimpl::ldblockf_aius();
+ //ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE
+ 0x1E: FailUnimpl::ldblockf_aiupl();
+ //ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE
+ 0x1F: FailUnimpl::ldblockf_aiusl();
+ //ASI_BLOCK_PRIMARY
+ 0xF0: ldblockf_p({{Frd_N.udw = Mem.udw;}});
+ //ASI_BLOCK_SECONDARY
+ 0xF1: FailUnimpl::ldblockf_s();
+ //ASI_BLOCK_PRIMARY_LITTLE
+ 0xF8: FailUnimpl::ldblockf_pl();
+ //ASI_BLOCK_SECONDARY_LITTLE
+ 0xF9: FailUnimpl::ldblockf_sl();
+ }
+
+ //LDSHORTF
+ //ASI_FL8_PRIMARY
+ 0xD0: FailUnimpl::ldshortf_8p();
+ //ASI_FL8_SECONDARY
+ 0xD1: FailUnimpl::ldshortf_8s();
+ //ASI_FL8_PRIMARY_LITTLE
+ 0xD8: FailUnimpl::ldshortf_8pl();
+ //ASI_FL8_SECONDARY_LITTLE
+ 0xD9: FailUnimpl::ldshortf_8sl();
+ //ASI_FL16_PRIMARY
+ 0xD2: FailUnimpl::ldshortf_16p();
+ //ASI_FL16_SECONDARY
+ 0xD3: FailUnimpl::ldshortf_16s();
+ //ASI_FL16_PRIMARY_LITTLE
+ 0xDA: FailUnimpl::ldshortf_16pl();
+ //ASI_FL16_SECONDARY_LITTLE
+ 0xDB: FailUnimpl::ldshortf_16sl();
+ //Not an ASI which is legal with lddfa
+ default: Trap::lddfa_bad_asi(
+ {{fault = new DataAccessException;}});
+ }
+ }
+ 0x34: Store::stfa({{Mem.uw = Frd.uw;}});
0x36: stqfa({{fault = new FpDisabled;}});
- //XXX need to work in the ASI thing
- 0x37: Store::stdfa({{Mem = Frd.udw;}}, {{64}});
+ format StoreAlt {
+ 0x37: decode EXT_ASI {
+ //ASI_NUCLEUS
+ 0x04: FailUnimpl::stdfa_n();
+ //ASI_NUCLEUS_LITTLE
+ 0x0C: FailUnimpl::stdfa_nl();
+ //ASI_AS_IF_USER_PRIMARY
+ 0x10: FailUnimpl::stdfa_aiup();
+ //ASI_AS_IF_USER_PRIMARY_LITTLE
+ 0x18: FailUnimpl::stdfa_aiupl();
+ //ASI_AS_IF_USER_SECONDARY
+ 0x11: FailUnimpl::stdfa_aius();
+ //ASI_AS_IF_USER_SECONDARY_LITTLE
+ 0x19: FailUnimpl::stdfa_aiusl();
+ //ASI_REAL
+ 0x14: FailUnimpl::stdfa_real();
+ //ASI_REAL_LITTLE
+ 0x1C: FailUnimpl::stdfa_real_l();
+ //ASI_REAL_IO
+ 0x15: FailUnimpl::stdfa_real_io();
+ //ASI_REAL_IO_LITTLE
+ 0x1D: FailUnimpl::stdfa_real_io_l();
+ //ASI_PRIMARY
+ 0x80: FailUnimpl::stdfa_p();
+ //ASI_PRIMARY_LITTLE
+ 0x88: FailUnimpl::stdfa_pl();
+ //ASI_SECONDARY
+ 0x81: FailUnimpl::stdfa_s();
+ //ASI_SECONDARY_LITTLE
+ 0x89: FailUnimpl::stdfa_sl();
+ //ASI_PRIMARY_NO_FAULT
+ 0x82: FailUnimpl::stdfa_pnf();
+ //ASI_PRIMARY_NO_FAULT_LITTLE
+ 0x8A: FailUnimpl::stdfa_pnfl();
+ //ASI_SECONDARY_NO_FAULT
+ 0x83: FailUnimpl::stdfa_snf();
+ //ASI_SECONDARY_NO_FAULT_LITTLE
+ 0x8B: FailUnimpl::stdfa_snfl();
+
+ format BlockStore {
+ // STBLOCKF
+ //ASI_BLOCK_AS_IF_USER_PRIMARY
+ 0x16: FailUnimpl::stblockf_aiup();
+ //ASI_BLOCK_AS_IF_USER_SECONDARY
+ 0x17: FailUnimpl::stblockf_aius();
+ //ASI_BLOCK_AS_IF_USER_PRIMARY_LITTLE
+ 0x1E: FailUnimpl::stblockf_aiupl();
+ //ASI_BLOCK_AS_IF_USER_SECONDARY_LITTLE
+ 0x1F: FailUnimpl::stblockf_aiusl();
+ //ASI_BLOCK_PRIMARY
+ 0xF0: stblockf_p({{Mem.udw = Frd_N.udw;}});
+ //ASI_BLOCK_SECONDARY
+ 0xF1: FailUnimpl::stblockf_s();
+ //ASI_BLOCK_PRIMARY_LITTLE
+ 0xF8: FailUnimpl::stblockf_pl();
+ //ASI_BLOCK_SECONDARY_LITTLE
+ 0xF9: FailUnimpl::stblockf_sl();
+ }
+
+ //STSHORTF
+ //ASI_FL8_PRIMARY
+ 0xD0: FailUnimpl::stshortf_8p();
+ //ASI_FL8_SECONDARY
+ 0xD1: FailUnimpl::stshortf_8s();
+ //ASI_FL8_PRIMARY_LITTLE
+ 0xD8: FailUnimpl::stshortf_8pl();
+ //ASI_FL8_SECONDARY_LITTLE
+ 0xD9: FailUnimpl::stshortf_8sl();
+ //ASI_FL16_PRIMARY
+ 0xD2: FailUnimpl::stshortf_16p();
+ //ASI_FL16_SECONDARY
+ 0xD3: FailUnimpl::stshortf_16s();
+ //ASI_FL16_PRIMARY_LITTLE
+ 0xDA: FailUnimpl::stshortf_16pl();
+ //ASI_FL16_SECONDARY_LITTLE
+ 0xDB: FailUnimpl::stshortf_16sl();
+ //Not an ASI which is legal with lddfa
+ default: Trap::stdfa_bad_asi(
+ {{fault = new DataAccessException;}});
+ }
+ }
0x3C: Cas::casa({{
uint64_t val = Mem.uw;
if(Rs2.uw == val)
diff --git a/src/arch/sparc/isa/formats.isa b/src/arch/sparc/isa/formats.isa
deleted file mode 100644
index 17d68061b..000000000
--- a/src/arch/sparc/isa/formats.isa
+++ /dev/null
@@ -1,28 +0,0 @@
-//Include the basic format
-//Templates from this format are used later
-##include "formats/basic.isa"
-
-//Include the noop format
-##include "formats/nop.isa"
-
-//Include the integerOp and integerOpCc format
-##include "formats/integerop.isa"
-
-//Include the memory format
-##include "formats/mem.isa"
-
-//Include the compare and swap format
-##include "formats/cas.isa"
-
-//Include the trap format
-##include "formats/trap.isa"
-
-//Include the "unknown" format
-##include "formats/unknown.isa"
-
-//Include the priveleged mode format
-##include "formats/priv.isa"
-
-//Include the branch format
-##include "formats/branch.isa"
-
diff --git a/src/arch/sparc/isa/formats/basic.isa b/src/arch/sparc/isa/formats/basic.isa
index 0a47a7ffe..a4c05387b 100644
--- a/src/arch/sparc/isa/formats/basic.isa
+++ b/src/arch/sparc/isa/formats/basic.isa
@@ -33,6 +33,14 @@ def template BasicExecDeclare {{
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
+// Definitions of execute methods that panic.
+def template BasicExecPanic {{
+ Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
+ {
+ panic("Execute method called when it shouldn't!");
+ }
+}};
+
// Basic instruction class declaration template.
def template BasicDeclare {{
/**
@@ -42,14 +50,14 @@ def template BasicDeclare {{
{
public:
// Constructor.
- %(class_name)s(MachInst machInst);
+ %(class_name)s(ExtMachInst machInst);
%(BasicExecDeclare)s
};
}};
// Basic instruction class constructor template.
def template BasicConstructor {{
- inline %(class_name)s::%(class_name)s(MachInst machInst)
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
: %(base_class)s("%(mnemonic)s", machInst, %(op_class)s)
{
%(constructor)s;
@@ -80,6 +88,11 @@ def template BasicDecode {{
return new %(class_name)s(machInst);
}};
+// Basic decode template, passing mnemonic in as string arg to constructor.
+def template BasicDecodeWithMnemonic {{
+ return new %(class_name)s("%(mnemonic)s", machInst);
+}};
+
// The most basic instruction format... used only for a few misc. insts
def format BasicOperate(code, *flags) {{
iop = InstObjParams(name, Name, 'SparcStaticInst',
diff --git a/src/arch/sparc/isa/formats/branch.isa b/src/arch/sparc/isa/formats/branch.isa
index 2c206354b..5fb7ade2d 100644
--- a/src/arch/sparc/isa/formats/branch.isa
+++ b/src/arch/sparc/isa/formats/branch.isa
@@ -80,7 +80,7 @@ output header {{
OpClass __opClass) :
BranchDisp(mnem, _machInst, __opClass)
{
- disp = sign_ext(_machInst << 2, bits + 2);
+ disp = sext<bits + 2>((_machInst & mask(bits)) << 2);
}
};
@@ -95,7 +95,7 @@ output header {{
OpClass __opClass) :
BranchDisp(mnem, _machInst, __opClass)
{
- disp = sign_ext((D16HI << 16) | (D16LO << 2), 18);
+ disp = sext<18>((D16HI << 16) | (D16LO << 2));
}
};
@@ -108,7 +108,7 @@ output header {{
protected:
// Constructor
BranchImm13(const char *mnem, MachInst _machInst, OpClass __opClass) :
- Branch(mnem, _machInst, __opClass), imm(sign_ext(SIMM13, 13))
+ Branch(mnem, _machInst, __opClass), imm(sext<13>(SIMM13))
{
}
diff --git a/src/arch/sparc/isa/formats/formats.isa b/src/arch/sparc/isa/formats/formats.isa
new file mode 100644
index 000000000..5b81a1ab1
--- /dev/null
+++ b/src/arch/sparc/isa/formats/formats.isa
@@ -0,0 +1,62 @@
+// 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: Gabe Black
+
+//Include the basic format
+//Templates from this format are used later
+##include "basic.isa"
+
+//Include base classes for microcoding instructions
+##include "micro.isa"
+
+//Include the noop format
+##include "nop.isa"
+
+//Include the integerOp and integerOpCc format
+##include "integerop.isa"
+
+//Include the memory formats
+##include "mem/mem.isa"
+
+//Include the compare and swap format
+##include "cas.isa"
+
+//Include the trap format
+##include "trap.isa"
+
+//Include the unimplemented format
+##include "unimp.isa"
+
+//Include the "unknown" format
+##include "unknown.isa"
+
+//Include the priveleged mode format
+##include "priv.isa"
+
+//Include the branch format
+##include "branch.isa"
+
diff --git a/src/arch/sparc/isa/formats/integerop.isa b/src/arch/sparc/isa/formats/integerop.isa
index 83c7e6958..4f8ebebcc 100644
--- a/src/arch/sparc/isa/formats/integerop.isa
+++ b/src/arch/sparc/isa/formats/integerop.isa
@@ -87,7 +87,7 @@ output header {{
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
- imm = sign_ext(SIMM10, 10);
+ imm = sext<10>(SIMM10);
}
};
@@ -102,7 +102,7 @@ output header {{
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
- imm = sign_ext(SIMM11, 11);
+ imm = sext<11>(SIMM11);
}
};
@@ -117,7 +117,7 @@ output header {{
OpClass __opClass) :
IntOpImm(mnem, _machInst, __opClass)
{
- imm = sign_ext(SIMM13, 13);
+ imm = sext<13>(SIMM13);
}
};
@@ -264,13 +264,13 @@ let {{
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
iop = InstObjParams(name, Name, 'IntOp', code,
- opt_flags, ("cc_code", ccCode))
+ opt_flags, {"cc_code": ccCode})
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = IntOpExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString,
- immCode, opt_flags, ("cc_code", ccCode))
+ immCode, opt_flags, {"cc_code": ccCode})
header_output += BasicDeclare.subst(imm_iop)
decoder_output += BasicConstructor.subst(imm_iop)
exec_output += IntOpExecute.subst(imm_iop)
@@ -341,7 +341,7 @@ def format IntOpCcRes(code, *opt_flags) {{
def format SetHi(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'SetHi',
- code, opt_flags, ("cc_code", ''))
+ code, opt_flags, {"cc_code": ''})
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = IntOpExecute.subst(iop)
diff --git a/src/arch/sparc/isa/formats/mem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa
index 9011c1fc6..c13194d0f 100644
--- a/src/arch/sparc/isa/formats/mem.isa
+++ b/src/arch/sparc/isa/formats/mem/basicmem.isa
@@ -1,3 +1,32 @@
+// 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
+// Gabe Black
+
////////////////////////////////////////////////////////////////////
//
// Mem instructions
@@ -30,15 +59,13 @@ output header {{
// Constructor
MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) :
- Mem(mnem, _machInst, __opClass)
- {
- imm = sign_ext(SIMM13, 13);
- }
+ Mem(mnem, _machInst, __opClass), imm(sext<13>(SIMM13))
+ {}
std::string generateDisassembly(Addr pc,
const SymbolTable *symtab) const;
- int32_t imm;
+ const int32_t imm;
};
}};
@@ -99,73 +126,69 @@ output decoder {{
}
}};
-def template MemExecute {{
- Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
- Trace::InstRecord *traceData) const
+def template MemDeclare {{
+ /**
+ * Static instruction class for "%(mnemonic)s".
+ */
+ class %(class_name)s : public %(base_class)s
{
- Fault fault = NoFault;
- Addr EA;
- %(op_decl)s;
- %(op_rd)s;
- %(ea_code)s;
- DPRINTF(Sparc, "The address is 0x%x\n", EA);
- %(load)s;
- %(code)s;
-
- if(fault == NoFault)
- {
- %(store)s;
- //Write the resulting state to the execution context
- %(op_wb)s;
- }
+ public:
- return fault;
- }
+ /// Constructor.
+ %(class_name)s(ExtMachInst machInst);
+
+ %(BasicExecDeclare)s
+
+ %(InitiateAccDeclare)s
+
+ %(CompleteAccDeclare)s
+ };
}};
let {{
- # Leave memAccessFlags at 0 for now
- loadString = "xc->read(EA, (uint%(width)s_t&)Mem, 0);"
- storeString = "uint64_t write_result = 0; \
- xc->write((uint%(width)s_t)Mem, EA, 0, &write_result);"
-
- def doMemFormat(code, load, store, name, Name, opt_flags):
+ def doMemFormat(code, execute, faultCode, name, Name, opt_flags):
addrCalcReg = 'EA = Rs1 + Rs2;'
addrCalcImm = 'EA = Rs1 + imm;'
iop = InstObjParams(name, Name, 'Mem', code,
- opt_flags, ("ea_code", addrCalcReg),
- ("load", load), ("store", store))
- iop_imm = InstObjParams(name, Name + 'Imm', 'MemImm', code,
- opt_flags, ("ea_code", addrCalcImm),
- ("load", load), ("store", store))
- header_output = BasicDeclare.subst(iop) + BasicDeclare.subst(iop_imm)
+ opt_flags, {"fault_check": faultCode, "ea_code": addrCalcReg})
+ iop_imm = InstObjParams(name, Name + "Imm", 'MemImm', code,
+ opt_flags, {"fault_check": faultCode, "ea_code": addrCalcImm})
+ header_output = MemDeclare.subst(iop) + MemDeclare.subst(iop_imm)
decoder_output = BasicConstructor.subst(iop) + BasicConstructor.subst(iop_imm)
decode_block = ROrImmDecode.subst(iop)
- exec_output = MemExecute.subst(iop) + MemExecute.subst(iop_imm)
+ exec_output = doSplitExecute(code, addrCalcReg, addrCalcImm, execute,
+ faultCode, name, name + "Imm", Name, Name + "Imm", opt_flags)
return (header_output, decoder_output, exec_output, decode_block)
}};
-def format Load(code, width, *opt_flags) {{
+def format LoadAlt(code, *opt_flags) {{
(header_output,
decoder_output,
exec_output,
- decode_block) = doMemFormat(code,
- loadString % {"width":width}, '', name, Name, opt_flags)
+ decode_block) = doMemFormat(code, LoadExecute,
+ AlternateAsiPrivFaultCheck, name, Name, opt_flags)
}};
-def format Store(code, width, *opt_flags) {{
+def format StoreAlt(code, *opt_flags) {{
(header_output,
decoder_output,
exec_output,
- decode_block) = doMemFormat(code, '',
- storeString % {"width":width}, name, Name, opt_flags)
+ decode_block) = doMemFormat(code, StoreExecute,
+ AlternateAsiPrivFaultCheck, name, Name, opt_flags)
+}};
+
+def format Load(code, *opt_flags) {{
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doMemFormat(code,
+ LoadExecute, '', name, Name, opt_flags)
}};
-def format LoadStore(code, width, *opt_flags) {{
+def format Store(code, *opt_flags) {{
(header_output,
decoder_output,
exec_output,
decode_block) = doMemFormat(code,
- loadString % {"width":width}, storeString % {"width":width},
- name, Name, opt_flags)
+ StoreExecute, '', name, Name, opt_flags)
}};
diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa
new file mode 100644
index 000000000..93ad1b2b8
--- /dev/null
+++ b/src/arch/sparc/isa/formats/mem/blockmem.isa
@@ -0,0 +1,337 @@
+// 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
+// Gabe Black
+
+////////////////////////////////////////////////////////////////////
+//
+// Block Memory instructions
+//
+
+output header {{
+
+ class BlockMem : public SparcMacroInst
+ {
+ protected:
+
+ // Constructor
+ // We make the assumption that all block memory operations
+ // Will take 8 instructions to execute
+ BlockMem(const char *mnem, ExtMachInst _machInst) :
+ SparcMacroInst(mnem, _machInst, No_OpClass, 8)
+ {}
+ };
+
+ class BlockMemImm : public BlockMem
+ {
+ protected:
+
+ // Constructor
+ BlockMemImm(const char *mnem, ExtMachInst _machInst) :
+ BlockMem(mnem, _machInst)
+ {}
+ };
+
+ class BlockMemMicro : public SparcDelayedMicroInst
+ {
+ protected:
+
+ // Constructor
+ BlockMemMicro(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, int8_t _offset) :
+ SparcDelayedMicroInst(mnem, _machInst, __opClass),
+ offset(_offset)
+ {}
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ const int8_t offset;
+ };
+
+ class BlockMemImmMicro : public BlockMemMicro
+ {
+ protected:
+
+ // Constructor
+ BlockMemImmMicro(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, int8_t _offset) :
+ BlockMemMicro(mnem, _machInst, __opClass, _offset),
+ imm(sext<13>(SIMM13))
+ {}
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ const int32_t imm;
+ };
+}};
+
+output decoder {{
+ std::string BlockMemMicro::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+ bool load = flags[IsLoad];
+ bool save = flags[IsStore];
+
+ printMnemonic(response, mnemonic);
+ if(save)
+ {
+ printReg(response, _srcRegIdx[0]);
+ ccprintf(response, ", ");
+ }
+ ccprintf(response, "[ ");
+ printReg(response, _srcRegIdx[!save ? 0 : 1]);
+ ccprintf(response, " + ");
+ printReg(response, _srcRegIdx[!save ? 1 : 2]);
+ ccprintf(response, " ]");
+ if(load)
+ {
+ ccprintf(response, ", ");
+ printReg(response, _destRegIdx[0]);
+ }
+
+ return response.str();
+ }
+
+ std::string BlockMemImmMicro::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+ bool load = flags[IsLoad];
+ bool save = flags[IsStore];
+
+ printMnemonic(response, mnemonic);
+ if(save)
+ {
+ printReg(response, _srcRegIdx[1]);
+ ccprintf(response, ", ");
+ }
+ ccprintf(response, "[ ");
+ printReg(response, _srcRegIdx[0]);
+ if(imm >= 0)
+ ccprintf(response, " + 0x%x ]", imm);
+ else
+ ccprintf(response, " + -0x%x ]", -imm);
+ if(load)
+ {
+ ccprintf(response, ", ");
+ printReg(response, _destRegIdx[0]);
+ }
+
+ return response.str();
+ }
+
+}};
+
+def template BlockMemDeclare {{
+ /**
+ * Static instruction class for a block memory operation
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ public:
+ //Constructor
+ %(class_name)s(ExtMachInst machInst);
+
+ protected:
+ class %(class_name)s_0 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_0(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_1 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_1(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_2 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_2(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_3 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_3(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_4 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_4(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_5 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_5(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_6 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_6(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+
+ class %(class_name)s_7 : public %(base_class)sMicro
+ {
+ public:
+ //Constructor
+ %(class_name)s_7(ExtMachInst machInst);
+ %(BasicExecDeclare)s
+ %(InitiateAccDeclare)s
+ %(CompleteAccDeclare)s
+ };
+ };
+}};
+
+// Basic instruction class constructor template.
+def template BlockMemConstructor {{
+ inline %(class_name)s::%(class_name)s(ExtMachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst)
+ {
+ %(constructor)s;
+ microOps[0] = new %(class_name)s_0(machInst);
+ microOps[1] = new %(class_name)s_1(machInst);
+ microOps[2] = new %(class_name)s_2(machInst);
+ microOps[3] = new %(class_name)s_3(machInst);
+ microOps[4] = new %(class_name)s_4(machInst);
+ microOps[5] = new %(class_name)s_5(machInst);
+ microOps[6] = new %(class_name)s_6(machInst);
+ microOps[7] = new %(class_name)s_7(machInst);
+ }
+}};
+
+def template BlockMemMicroConstructor {{
+ inline %(class_name)s::
+ %(class_name)s_%(micro_pc)s::
+ %(class_name)s_%(micro_pc)s(ExtMachInst machInst) :
+ %(base_class)sMicro("%(mnemonic)s[%(micro_pc)s]",
+ machInst, %(op_class)s, %(micro_pc)s * 8)
+ {
+ %(constructor)s;
+ %(set_flags)s;
+ }
+}};
+
+let {{
+
+ def doBlockMemFormat(code, faultCode, execute, name, Name, opt_flags):
+ # XXX Need to take care of pstate.hpriv as well. The lower ASIs
+ # are split into ones that are available in priv and hpriv, and
+ # those that are only available in hpriv
+ addrCalcReg = 'EA = Rs1 + Rs2 + offset;'
+ addrCalcImm = 'EA = Rs1 + imm + offset;'
+ iop = InstObjParams(name, Name, 'BlockMem', code, opt_flags)
+ iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', code, opt_flags)
+ header_output = BlockMemDeclare.subst(iop) + BlockMemDeclare.subst(iop_imm)
+ decoder_output = BlockMemConstructor.subst(iop) + BlockMemConstructor.subst(iop_imm)
+ decode_block = ROrImmDecode.subst(iop)
+ matcher = re.compile(r'Frd_N')
+ exec_output = ''
+ for microPc in range(8):
+ flag_code = ''
+ if (microPc == 7):
+ flag_code = "flags[IsLastMicroOp] = true;"
+ pcedCode = matcher.sub("Frd_%d" % microPc, code)
+ iop = InstObjParams(name, Name, 'BlockMem', pcedCode,
+ opt_flags, {"ea_code": addrCalcReg,
+ "fault_check": faultCode, "micro_pc": microPc,
+ "set_flags": flag_code})
+ iop_imm = InstObjParams(name, Name + 'Imm', 'BlockMemImm', pcedCode,
+ opt_flags, {"ea_code": addrCalcImm,
+ "fault_check": faultCode, "micro_pc": microPc,
+ "set_flags": flag_code})
+ decoder_output += BlockMemMicroConstructor.subst(iop)
+ decoder_output += BlockMemMicroConstructor.subst(iop_imm)
+ exec_output += doSplitExecute(
+ pcedCode, addrCalcReg, addrCalcImm, execute, faultCode,
+ makeMicroName(name, microPc),
+ makeMicroName(name + "Imm", microPc),
+ makeMicroName(Name, microPc),
+ makeMicroName(Name + "Imm", microPc),
+ opt_flags);
+ faultCode = ''
+ return (header_output, decoder_output, exec_output, decode_block)
+}};
+
+def format BlockLoad(code, *opt_flags) {{
+ # We need to make sure to check the highest priority fault last.
+ # That way, if other faults have been detected, they'll be overwritten
+ # rather than the other way around.
+ faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doBlockMemFormat(code, faultCode,
+ LoadExecute, name, Name, opt_flags)
+}};
+
+def format BlockStore(code, *opt_flags) {{
+ # We need to make sure to check the highest priority fault last.
+ # That way, if other faults have been detected, they'll be overwritten
+ # rather than the other way around.
+ faultCode = AlternateASIPrivFaultCheck + BlockAlignmentFaultCheck
+ (header_output,
+ decoder_output,
+ exec_output,
+ decode_block) = doBlockMemFormat(code, faultCode,
+ StoreExecute, name, Name, opt_flags)
+}};
diff --git a/src/arch/sparc/isa/formats/mem/mem.isa b/src/arch/sparc/isa/formats/mem/mem.isa
new file mode 100644
index 000000000..20a22c45d
--- /dev/null
+++ b/src/arch/sparc/isa/formats/mem/mem.isa
@@ -0,0 +1,45 @@
+// 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
+// Gabe Black
+
+////////////////////////////////////////////////////////////////////
+//
+// Mem formats
+//
+
+//Include mem utility templates and functions
+##include "util.isa"
+
+//Include the basic memory format
+##include "basicmem.isa"
+
+//Include the block memory format
+##include "blockmem.isa"
+
+//Include the load/store memory format
+##include "loadstore.isa"
diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa
new file mode 100644
index 000000000..241a25d17
--- /dev/null
+++ b/src/arch/sparc/isa/formats/mem/util.isa
@@ -0,0 +1,226 @@
+// 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
+// Gabe Black
+// Steve Reinhardt
+
+////////////////////////////////////////////////////////////////////
+//
+// Mem utility templates and functions
+//
+
+//This template provides the execute functions for a load
+def template LoadExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ Addr EA;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+ DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ %(fault_check)s;
+ if(fault == NoFault)
+ {
+ fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
+ }
+ if(fault == NoFault)
+ {
+ %(code)s;
+ }
+ if(fault == NoFault)
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ Fault fault = NoFault;
+ Addr EA;
+ uint%(mem_acc_size)s_t Mem;
+ %(ea_decl)s;
+ %(ea_rd)s;
+ %(ea_code)s;
+ %(fault_check)s;
+ if(fault == NoFault)
+ {
+ fault = xc->read(EA, (uint%(mem_acc_size)s_t&)Mem, 0);
+ }
+ return fault;
+ }
+
+ Fault %(class_name)s::completeAcc(PacketPtr pkt, %(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ Fault fault = NoFault;
+ %(code_decl)s;
+ %(code_rd)s;
+ Mem = pkt->get<typeof(Mem)>();
+ %(code)s;
+ if(fault == NoFault)
+ {
+ %(code_wb)s;
+ }
+ return fault;
+ }
+}};
+
+//This template provides the execute functions for a store
+def template StoreExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ uint64_t write_result = 0;
+ Addr EA;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+ DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ %(fault_check)s;
+ if(fault == NoFault)
+ {
+ %(code)s;
+ }
+ if(fault == NoFault)
+ {
+ fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
+ }
+ if(fault == NoFault)
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ Fault fault = NoFault;
+ uint64_t write_result = 0;
+ Addr EA;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+ DPRINTF(Sparc, "The address is 0x%x\n", EA);
+ %(fault_check)s;
+ if(fault == NoFault)
+ {
+ %(code)s;
+ }
+ if(fault == NoFault)
+ {
+ fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result);
+ }
+ if(fault == NoFault)
+ {
+ //Write the resulting state to the execution context
+ %(op_wb)s;
+ }
+ return fault;
+ }
+
+ Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc,
+ Trace::InstRecord * traceData) const
+ {
+ return NoFault;
+ }
+}};
+
+//This delcares the initiateAcc function in memory operations
+def template InitiateAccDeclare {{
+ Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+//This declares the completeAcc function in memory operations
+def template CompleteAccDeclare {{
+ Fault completeAcc(PacketPtr, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+//Here are some code snippets which check for various fault conditions
+let {{
+ # The LSB can be zero, since it's really the MSB in doubles and quads
+ # and we're dealing with doubles
+ BlockAlignmentFaultCheck = '''
+ if(RD & 0xe)
+ fault = new IllegalInstruction;
+ else if(EA & 0x3f)
+ fault = new MemAddressNotAligned;
+ '''
+ # XXX Need to take care of pstate.hpriv as well. The lower ASIs
+ # are split into ones that are available in priv and hpriv, and
+ # those that are only available in hpriv
+ AlternateASIPrivFaultCheck = '''
+ if(bits(Pstate,2,2) == 0 && (EXT_ASI & 0x80) == 0)
+ fault = new PrivilegedAction;
+ else if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2))
+ fault = new PrivilegedAction;
+ '''
+
+}};
+
+//A simple function to generate the name of the macro op of a certain
+//instruction at a certain micropc
+let {{
+ def makeMicroName(name, microPc):
+ return name + "::" + name + "_" + str(microPc)
+}};
+
+//This function properly generates the execute functions for one of the
+//templates above. This is needed because in one case, ea computation,
+//fault checks and the actual code all occur in the same function,
+//and in the other they're distributed across two. Also note that for
+//execute functions, the name of the base class doesn't matter.
+let {{
+ def doSplitExecute(code, eaRegCode, eaImmCode, execute,
+ faultCode, nameReg, nameImm, NameReg, NameImm, opt_flags):
+ codeIop = InstObjParams(nameReg, NameReg, '', code, opt_flags)
+ executeCode = ''
+ for (eaCode, name, Name) in (
+ (eaRegCode, nameReg, NameReg),
+ (eaImmCode, nameImm, NameImm)):
+ eaIop = InstObjParams(name, Name, '', eaCode,
+ opt_flags, {"fault_check": faultCode})
+ iop = InstObjParams(name, Name, '', code, opt_flags,
+ {"fault_check": faultCode, "ea_code" : eaCode})
+ (iop.ea_decl,
+ iop.ea_rd,
+ iop.ea_wb) = (eaIop.op_decl, eaIop.op_rd, eaIop.op_wb)
+ (iop.code_decl,
+ iop.code_rd,
+ iop.code_wb) = (codeIop.op_decl, codeIop.op_rd, codeIop.op_wb)
+ executeCode += execute.subst(iop)
+ return executeCode
+}};
diff --git a/src/arch/sparc/isa/formats/micro.isa b/src/arch/sparc/isa/formats/micro.isa
new file mode 100644
index 000000000..82d7fb4cb
--- /dev/null
+++ b/src/arch/sparc/isa/formats/micro.isa
@@ -0,0 +1,103 @@
+// 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: Gabe Black
+
+output header {{
+
+ class SparcMacroInst : public SparcStaticInst
+ {
+ protected:
+ const uint32_t numMicroOps;
+
+ //Constructor.
+ SparcMacroInst(const char *mnem, ExtMachInst _machInst,
+ OpClass __opClass, uint32_t _numMicroOps)
+ : SparcStaticInst(mnem, _machInst, __opClass),
+ numMicroOps(_numMicroOps)
+ {
+ assert(numMicroOps);
+ microOps = new StaticInstPtr[numMicroOps];
+ flags[IsMacroOp] = true;
+ }
+
+ ~SparcMacroInst()
+ {
+ delete [] microOps;
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
+ StaticInstPtr * microOps;
+
+ StaticInstPtr fetchMicroOp(MicroPC microPC)
+ {
+ assert(microPC < numMicroOps);
+ return microOps[microPC];
+ }
+
+ %(BasicExecPanic)s
+ };
+
+ class SparcMicroInst : public SparcStaticInst
+ {
+ protected:
+ //Constructor.
+ SparcMicroInst(const char *mnem,
+ ExtMachInst _machInst, OpClass __opClass)
+ : SparcStaticInst(mnem, _machInst, __opClass)
+ {
+ flags[IsMicroOp] = true;
+ }
+ };
+
+ class SparcDelayedMicroInst : public SparcMicroInst
+ {
+ protected:
+ //Constructor.
+ SparcDelayedMicroInst(const char *mnem,
+ ExtMachInst _machInst, OpClass __opClass)
+ : SparcMicroInst(mnem, _machInst, __opClass)
+ {
+ flags[IsDelayedCommit] = true;
+ }
+ };
+}};
+
+output decoder {{
+
+ std::string SparcMacroInst::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, mnemonic);
+
+ return response.str();
+ }
+
+}};
diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa
index d7ee01519..2a38422a7 100644
--- a/src/arch/sparc/isa/formats/priv.isa
+++ b/src/arch/sparc/isa/formats/priv.isa
@@ -103,13 +103,13 @@ let {{
(usesImm, code, immCode,
rString, iString) = splitOutImm(code)
iop = InstObjParams(name, Name, 'Priv', code,
- opt_flags, ("check", checkCode))
+ opt_flags, {"check": checkCode})
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
exec_output = PrivExecute.subst(iop)
if usesImm:
imm_iop = InstObjParams(name, Name + 'Imm', 'PrivImm',
- immCode, opt_flags, ("check", checkCode))
+ immCode, opt_flags, {"check": checkCode})
header_output += BasicDeclare.subst(imm_iop)
decoder_output += BasicConstructor.subst(imm_iop)
exec_output += PrivExecute.subst(imm_iop)
diff --git a/src/arch/sparc/isa/formats/unimp.isa b/src/arch/sparc/isa/formats/unimp.isa
new file mode 100644
index 000000000..a623507a1
--- /dev/null
+++ b/src/arch/sparc/isa/formats/unimp.isa
@@ -0,0 +1,147 @@
+// -*- mode:c++ -*-
+
+// Copyright (c) 2003-2005 The Regents of The University of Michigan
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met: redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer;
+// redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution;
+// neither the name of the copyright holders nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Authors: Steve Reinhardt
+
+////////////////////////////////////////////////////////////////////
+//
+// Unimplemented instructions
+//
+
+output header {{
+ /**
+ * Static instruction class for unimplemented instructions that
+ * cause simulator termination. Note that these are recognized
+ * (legal) instructions that the simulator does not support; the
+ * 'Unknown' class is used for unrecognized/illegal instructions.
+ * This is a leaf class.
+ */
+ class FailUnimplemented : public SparcStaticInst
+ {
+ public:
+ /// Constructor
+ FailUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
+ : SparcStaticInst(_mnemonic, _machInst, No_OpClass)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+ /**
+ * Base class for unimplemented instructions that cause a warning
+ * to be printed (but do not terminate simulation). This
+ * implementation is a little screwy in that it will print a
+ * warning for each instance of a particular unimplemented machine
+ * instruction, not just for each unimplemented opcode. Should
+ * probably make the 'warned' flag a static member of the derived
+ * class.
+ */
+ class WarnUnimplemented : public SparcStaticInst
+ {
+ private:
+ /// Have we warned on this instruction yet?
+ mutable bool warned;
+
+ public:
+ /// Constructor
+ WarnUnimplemented(const char *_mnemonic, ExtMachInst _machInst)
+ : SparcStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
+ {
+ // don't call execute() (which panics) if we're on a
+ // speculative path
+ flags[IsNonSpeculative] = true;
+ }
+
+ %(BasicExecDeclare)s
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string
+ FailUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s (unimplemented)", mnemonic);
+ }
+
+ std::string
+ WarnUnimplemented::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+#ifdef SS_COMPATIBLE_DISASSEMBLY
+ return csprintf("%-10s", mnemonic);
+#else
+ return csprintf("%-10s (unimplemented)", mnemonic);
+#endif
+ }
+}};
+
+output exec {{
+ Fault
+ FailUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ panic("attempt to execute unimplemented instruction '%s' "
+ "(inst 0x%08x)", mnemonic, machInst);
+ return NoFault;
+ }
+
+ Fault
+ WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ if (!warned) {
+ warn("instruction '%s' unimplemented\n", mnemonic);
+ warned = true;
+ }
+
+ return NoFault;
+ }
+}};
+
+
+def format FailUnimpl() {{
+ iop = InstObjParams(name, 'FailUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+
+def format WarnUnimpl() {{
+ iop = InstObjParams(name, 'WarnUnimplemented')
+ decode_block = BasicDecodeWithMnemonic.subst(iop)
+}};
+
diff --git a/src/arch/sparc/isa/includes.isa b/src/arch/sparc/isa/includes.isa
index f1c2bee96..a324756ec 100644
--- a/src/arch/sparc/isa/includes.isa
+++ b/src/arch/sparc/isa/includes.isa
@@ -40,6 +40,7 @@ output header {{
#include "cpu/static_inst.hh"
#include "arch/sparc/faults.hh"
#include "mem/request.hh" // some constructors use MemReq flags
+#include "mem/packet.hh"
#include "arch/sparc/isa_traits.hh"
#include "arch/sparc/regfile.hh"
}};
@@ -48,6 +49,7 @@ output decoder {{
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "cpu/thread_context.hh" // for Jump::branchTarget()
+#include "mem/packet.hh"
#if defined(linux)
#include <fenv.h>
@@ -65,6 +67,8 @@ output exec {{
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "sim/sim_exit.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
using namespace SparcISA;
}};
diff --git a/src/arch/sparc/isa/main.isa b/src/arch/sparc/isa/main.isa
index 14acf54fa..df5ad0c99 100644
--- a/src/arch/sparc/isa/main.isa
+++ b/src/arch/sparc/isa/main.isa
@@ -26,7 +26,7 @@
// (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: Korey Sewell
+// Authors: Gabe Black
////////////////////////////////////////////////////////////////////
//
@@ -55,7 +55,7 @@ namespace SparcISA;
##include "base.isa"
//Include the definitions for the instruction formats
-##include "formats.isa"
+##include "formats/formats.isa"
//Include the decoder definition
##include "decoder.isa"
diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa
index 605816083..b8b75170b 100644
--- a/src/arch/sparc/isa/operands.isa
+++ b/src/arch/sparc/isa/operands.isa
@@ -42,6 +42,16 @@ def operand_types {{
'qf' : ('float', 128)
}};
+output header {{
+ // A function to "decompress" double and quad floating point
+ // register numbers stuffed into 5 bit fields. These have their
+ // MSB put in the LSB position but are otherwise normal.
+ static inline unsigned int dfpr(unsigned int regNum)
+ {
+ return (regNum & (~1)) | ((regNum & 1) << 5);
+ }
+}};
+
def operands {{
# Int regs default to unsigned, but code should not count on this.
# For clarity, descriptions that depend on unsigned behavior should
@@ -51,10 +61,22 @@ def operands {{
'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 3),
'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 4),
'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 5),
- 'Frd': ('FloatReg', 'df', 'RD', 'IsFloating', 10),
- 'Frs1': ('FloatReg', 'df', 'RS1', 'IsFloating', 11),
- 'Frs2': ('FloatReg', 'df', 'RS2', 'IsFloating', 12),
- 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 20),
+ 'Frds': ('FloatReg', 'sf', 'RD', 'IsFloating', 10),
+ 'Frd': ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10),
+ # Each Frd_N refers to the Nth double precision register from Frd.
+ # Note that this adds twice N to the register number.
+ 'Frd_0': ('FloatReg', 'df', 'dfpr(RD)', 'IsFloating', 10),
+ 'Frd_1': ('FloatReg', 'df', 'dfpr(RD) + 2', 'IsFloating', 10),
+ 'Frd_2': ('FloatReg', 'df', 'dfpr(RD) + 4', 'IsFloating', 10),
+ 'Frd_3': ('FloatReg', 'df', 'dfpr(RD) + 6', 'IsFloating', 10),
+ 'Frd_4': ('FloatReg', 'df', 'dfpr(RD) + 8', 'IsFloating', 10),
+ 'Frd_5': ('FloatReg', 'df', 'dfpr(RD) + 10', 'IsFloating', 10),
+ 'Frd_6': ('FloatReg', 'df', 'dfpr(RD) + 12', 'IsFloating', 10),
+ 'Frd_7': ('FloatReg', 'df', 'dfpr(RD) + 14', 'IsFloating', 10),
+ 'Frs1s': ('FloatReg', 'df', 'RS1', 'IsFloating', 11),
+ 'Frs1': ('FloatReg', 'df', 'dfpr(RS1)', 'IsFloating', 11),
+ 'Frs2s': ('FloatReg', 'df', 'RS2', 'IsFloating', 12),
+ 'Frs2': ('FloatReg', 'df', 'dfpr(RS2)', 'IsFloating', 12),
'NPC': ('NPC', 'udw', None, ( None, None, 'IsControl' ), 31),
'NNPC': ('NNPC', 'udw', None, (None, None, 'IsControl' ), 32),
#'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
@@ -84,6 +106,8 @@ def operands {{
'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 54),
'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 55),
- 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 56)
+ 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 56),
+ # Mem gets a large number so it's always last
+ 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100)
}};
diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh
index f1c071148..23fddf0e9 100644
--- a/src/arch/sparc/utility.hh
+++ b/src/arch/sparc/utility.hh
@@ -33,12 +33,25 @@
#include "arch/sparc/isa_traits.hh"
#include "base/misc.hh"
+#include "base/bitfield.hh"
+#include "cpu/thread_context.hh"
namespace SparcISA
{
inline ExtMachInst
- makeExtMI(MachInst inst, const Addr &pc) {
- return ExtMachInst(inst);
+ makeExtMI(MachInst inst, ThreadContext * xc) {
+ ExtMachInst emi = (unsigned MachInst) inst;
+ //The I bit, bit 13, is used to figure out where the ASI
+ //should come from. Use that in the ExtMachInst. This is
+ //slightly redundant, but it removes the need to put a condition
+ //into all the execute functions
+ if(inst & (1 << 13))
+ emi |= (static_cast<ExtMachInst>(xc->readMiscReg(MISCREG_ASI))
+ << (sizeof(MachInst) * 8));
+ else
+ emi |= (static_cast<ExtMachInst>(bits(inst, 12, 5))
+ << (sizeof(MachInst) * 8));
+ return emi;
}
inline bool isCallerSaveIntegerRegister(unsigned int reg) {
diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh
index f4e49aa8d..879780d56 100644
--- a/src/base/bitfield.hh
+++ b/src/base/bitfield.hh
@@ -32,7 +32,7 @@
#ifndef __BASE_BITFIELD_HH__
#define __BASE_BITFIELD_HH__
-#include "sim/host.hh"
+#include <inttypes.h>
/**
* Generate a 64-bit mask of 'nbits' 1s, right justified.
diff --git a/src/base/traceflags.py b/src/base/traceflags.py
index 757c9e7b7..2402cf361 100644
--- a/src/base/traceflags.py
+++ b/src/base/traceflags.py
@@ -133,6 +133,7 @@ baseFlags = [
'PciConfigAll',
'Pipeline',
'Printf',
+ 'Quiesce',
'ROB',
'Regs',
'Rename',
@@ -182,7 +183,8 @@ compoundFlagMap = {
'EthernetNoData' : [ 'Ethernet', 'EthernetPIO', 'EthernetDesc', 'EthernetIntr', 'EthernetSM', 'EthernetCksum' ],
'IdeAll' : [ 'IdeCtrl', 'IdeDisk' ],
'O3CPUAll' : [ 'Fetch', 'Decode', 'Rename', 'IEW', 'Commit', 'IQ', 'ROB', 'FreeList', 'RenameMap', 'LSQ', 'LSQUnit', 'StoreSet', 'MemDepUnit', 'DynInst', 'FullCPU', 'O3CPU', 'Activity','Scoreboard','Writeback'],
- 'OzoneCPUAll' : [ 'BE', 'FE', 'IBE', 'OzoneLSQ', 'OzoneCPU']
+ 'OzoneCPUAll' : [ 'BE', 'FE', 'IBE', 'OzoneLSQ', 'OzoneCPU'],
+ 'All' : baseFlags
}
#############################################################
diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc
index f6d56eef6..9cb6b032e 100644
--- a/src/cpu/checker/cpu.cc
+++ b/src/cpu/checker/cpu.cc
@@ -34,10 +34,8 @@
#include "cpu/base.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/simple_thread.hh"
-#include "cpu/thread_context.hh"
#include "cpu/static_inst.hh"
-#include "mem/packet_impl.hh"
-#include "sim/byteswap.hh"
+#include "cpu/thread_context.hh"
#if FULL_SYSTEM
#include "arch/vtophys.hh"
@@ -171,7 +169,7 @@ CheckerCPU::read(Addr addr, T &data, unsigned flags)
// translate to physical address
translateDataReadReq(memReq);
- Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
+ PacketPtr pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
pkt->dataStatic(&data);
@@ -258,7 +256,7 @@ CheckerCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
T inst_data;
/*
// This code would work if the LSQ allowed for snooping.
- Packet *pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
+ PacketPtr pkt = new Packet(memReq, Packet::ReadReq, Packet::Broadcast);
pkt.dataStatic(&inst_data);
dcachePort->sendFunctional(pkt);
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 8aec79754..36c7349e6 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -37,8 +37,6 @@
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "cpu/static_inst.hh"
-#include "mem/packet_impl.hh"
-#include "sim/byteswap.hh"
#include "sim/sim_object.hh"
#include "sim/stats.hh"
@@ -183,7 +181,7 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
}
if (fault == NoFault) {
- Packet *pkt = new Packet(memReq, Packet::ReadReq,
+ PacketPtr pkt = new Packet(memReq, Packet::ReadReq,
Packet::Broadcast);
pkt->dataStatic(&machInst);
@@ -202,7 +200,7 @@ Checker<DynInstPtr>::verify(DynInstPtr &completed_inst)
validateInst(inst);
curStaticInst = StaticInst::decode(makeExtMI(machInst,
- thread->readPC()));
+ thread->getTC()));
#if FULL_SYSTEM
thread->setInst(machInst);
diff --git a/src/cpu/exetrace.cc b/src/cpu/exetrace.cc
index 8b1e60aea..9d85311bb 100644
--- a/src/cpu/exetrace.cc
+++ b/src/cpu/exetrace.cc
@@ -60,61 +60,66 @@ Trace::InstRecord::dump(ostream &outs)
if (flags[PRINT_REG_DELTA])
{
#if THE_ISA == SPARC_ISA
- static uint64_t regs[32] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0};
- static uint64_t ccr = 0;
- static uint64_t y = 0;
- static uint64_t floats[32];
- uint64_t newVal;
- static const char * prefixes[4] = {"G", "O", "L", "I"};
-
- char buf[256];
- sprintf(buf, "PC = 0x%016llx", thread->readNextPC());
- outs << buf;
- sprintf(buf, " NPC = 0x%016llx", thread->readNextNPC());
- outs << buf;
- newVal = thread->readMiscReg(SparcISA::MISCREG_CCR);
- if(newVal != ccr)
+ //Don't print what happens for each micro-op, just print out
+ //once at the last op, and for regular instructions.
+ if(!staticInst->isMicroOp() || staticInst->isLastMicroOp())
{
- sprintf(buf, " CCR = 0x%016llx", newVal);
+ static uint64_t regs[32] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0};
+ static uint64_t ccr = 0;
+ static uint64_t y = 0;
+ static uint64_t floats[32];
+ uint64_t newVal;
+ static const char * prefixes[4] = {"G", "O", "L", "I"};
+
+ char buf[256];
+ sprintf(buf, "PC = 0x%016llx", thread->readNextPC());
outs << buf;
- ccr = newVal;
- }
- newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
- if(newVal != y)
- {
- sprintf(buf, " Y = 0x%016llx", newVal);
+ sprintf(buf, " NPC = 0x%016llx", thread->readNextNPC());
outs << buf;
- y = newVal;
- }
- for(int y = 0; y < 4; y++)
- {
- for(int x = 0; x < 8; x++)
+ newVal = thread->readMiscReg(SparcISA::MISCREG_CCR);
+ if(newVal != ccr)
+ {
+ sprintf(buf, " CCR = 0x%016llx", newVal);
+ outs << buf;
+ ccr = newVal;
+ }
+ newVal = thread->readMiscReg(SparcISA::MISCREG_Y);
+ if(newVal != y)
+ {
+ sprintf(buf, " Y = 0x%016llx", newVal);
+ outs << buf;
+ y = newVal;
+ }
+ for(int y = 0; y < 4; y++)
{
- int index = x + 8 * y;
- newVal = thread->readIntReg(index);
- if(regs[index] != newVal)
+ for(int x = 0; x < 8; x++)
{
- sprintf(buf, " %s%d = 0x%016llx", prefixes[y], x, newVal);
- outs << buf;
- regs[index] = newVal;
+ int index = x + 8 * y;
+ newVal = thread->readIntReg(index);
+ if(regs[index] != newVal)
+ {
+ sprintf(buf, " %s%d = 0x%016llx", prefixes[y], x, newVal);
+ outs << buf;
+ regs[index] = newVal;
+ }
}
}
- }
- for(int y = 0; y < 32; y++)
- {
- newVal = thread->readFloatRegBits(2 * y, 64);
- if(floats[y] != newVal)
+ for(int y = 0; y < 32; y++)
{
- sprintf(buf, " F%d = 0x%016llx", y, newVal);
- outs << buf;
- floats[y] = newVal;
+ newVal = thread->readFloatRegBits(2 * y, 64);
+ if(floats[y] != newVal)
+ {
+ sprintf(buf, " F%d = 0x%016llx", 2 * y, newVal);
+ outs << buf;
+ floats[y] = newVal;
+ }
}
+ outs << endl;
}
- outs << endl;
#endif
}
else if (flags[INTEL_FORMAT]) {
diff --git a/src/cpu/memtest/memtest.cc b/src/cpu/memtest/memtest.cc
index 024cd7e41..91e073cf0 100644
--- a/src/cpu/memtest/memtest.cc
+++ b/src/cpu/memtest/memtest.cc
@@ -38,42 +38,42 @@
#include "base/misc.hh"
#include "base/statistics.hh"
-//#include "cpu/simple_thread.hh"
#include "cpu/memtest/memtest.hh"
+//#include "cpu/simple_thread.hh"
//#include "mem/cache/base_cache.hh"
+#include "mem/mem_object.hh"
+#include "mem/port.hh"
+#include "mem/packet.hh"
//#include "mem/physical.hh"
+#include "mem/request.hh"
#include "sim/builder.hh"
#include "sim/sim_events.hh"
#include "sim/stats.hh"
-#include "mem/packet.hh"
-#include "mem/request.hh"
-#include "mem/port.hh"
-#include "mem/mem_object.hh"
using namespace std;
int TESTER_ALLOCATOR=0;
bool
-MemTest::CpuPort::recvTiming(Packet *pkt)
+MemTest::CpuPort::recvTiming(PacketPtr pkt)
{
memtest->completeRequest(pkt);
return true;
}
Tick
-MemTest::CpuPort::recvAtomic(Packet *pkt)
+MemTest::CpuPort::recvAtomic(PacketPtr pkt)
{
panic("MemTest doesn't expect recvAtomic callback!");
return curTick;
}
void
-MemTest::CpuPort::recvFunctional(Packet *pkt)
+MemTest::CpuPort::recvFunctional(PacketPtr pkt)
{
//Do nothing if we see one come through
- if (curTick != 0)//Supress warning durring initialization
- warn("Functional Writes not implemented in MemTester\n");
+// if (curTick != 0)//Supress warning durring initialization
+// warn("Functional Writes not implemented in MemTester\n");
//Need to find any response values that intersect and update
return;
}
@@ -94,7 +94,7 @@ MemTest::CpuPort::recvRetry()
}
void
-MemTest::sendPkt(Packet *pkt) {
+MemTest::sendPkt(PacketPtr pkt) {
if (atomic) {
cachePort.sendAtomic(pkt);
pkt->makeAtomicResponse();
@@ -113,7 +113,7 @@ MemTest::MemTest(const string &name,
// PhysicalMemory *check_mem,
unsigned _memorySize,
unsigned _percentReads,
-// unsigned _percentCopies,
+ unsigned _percentFunctional,
unsigned _percentUncacheable,
unsigned _progressInterval,
unsigned _percentSourceUnaligned,
@@ -130,7 +130,7 @@ MemTest::MemTest(const string &name,
// checkMem(check_mem),
size(_memorySize),
percentReads(_percentReads),
-// percentCopies(_percentCopies),
+ percentFunctional(_percentFunctional),
percentUncacheable(_percentUncacheable),
progressInterval(_progressInterval),
nextProgressMessage(_progressInterval),
@@ -204,7 +204,7 @@ printData(ostream &os, uint8_t *data, int nbytes)
}
void
-MemTest::completeRequest(Packet *pkt)
+MemTest::completeRequest(PacketPtr pkt)
{
MemTestSenderState *state =
dynamic_cast<MemTestSenderState *>(pkt->senderState);
@@ -345,8 +345,8 @@ MemTest::tick()
} else {
paddr = ((base) ? baseAddr1 : baseAddr2) + offset;
}
- //bool probe = (random() % 2 == 1) && !req->isUncacheable();
- bool probe = false;
+ bool probe = (random() % 100 < percentFunctional) && !(flags & UNCACHEABLE);
+ //bool probe = false;
paddr &= ~((1 << access_size) - 1);
req->setPhys(paddr, 1 << access_size, flags);
@@ -381,13 +381,14 @@ MemTest::tick()
<< dec << curTick << endl;
}
- Packet *pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
+ PacketPtr pkt = new Packet(req, Packet::ReadReq, Packet::Broadcast);
pkt->dataDynamicArray(new uint8_t[req->getSize()]);
MemTestSenderState *state = new MemTestSenderState(result);
pkt->senderState = state;
if (probe) {
cachePort.sendFunctional(pkt);
+ pkt->makeAtomicResponse();
completeRequest(pkt);
} else {
// req->completionEvent = new MemCompleteEvent(req, result, this);
@@ -420,7 +421,7 @@ MemTest::tick()
<< dec << curTick << endl;
}
*/
- Packet *pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
+ PacketPtr pkt = new Packet(req, Packet::WriteReq, Packet::Broadcast);
uint8_t *pkt_data = new uint8_t[req->getSize()];
pkt->dataDynamicArray(pkt_data);
memcpy(pkt_data, &data, req->getSize());
@@ -431,6 +432,7 @@ MemTest::tick()
if (probe) {
cachePort.sendFunctional(pkt);
+ pkt->makeAtomicResponse();
completeRequest(pkt);
} else {
// req->completionEvent = new MemCompleteEvent(req, NULL, this);
@@ -499,7 +501,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(MemTest)
// SimObjectParam<PhysicalMemory *> check_mem;
Param<unsigned> memory_size;
Param<unsigned> percent_reads;
-// Param<unsigned> percent_copies;
+ Param<unsigned> percent_functional;
Param<unsigned> percent_uncacheable;
Param<unsigned> progress_interval;
Param<unsigned> percent_source_unaligned;
@@ -518,7 +520,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(MemTest)
// INIT_PARAM(check_mem, "check memory"),
INIT_PARAM(memory_size, "memory size"),
INIT_PARAM(percent_reads, "target read percentage"),
-// INIT_PARAM(percent_copies, "target copy percentage"),
+ INIT_PARAM(percent_functional, "percentage of access that are functional"),
INIT_PARAM(percent_uncacheable, "target uncacheable percentage"),
INIT_PARAM(progress_interval, "progress report interval (in accesses)"),
INIT_PARAM(percent_source_unaligned,
@@ -535,7 +537,7 @@ END_INIT_SIM_OBJECT_PARAMS(MemTest)
CREATE_SIM_OBJECT(MemTest)
{
return new MemTest(getInstanceName(), /*cache->getInterface(),*/ /*main_mem,*/
- /*check_mem,*/ memory_size, percent_reads, /*percent_copies,*/
+ /*check_mem,*/ memory_size, percent_reads, percent_functional,
percent_uncacheable, progress_interval,
percent_source_unaligned, percent_dest_unaligned,
trace_addr, max_loads, atomic);
diff --git a/src/cpu/memtest/memtest.hh b/src/cpu/memtest/memtest.hh
index 5de41f0d8..edde4a3b2 100644
--- a/src/cpu/memtest/memtest.hh
+++ b/src/cpu/memtest/memtest.hh
@@ -55,7 +55,7 @@ class MemTest : public MemObject
// PhysicalMemory *check_mem,
unsigned _memorySize,
unsigned _percentReads,
-// unsigned _percentCopies,
+ unsigned _percentFunctional,
unsigned _percentUncacheable,
unsigned _progressInterval,
unsigned _percentSourceUnaligned,
@@ -102,11 +102,11 @@ class MemTest : public MemObject
protected:
- virtual bool recvTiming(Packet *pkt);
+ virtual bool recvTiming(PacketPtr pkt);
- virtual Tick recvAtomic(Packet *pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
- virtual void recvFunctional(Packet *pkt);
+ virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status);
@@ -133,7 +133,7 @@ class MemTest : public MemObject
};
// Request *dataReq;
- Packet *retryPkt;
+ PacketPtr retryPkt;
// MemInterface *cacheInterface;
// PhysicalMemory *mainMem;
// PhysicalMemory *checkMem;
@@ -144,7 +144,7 @@ class MemTest : public MemObject
unsigned size; // size of testing memory region
unsigned percentReads; // target percentage of read accesses
-// unsigned percentCopies; // target percentage of copy accesses
+ unsigned percentFunctional; // target percentage of functional accesses
unsigned percentUncacheable;
int id;
@@ -184,9 +184,9 @@ class MemTest : public MemObject
Stats::Scalar<> numCopiesStat;
// called by MemCompleteEvent::process()
- void completeRequest(Packet *pkt);
+ void completeRequest(PacketPtr pkt);
- void sendPkt(Packet *pkt);
+ void sendPkt(PacketPtr pkt);
void doRetry();
diff --git a/src/cpu/o3/alpha/dyn_inst.hh b/src/cpu/o3/alpha/dyn_inst.hh
index 9dee610b6..294aadde8 100644
--- a/src/cpu/o3/alpha/dyn_inst.hh
+++ b/src/cpu/o3/alpha/dyn_inst.hh
@@ -86,7 +86,7 @@ class AlphaDynInst : public BaseDynInst<Impl>
Fault initiateAcc();
/** Completes the access. Only valid for memory operations. */
- Fault completeAcc(Packet *pkt);
+ Fault completeAcc(PacketPtr pkt);
private:
/** Initializes variables. */
diff --git a/src/cpu/o3/alpha/dyn_inst_impl.hh b/src/cpu/o3/alpha/dyn_inst_impl.hh
index 2d1b4b309..b273a7b9b 100644
--- a/src/cpu/o3/alpha/dyn_inst_impl.hh
+++ b/src/cpu/o3/alpha/dyn_inst_impl.hh
@@ -100,7 +100,7 @@ AlphaDynInst<Impl>::initiateAcc()
template <class Impl>
Fault
-AlphaDynInst<Impl>::completeAcc(Packet *pkt)
+AlphaDynInst<Impl>::completeAcc(PacketPtr pkt)
{
this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh
index 280bf0e71..5555bff85 100644
--- a/src/cpu/o3/fetch.hh
+++ b/src/cpu/o3/fetch.hh
@@ -36,7 +36,7 @@
#include "base/statistics.hh"
#include "base/timebuf.hh"
#include "cpu/pc_event.hh"
-#include "mem/packet_impl.hh"
+#include "mem/packet.hh"
#include "mem/port.hh"
#include "sim/eventq.hh"
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 07d4ebb42..e7bf83b20 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -78,9 +78,12 @@ DefaultFetch<Impl>::IcachePort::recvStatusChange(Status status)
template<class Impl>
bool
-DefaultFetch<Impl>::IcachePort::recvTiming(Packet *pkt)
+DefaultFetch<Impl>::IcachePort::recvTiming(PacketPtr pkt)
{
- fetch->processCacheCompletion(pkt);
+ if (pkt->isResponse()) {
+ fetch->processCacheCompletion(pkt);
+ }
+ //else Snooped a coherence request, just return
return true;
}
@@ -1115,7 +1118,7 @@ DefaultFetch<Impl>::fetch(bool &status_change)
inst = TheISA::gtoh(*reinterpret_cast<TheISA::MachInst *>
(&cacheData[tid][offset]));
- ext_inst = TheISA::makeExtMI(inst, fetch_PC);
+ ext_inst = TheISA::makeExtMI(inst, cpu->tcBase(tid));
// Create a new DynInst from the instruction fetched.
DynInstPtr instruction = new DynInst(ext_inst, fetch_PC,
diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh
index 7b7d1eb8e..317e23b14 100644
--- a/src/cpu/o3/lsq_impl.hh
+++ b/src/cpu/o3/lsq_impl.hh
@@ -63,7 +63,14 @@ template <class Impl>
bool
LSQ<Impl>::DcachePort::recvTiming(PacketPtr pkt)
{
- lsq->thread[pkt->req->getThreadNum()].completeDataAccess(pkt);
+ if (pkt->isResponse()) {
+ lsq->thread[pkt->req->getThreadNum()].completeDataAccess(pkt);
+ }
+ else {
+ //else it is a coherence request, maybe you need to do something
+ warn("Recieved a coherence request (Invalidate?), 03CPU doesn't"
+ "update LSQ for these\n");
+ }
return true;
}
diff --git a/src/cpu/o3/lsq_unit.hh b/src/cpu/o3/lsq_unit.hh
index 11a02e7c7..1b207fdbc 100644
--- a/src/cpu/o3/lsq_unit.hh
+++ b/src/cpu/o3/lsq_unit.hh
@@ -40,7 +40,7 @@
#include "config/full_system.hh"
#include "base/hashmap.hh"
#include "cpu/inst_seq.hh"
-#include "mem/packet_impl.hh"
+#include "mem/packet.hh"
#include "mem/port.hh"
/**
@@ -219,7 +219,7 @@ class LSQUnit {
void writeback(DynInstPtr &inst, PacketPtr pkt);
/** Handles completing the send of a store to memory. */
- void storePostSend(Packet *pkt);
+ void storePostSend(PacketPtr pkt);
/** Completes the store at the specified index. */
void completeStore(int store_idx);
diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh
index 3f9db912f..d940d7cb3 100644
--- a/src/cpu/o3/lsq_unit_impl.hh
+++ b/src/cpu/o3/lsq_unit_impl.hh
@@ -763,7 +763,7 @@ LSQUnit<Impl>::squash(const InstSeqNum &squashed_num)
template <class Impl>
void
-LSQUnit<Impl>::storePostSend(Packet *pkt)
+LSQUnit<Impl>::storePostSend(PacketPtr pkt)
{
if (isStalled() &&
storeQueue[storeWBIdx].inst->seqNum == stallingStoreIsn) {
diff --git a/src/cpu/o3/mips/dyn_inst.hh b/src/cpu/o3/mips/dyn_inst.hh
index 06bdfcec4..aa30bfa1e 100755
--- a/src/cpu/o3/mips/dyn_inst.hh
+++ b/src/cpu/o3/mips/dyn_inst.hh
@@ -87,7 +87,7 @@ class MipsDynInst : public BaseDynInst<Impl>
Fault initiateAcc();
/** Completes the access. Only valid for memory operations. */
- Fault completeAcc(Packet *pkt);
+ Fault completeAcc(PacketPtr pkt);
private:
/** Initializes variables. */
diff --git a/src/cpu/o3/mips/dyn_inst_impl.hh b/src/cpu/o3/mips/dyn_inst_impl.hh
index 57dec1ccf..5bc01b9b3 100755
--- a/src/cpu/o3/mips/dyn_inst_impl.hh
+++ b/src/cpu/o3/mips/dyn_inst_impl.hh
@@ -100,7 +100,7 @@ MipsDynInst<Impl>::initiateAcc()
template <class Impl>
Fault
-MipsDynInst<Impl>::completeAcc(Packet *pkt)
+MipsDynInst<Impl>::completeAcc(PacketPtr pkt)
{
this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
diff --git a/src/cpu/ozone/dyn_inst.hh b/src/cpu/ozone/dyn_inst.hh
index 75ac464ec..e7390626e 100644
--- a/src/cpu/ozone/dyn_inst.hh
+++ b/src/cpu/ozone/dyn_inst.hh
@@ -133,7 +133,7 @@ class OzoneDynInst : public BaseDynInst<Impl>
Fault initiateAcc();
- Fault completeAcc(Packet *pkt);
+ Fault completeAcc(PacketPtr pkt);
// The register accessor methods provide the index of the
// instruction's operand (e.g., 0 or 1), not the architectural
diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh
index db1460eba..0a1e1c139 100644
--- a/src/cpu/ozone/dyn_inst_impl.hh
+++ b/src/cpu/ozone/dyn_inst_impl.hh
@@ -108,7 +108,7 @@ OzoneDynInst<Impl>::initiateAcc()
template <class Impl>
Fault
-OzoneDynInst<Impl>::completeAcc(Packet *pkt)
+OzoneDynInst<Impl>::completeAcc(PacketPtr pkt)
{
this->fault = this->staticInst->completeAcc(pkt, this, this->traceData);
diff --git a/src/cpu/ozone/front_end.hh b/src/cpu/ozone/front_end.hh
index 59cf9785c..2bdca35b9 100644
--- a/src/cpu/ozone/front_end.hh
+++ b/src/cpu/ozone/front_end.hh
@@ -129,7 +129,7 @@ class FrontEnd
const bool is_branch = false, const bool branch_taken = false);
DynInstPtr getInst();
- void processCacheCompletion(Packet *pkt);
+ void processCacheCompletion(PacketPtr pkt);
void addFreeRegs(int num_freed);
diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh
index c814ff9c7..36e87ec9c 100644
--- a/src/cpu/ozone/front_end_impl.hh
+++ b/src/cpu/ozone/front_end_impl.hh
@@ -74,7 +74,7 @@ FrontEnd<Impl>::IcachePort::recvStatusChange(Status status)
template<class Impl>
bool
-FrontEnd<Impl>::IcachePort::recvTiming(Packet *pkt)
+FrontEnd<Impl>::IcachePort::recvTiming(PacketPtr pkt)
{
fe->processCacheCompletion(pkt);
return true;
@@ -883,7 +883,7 @@ FrontEnd<Impl>::getInstFromCacheline()
// Get the instruction from the array of the cache line.
inst = htog(*reinterpret_cast<MachInst *>(&cacheData[offset]));
- ExtMachInst decode_inst = TheISA::makeExtMI(inst, PC);
+ ExtMachInst decode_inst = TheISA::makeExtMI(inst, tc);
// Create a new DynInst from the instruction fetched.
DynInstPtr instruction = new DynInst(decode_inst, PC, PC+sizeof(MachInst),
diff --git a/src/cpu/ozone/lw_lsq.hh b/src/cpu/ozone/lw_lsq.hh
index 9b93ce74f..dc58a8285 100644
--- a/src/cpu/ozone/lw_lsq.hh
+++ b/src/cpu/ozone/lw_lsq.hh
@@ -222,7 +222,7 @@ class OzoneLWLSQ {
void writeback(DynInstPtr &inst, PacketPtr pkt);
/** Handles completing the send of a store to memory. */
- void storePostSend(Packet *pkt, DynInstPtr &inst);
+ void storePostSend(PacketPtr pkt, DynInstPtr &inst);
/** Completes the store at the specified index. */
void completeStore(DynInstPtr &inst);
@@ -260,7 +260,7 @@ class OzoneLWLSQ {
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop)
- { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1); }
+ { resp.clear(); snoop.clear(); snoop.push_back(RangeSize(0,-1)); }
virtual bool recvTiming(PacketPtr pkt);
diff --git a/src/cpu/ozone/lw_lsq_impl.hh b/src/cpu/ozone/lw_lsq_impl.hh
index e523712da..1f3f18502 100644
--- a/src/cpu/ozone/lw_lsq_impl.hh
+++ b/src/cpu/ozone/lw_lsq_impl.hh
@@ -832,7 +832,7 @@ OzoneLWLSQ<Impl>::dumpInsts()
template <class Impl>
void
-OzoneLWLSQ<Impl>::storePostSend(Packet *pkt, DynInstPtr &inst)
+OzoneLWLSQ<Impl>::storePostSend(PacketPtr pkt, DynInstPtr &inst)
{
if (isStalled() &&
inst->seqNum == stallingStoreIsn) {
diff --git a/src/cpu/quiesce_event.cc b/src/cpu/quiesce_event.cc
index 8dd20db02..fa79e6d1e 100644
--- a/src/cpu/quiesce_event.cc
+++ b/src/cpu/quiesce_event.cc
@@ -28,6 +28,7 @@
* Authors: Kevin Lim
*/
+#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "cpu/quiesce_event.hh"
@@ -39,6 +40,7 @@ EndQuiesceEvent::EndQuiesceEvent(ThreadContext *_tc)
void
EndQuiesceEvent::process()
{
+ DPRINTF(Quiesce, "activating %s\n", tc->getCpuPtr()->name());
tc->activate();
}
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 87ecafd69..edba55b0d 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -32,7 +32,8 @@
#include "arch/utility.hh"
#include "cpu/exetrace.hh"
#include "cpu/simple/atomic.hh"
-#include "mem/packet_impl.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/builder.hh"
#include "sim/system.hh"
@@ -92,21 +93,21 @@ AtomicSimpleCPU::init()
}
bool
-AtomicSimpleCPU::CpuPort::recvTiming(Packet *pkt)
+AtomicSimpleCPU::CpuPort::recvTiming(PacketPtr pkt)
{
panic("AtomicSimpleCPU doesn't expect recvTiming callback!");
return true;
}
Tick
-AtomicSimpleCPU::CpuPort::recvAtomic(Packet *pkt)
+AtomicSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt)
{
- panic("AtomicSimpleCPU doesn't expect recvAtomic callback!");
+ //Snooping a coherence request, just return
return curTick;
}
void
-AtomicSimpleCPU::CpuPort::recvFunctional(Packet *pkt)
+AtomicSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt)
{
//No internal storage to update, just return
return;
@@ -262,7 +263,7 @@ AtomicSimpleCPU::read(Addr addr, T &data, unsigned flags)
{
// use the CPU's statically allocated read request and packet objects
Request *req = data_read_req;
- Packet *pkt = data_read_pkt;
+ PacketPtr pkt = data_read_pkt;
req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
@@ -344,7 +345,7 @@ AtomicSimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
// use the CPU's statically allocated write request and packet objects
Request *req = data_write_req;
- Packet *pkt = data_write_pkt;
+ PacketPtr pkt = data_write_pkt;
req->setVirt(0, addr, sizeof(T), flags, thread->readPC());
@@ -450,7 +451,8 @@ AtomicSimpleCPU::tick()
for (int i = 0; i < width; ++i) {
numCycles++;
- checkForInterrupts();
+ if (!curStaticInst || !curStaticInst->isDelayedCommit())
+ checkForInterrupts();
Fault fault = setupFetchRequest(ifetch_req);
diff --git a/src/cpu/simple/atomic.hh b/src/cpu/simple/atomic.hh
index 52afd76ef..0edca9369 100644
--- a/src/cpu/simple/atomic.hh
+++ b/src/cpu/simple/atomic.hh
@@ -92,11 +92,11 @@ class AtomicSimpleCPU : public BaseSimpleCPU
protected:
- virtual bool recvTiming(Packet *pkt);
+ virtual bool recvTiming(PacketPtr pkt);
- virtual Tick recvAtomic(Packet *pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
- virtual void recvFunctional(Packet *pkt);
+ virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status);
@@ -110,12 +110,12 @@ class AtomicSimpleCPU : public BaseSimpleCPU
CpuPort icachePort;
CpuPort dcachePort;
- Request *ifetch_req;
- Packet *ifetch_pkt;
- Request *data_read_req;
- Packet *data_read_pkt;
- Request *data_write_req;
- Packet *data_write_pkt;
+ Request *ifetch_req;
+ PacketPtr ifetch_pkt;
+ Request *data_read_req;
+ PacketPtr data_read_pkt;
+ Request *data_write_req;
+ PacketPtr data_write_pkt;
bool dcache_access;
Tick dcache_latency;
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 522fe79aa..cbb3980cb 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -47,7 +47,7 @@
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "kern/kernel_stats.hh"
-#include "mem/packet_impl.hh"
+#include "mem/packet.hh"
#include "sim/builder.hh"
#include "sim/byteswap.hh"
#include "sim/debug.hh"
@@ -396,7 +396,20 @@ BaseSimpleCPU::preExecute()
// decode the instruction
inst = gtoh(inst);
- curStaticInst = StaticInst::decode(makeExtMI(inst, thread->readPC()));
+ //If we're not in the middle of a macro instruction
+ if (!curMacroStaticInst) {
+ StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC()));
+ if (instPtr->isMacroOp()) {
+ curMacroStaticInst = instPtr;
+ curStaticInst = curMacroStaticInst->fetchMicroOp(0);
+ } else {
+ curStaticInst = instPtr;
+ }
+ } else {
+ //Read the next micro op from the macro op
+ curStaticInst = curMacroStaticInst->fetchMicroOp(thread->readMicroPC());
+ }
+
traceData = Trace::getInstRecord(curTick, tc, curStaticInst,
thread->readPC());
@@ -446,18 +459,35 @@ BaseSimpleCPU::advancePC(Fault fault)
{
if (fault != NoFault) {
fault->invoke(tc);
- }
- else {
- // go to the next instruction
- thread->setPC(thread->readNextPC());
+ } else {
+ //If we're at the last micro op for this instruction
+ if (curStaticInst->isLastMicroOp()) {
+ //We should be working with a macro op
+ assert(curMacroStaticInst);
+ //Close out this macro op, and clean up the
+ //microcode state
+ curMacroStaticInst = StaticInst::nullStaticInstPtr;
+ thread->setMicroPC(0);
+ thread->setNextMicroPC(1);
+ }
+ //If we're still in a macro op
+ if (curMacroStaticInst) {
+ //Advance the micro pc
+ thread->setMicroPC(thread->readNextMicroPC());
+ //Advance the "next" micro pc. Note that there are no delay
+ //slots, and micro ops are "word" addressed.
+ thread->setNextMicroPC(thread->readNextMicroPC() + 1);
+ } else {
+ // go to the next instruction
+ thread->setPC(thread->readNextPC());
#if ISA_HAS_DELAY_SLOT
- thread->setNextPC(thread->readNextNPC());
- thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
- assert(thread->readNextPC() != thread->readNextNPC());
+ thread->setNextPC(thread->readNextNPC());
+ thread->setNextNPC(thread->readNextNPC() + sizeof(MachInst));
+ assert(thread->readNextPC() != thread->readNextNPC());
#else
- thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
+ thread->setNextPC(thread->readNextPC() + sizeof(MachInst));
#endif
-
+ }
}
#if FULL_SYSTEM
diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh
index 57cfa3c2c..af6b6f835 100644
--- a/src/cpu/simple/base.hh
+++ b/src/cpu/simple/base.hh
@@ -128,6 +128,7 @@ class BaseSimpleCPU : public BaseCPU
TheISA::IntReg dataReg;
StaticInstPtr curStaticInst;
+ StaticInstPtr curMacroStaticInst;
void checkForInterrupts();
Fault setupFetchRequest(Request *req);
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index ad5c0e5d6..fe6775ea4 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -32,7 +32,8 @@
#include "arch/utility.hh"
#include "cpu/exetrace.hh"
#include "cpu/simple/timing.hh"
-#include "mem/packet_impl.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/builder.hh"
#include "sim/system.hh"
@@ -65,14 +66,14 @@ TimingSimpleCPU::init()
}
Tick
-TimingSimpleCPU::CpuPort::recvAtomic(Packet *pkt)
+TimingSimpleCPU::CpuPort::recvAtomic(PacketPtr pkt)
{
panic("TimingSimpleCPU doesn't expect recvAtomic callback!");
return curTick;
}
void
-TimingSimpleCPU::CpuPort::recvFunctional(Packet *pkt)
+TimingSimpleCPU::CpuPort::recvFunctional(PacketPtr pkt)
{
//No internal storage to update, jusst return
return;
@@ -89,7 +90,7 @@ TimingSimpleCPU::CpuPort::recvStatusChange(Status status)
void
-TimingSimpleCPU::CpuPort::TickEvent::schedule(Packet *_pkt, Tick t)
+TimingSimpleCPU::CpuPort::TickEvent::schedule(PacketPtr _pkt, Tick t)
{
pkt = _pkt;
Event::schedule(t);
@@ -268,7 +269,7 @@ TimingSimpleCPU::read(Addr addr, T &data, unsigned flags)
// Now do the access.
if (fault == NoFault) {
- Packet *pkt =
+ PacketPtr pkt =
new Packet(req, Packet::ReadReq, Packet::Broadcast);
pkt->dataDynamic<T>(new T);
@@ -426,7 +427,8 @@ TimingSimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
void
TimingSimpleCPU::fetch()
{
- checkForInterrupts();
+ if (!curStaticInst || !curStaticInst->isDelayedCommit())
+ checkForInterrupts();
Request *ifetch_req = new Request();
ifetch_req->setThreadContext(cpu_id, /* thread ID */ 0);
@@ -470,7 +472,7 @@ TimingSimpleCPU::advanceInst(Fault fault)
void
-TimingSimpleCPU::completeIfetch(Packet *pkt)
+TimingSimpleCPU::completeIfetch(PacketPtr pkt)
{
// received a response from the icache: execute the received
// instruction
@@ -526,19 +528,25 @@ TimingSimpleCPU::IcachePort::ITickEvent::process()
}
bool
-TimingSimpleCPU::IcachePort::recvTiming(Packet *pkt)
+TimingSimpleCPU::IcachePort::recvTiming(PacketPtr pkt)
{
- // delay processing of returned data until next CPU clock edge
- Tick time = pkt->req->getTime();
- while (time < curTick)
- time += lat;
+ if (pkt->isResponse()) {
+ // delay processing of returned data until next CPU clock edge
+ Tick time = pkt->req->getTime();
+ while (time < curTick)
+ time += lat;
- if (time == curTick)
- cpu->completeIfetch(pkt);
- else
- tickEvent.schedule(pkt, time);
+ if (time == curTick)
+ cpu->completeIfetch(pkt);
+ else
+ tickEvent.schedule(pkt, time);
- return true;
+ return true;
+ }
+ else {
+ //Snooping a Coherence Request, do nothing
+ return true;
+ }
}
void
@@ -548,7 +556,7 @@ TimingSimpleCPU::IcachePort::recvRetry()
// waiting to transmit
assert(cpu->ifetch_pkt != NULL);
assert(cpu->_status == IcacheRetry);
- Packet *tmp = cpu->ifetch_pkt;
+ PacketPtr tmp = cpu->ifetch_pkt;
if (sendTiming(tmp)) {
cpu->_status = IcacheWaitResponse;
cpu->ifetch_pkt = NULL;
@@ -556,7 +564,7 @@ TimingSimpleCPU::IcachePort::recvRetry()
}
void
-TimingSimpleCPU::completeDataAccess(Packet *pkt)
+TimingSimpleCPU::completeDataAccess(PacketPtr pkt)
{
// received a response from the dcache: complete the load or store
// instruction
@@ -598,19 +606,25 @@ TimingSimpleCPU::completeDrain()
}
bool
-TimingSimpleCPU::DcachePort::recvTiming(Packet *pkt)
+TimingSimpleCPU::DcachePort::recvTiming(PacketPtr pkt)
{
- // delay processing of returned data until next CPU clock edge
- Tick time = pkt->req->getTime();
- while (time < curTick)
- time += lat;
+ if (pkt->isResponse()) {
+ // delay processing of returned data until next CPU clock edge
+ Tick time = pkt->req->getTime();
+ while (time < curTick)
+ time += lat;
- if (time == curTick)
- cpu->completeDataAccess(pkt);
- else
- tickEvent.schedule(pkt, time);
+ if (time == curTick)
+ cpu->completeDataAccess(pkt);
+ else
+ tickEvent.schedule(pkt, time);
- return true;
+ return true;
+ }
+ else {
+ //Snooping a coherence req, do nothing
+ return true;
+ }
}
void
@@ -626,7 +640,7 @@ TimingSimpleCPU::DcachePort::recvRetry()
// waiting to transmit
assert(cpu->dcache_pkt != NULL);
assert(cpu->_status == DcacheRetry);
- Packet *tmp = cpu->dcache_pkt;
+ PacketPtr tmp = cpu->dcache_pkt;
if (sendTiming(tmp)) {
cpu->_status = DcacheWaitResponse;
// memory system takes ownership of packet
diff --git a/src/cpu/simple/timing.hh b/src/cpu/simple/timing.hh
index 988ddeded..577e13e40 100644
--- a/src/cpu/simple/timing.hh
+++ b/src/cpu/simple/timing.hh
@@ -84,9 +84,9 @@ class TimingSimpleCPU : public BaseSimpleCPU
protected:
- virtual Tick recvAtomic(Packet *pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
- virtual void recvFunctional(Packet *pkt);
+ virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status);
@@ -96,13 +96,13 @@ class TimingSimpleCPU : public BaseSimpleCPU
struct TickEvent : public Event
{
- Packet *pkt;
+ PacketPtr pkt;
TimingSimpleCPU *cpu;
TickEvent(TimingSimpleCPU *_cpu)
:Event(&mainEventQueue), cpu(_cpu) {}
const char *description() { return "Timing CPU clock event"; }
- void schedule(Packet *_pkt, Tick t);
+ void schedule(PacketPtr _pkt, Tick t);
};
};
@@ -117,7 +117,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
protected:
- virtual bool recvTiming(Packet *pkt);
+ virtual bool recvTiming(PacketPtr pkt);
virtual void recvRetry();
@@ -144,7 +144,7 @@ class TimingSimpleCPU : public BaseSimpleCPU
protected:
- virtual bool recvTiming(Packet *pkt);
+ virtual bool recvTiming(PacketPtr pkt);
virtual void recvRetry();
@@ -163,8 +163,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
IcachePort icachePort;
DcachePort dcachePort;
- Packet *ifetch_pkt;
- Packet *dcache_pkt;
+ PacketPtr ifetch_pkt;
+ PacketPtr dcache_pkt;
int cpu_id;
Tick previousTick;
@@ -192,8 +192,8 @@ class TimingSimpleCPU : public BaseSimpleCPU
Fault write(T data, Addr addr, unsigned flags, uint64_t *res);
void fetch();
- void completeIfetch(Packet *);
- void completeDataAccess(Packet *);
+ void completeIfetch(PacketPtr );
+ void completeDataAccess(PacketPtr );
void advanceInst(Fault fault);
private:
void completeDrain();
diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh
index 6fa6500bd..fe22e6c43 100644
--- a/src/cpu/simple_thread.hh
+++ b/src/cpu/simple_thread.hh
@@ -377,6 +377,16 @@ class SimpleThread : public ThreadState
regs.setPC(val);
}
+ uint64_t readMicroPC()
+ {
+ return microPC;
+ }
+
+ void setMicroPC(uint64_t val)
+ {
+ microPC = val;
+ }
+
uint64_t readNextPC()
{
return regs.readNextPC();
@@ -387,6 +397,16 @@ class SimpleThread : public ThreadState
regs.setNextPC(val);
}
+ uint64_t readNextMicroPC()
+ {
+ return nextMicroPC;
+ }
+
+ void setNextMicroPC(uint64_t val)
+ {
+ nextMicroPC = val;
+ }
+
uint64_t readNextNPC()
{
return regs.readNextNPC();
diff --git a/src/cpu/static_inst.cc b/src/cpu/static_inst.cc
index c311d2282..cb4a7cdf7 100644
--- a/src/cpu/static_inst.cc
+++ b/src/cpu/static_inst.cc
@@ -75,3 +75,10 @@ StaticInst::hasBranchTarget(Addr pc, ThreadContext *tc, Addr &tgt) const
return false;
}
+StaticInstPtr
+StaticInst::fetchMicroOp(MicroPC micropc)
+{
+ panic("StaticInst::fetchMicroOp() called on instruction "
+ "that is not microcoded.");
+}
+
diff --git a/src/cpu/static_inst.hh b/src/cpu/static_inst.hh
index 578d14191..523cfae40 100644
--- a/src/cpu/static_inst.hh
+++ b/src/cpu/static_inst.hh
@@ -67,6 +67,8 @@ namespace Trace {
class InstRecord;
}
+typedef uint32_t MicroPC;
+
/**
* Base, ISA-independent static instruction class.
*
@@ -139,6 +141,14 @@ class StaticInstBase : public RefCounted
IsIprAccess, ///< Accesses IPRs
IsUnverifiable, ///< Can't be verified by a checker
+ //Flags for microcode
+ IsMacroOp, ///< Is a macroop containing microops
+ IsMicroOp, ///< Is a microop
+ IsDelayedCommit, ///< This microop doesn't commit right away
+ IsLastMicroOp, ///< This microop ends a microop sequence
+ //This flag doesn't do anything yet
+ IsMicroBranch, ///< This microop branches within the microcode for a macroop
+
NumFlags
};
@@ -230,6 +240,12 @@ class StaticInstBase : public RefCounted
bool isQuiesce() const { return flags[IsQuiesce]; }
bool isIprAccess() const { return flags[IsIprAccess]; }
bool isUnverifiable() const { return flags[IsUnverifiable]; }
+ bool isMacroOp() const { return flags[IsMacroOp]; }
+ bool isMicroOp() const { return flags[IsMicroOp]; }
+ bool isDelayedCommit() const { return flags[IsDelayedCommit]; }
+ bool isLastMicroOp() const { return flags[IsLastMicroOp]; }
+ //This flag doesn't do anything yet
+ bool isMicroBranch() const { return flags[IsMicroBranch]; }
//@}
/// Operation class. Used to select appropriate function unit in issue.
@@ -347,6 +363,12 @@ class StaticInst : public StaticInstBase
#include "cpu/static_inst_exec_sigs.hh"
/**
+ * Return the microop that goes with a particular micropc. This should
+ * only be defined/used in macroops which will contain microops
+ */
+ virtual StaticInstPtr fetchMicroOp(MicroPC micropc);
+
+ /**
* Return the target address for a PC-relative branch.
* Invalid if not a PC-relative branch (i.e. isDirectCtrl()
* should be true).
diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc
index 6a96560f1..c644ae8d7 100644
--- a/src/cpu/thread_state.cc
+++ b/src/cpu/thread_state.cc
@@ -42,13 +42,13 @@
ThreadState::ThreadState(int _cpuId, int _tid)
: cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
- funcExeInst(0), storeCondFailures(0)
+ microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0)
#else
ThreadState::ThreadState(int _cpuId, int _tid, Process *_process,
short _asid, MemObject *mem)
: cpuId(_cpuId), tid(_tid), lastActivate(0), lastSuspend(0),
process(_process), asid(_asid),
- funcExeInst(0), storeCondFailures(0)
+ microPC(0), nextMicroPC(1), funcExeInst(0), storeCondFailures(0)
#endif
{
numInst = 0;
diff --git a/src/cpu/thread_state.hh b/src/cpu/thread_state.hh
index 14e033b7f..60353760c 100644
--- a/src/cpu/thread_state.hh
+++ b/src/cpu/thread_state.hh
@@ -200,6 +200,16 @@ struct ThreadState {
*/
TheISA::MachInst inst;
+ /** The current microcode pc for the currently executing macro
+ * operation.
+ */
+ MicroPC microPC;
+
+ /** The next microcode pc for the currently executing macro
+ * operation.
+ */
+ MicroPC nextMicroPC;
+
public:
/**
* Temporary storage to pass the source address from copy_load to
diff --git a/src/dev/alpha_console.cc b/src/dev/alpha_console.cc
index 181bbf934..40868de51 100644
--- a/src/dev/alpha_console.cc
+++ b/src/dev/alpha_console.cc
@@ -48,6 +48,8 @@
#include "dev/platform.hh"
#include "dev/simconsole.hh"
#include "dev/simple_disk.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "mem/physical.hh"
#include "sim/builder.hh"
#include "sim/sim_object.hh"
@@ -92,7 +94,7 @@ AlphaConsole::startup()
}
Tick
-AlphaConsole::read(Packet *pkt)
+AlphaConsole::read(PacketPtr pkt)
{
/** XXX Do we want to push the addr munging to a bus brige or something? So
@@ -193,7 +195,7 @@ AlphaConsole::read(Packet *pkt)
}
Tick
-AlphaConsole::write(Packet *pkt)
+AlphaConsole::write(PacketPtr pkt)
{
assert(pkt->result == Packet::Unknown);
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
diff --git a/src/dev/alpha_console.hh b/src/dev/alpha_console.hh
index b6360d40f..7d6d1e679 100644
--- a/src/dev/alpha_console.hh
+++ b/src/dev/alpha_console.hh
@@ -118,8 +118,8 @@ class AlphaConsole : public BasicPioDevice
/**
* memory mapped reads and writes
*/
- virtual Tick read(Packet *pkt);
- virtual Tick write(Packet *pkt);
+ virtual Tick read(PacketPtr pkt);
+ virtual Tick write(PacketPtr pkt);
/**
* standard serialization routines for checkpointing
diff --git a/src/dev/baddev.cc b/src/dev/baddev.cc
index e4297be19..1bab93492 100644
--- a/src/dev/baddev.cc
+++ b/src/dev/baddev.cc
@@ -53,13 +53,13 @@ BadDevice::BadDevice(Params *p)
}
Tick
-BadDevice::read(Packet *pkt)
+BadDevice::read(PacketPtr pkt)
{
panic("Device %s not imlpmented\n", devname);
}
Tick
-BadDevice::write(Packet *pkt)
+BadDevice::write(PacketPtr pkt)
{
panic("Device %s not imlpmented\n", devname);
}
diff --git a/src/dev/baddev.hh b/src/dev/baddev.hh
index d7d778af4..040fff8e5 100644
--- a/src/dev/baddev.hh
+++ b/src/dev/baddev.hh
@@ -67,8 +67,8 @@ class BadDevice : public BasicPioDevice
*/
BadDevice(Params *p);
- virtual Tick read(Packet *pkt);
- virtual Tick write(Packet *pkt);
+ virtual Tick read(PacketPtr pkt);
+ virtual Tick write(PacketPtr pkt);
};
#endif // __DEV_BADDEV_HH__
diff --git a/src/dev/i8254xGBe.cc b/src/dev/i8254xGBe.cc
index 77c731899..943e6881f 100644
--- a/src/dev/i8254xGBe.cc
+++ b/src/dev/i8254xGBe.cc
@@ -47,7 +47,7 @@ IGbE::IGbE(Params *p)
Tick
-IGbE::writeConfig(Packet *pkt)
+IGbE::writeConfig(PacketPtr pkt)
{
int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
if (offset < PCI_DEVICE_SPECIFIC)
@@ -63,7 +63,7 @@ IGbE::writeConfig(Packet *pkt)
}
Tick
-IGbE::read(Packet *pkt)
+IGbE::read(PacketPtr pkt)
{
int bar;
Addr daddr;
@@ -88,7 +88,7 @@ IGbE::read(Packet *pkt)
}
Tick
-IGbE::write(Packet *pkt)
+IGbE::write(PacketPtr pkt)
{
int bar;
Addr daddr;
diff --git a/src/dev/i8254xGBe.hh b/src/dev/i8254xGBe.hh
index 88931eb6d..161d8befc 100644
--- a/src/dev/i8254xGBe.hh
+++ b/src/dev/i8254xGBe.hh
@@ -59,10 +59,10 @@ class IGbE : public PciDev
IGbE(Params *params);
~IGbE() {;}
- virtual Tick read(Packet *pkt);
- virtual Tick write(Packet *pkt);
+ virtual Tick read(PacketPtr pkt);
+ virtual Tick write(PacketPtr pkt);
- virtual Tick writeConfig(Packet *pkt);
+ virtual Tick writeConfig(PacketPtr pkt);
bool ethRxPkt(EthPacketPtr packet);
void ethTxDone();
diff --git a/src/dev/ide_ctrl.cc b/src/dev/ide_ctrl.cc
index 8007fda5e..1afad529f 100644
--- a/src/dev/ide_ctrl.cc
+++ b/src/dev/ide_ctrl.cc
@@ -43,6 +43,7 @@
#include "dev/pcireg.h"
#include "dev/platform.hh"
#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/builder.hh"
#include "sim/sim_object.hh"
#include "sim/byteswap.hh"
@@ -228,7 +229,7 @@ IdeController::setDmaComplete(IdeDisk *disk)
////
Tick
-IdeController::readConfig(Packet *pkt)
+IdeController::readConfig(PacketPtr pkt)
{
int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
if (offset < PCI_DEVICE_SPECIFIC)
@@ -301,7 +302,7 @@ IdeController::readConfig(Packet *pkt)
Tick
-IdeController::writeConfig(Packet *pkt)
+IdeController::writeConfig(PacketPtr pkt)
{
int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
if (offset < PCI_DEVICE_SPECIFIC) {
@@ -408,7 +409,7 @@ IdeController::writeConfig(Packet *pkt)
Tick
-IdeController::read(Packet *pkt)
+IdeController::read(PacketPtr pkt)
{
Addr offset;
IdeChannel channel;
@@ -494,7 +495,7 @@ IdeController::read(Packet *pkt)
}
Tick
-IdeController::write(Packet *pkt)
+IdeController::write(PacketPtr pkt)
{
Addr offset;
IdeChannel channel;
diff --git a/src/dev/ide_ctrl.hh b/src/dev/ide_ctrl.hh
index 5842d322e..291446d1c 100644
--- a/src/dev/ide_ctrl.hh
+++ b/src/dev/ide_ctrl.hh
@@ -204,8 +204,8 @@ class IdeController : public PciDev
IdeController(Params *p);
~IdeController();
- virtual Tick writeConfig(Packet *pkt);
- virtual Tick readConfig(Packet *pkt);
+ virtual Tick writeConfig(PacketPtr pkt);
+ virtual Tick readConfig(PacketPtr pkt);
void setDmaComplete(IdeDisk *disk);
@@ -214,14 +214,14 @@ class IdeController : public PciDev
* @param pkt Packet describing what is to be read
* @return The amount of time to complete this request
*/
- virtual Tick read(Packet *pkt);
+ virtual Tick read(PacketPtr pkt);
/**
* Write a done field for a given target.
* @param pkt Packet describing what is to be written
* @return The amount of time to complete this request
*/
- virtual Tick write(Packet *pkt);
+ virtual Tick write(PacketPtr pkt);
/**
* Serialize this object to the given output stream.
diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc
index 408d8de3e..9671d77cc 100644
--- a/src/dev/io_device.cc
+++ b/src/dev/io_device.cc
@@ -42,7 +42,7 @@ PioPort::PioPort(PioDevice *dev, System *s, std::string pname)
Tick
-PioPort::recvAtomic(Packet *pkt)
+PioPort::recvAtomic(PacketPtr pkt)
{
return pkt->isRead() ? device->read(pkt) : device->write(pkt);
}
@@ -97,7 +97,7 @@ DmaPort::DmaPort(DmaDevice *dev, System *s)
{ }
bool
-DmaPort::recvTiming(Packet *pkt)
+DmaPort::recvTiming(PacketPtr pkt)
{
@@ -165,7 +165,7 @@ DmaPort::drain(Event *de)
void
DmaPort::recvRetry()
{
- Packet* pkt = transmitList.front();
+ PacketPtr pkt = transmitList.front();
bool result = true;
while (result && transmitList.size()) {
DPRINTF(DMA, "Retry on Packet %#x with senderState: %#x\n",
@@ -194,7 +194,7 @@ DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
for (ChunkGenerator gen(addr, size, peerBlockSize());
!gen.done(); gen.next()) {
Request *req = new Request(gen.addr(), gen.size(), 0);
- Packet *pkt = new Packet(req, cmd, Packet::Broadcast);
+ PacketPtr pkt = new Packet(req, cmd, Packet::Broadcast);
// Increment the data pointer on a write
if (data)
@@ -211,7 +211,7 @@ DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
void
-DmaPort::sendDma(Packet *pkt, bool front)
+DmaPort::sendDma(PacketPtr pkt, bool front)
{
// some kind of selction between access methods
// more work is going to have to be done to make
diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh
index 24e822a40..aa242d170 100644
--- a/src/dev/io_device.hh
+++ b/src/dev/io_device.hh
@@ -33,9 +33,9 @@
#define __DEV_IO_DEVICE_HH__
#include "mem/mem_object.hh"
-#include "mem/packet_impl.hh"
-#include "sim/sim_object.hh"
+#include "mem/packet.hh"
#include "mem/tport.hh"
+#include "sim/sim_object.hh"
class Event;
class Platform;
@@ -56,7 +56,7 @@ class PioPort : public SimpleTimingPort
/** The device that this port serves. */
PioDevice *device;
- virtual Tick recvAtomic(Packet *pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop);
@@ -91,7 +91,7 @@ class DmaPort : public Port
};
DmaDevice *device;
- std::list<Packet*> transmitList;
+ std::list<PacketPtr> transmitList;
/** The system that device/port are in. This is used to select which mode
* we are currently operating in. */
@@ -107,10 +107,10 @@ class DmaPort : public Port
* here.*/
Event *drainEvent;
- virtual bool recvTiming(Packet *pkt);
- virtual Tick recvAtomic(Packet *pkt)
+ virtual bool recvTiming(PacketPtr pkt);
+ virtual Tick recvAtomic(PacketPtr pkt)
{ panic("dma port shouldn't be used for pio access."); }
- virtual void recvFunctional(Packet *pkt)
+ virtual void recvFunctional(PacketPtr pkt)
{ panic("dma port shouldn't be used for pio access."); }
virtual void recvStatusChange(Status status)
@@ -122,7 +122,7 @@ class DmaPort : public Port
AddrRangeList &snoop)
{ resp.clear(); snoop.clear(); }
- void sendDma(Packet *pkt, bool front = false);
+ void sendDma(PacketPtr pkt, bool front = false);
public:
DmaPort(DmaDevice *dev, System *s);
@@ -163,14 +163,14 @@ class PioDevice : public MemObject
* @param pkt Packet describing this request
* @return number of ticks it took to complete
*/
- virtual Tick read(Packet *pkt) = 0;
+ virtual Tick read(PacketPtr pkt) = 0;
/** Pure virtual function that the device must implement. Called when a
* write command is recieved by the port.
* @param pkt Packet describing this request
* @return number of ticks it took to complete
*/
- virtual Tick write(Packet *pkt) = 0;
+ virtual Tick write(PacketPtr pkt) = 0;
public:
/** Params struct which is extended through each device based on
diff --git a/src/dev/isa_fake.cc b/src/dev/isa_fake.cc
index 9622f015c..23761cd10 100644
--- a/src/dev/isa_fake.cc
+++ b/src/dev/isa_fake.cc
@@ -40,6 +40,7 @@
#include "base/trace.hh"
#include "dev/isa_fake.hh"
#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/builder.hh"
#include "sim/system.hh"
@@ -52,7 +53,7 @@ IsaFake::IsaFake(Params *p)
}
Tick
-IsaFake::read(Packet *pkt)
+IsaFake::read(PacketPtr pkt)
{
assert(pkt->result == Packet::Unknown);
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
@@ -60,6 +61,7 @@ IsaFake::read(Packet *pkt)
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());
switch (pkt->getSize()) {
+ case sizeof(uint64_t):
pkt->set(0xFFFFFFFFFFFFFFFFULL);
break;
case sizeof(uint32_t):
@@ -79,7 +81,7 @@ IsaFake::read(Packet *pkt)
}
Tick
-IsaFake::write(Packet *pkt)
+IsaFake::write(PacketPtr pkt)
{
DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt->getAddr(), pkt->getSize());
pkt->result = Packet::Success;
diff --git a/src/dev/isa_fake.hh b/src/dev/isa_fake.hh
index 5166882f8..366061c25 100644
--- a/src/dev/isa_fake.hh
+++ b/src/dev/isa_fake.hh
@@ -36,9 +36,10 @@
#ifndef __ISA_FAKE_HH__
#define __ISA_FAKE_HH__
-#include "dev/tsunami.hh"
#include "base/range.hh"
#include "dev/io_device.hh"
+#include "dev/tsunami.hh"
+#include "mem/packet.hh"
/**
* IsaFake is a device that returns -1 on all reads and
@@ -68,14 +69,14 @@ class IsaFake : public BasicPioDevice
* @param pkt The memory request.
* @param data Where to put the data.
*/
- virtual Tick read(Packet *pkt);
+ virtual Tick read(PacketPtr pkt);
/**
* All writes are simply ignored.
* @param pkt The memory request.
* @param data the data to not write.
*/
- virtual Tick write(Packet *pkt);
+ virtual Tick write(PacketPtr pkt);
};
#endif // __TSUNAMI_FAKE_HH__
diff --git a/src/dev/ns_gige.cc b/src/dev/ns_gige.cc
index 704afcf7d..19c553d87 100644
--- a/src/dev/ns_gige.cc
+++ b/src/dev/ns_gige.cc
@@ -43,6 +43,7 @@
#include "dev/ns_gige.hh"
#include "dev/pciconfigall.hh"
#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/builder.hh"
#include "sim/debug.hh"
#include "sim/host.hh"
@@ -466,7 +467,7 @@ NSGigE::regStats()
* This is to write to the PCI general configuration registers
*/
Tick
-NSGigE::writeConfig(Packet *pkt)
+NSGigE::writeConfig(PacketPtr pkt)
{
int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
if (offset < PCI_DEVICE_SPECIFIC)
@@ -494,7 +495,7 @@ NSGigE::writeConfig(Packet *pkt)
* spec sheet
*/
Tick
-NSGigE::read(Packet *pkt)
+NSGigE::read(PacketPtr pkt)
{
assert(ioEnable);
@@ -718,7 +719,7 @@ NSGigE::read(Packet *pkt)
}
Tick
-NSGigE::write(Packet *pkt)
+NSGigE::write(PacketPtr pkt)
{
assert(ioEnable);
diff --git a/src/dev/ns_gige.hh b/src/dev/ns_gige.hh
index 080c0b1f3..a40fe3b29 100644
--- a/src/dev/ns_gige.hh
+++ b/src/dev/ns_gige.hh
@@ -375,10 +375,10 @@ class NSGigE : public PciDev
~NSGigE();
const Params *params() const { return (const Params *)_params; }
- virtual Tick writeConfig(Packet *pkt);
+ virtual Tick writeConfig(PacketPtr pkt);
- virtual Tick read(Packet *pkt);
- virtual Tick write(Packet *pkt);
+ virtual Tick read(PacketPtr pkt);
+ virtual Tick write(PacketPtr pkt);
bool cpuIntrPending() const;
void cpuIntrAck() { cpuIntrClear(); }
diff --git a/src/dev/pciconfigall.cc b/src/dev/pciconfigall.cc
index 68013eab8..39c8f0fa0 100644
--- a/src/dev/pciconfigall.cc
+++ b/src/dev/pciconfigall.cc
@@ -38,6 +38,7 @@
#include "dev/pcireg.h"
#include "dev/platform.hh"
#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/builder.hh"
#include "sim/system.hh"
@@ -51,7 +52,7 @@ PciConfigAll::PciConfigAll(Params *p)
Tick
-PciConfigAll::read(Packet *pkt)
+PciConfigAll::read(PacketPtr pkt)
{
assert(pkt->result == Packet::Unknown);
@@ -78,7 +79,7 @@ PciConfigAll::read(Packet *pkt)
}
Tick
-PciConfigAll::write(Packet *pkt)
+PciConfigAll::write(PacketPtr pkt)
{
assert(pkt->result == Packet::Unknown);
panic("Attempting to write to config space on non-existant device\n");
diff --git a/src/dev/pciconfigall.hh b/src/dev/pciconfigall.hh
index 07eaf8112..720a2f005 100644
--- a/src/dev/pciconfigall.hh
+++ b/src/dev/pciconfigall.hh
@@ -73,7 +73,7 @@ class PciConfigAll : public PioDevice
* @param pkt Contains information about the read operation
* @return Amount of time to do the read
*/
- virtual Tick read(Packet *pkt);
+ virtual Tick read(PacketPtr pkt);
/**
* Write to PCI config spcae. If the device does not exit the simulator
@@ -83,7 +83,7 @@ class PciConfigAll : public PioDevice
* @return Amount of time to do the read
*/
- virtual Tick write(Packet *pkt);
+ virtual Tick write(PacketPtr pkt);
void addressRanges(AddrRangeList &range_list);
diff --git a/src/dev/pcidev.cc b/src/dev/pcidev.cc
index b16ddb31a..8c0d03817 100644
--- a/src/dev/pcidev.cc
+++ b/src/dev/pcidev.cc
@@ -47,6 +47,7 @@
#include "dev/pcidev.hh"
#include "dev/tsunamireg.h"
#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/builder.hh"
#include "sim/byteswap.hh"
#include "sim/param.hh"
@@ -65,7 +66,7 @@ PciDev::PciConfigPort::PciConfigPort(PciDev *dev, int busid, int devid,
Tick
-PciDev::PciConfigPort::recvAtomic(Packet *pkt)
+PciDev::PciConfigPort::recvAtomic(PacketPtr pkt)
{
assert(pkt->result == Packet::Unknown);
assert(pkt->getAddr() >= configAddr &&
@@ -122,7 +123,7 @@ PciDev::drain(Event *de)
}
Tick
-PciDev::readConfig(Packet *pkt)
+PciDev::readConfig(PacketPtr pkt)
{
int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
if (offset >= PCI_DEVICE_SPECIFIC)
@@ -171,7 +172,7 @@ PciDev::addressRanges(AddrRangeList &range_list)
}
Tick
-PciDev::writeConfig(Packet *pkt)
+PciDev::writeConfig(PacketPtr pkt)
{
int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
if (offset >= PCI_DEVICE_SPECIFIC)
diff --git a/src/dev/pcidev.hh b/src/dev/pcidev.hh
index 22dd6296e..fbfdbb65c 100644
--- a/src/dev/pcidev.hh
+++ b/src/dev/pcidev.hh
@@ -40,6 +40,7 @@
#include "dev/io_device.hh"
#include "dev/pcireg.h"
#include "dev/platform.hh"
+#include "sim/byteswap.hh"
#define BAR_IO_MASK 0x3
#define BAR_MEM_MASK 0xF
@@ -83,7 +84,7 @@ class PciDev : public DmaDevice
protected:
PciDev *device;
- virtual Tick recvAtomic(Packet *pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
virtual void getDeviceAddressRanges(AddrRangeList &resp,
AddrRangeList &snoop);
@@ -201,7 +202,7 @@ class PciDev : public DmaDevice
* for normal operations that it does not need to override.
* @param pkt packet containing the write the offset into config space
*/
- virtual Tick writeConfig(Packet *pkt);
+ virtual Tick writeConfig(PacketPtr pkt);
/**
@@ -210,7 +211,7 @@ class PciDev : public DmaDevice
* for normal operations that it does not need to override.
* @param pkt packet containing the write the offset into config space
*/
- virtual Tick readConfig(Packet *pkt);
+ virtual Tick readConfig(PacketPtr pkt);
public:
Addr pciToDma(Addr pciAddr) const
diff --git a/src/dev/sinic.cc b/src/dev/sinic.cc
index 61fb3aa24..f61c161aa 100644
--- a/src/dev/sinic.cc
+++ b/src/dev/sinic.cc
@@ -38,6 +38,7 @@
#include "dev/etherlink.hh"
#include "dev/sinic.hh"
#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/builder.hh"
#include "sim/debug.hh"
#include "sim/eventq.hh"
@@ -313,7 +314,7 @@ Device::prepareWrite(int cpu, int index)
* I/O read of device register
*/
Tick
-Device::read(Packet *pkt)
+Device::read(PacketPtr pkt)
{
assert(config.command & PCI_CMD_MSE);
assert(pkt->getAddr() >= BARAddrs[0] && pkt->getSize() < BARSize[0]);
@@ -400,7 +401,7 @@ Device::iprRead(Addr daddr, int cpu, uint64_t &result)
* I/O write of device register
*/
Tick
-Device::write(Packet *pkt)
+Device::write(PacketPtr pkt)
{
assert(config.command & PCI_CMD_MSE);
assert(pkt->getAddr() >= BARAddrs[0] && pkt->getSize() < BARSize[0]);
diff --git a/src/dev/sinic.hh b/src/dev/sinic.hh
index eece4ba6b..3904c2a8a 100644
--- a/src/dev/sinic.hh
+++ b/src/dev/sinic.hh
@@ -264,8 +264,8 @@ class Device : public Base
* Memory Interface
*/
public:
- virtual Tick read(Packet *pkt);
- virtual Tick write(Packet *pkt);
+ virtual Tick read(PacketPtr pkt);
+ virtual Tick write(PacketPtr pkt);
virtual void resume();
void prepareIO(int cpu, int index);
diff --git a/src/dev/tsunami_cchip.cc b/src/dev/tsunami_cchip.cc
index 3feb7439f..74a68566c 100644
--- a/src/dev/tsunami_cchip.cc
+++ b/src/dev/tsunami_cchip.cc
@@ -39,12 +39,14 @@
#include "arch/alpha/ev5.hh"
#include "base/trace.hh"
+#include "cpu/intr_control.hh"
+#include "cpu/thread_context.hh"
+#include "dev/tsunami.hh"
#include "dev/tsunami_cchip.hh"
#include "dev/tsunamireg.h"
-#include "dev/tsunami.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "mem/port.hh"
-#include "cpu/thread_context.hh"
-#include "cpu/intr_control.hh"
#include "sim/builder.hh"
#include "sim/system.hh"
@@ -72,7 +74,7 @@ TsunamiCChip::TsunamiCChip(Params *p)
}
Tick
-TsunamiCChip::read(Packet *pkt)
+TsunamiCChip::read(PacketPtr pkt)
{
DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt->getAddr(), pkt->getSize());
@@ -182,7 +184,7 @@ TsunamiCChip::read(Packet *pkt)
}
Tick
-TsunamiCChip::write(Packet *pkt)
+TsunamiCChip::write(PacketPtr pkt)
{
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
Addr daddr = pkt->getAddr() - pioAddr;
diff --git a/src/dev/tsunami_cchip.hh b/src/dev/tsunami_cchip.hh
index ef43f621f..297a94129 100644
--- a/src/dev/tsunami_cchip.hh
+++ b/src/dev/tsunami_cchip.hh
@@ -94,9 +94,9 @@ class TsunamiCChip : public BasicPioDevice
*/
TsunamiCChip(Params *p);
- virtual Tick read(Packet *pkt);
+ virtual Tick read(PacketPtr pkt);
- virtual Tick write(Packet *pkt);
+ virtual Tick write(PacketPtr pkt);
/**
* post an RTC interrupt to the CPU
diff --git a/src/dev/tsunami_io.cc b/src/dev/tsunami_io.cc
index e3da10eb5..73af6c2ef 100644
--- a/src/dev/tsunami_io.cc
+++ b/src/dev/tsunami_io.cc
@@ -47,6 +47,8 @@
#include "dev/tsunami.hh"
#include "dev/tsunami_io.hh"
#include "dev/tsunamireg.h"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "mem/port.hh"
#include "sim/builder.hh"
#include "sim/system.hh"
@@ -446,7 +448,7 @@ TsunamiIO::frequency() const
}
Tick
-TsunamiIO::read(Packet *pkt)
+TsunamiIO::read(PacketPtr pkt)
{
assert(pkt->result == Packet::Unknown);
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
@@ -512,7 +514,7 @@ TsunamiIO::read(Packet *pkt)
}
Tick
-TsunamiIO::write(Packet *pkt)
+TsunamiIO::write(PacketPtr pkt)
{
assert(pkt->result == Packet::Unknown);
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
diff --git a/src/dev/tsunami_io.hh b/src/dev/tsunami_io.hh
index 9084a1be8..5ea3628c1 100644
--- a/src/dev/tsunami_io.hh
+++ b/src/dev/tsunami_io.hh
@@ -328,8 +328,8 @@ class TsunamiIO : public BasicPioDevice
*/
TsunamiIO(Params *p);
- virtual Tick read(Packet *pkt);
- virtual Tick write(Packet *pkt);
+ virtual Tick read(PacketPtr pkt);
+ virtual Tick write(PacketPtr pkt);
/**
* Post an PIC interrupt to the CPU via the CChip
diff --git a/src/dev/tsunami_pchip.cc b/src/dev/tsunami_pchip.cc
index 8a542b9b0..549db1a50 100644
--- a/src/dev/tsunami_pchip.cc
+++ b/src/dev/tsunami_pchip.cc
@@ -42,6 +42,7 @@
#include "dev/tsunamireg.h"
#include "dev/tsunami.hh"
#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/builder.hh"
#include "sim/system.hh"
@@ -68,7 +69,7 @@ TsunamiPChip::TsunamiPChip(Params *p)
}
Tick
-TsunamiPChip::read(Packet *pkt)
+TsunamiPChip::read(PacketPtr pkt)
{
assert(pkt->result == Packet::Unknown);
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
@@ -150,7 +151,7 @@ TsunamiPChip::read(Packet *pkt)
}
Tick
-TsunamiPChip::write(Packet *pkt)
+TsunamiPChip::write(PacketPtr pkt)
{
assert(pkt->result == Packet::Unknown);
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
diff --git a/src/dev/tsunami_pchip.hh b/src/dev/tsunami_pchip.hh
index 2c97a1fea..d0a9c3157 100644
--- a/src/dev/tsunami_pchip.hh
+++ b/src/dev/tsunami_pchip.hh
@@ -85,8 +85,8 @@ class TsunamiPChip : public BasicPioDevice
Addr calcConfigAddr(int bus, int dev, int func);
- virtual Tick read(Packet *pkt);
- virtual Tick write(Packet *pkt);
+ virtual Tick read(PacketPtr pkt);
+ virtual Tick write(PacketPtr pkt);
/**
* Serialize this object to the given output stream.
diff --git a/src/dev/uart8250.cc b/src/dev/uart8250.cc
index b92527b5a..9051a26a2 100644
--- a/src/dev/uart8250.cc
+++ b/src/dev/uart8250.cc
@@ -42,6 +42,8 @@
#include "dev/simconsole.hh"
#include "dev/uart8250.hh"
#include "dev/platform.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
#include "sim/builder.hh"
using namespace std;
@@ -110,7 +112,7 @@ Uart8250::Uart8250(Params *p)
}
Tick
-Uart8250::read(Packet *pkt)
+Uart8250::read(PacketPtr pkt)
{
assert(pkt->result == Packet::Unknown);
assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
@@ -192,7 +194,7 @@ Uart8250::read(Packet *pkt)
}
Tick
-Uart8250::write(Packet *pkt)
+Uart8250::write(PacketPtr pkt)
{
assert(pkt->result == Packet::Unknown);
diff --git a/src/dev/uart8250.hh b/src/dev/uart8250.hh
index 44e90132f..2e768216a 100644
--- a/src/dev/uart8250.hh
+++ b/src/dev/uart8250.hh
@@ -82,8 +82,8 @@ class Uart8250 : public Uart
public:
Uart8250(Params *p);
- virtual Tick read(Packet *pkt);
- virtual Tick write(Packet *pkt);
+ virtual Tick read(PacketPtr pkt);
+ virtual Tick write(PacketPtr pkt);
virtual void addressRanges(AddrRangeList &range_list);
diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh
index 3a2677642..6e0b37d91 100644
--- a/src/kern/linux/linux.hh
+++ b/src/kern/linux/linux.hh
@@ -54,11 +54,11 @@ class Linux : public OperatingSystem
//@{
/// Basic Linux types.
-/* typedef uint64_t size_t;
+ typedef uint64_t size_t;
typedef uint64_t off_t;
typedef int64_t time_t;
typedef uint32_t uid_t;
- typedef uint32_t gid_t;*/
+ typedef uint32_t gid_t;
//@}
/// Stat buffer. Note that we can't call it 'stat' since that
diff --git a/src/kern/solaris/solaris.hh b/src/kern/solaris/solaris.hh
index a5ca41cdd..ed574fdbf 100644
--- a/src/kern/solaris/solaris.hh
+++ b/src/kern/solaris/solaris.hh
@@ -56,7 +56,7 @@ class Solaris : public OperatingSystem
//@{
/// Basic Solaris types.
-/* typedef uint64_t size_t;
+ typedef uint64_t size_t;
typedef uint64_t off_t;
typedef int64_t time_t;
typedef int32_t uid_t;
@@ -65,7 +65,7 @@ class Solaris : public OperatingSystem
typedef uint64_t ino_t;
typedef uint64_t dev_t;
typedef uint32_t mode_t;
- typedef uint32_t nlink_t;*/
+ typedef uint32_t nlink_t;
//@}
struct tgt_timespec {
diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh
index 18671c364..6d6d0d96d 100644
--- a/src/kern/tru64/tru64.hh
+++ b/src/kern/tru64/tru64.hh
@@ -393,34 +393,6 @@ class Tru64 : public OperatingSystem
uint64_t pad2[2]; //!< pad2
};
- /*/// Helper function to convert a host stat buffer to a target stat
- /// buffer. Also copies the target buffer out to the simulated
- /// memory space. Used by stat(), fstat(), and lstat().
- template <class T>
- static void
- copyOutStatBuf(TranslatingPort *mem, Addr addr, global_stat *host)
- {
- using namespace TheISA;
-
- TypedBufferArg<T> tgt(addr);
-
- tgt->st_dev = htog(host->st_dev);
- tgt->st_ino = htog(host->st_ino);
- tgt->st_mode = htog(host->st_mode);
- tgt->st_nlink = htog(host->st_nlink);
- tgt->st_uid = htog(host->st_uid);
- tgt->st_gid = htog(host->st_gid);
- tgt->st_rdev = htog(host->st_rdev);
- tgt->st_size = htog(host->st_size);
- tgt->st_atimeX = htog(host->st_atime);
- tgt->st_mtimeX = htog(host->st_mtime);
- tgt->st_ctimeX = htog(host->st_ctime);
- tgt->st_blksize = htog(host->st_blksize);
- tgt->st_blocks = htog(host->st_blocks);
-
- tgt.copyOut(mem);
- }*/
-
/// Helper function to convert a host statfs buffer to a target statfs
/// buffer. Also copies the target buffer out to the simulated
/// memory space. Used by statfs() and fstatfs().
@@ -450,34 +422,6 @@ class Tru64 : public OperatingSystem
tgt.copyOut(mem);
}
-/* /// Helper function to convert a host stat buffer to an old pre-F64
- /// (4.x) target stat buffer. Also copies the target buffer out to
- /// the simulated memory space. Used by pre_F64_stat(),
- /// pre_F64_fstat(), and pre_F64_lstat().
- static void
- copyOutPreF64StatBuf(TranslatingPort *mem, Addr addr, struct stat *host)
- {
- using namespace TheISA;
-
- TypedBufferArg<Tru64::pre_F64_stat> tgt(addr);
-
- tgt->st_dev = htog(host->st_dev);
- tgt->st_ino = htog(host->st_ino);
- tgt->st_mode = htog(host->st_mode);
- tgt->st_nlink = htog(host->st_nlink);
- tgt->st_uid = htog(host->st_uid);
- tgt->st_gid = htog(host->st_gid);
- tgt->st_rdev = htog(host->st_rdev);
- tgt->st_size = htog(host->st_size);
- tgt->st_atimeX = htog(host->st_atime);
- tgt->st_mtimeX = htog(host->st_mtime);
- tgt->st_ctimeX = htog(host->st_ctime);
- tgt->st_blksize = htog(host->st_blksize);
- tgt->st_blocks = htog(host->st_blocks);
-
- tgt.copyOut(mem);
- }*/
-
/// The target system's hostname.
static const char *hostname;
@@ -600,12 +544,19 @@ class Tru64 : public OperatingSystem
process->next_thread_stack_base -= stack_size;
}
- stack_base = roundDown(stack_base, VMPageSize);
+ Addr rounded_stack_base = roundDown(stack_base, VMPageSize);
+ Addr rounded_stack_size = roundUp(stack_size, VMPageSize);
+
+ DPRINTF(SyscallVerbose,
+ "stack_create: allocating stack @ %#x size %#x "
+ "(rounded from %#x, %#x)\n",
+ rounded_stack_base, rounded_stack_size,
+ stack_base, stack_size);
// map memory
- process->pTable->allocate(stack_base, roundUp(stack_size, VMPageSize));
+ process->pTable->allocate(rounded_stack_base, rounded_stack_size);
- argp->address = gtoh(stack_base);
+ argp->address = gtoh(rounded_stack_base);
argp.copyOut(tc->getMemPort());
return 0;
diff --git a/src/mem/bridge.cc b/src/mem/bridge.cc
index b181dd583..38dcfd2e8 100644
--- a/src/mem/bridge.cc
+++ b/src/mem/bridge.cc
@@ -89,7 +89,7 @@ Bridge::init()
/** Function called by the port when the bus is receiving a Timing
* transaction.*/
bool
-Bridge::BridgePort::recvTiming(Packet *pkt)
+Bridge::BridgePort::recvTiming(PacketPtr pkt)
{
DPRINTF(BusBridge, "recvTiming: src %d dest %d addr 0x%x\n",
pkt->getSrc(), pkt->getDest(), pkt->getAddr());
@@ -99,7 +99,7 @@ Bridge::BridgePort::recvTiming(Packet *pkt)
bool
-Bridge::BridgePort::queueForSendTiming(Packet *pkt)
+Bridge::BridgePort::queueForSendTiming(PacketPtr pkt)
{
if (queueFull())
return false;
@@ -148,7 +148,7 @@ Bridge::BridgePort::trySend()
assert(buf->ready <= curTick);
- Packet *pkt = buf->pkt;
+ PacketPtr pkt = buf->pkt;
DPRINTF(BusBridge, "trySend: origSrc %d dest %d addr 0x%x\n",
buf->origSrc, pkt->getDest(), pkt->getAddr());
@@ -198,7 +198,7 @@ Bridge::BridgePort::recvRetry()
/** Function called by the port when the bus is receiving a Atomic
* transaction.*/
Tick
-Bridge::BridgePort::recvAtomic(Packet *pkt)
+Bridge::BridgePort::recvAtomic(PacketPtr pkt)
{
return otherPort->sendAtomic(pkt) + delay;
}
@@ -206,7 +206,7 @@ Bridge::BridgePort::recvAtomic(Packet *pkt)
/** Function called by the port when the bus is receiving a Functional
* transaction.*/
void
-Bridge::BridgePort::recvFunctional(Packet *pkt)
+Bridge::BridgePort::recvFunctional(PacketPtr pkt)
{
std::list<PacketBuffer*>::iterator i;
bool pktContinue = true;
diff --git a/src/mem/bridge.hh b/src/mem/bridge.hh
index 2ab9799c7..f7d0d12d0 100644
--- a/src/mem/bridge.hh
+++ b/src/mem/bridge.hh
@@ -70,12 +70,12 @@ class Bridge : public MemObject
public:
Tick ready;
- Packet *pkt;
+ PacketPtr pkt;
Packet::SenderState *origSenderState;
short origSrc;
bool expectResponse;
- PacketBuffer(Packet *_pkt, Tick t)
+ PacketBuffer(PacketPtr _pkt, Tick t)
: ready(t), pkt(_pkt),
origSenderState(_pkt->senderState), origSrc(_pkt->getSrc()),
expectResponse(_pkt->needsResponse())
@@ -84,7 +84,7 @@ class Bridge : public MemObject
pkt->senderState = this;
}
- void fixResponse(Packet *pkt)
+ void fixResponse(PacketPtr pkt)
{
assert(pkt->senderState == this);
pkt->setDest(origSrc);
@@ -109,7 +109,7 @@ class Bridge : public MemObject
*/
bool queueFull() { return (sendQueue.size() == queueLimit); }
- bool queueForSendTiming(Packet *pkt);
+ bool queueForSendTiming(PacketPtr pkt);
void finishSend(PacketBuffer *buf);
@@ -146,7 +146,7 @@ class Bridge : public MemObject
/** When receiving a timing request from the peer port,
pass it to the bridge. */
- virtual bool recvTiming(Packet *pkt);
+ virtual bool recvTiming(PacketPtr pkt);
/** When receiving a retry request from the peer port,
pass it to the bridge. */
@@ -154,11 +154,11 @@ class Bridge : public MemObject
/** When receiving a Atomic requestfrom the peer port,
pass it to the bridge. */
- virtual Tick recvAtomic(Packet *pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
/** When receiving a Functional request from the peer port,
pass it to the bridge. */
- virtual void recvFunctional(Packet *pkt);
+ virtual void recvFunctional(PacketPtr pkt);
/** When receiving a status changefrom the peer port,
pass it to the bridge. */
diff --git a/src/mem/bus.cc b/src/mem/bus.cc
index b11b6de58..86a148f87 100644
--- a/src/mem/bus.cc
+++ b/src/mem/bus.cc
@@ -138,7 +138,7 @@ void Bus::occupyBus(PacketPtr pkt)
/** Function called by the port when the bus is receiving a Timing
* transaction.*/
bool
-Bus::recvTiming(Packet *pkt)
+Bus::recvTiming(PacketPtr pkt)
{
Port *port;
DPRINTF(Bus, "recvTiming: packet src %d dest %d addr 0x%x cmd %s\n",
@@ -160,9 +160,12 @@ Bus::recvTiming(Packet *pkt)
short dest = pkt->getDest();
if (dest == Packet::Broadcast) {
if (timingSnoop(pkt)) {
+ bool success;
+
pkt->flags |= SNOOP_COMMIT;
- bool success = timingSnoop(pkt);
+ success = timingSnoop(pkt);
assert(success);
+
if (pkt->flags & SATISFIED) {
//Cache-Cache transfer occuring
if (inRetry) {
@@ -298,7 +301,7 @@ Bus::findSnoopPorts(Addr addr, int id)
}
Tick
-Bus::atomicSnoop(Packet *pkt)
+Bus::atomicSnoop(PacketPtr pkt)
{
std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc());
Tick response_time = 0;
@@ -316,7 +319,7 @@ Bus::atomicSnoop(Packet *pkt)
}
void
-Bus::functionalSnoop(Packet *pkt)
+Bus::functionalSnoop(PacketPtr pkt)
{
std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc());
@@ -328,7 +331,7 @@ Bus::functionalSnoop(Packet *pkt)
}
bool
-Bus::timingSnoop(Packet *pkt)
+Bus::timingSnoop(PacketPtr pkt)
{
std::vector<int> ports = findSnoopPorts(pkt->getAddr(), pkt->getSrc());
bool success = true;
@@ -346,7 +349,7 @@ Bus::timingSnoop(Packet *pkt)
/** Function called by the port when the bus is receiving a Atomic
* transaction.*/
Tick
-Bus::recvAtomic(Packet *pkt)
+Bus::recvAtomic(PacketPtr pkt)
{
DPRINTF(Bus, "recvAtomic: packet src %d dest %d addr 0x%x cmd %s\n",
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
@@ -361,7 +364,7 @@ Bus::recvAtomic(Packet *pkt)
/** Function called by the port when the bus is receiving a Functional
* transaction.*/
void
-Bus::recvFunctional(Packet *pkt)
+Bus::recvFunctional(PacketPtr pkt)
{
DPRINTF(Bus, "recvFunctional: packet src %d dest %d addr 0x%x cmd %s\n",
pkt->getSrc(), pkt->getDest(), pkt->getAddr(), pkt->cmdString());
diff --git a/src/mem/bus.hh b/src/mem/bus.hh
index 509b8cf9b..9fb33b7c3 100644
--- a/src/mem/bus.hh
+++ b/src/mem/bus.hh
@@ -71,15 +71,15 @@ class Bus : public MemObject
/** Function called by the port when the bus is recieving a Timing
transaction.*/
- bool recvTiming(Packet *pkt);
+ bool recvTiming(PacketPtr pkt);
/** Function called by the port when the bus is recieving a Atomic
transaction.*/
- Tick recvAtomic(Packet *pkt);
+ Tick recvAtomic(PacketPtr pkt);
/** Function called by the port when the bus is recieving a Functional
transaction.*/
- void recvFunctional(Packet *pkt);
+ void recvFunctional(PacketPtr pkt);
/** Timing function called by port when it is once again able to process
* requests. */
@@ -107,16 +107,16 @@ class Bus : public MemObject
std::vector<int> findSnoopPorts(Addr addr, int id);
/** Snoop all relevant ports atomicly. */
- Tick atomicSnoop(Packet *pkt);
+ Tick atomicSnoop(PacketPtr pkt);
/** Snoop all relevant ports functionally. */
- void functionalSnoop(Packet *pkt);
+ void functionalSnoop(PacketPtr pkt);
/** Call snoop on caches, be sure to set SNOOP_COMMIT bit if you want
* the snoop to happen
* @return True if succeds.
*/
- bool timingSnoop(Packet *pkt);
+ bool timingSnoop(PacketPtr pkt);
/** Process address range request.
* @param resp addresses that we can respond to
@@ -157,17 +157,17 @@ class Bus : public MemObject
/** When reciving a timing request from the peer port (at id),
pass it to the bus. */
- virtual bool recvTiming(Packet *pkt)
+ virtual bool recvTiming(PacketPtr pkt)
{ pkt->setSrc(id); return bus->recvTiming(pkt); }
/** When reciving a Atomic requestfrom the peer port (at id),
pass it to the bus. */
- virtual Tick recvAtomic(Packet *pkt)
+ virtual Tick recvAtomic(PacketPtr pkt)
{ pkt->setSrc(id); return bus->recvAtomic(pkt); }
/** When reciving a Functional requestfrom the peer port (at id),
pass it to the bus. */
- virtual void recvFunctional(Packet *pkt)
+ virtual void recvFunctional(PacketPtr pkt)
{ pkt->setSrc(id); bus->recvFunctional(pkt); }
/** When reciving a status changefrom the peer port (at id),
diff --git a/src/mem/cache/base_cache.cc b/src/mem/cache/base_cache.cc
index 51b4ed55e..0694aae6e 100644
--- a/src/mem/cache/base_cache.cc
+++ b/src/mem/cache/base_cache.cc
@@ -33,11 +33,10 @@
* Definition of BaseCache functions.
*/
+#include "cpu/base.hh"
+#include "cpu/smt.hh"
#include "mem/cache/base_cache.hh"
#include "mem/cache/miss/mshr.hh"
-#include "mem/packet_impl.hh"
-#include "cpu/smt.hh"
-#include "cpu/base.hh"
using namespace std;
@@ -72,7 +71,7 @@ BaseCache::CachePort::deviceBlockSize()
}
bool
-BaseCache::CachePort::recvTiming(Packet *pkt)
+BaseCache::CachePort::recvTiming(PacketPtr pkt)
{
if (isCpuSide
&& !pkt->req->isUncacheable()
@@ -100,48 +99,23 @@ BaseCache::CachePort::recvTiming(Packet *pkt)
}
Tick
-BaseCache::CachePort::recvAtomic(Packet *pkt)
+BaseCache::CachePort::recvAtomic(PacketPtr pkt)
{
return cache->doAtomicAccess(pkt, isCpuSide);
}
void
-BaseCache::CachePort::recvFunctional(Packet *pkt)
+BaseCache::CachePort::recvFunctional(PacketPtr pkt)
{
//Check storage here first
- list<Packet *>::iterator i = drainList.begin();
- list<Packet *>::iterator end = drainList.end();
+ list<PacketPtr>::iterator i = drainList.begin();
+ list<PacketPtr>::iterator end = drainList.end();
for (; i != end; ++i) {
- Packet * target = *i;
+ PacketPtr target = *i;
// If the target contains data, and it overlaps the
// probed request, need to update data
if (target->intersect(pkt)) {
- uint8_t* pkt_data;
- uint8_t* write_data;
- int data_size;
- if (target->getAddr() < pkt->getAddr()) {
- int offset = pkt->getAddr() - target->getAddr();
- pkt_data = pkt->getPtr<uint8_t>();
- write_data = target->getPtr<uint8_t>() + offset;
- data_size = target->getSize() - offset;
- assert(data_size > 0);
- if (data_size > pkt->getSize())
- data_size = pkt->getSize();
- } else {
- int offset = target->getAddr() - pkt->getAddr();
- pkt_data = pkt->getPtr<uint8_t>() + offset;
- write_data = target->getPtr<uint8_t>();
- data_size = pkt->getSize() - offset;
- assert(data_size > pkt->getSize());
- if (data_size > target->getSize())
- data_size = target->getSize();
- }
-
- if (pkt->isWrite()) {
- memcpy(pkt_data, write_data, data_size);
- } else {
- memcpy(write_data, pkt_data, data_size);
- }
+ fixPacket(pkt, target);
}
}
cache->doFunctionalAccess(pkt, isCpuSide);
@@ -150,7 +124,7 @@ BaseCache::CachePort::recvFunctional(Packet *pkt)
void
BaseCache::CachePort::recvRetry()
{
- Packet *pkt;
+ PacketPtr pkt;
assert(waitingOnRetry);
if (!drainList.empty()) {
DPRINTF(CachePort, "%s attempting to send a retry for response\n", name());
@@ -182,7 +156,7 @@ BaseCache::CachePort::recvRetry()
pkt = cache->getPacket();
MSHR* mshr = (MSHR*) pkt->senderState;
//Copy the packet, it may be modified/destroyed elsewhere
- Packet * copyPkt = new Packet(*pkt);
+ PacketPtr copyPkt = new Packet(*pkt);
copyPkt->dataStatic<uint8_t>(pkt->getPtr<uint8_t>());
mshr->pkt = copyPkt;
@@ -258,7 +232,7 @@ BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort)
pkt = NULL;
}
-BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort, Packet *_pkt)
+BaseCache::CacheEvent::CacheEvent(CachePort *_cachePort, PacketPtr _pkt)
: Event(&mainEventQueue, CPU_Tick_Pri), cachePort(_cachePort), pkt(_pkt)
{
this->setFlags(AutoDelete);
@@ -302,7 +276,7 @@ BaseCache::CacheEvent::process()
pkt = cachePort->cache->getPacket();
MSHR* mshr = (MSHR*) pkt->senderState;
//Copy the packet, it may be modified/destroyed elsewhere
- Packet * copyPkt = new Packet(*pkt);
+ PacketPtr copyPkt = new Packet(*pkt);
copyPkt->dataStatic<uint8_t>(pkt->getPtr<uint8_t>());
mshr->pkt = copyPkt;
@@ -332,7 +306,7 @@ BaseCache::CacheEvent::process()
pkt = cachePort->cache->getCoherencePacket();
MSHR* cshr = (MSHR*) pkt->senderState;
bool success = cachePort->sendTiming(pkt);
- cachePort->cache->sendResult(pkt, cshr, success);
+ cachePort->cache->sendCoherenceResult(pkt, cshr, success);
cachePort->waitingOnRetry = !success;
if (cachePort->waitingOnRetry)
DPRINTF(CachePort, "%s now waiting on a retry\n", cachePort->name());
diff --git a/src/mem/cache/base_cache.hh b/src/mem/cache/base_cache.hh
index 93830b04f..565280aef 100644
--- a/src/mem/cache/base_cache.hh
+++ b/src/mem/cache/base_cache.hh
@@ -85,11 +85,11 @@ class BaseCache : public MemObject
CachePort(const std::string &_name, BaseCache *_cache, bool _isCpuSide);
protected:
- virtual bool recvTiming(Packet *pkt);
+ virtual bool recvTiming(PacketPtr pkt);
- virtual Tick recvAtomic(Packet *pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
- virtual void recvFunctional(Packet *pkt);
+ virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status);
@@ -113,23 +113,25 @@ class BaseCache : public MemObject
bool waitingOnRetry;
- std::list<Packet *> drainList;
+ std::list<PacketPtr> drainList;
};
struct CacheEvent : public Event
{
CachePort *cachePort;
- Packet *pkt;
+ PacketPtr pkt;
CacheEvent(CachePort *_cachePort);
- CacheEvent(CachePort *_cachePort, Packet *_pkt);
+ CacheEvent(CachePort *_cachePort, PacketPtr _pkt);
void process();
const char *description();
};
- protected:
+ public: //Made public so coherence can get at it.
CachePort *cpuSidePort;
+
+ protected:
CachePort *memSidePort;
bool snoopRangesSent;
@@ -139,17 +141,17 @@ class BaseCache : public MemObject
private:
//To be defined in cache_impl.hh not in base class
- virtual bool doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide)
+ virtual bool doTimingAccess(PacketPtr pkt, CachePort *cachePort, bool isCpuSide)
{
fatal("No implementation");
}
- virtual Tick doAtomicAccess(Packet *pkt, bool isCpuSide)
+ virtual Tick doAtomicAccess(PacketPtr pkt, bool isCpuSide)
{
fatal("No implementation");
}
- virtual void doFunctionalAccess(Packet *pkt, bool isCpuSide)
+ virtual void doFunctionalAccess(PacketPtr pkt, bool isCpuSide)
{
fatal("No implementation");
}
@@ -170,23 +172,23 @@ class BaseCache : public MemObject
}
}
- virtual Packet *getPacket()
+ virtual PacketPtr getPacket()
{
fatal("No implementation");
}
- virtual Packet *getCoherencePacket()
+ virtual PacketPtr getCoherencePacket()
{
fatal("No implementation");
}
- virtual void sendResult(Packet* &pkt, MSHR* mshr, bool success)
+ virtual void sendResult(PacketPtr &pkt, MSHR* mshr, bool success)
{
fatal("No implementation");
}
- virtual void sendCoherenceResult(Packet* &pkt, MSHR* mshr, bool success)
+ virtual void sendCoherenceResult(PacketPtr &pkt, MSHR* mshr, bool success)
{
fatal("No implementation");
@@ -517,7 +519,7 @@ class BaseCache : public MemObject
* @param pkt The request being responded to.
* @param time The time the response is ready.
*/
- void respond(Packet *pkt, Tick time)
+ void respond(PacketPtr pkt, Tick time)
{
if (pkt->needsResponse()) {
CacheEvent *reqCpu = new CacheEvent(cpuSidePort, pkt);
@@ -537,7 +539,7 @@ class BaseCache : public MemObject
* @param pkt The request to respond to.
* @param time The time the response is ready.
*/
- void respondToMiss(Packet *pkt, Tick time)
+ void respondToMiss(PacketPtr pkt, Tick time)
{
if (!pkt->req->isUncacheable()) {
missLatency[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/] += time - pkt->time;
@@ -559,7 +561,7 @@ class BaseCache : public MemObject
* Suppliess the data if cache to cache transfers are enabled.
* @param pkt The bus transaction to fulfill.
*/
- void respondToSnoop(Packet *pkt, Tick time)
+ void respondToSnoop(PacketPtr pkt, Tick time)
{
assert (pkt->needsResponse());
CacheEvent *reqMem = new CacheEvent(memSidePort, pkt);
diff --git a/src/mem/cache/cache.hh b/src/mem/cache/cache.hh
index 07d9d6336..1f3b087bb 100644
--- a/src/mem/cache/cache.hh
+++ b/src/mem/cache/cache.hh
@@ -96,7 +96,7 @@ class Cache : public BaseCache
* A permanent mem req to always be used to cause invalidations.
* Used to append to target list, to cause an invalidation.
*/
- Packet * invalidatePkt;
+ PacketPtr invalidatePkt;
Request *invalidateReq;
public:
@@ -127,12 +127,12 @@ class Cache : public BaseCache
/** Instantiates a basic cache object. */
Cache(const std::string &_name, Params &params);
- virtual bool doTimingAccess(Packet *pkt, CachePort *cachePort,
+ virtual bool doTimingAccess(PacketPtr pkt, CachePort *cachePort,
bool isCpuSide);
- virtual Tick doAtomicAccess(Packet *pkt, bool isCpuSide);
+ virtual Tick doAtomicAccess(PacketPtr pkt, bool isCpuSide);
- virtual void doFunctionalAccess(Packet *pkt, bool isCpuSide);
+ virtual void doFunctionalAccess(PacketPtr pkt, bool isCpuSide);
virtual void recvStatusChange(Port::Status status, bool isCpuSide);
@@ -143,47 +143,47 @@ class Cache : public BaseCache
* @param pkt The request to perform.
* @return The result of the access.
*/
- bool access(Packet * &pkt);
+ bool access(PacketPtr &pkt);
/**
* Selects a request to send on the bus.
* @return The memory request to service.
*/
- virtual Packet * getPacket();
+ virtual PacketPtr getPacket();
/**
* Was the request was sent successfully?
* @param pkt The request.
* @param success True if the request was sent successfully.
*/
- virtual void sendResult(Packet * &pkt, MSHR* mshr, bool success);
+ virtual void sendResult(PacketPtr &pkt, MSHR* mshr, bool success);
/**
* Was the CSHR request was sent successfully?
* @param pkt The request.
* @param success True if the request was sent successfully.
*/
- virtual void sendCoherenceResult(Packet * &pkt, MSHR* cshr, bool success);
+ virtual void sendCoherenceResult(PacketPtr &pkt, MSHR* cshr, bool success);
/**
* Handles a response (cache line fill/write ack) from the bus.
* @param pkt The request being responded to.
*/
- void handleResponse(Packet * &pkt);
+ void handleResponse(PacketPtr &pkt);
/**
* Selects a coherence message to forward to lower levels of the hierarchy.
* @return The coherence message to forward.
*/
- virtual Packet * getCoherencePacket();
+ virtual PacketPtr getCoherencePacket();
/**
* Snoops bus transactions to maintain coherence.
* @param pkt The current bus transaction.
*/
- void snoop(Packet * &pkt);
+ void snoop(PacketPtr &pkt);
- void snoopResponse(Packet * &pkt);
+ void snoopResponse(PacketPtr &pkt);
/**
* Invalidates the block containing address if found.
@@ -224,7 +224,7 @@ class Cache : public BaseCache
* request.
* @return The estimated completion time.
*/
- Tick probe(Packet * &pkt, bool update, CachePort * otherSidePort);
+ Tick probe(PacketPtr &pkt, bool update, CachePort * otherSidePort);
/**
* Snoop for the provided request in the cache and return the estimated
@@ -235,7 +235,7 @@ class Cache : public BaseCache
* request.
* @return The estimated completion time.
*/
- Tick snoopProbe(Packet * &pkt);
+ Tick snoopProbe(PacketPtr &pkt);
};
#endif // __CACHE_HH__
diff --git a/src/mem/cache/cache_blk.hh b/src/mem/cache/cache_blk.hh
index 078c82d82..7b999e4b1 100644
--- a/src/mem/cache/cache_blk.hh
+++ b/src/mem/cache/cache_blk.hh
@@ -35,8 +35,11 @@
#ifndef __CACHE_BLK_HH__
#define __CACHE_BLK_HH__
+#include <list>
+
#include "sim/root.hh" // for Tick
#include "arch/isa_traits.hh" // for Addr
+#include "mem/request.hh"
/**
* Cache block status bit assignments
@@ -96,6 +99,35 @@ class CacheBlk
/** Number of references to this block since it was brought in. */
int refCount;
+ protected:
+ /**
+ * Represents that the indicated thread context has a "lock" on
+ * the block, in the LL/SC sense.
+ */
+ class Lock {
+ public:
+ int cpuNum; // locking CPU
+ int threadNum; // locking thread ID within CPU
+
+ // check for matching execution context
+ bool matchesContext(Request *req)
+ {
+ return (cpuNum == req->getCpuNum() &&
+ threadNum == req->getThreadNum());
+ }
+
+ Lock(Request *req)
+ : cpuNum(req->getCpuNum()), threadNum(req->getThreadNum())
+ {
+ }
+ };
+
+ /** List of thread contexts that have performed a load-locked (LL)
+ * on the block since the last store. */
+ std::list<Lock> lockList;
+
+ public:
+
CacheBlk()
: asid(-1), tag(0), data(0) ,size(0), status(0), whenReady(0),
set(-1), refCount(0)
@@ -175,7 +207,58 @@ class CacheBlk
return (status & BlkHWPrefetched) != 0;
}
+ /**
+ * Track the fact that a local locked was issued to the block. If
+ * multiple LLs get issued from the same context we could have
+ * redundant records on the list, but that's OK, as they'll all
+ * get blown away at the next store.
+ */
+ void trackLoadLocked(Request *req)
+ {
+ assert(req->isLocked());
+ lockList.push_front(Lock(req));
+ }
+
+ /**
+ * Clear the list of valid load locks. Should be called whenever
+ * block is written to or invalidated.
+ */
+ void clearLoadLocks() { lockList.clear(); }
+ /**
+ * Handle interaction of load-locked operations and stores.
+ * @return True if write should proceed, false otherwise. Returns
+ * false only in the case of a failed store conditional.
+ */
+ bool checkWrite(Request *req)
+ {
+ if (req->isLocked()) {
+ // it's a store conditional... have to check for matching
+ // load locked.
+ bool success = false;
+
+ for (std::list<Lock>::iterator i = lockList.begin();
+ i != lockList.end(); ++i)
+ {
+ if (i->matchesContext(req)) {
+ // it's a store conditional, and as far as the memory
+ // system can tell, the requesting context's lock is
+ // still valid.
+ success = true;
+ break;
+ }
+ }
+
+ req->setScResult(success ? 1 : 0);
+ clearLoadLocks();
+ return success;
+ } else {
+ // for *all* stores (conditional or otherwise) we have to
+ // clear the list of load-locks as they're all invalid now.
+ clearLoadLocks();
+ return true;
+ }
+ }
};
#endif //__CACHE_BLK_HH__
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 520e5abb5..3c47762f6 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -56,7 +56,7 @@
template<class TagStore, class Buffering, class Coherence>
bool
Cache<TagStore,Buffering,Coherence>::
-doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide)
+doTimingAccess(PacketPtr pkt, CachePort *cachePort, bool isCpuSide)
{
if (isCpuSide)
{
@@ -82,15 +82,10 @@ doTimingAccess(Packet *pkt, CachePort *cachePort, bool isCpuSide)
template<class TagStore, class Buffering, class Coherence>
Tick
Cache<TagStore,Buffering,Coherence>::
-doAtomicAccess(Packet *pkt, bool isCpuSide)
+doAtomicAccess(PacketPtr pkt, bool isCpuSide)
{
if (isCpuSide)
{
- //Temporary solution to LL/SC
- if (pkt->isWrite() && (pkt->req->isLocked())) {
- pkt->req->setScResult(1);
- }
-
probe(pkt, true, NULL);
//TEMP ALWAYS SUCCES FOR NOW
pkt->result = Packet::Success;
@@ -109,18 +104,13 @@ doAtomicAccess(Packet *pkt, bool isCpuSide)
template<class TagStore, class Buffering, class Coherence>
void
Cache<TagStore,Buffering,Coherence>::
-doFunctionalAccess(Packet *pkt, bool isCpuSide)
+doFunctionalAccess(PacketPtr pkt, bool isCpuSide)
{
if (isCpuSide)
{
//TEMP USE CPU?THREAD 0 0
pkt->req->setThreadContext(0,0);
- //Temporary solution to LL/SC
- if (pkt->isWrite() && (pkt->req->isLocked())) {
- assert("Can't handle LL/SC on functional path\n");
- }
-
probe(pkt, false, memSidePort);
//TEMP ALWAYS SUCCESFUL FOR NOW
pkt->result = Packet::Success;
@@ -241,18 +231,26 @@ Cache<TagStore,Buffering,Coherence>::access(PacketPtr &pkt)
exitSimLoop("A cache reached the maximum miss count");
}
}
- missQueue->handleMiss(pkt, size, curTick + hitLatency);
-// return MA_CACHE_MISS;
+
+ if (pkt->flags & SATISFIED) {
+ // happens when a store conditional fails because it missed
+ // the cache completely
+ if (pkt->needsResponse())
+ respond(pkt, curTick+lat);
+ } else {
+ missQueue->handleMiss(pkt, size, curTick + hitLatency);
+ }
+
return true;
}
template<class TagStore, class Buffering, class Coherence>
-Packet *
+PacketPtr
Cache<TagStore,Buffering,Coherence>::getPacket()
{
assert(missQueue->havePending());
- Packet * pkt = missQueue->getPacket();
+ PacketPtr pkt = missQueue->getPacket();
if (pkt) {
if (!pkt->req->isUncacheable()) {
if (pkt->cmd == Packet::HardPFReq)
@@ -316,7 +314,7 @@ Cache<TagStore,Buffering,Coherence>::sendResult(PacketPtr &pkt, MSHR* mshr,
template<class TagStore, class Buffering, class Coherence>
void
-Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt)
+Cache<TagStore,Buffering,Coherence>::handleResponse(PacketPtr &pkt)
{
BlkType *blk = NULL;
if (pkt->senderState) {
@@ -358,7 +356,7 @@ Cache<TagStore,Buffering,Coherence>::handleResponse(Packet * &pkt)
}
template<class TagStore, class Buffering, class Coherence>
-Packet *
+PacketPtr
Cache<TagStore,Buffering,Coherence>::getCoherencePacket()
{
return coherence->getPacket();
@@ -366,7 +364,7 @@ Cache<TagStore,Buffering,Coherence>::getCoherencePacket()
template<class TagStore, class Buffering, class Coherence>
void
-Cache<TagStore,Buffering,Coherence>::sendCoherenceResult(Packet* &pkt,
+Cache<TagStore,Buffering,Coherence>::sendCoherenceResult(PacketPtr &pkt,
MSHR *cshr,
bool success)
{
@@ -376,17 +374,22 @@ Cache<TagStore,Buffering,Coherence>::sendCoherenceResult(Packet* &pkt,
template<class TagStore, class Buffering, class Coherence>
void
-Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
+Cache<TagStore,Buffering,Coherence>::snoop(PacketPtr &pkt)
{
if (pkt->req->isUncacheable()) {
//Can't get a hit on an uncacheable address
//Revisit this for multi level coherence
return;
}
+
+ //Send a timing (true) invalidate up if the protocol calls for it
+ coherence->propogateInvalidate(pkt, true);
+
Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
BlkType *blk = tags->findBlock(pkt);
MSHR *mshr = missQueue->findMSHR(blk_addr);
- if (coherence->hasProtocol()) { //@todo Move this into handle bus req
+ if (coherence->hasProtocol() || pkt->isInvalidate()) {
+ //@todo Move this into handle bus req
//If we find an mshr, and it is in service, we need to NACK or
//invalidate
if (mshr) {
@@ -490,7 +493,7 @@ Cache<TagStore,Buffering,Coherence>::snoop(Packet * &pkt)
template<class TagStore, class Buffering, class Coherence>
void
-Cache<TagStore,Buffering,Coherence>::snoopResponse(Packet * &pkt)
+Cache<TagStore,Buffering,Coherence>::snoopResponse(PacketPtr &pkt)
{
//Need to handle the response, if NACKED
if (pkt->flags & NACKED_LINE) {
@@ -520,7 +523,7 @@ Cache<TagStore,Buffering,Coherence>::invalidateBlk(Addr addr)
*/
template<class TagStore, class Buffering, class Coherence>
Tick
-Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update,
+Cache<TagStore,Buffering,Coherence>::probe(PacketPtr &pkt, bool update,
CachePort* otherSidePort)
{
// MemDebug::cacheProbe(pkt);
@@ -536,6 +539,13 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update,
}
}
+ if (!update && (pkt->isWrite() || (otherSidePort == cpuSidePort))) {
+ // Still need to change data in all locations.
+ otherSidePort->sendFunctional(pkt);
+ if (pkt->isRead() && pkt->result == Packet::Success)
+ return 0;
+ }
+
PacketList writebacks;
int lat;
BlkType *blk = tags->handleAccess(pkt, lat, writebacks, update);
@@ -544,179 +554,127 @@ Cache<TagStore,Buffering,Coherence>::probe(Packet * &pkt, bool update,
pkt->getAddr() & (((ULL(1))<<48)-1), (blk) ? "hit" : "miss",
pkt->getAddr() & ~((Addr)blkSize - 1));
- if (!blk) {
- // Need to check for outstanding misses and writes
- Addr blk_addr = pkt->getAddr() & ~(blkSize - 1);
-
- // There can only be one matching outstanding miss.
- MSHR* mshr = missQueue->findMSHR(blk_addr);
-
- // There can be many matching outstanding writes.
- std::vector<MSHR*> writes;
- missQueue->findWrites(blk_addr, writes);
-
- if (!update) {
- otherSidePort->sendFunctional(pkt);
-
- // Check for data in MSHR and writebuffer.
- if (mshr) {
- warn("Found outstanding miss on an non-update probe");
- MSHR::TargetList *targets = mshr->getTargetList();
- MSHR::TargetList::iterator i = targets->begin();
- MSHR::TargetList::iterator end = targets->end();
- for (; i != end; ++i) {
- Packet * target = *i;
- // If the target contains data, and it overlaps the
- // probed request, need to update data
- if (target->isWrite() && target->intersect(pkt)) {
- uint8_t* pkt_data;
- uint8_t* write_data;
- int data_size;
- if (target->getAddr() < pkt->getAddr()) {
- int offset = pkt->getAddr() - target->getAddr();
- pkt_data = pkt->getPtr<uint8_t>();
- write_data = target->getPtr<uint8_t>() + offset;
- data_size = target->getSize() - offset;
- assert(data_size > 0);
- if (data_size > pkt->getSize())
- data_size = pkt->getSize();
- } else {
- int offset = target->getAddr() - pkt->getAddr();
- pkt_data = pkt->getPtr<uint8_t>() + offset;
- write_data = target->getPtr<uint8_t>();
- data_size = pkt->getSize() - offset;
- assert(data_size > pkt->getSize());
- if (data_size > target->getSize())
- data_size = target->getSize();
- }
-
- if (pkt->isWrite()) {
- memcpy(pkt_data, write_data, data_size);
- } else {
- memcpy(write_data, pkt_data, data_size);
- }
- }
- }
- }
- for (int i = 0; i < writes.size(); ++i) {
- Packet * write = writes[i]->pkt;
- if (write->intersect(pkt)) {
- warn("Found outstanding write on an non-update probe");
- uint8_t* pkt_data;
- uint8_t* write_data;
- int data_size;
- if (write->getAddr() < pkt->getAddr()) {
- int offset = pkt->getAddr() - write->getAddr();
- pkt_data = pkt->getPtr<uint8_t>();
- write_data = write->getPtr<uint8_t>() + offset;
- data_size = write->getSize() - offset;
- assert(data_size > 0);
- if (data_size > pkt->getSize())
- data_size = pkt->getSize();
- } else {
- int offset = write->getAddr() - pkt->getAddr();
- pkt_data = pkt->getPtr<uint8_t>() + offset;
- write_data = write->getPtr<uint8_t>();
- data_size = pkt->getSize() - offset;
- assert(data_size > pkt->getSize());
- if (data_size > write->getSize())
- data_size = write->getSize();
- }
- if (pkt->isWrite()) {
- memcpy(pkt_data, write_data, data_size);
- } else {
- memcpy(write_data, pkt_data, data_size);
- }
+ // Need to check for outstanding misses and writes
+ Addr blk_addr = pkt->getAddr() & ~(blkSize - 1);
+ // There can only be one matching outstanding miss.
+ MSHR* mshr = missQueue->findMSHR(blk_addr);
+
+ // There can be many matching outstanding writes.
+ std::vector<MSHR*> writes;
+ missQueue->findWrites(blk_addr, writes);
+
+ if (!update) {
+ // Check for data in MSHR and writebuffer.
+ if (mshr) {
+ MSHR::TargetList *targets = mshr->getTargetList();
+ MSHR::TargetList::iterator i = targets->begin();
+ MSHR::TargetList::iterator end = targets->end();
+ for (; i != end; ++i) {
+ PacketPtr target = *i;
+ // If the target contains data, and it overlaps the
+ // probed request, need to update data
+ if (target->intersect(pkt)) {
+ fixPacket(pkt, target);
}
}
- return 0;
- } else {
- // update the cache state and statistics
- if (mshr || !writes.empty()){
- // Can't handle it, return pktuest unsatisfied.
- panic("Atomic access ran into outstanding MSHR's or WB's!");
+ }
+ for (int i = 0; i < writes.size(); ++i) {
+ PacketPtr write = writes[i]->pkt;
+ if (write->intersect(pkt)) {
+ fixPacket(pkt, write);
}
- if (!pkt->req->isUncacheable()) {
+ }
+ if (pkt->isRead()
+ && pkt->result != Packet::Success
+ && otherSidePort == memSidePort) {
+ otherSidePort->sendFunctional(pkt);
+ assert(pkt->result == Packet::Success);
+ }
+ return 0;
+ } else if (!blk && !(pkt->flags & SATISFIED)) {
+ // update the cache state and statistics
+ if (mshr || !writes.empty()){
+ // Can't handle it, return pktuest unsatisfied.
+ panic("Atomic access ran into outstanding MSHR's or WB's!");
+ }
+ if (!pkt->req->isUncacheable()) {
// Fetch the cache block to fill
- BlkType *blk = tags->findBlock(pkt);
- Packet::Command temp_cmd = coherence->getBusCmd(pkt->cmd,
- (blk)? blk->status : 0);
+ BlkType *blk = tags->findBlock(pkt);
+ Packet::Command temp_cmd = coherence->getBusCmd(pkt->cmd,
+ (blk)? blk->status : 0);
- Packet * busPkt = new Packet(pkt->req,temp_cmd, -1, blkSize);
+ PacketPtr busPkt = new Packet(pkt->req,temp_cmd, -1, blkSize);
- busPkt->allocate();
+ busPkt->allocate();
- busPkt->time = curTick;
+ busPkt->time = curTick;
- DPRINTF(Cache, "Sending a atomic %s for %x blk_addr: %x\n",
- busPkt->cmdString(),
- busPkt->getAddr() & (((ULL(1))<<48)-1),
- busPkt->getAddr() & ~((Addr)blkSize - 1));
+ DPRINTF(Cache, "Sending a atomic %s for %x blk_addr: %x\n",
+ busPkt->cmdString(),
+ busPkt->getAddr() & (((ULL(1))<<48)-1),
+ busPkt->getAddr() & ~((Addr)blkSize - 1));
- lat = memSidePort->sendAtomic(busPkt);
+ lat = memSidePort->sendAtomic(busPkt);
- //Be sure to flip the response to a request for coherence
- if (busPkt->needsResponse()) {
- busPkt->makeAtomicResponse();
- }
+ //Be sure to flip the response to a request for coherence
+ if (busPkt->needsResponse()) {
+ busPkt->makeAtomicResponse();
+ }
/* if (!(busPkt->flags & SATISFIED)) {
- // blocked at a higher level, just return
- return 0;
- }
+// blocked at a higher level, just return
+return 0;
+}
*/ misses[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
- CacheBlk::State old_state = (blk) ? blk->status : 0;
- CacheBlk::State new_state =
- coherence->getNewState(busPkt, old_state);
- DPRINTF(Cache,
+ CacheBlk::State old_state = (blk) ? blk->status : 0;
+ CacheBlk::State new_state =
+ coherence->getNewState(busPkt, old_state);
+ DPRINTF(Cache,
"Receive response:%s for blk addr %x in state %i\n",
- busPkt->cmdString(),
- busPkt->getAddr() & (((ULL(1))<<48)-1), old_state);
- if (old_state != new_state)
+ busPkt->cmdString(),
+ busPkt->getAddr() & (((ULL(1))<<48)-1), old_state);
+ if (old_state != new_state)
DPRINTF(Cache, "Block for blk addr %x moving from "
"state %i to %i\n",
busPkt->getAddr() & (((ULL(1))<<48)-1),
old_state, new_state);
- tags->handleFill(blk, busPkt,
- new_state,
- writebacks, pkt);
- //Free the packet
- delete busPkt;
-
- // Handle writebacks if needed
- while (!writebacks.empty()){
- Packet *wbPkt = writebacks.front();
- memSidePort->sendAtomic(wbPkt);
- writebacks.pop_front();
- delete wbPkt;
- }
- return lat + hitLatency;
- } else {
- return memSidePort->sendAtomic(pkt);
+ tags->handleFill(blk, busPkt,
+ new_state,
+ writebacks, pkt);
+ //Free the packet
+ delete busPkt;
+
+ // Handle writebacks if needed
+ while (!writebacks.empty()){
+ PacketPtr wbPkt = writebacks.front();
+ memSidePort->sendAtomic(wbPkt);
+ writebacks.pop_front();
+ delete wbPkt;
}
+ return lat + hitLatency;
+ } else {
+ return memSidePort->sendAtomic(pkt);
}
} else {
- // There was a cache hit.
- // Handle writebacks if needed
- while (!writebacks.empty()){
- memSidePort->sendAtomic(writebacks.front());
- writebacks.pop_front();
- }
+ if (blk) {
+ // There was a cache hit.
+ // Handle writebacks if needed
+ while (!writebacks.empty()){
+ memSidePort->sendAtomic(writebacks.front());
+ writebacks.pop_front();
+ }
- if (update) {
hits[pkt->cmdToIndex()][0/*pkt->req->getThreadNum()*/]++;
- } else if (pkt->isWrite()) {
- // Still need to change data in all locations.
- otherSidePort->sendFunctional(pkt);
}
+
return hitLatency;
}
- fatal("Probe not handled.\n");
+
return 0;
}
@@ -724,24 +682,27 @@ template<class TagStore, class Buffering, class Coherence>
Tick
Cache<TagStore,Buffering,Coherence>::snoopProbe(PacketPtr &pkt)
{
- Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
- BlkType *blk = tags->findBlock(pkt);
- MSHR *mshr = missQueue->findMSHR(blk_addr);
- CacheBlk::State new_state = 0;
- bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
- if (satisfy) {
- DPRINTF(Cache, "Cache snooped a %s request for addr %x and "
- "now supplying data, new state is %i\n",
- pkt->cmdString(), blk_addr, new_state);
+ //Send a atomic (false) invalidate up if the protocol calls for it
+ coherence->propogateInvalidate(pkt, false);
+
+ Addr blk_addr = pkt->getAddr() & ~(Addr(blkSize-1));
+ BlkType *blk = tags->findBlock(pkt);
+ MSHR *mshr = missQueue->findMSHR(blk_addr);
+ CacheBlk::State new_state = 0;
+ bool satisfy = coherence->handleBusRequest(pkt,blk,mshr, new_state);
+ if (satisfy) {
+ DPRINTF(Cache, "Cache snooped a %s request for addr %x and "
+ "now supplying data, new state is %i\n",
+ pkt->cmdString(), blk_addr, new_state);
tags->handleSnoop(blk, new_state, pkt);
return hitLatency;
- }
- if (blk)
- DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
- "new state is %i\n",
+ }
+ if (blk)
+ DPRINTF(Cache, "Cache snooped a %s request for addr %x, "
+ "new state is %i\n",
pkt->cmdString(), blk_addr, new_state);
- tags->handleSnoop(blk, new_state);
- return 0;
+ tags->handleSnoop(blk, new_state);
+ return 0;
}
diff --git a/src/mem/cache/coherence/coherence_protocol.cc b/src/mem/cache/coherence/coherence_protocol.cc
index e28dda3dc..3d7721805 100644
--- a/src/mem/cache/coherence/coherence_protocol.cc
+++ b/src/mem/cache/coherence/coherence_protocol.cc
@@ -192,7 +192,7 @@ CoherenceProtocol::regStats()
bool
-CoherenceProtocol::invalidateTrans(BaseCache *cache, Packet * &pkt,
+CoherenceProtocol::invalidateTrans(BaseCache *cache, PacketPtr &pkt,
CacheBlk *blk, MSHR *mshr,
CacheBlk::State & new_state)
{
@@ -203,18 +203,17 @@ CoherenceProtocol::invalidateTrans(BaseCache *cache, Packet * &pkt,
bool
-CoherenceProtocol::supplyTrans(BaseCache *cache, Packet * &pkt,
+CoherenceProtocol::supplyTrans(BaseCache *cache, PacketPtr &pkt,
CacheBlk *blk,
MSHR *mshr,
- CacheBlk::State & new_state
- )
+ CacheBlk::State & new_state)
{
return true;
}
bool
-CoherenceProtocol::supplyAndGotoSharedTrans(BaseCache *cache, Packet * &pkt,
+CoherenceProtocol::supplyAndGotoSharedTrans(BaseCache *cache, PacketPtr &pkt,
CacheBlk *blk,
MSHR *mshr,
CacheBlk::State & new_state)
@@ -226,7 +225,7 @@ CoherenceProtocol::supplyAndGotoSharedTrans(BaseCache *cache, Packet * &pkt,
bool
-CoherenceProtocol::supplyAndGotoOwnedTrans(BaseCache *cache, Packet * &pkt,
+CoherenceProtocol::supplyAndGotoOwnedTrans(BaseCache *cache, PacketPtr &pkt,
CacheBlk *blk,
MSHR *mshr,
CacheBlk::State & new_state)
@@ -238,7 +237,7 @@ CoherenceProtocol::supplyAndGotoOwnedTrans(BaseCache *cache, Packet * &pkt,
bool
-CoherenceProtocol::supplyAndInvalidateTrans(BaseCache *cache, Packet * &pkt,
+CoherenceProtocol::supplyAndInvalidateTrans(BaseCache *cache, PacketPtr &pkt,
CacheBlk *blk,
MSHR *mshr,
CacheBlk::State & new_state)
@@ -248,7 +247,7 @@ CoherenceProtocol::supplyAndInvalidateTrans(BaseCache *cache, Packet * &pkt,
}
bool
-CoherenceProtocol::assertShared(BaseCache *cache, Packet * &pkt,
+CoherenceProtocol::assertShared(BaseCache *cache, PacketPtr &pkt,
CacheBlk *blk,
MSHR *mshr,
CacheBlk::State & new_state)
@@ -263,182 +262,106 @@ CoherenceProtocol::CoherenceProtocol(const string &name,
const bool doUpgrades)
: SimObject(name)
{
- if ((protocol == "mosi" || protocol == "moesi") && !doUpgrades) {
- cerr << "CoherenceProtocol: ownership protocols require upgrade transactions"
- << "(write miss on owned block generates ReadExcl, which will clobber dirty block)"
- << endl;
- fatal("");
+ // Python should catch this, but in case it doesn't...
+ if (!(protocol == "msi" || protocol == "mesi" ||
+ protocol == "mosi" || protocol == "moesi")) {
+ fatal("CoherenceProtocol: unrecognized protocol %s\n", protocol);
}
- Packet::Command writeToSharedCmd = doUpgrades ? Packet::UpgradeReq : Packet::ReadExReq;
- Packet::Command writeToSharedResp = doUpgrades ? Packet::UpgradeReq : Packet::ReadExResp;
-
-//@todo add in hardware prefetch to this list
- if (protocol == "msi") {
- // incoming requests: specify outgoing bus request
- transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq);
- transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq);
- transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd);
- //Prefetching causes a read
- transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq);
- transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq);
-
- // on response to given request: specify new state
- transitionTable[Invalid][Packet::ReadResp].onResponse(Shared);
- transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified);
- transitionTable[Shared][writeToSharedResp].onResponse(Modified);
-
- // bus snoop transition functions
- transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition);
- transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition);
- transitionTable[Shared][Packet::ReadReq].onSnoop(nullTransition);
- transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans);
- transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
- transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoSharedTrans);
- //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv)
- transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
-
- if (doUpgrades) {
- transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition);
- transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans);
- }
+ bool hasOwned = (protocol == "mosi" || protocol == "moesi");
+ bool hasExclusive = (protocol == "mesi" || protocol == "moesi");
+
+ if (hasOwned && !doUpgrades) {
+ fatal("CoherenceProtocol: ownership protocols require upgrade "
+ "transactions\n(write miss on owned block generates ReadExcl, "
+ "which will clobber dirty block)\n");
}
- else if(protocol == "mesi") {
- // incoming requests: specify outgoing bus request
- transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq);
- transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq);
- transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd);
- //Prefetching causes a read
- transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq);
- transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq);
-
- // on response to given request: specify new state
- transitionTable[Invalid][Packet::ReadResp].onResponse(Exclusive);
- //It will move into shared if the shared line is asserted in the
- //getNewState function
- transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified);
- transitionTable[Shared][writeToSharedResp].onResponse(Modified);
-
- // bus snoop transition functions
- transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition);
- transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition);
- transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared);
- transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans);
- transitionTable[Exclusive][Packet::ReadReq].onSnoop(assertShared);
- transitionTable[Exclusive][Packet::ReadExReq].onSnoop(invalidateTrans);
- transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
- transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoSharedTrans);
- //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv)
- transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Exclusive][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Exclusive][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
-
- if (doUpgrades) {
- transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition);
- transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans);
- }
+ // set up a few shortcuts to save typing & visual clutter
+ typedef Packet P;
+ StateTransition (&tt)[stateMax+1][NUM_MEM_CMDS] = transitionTable;
+
+ P::Command writeToSharedCmd = doUpgrades ? P::UpgradeReq : P::ReadExReq;
+ P::Command writeToSharedResp = doUpgrades ? P::UpgradeReq : P::ReadExResp;
+
+ // Note that all transitions by default cause a panic.
+ // Override the valid transitions with the appropriate actions here.
+
+ //
+ // ----- incoming requests: specify outgoing bus request -----
+ //
+ tt[Invalid][P::ReadReq].onRequest(P::ReadReq);
+ // we only support write allocate right now
+ tt[Invalid][P::WriteReq].onRequest(P::ReadExReq);
+ tt[Shared][P::WriteReq].onRequest(writeToSharedCmd);
+ if (hasOwned) {
+ tt[Owned][P::WriteReq].onRequest(writeToSharedCmd);
}
- else if(protocol == "mosi") {
- // incoming requests: specify outgoing bus request
- transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq);
- transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq);
- transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd);
- transitionTable[Owned][Packet::WriteReq].onRequest(writeToSharedCmd);
- //Prefetching causes a read
- transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq);
- transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq);
-
- // on response to given request: specify new state
- transitionTable[Invalid][Packet::ReadResp].onResponse(Shared);
- transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified);
- transitionTable[Shared][writeToSharedResp].onResponse(Modified);
- transitionTable[Owned][writeToSharedResp].onResponse(Modified);
-
- // bus snoop transition functions
- transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition);
- transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition);
- transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition);
- transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared);
- transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans);
- transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans);
- transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
- transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
- transitionTable[Owned][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
- transitionTable[Owned][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
- transitionTable[Owned][Packet::UpgradeReq].onSnoop(invalidateTrans);
- //Tansitions on seeing a DMA (writeInv(samelevel) or DMAInv)
- transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Owned][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Owned][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
+ // Prefetching causes a read
+ tt[Invalid][P::SoftPFReq].onRequest(P::ReadReq);
+ tt[Invalid][P::HardPFReq].onRequest(P::ReadReq);
+
+ //
+ // ----- on response to given request: specify new state -----
+ //
+ tt[Invalid][P::ReadExResp].onResponse(Modified);
+ tt[Shared][writeToSharedResp].onResponse(Modified);
+ // Go to Exclusive state on read response if we have one (will
+ // move into shared if the shared line is asserted in the
+ // getNewState function)
+ //
+ // originally had this as:
+ // tt[Invalid][P::ReadResp].onResponse(hasExclusive ? Exclusive: Shared);
+ // ...but for some reason that caused a link error...
+ if (hasExclusive) {
+ tt[Invalid][P::ReadResp].onResponse(Exclusive);
+ } else {
+ tt[Invalid][P::ReadResp].onResponse(Shared);
+ }
+ if (hasOwned) {
+ tt[Owned][writeToSharedResp].onResponse(Modified);
}
- else if(protocol == "moesi") {
- // incoming requests: specify outgoing bus request
- transitionTable[Invalid][Packet::ReadReq].onRequest(Packet::ReadReq);
- transitionTable[Invalid][Packet::WriteReq].onRequest(Packet::ReadExReq);
- transitionTable[Shared][Packet::WriteReq].onRequest(writeToSharedCmd);
- transitionTable[Owned][Packet::WriteReq].onRequest(writeToSharedCmd);
- //Prefetching causes a read
- transitionTable[Invalid][Packet::SoftPFReq].onRequest(Packet::ReadReq);
- transitionTable[Invalid][Packet::HardPFReq].onRequest(Packet::ReadReq);
-
- // on response to given request: specify new state
- transitionTable[Invalid][Packet::ReadResp].onResponse(Exclusive);
- //It will move into shared if the shared line is asserted in the
- //getNewState function
- transitionTable[Invalid][Packet::ReadExResp].onResponse(Modified);
- transitionTable[Shared][writeToSharedResp].onResponse(Modified);
- transitionTable[Owned][writeToSharedResp].onResponse(Modified);
-
- // bus snoop transition functions
- transitionTable[Invalid][Packet::ReadReq].onSnoop(nullTransition);
- transitionTable[Invalid][Packet::ReadExReq].onSnoop(nullTransition);
- transitionTable[Invalid][Packet::UpgradeReq].onSnoop(nullTransition);
- transitionTable[Shared][Packet::ReadReq].onSnoop(assertShared);
- transitionTable[Shared][Packet::ReadExReq].onSnoop(invalidateTrans);
- transitionTable[Shared][Packet::UpgradeReq].onSnoop(invalidateTrans);
- transitionTable[Exclusive][Packet::ReadReq].onSnoop(assertShared);
- transitionTable[Exclusive][Packet::ReadExReq].onSnoop(invalidateTrans);
- transitionTable[Modified][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
- transitionTable[Modified][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
- transitionTable[Owned][Packet::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
- transitionTable[Owned][Packet::ReadExReq].onSnoop(supplyAndInvalidateTrans);
- transitionTable[Owned][Packet::UpgradeReq].onSnoop(invalidateTrans);
- //Transitions on seeing a DMA (writeInv(samelevel) or DMAInv)
- transitionTable[Invalid][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Shared][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Exclusive][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Modified][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Owned][Packet::InvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Invalid][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Shared][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Exclusive][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Modified][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
- transitionTable[Owned][Packet::WriteInvalidateReq].onSnoop(invalidateTrans);
+ //
+ // ----- bus snoop transition functions -----
+ //
+ tt[Invalid][P::ReadReq].onSnoop(nullTransition);
+ tt[Invalid][P::ReadExReq].onSnoop(nullTransition);
+ tt[Invalid][P::InvalidateReq].onSnoop(invalidateTrans);
+ tt[Invalid][P::WriteInvalidateReq].onSnoop(invalidateTrans);
+ tt[Shared][P::ReadReq].onSnoop(hasExclusive
+ ? assertShared : nullTransition);
+ tt[Shared][P::ReadExReq].onSnoop(invalidateTrans);
+ tt[Shared][P::InvalidateReq].onSnoop(invalidateTrans);
+ tt[Shared][P::WriteInvalidateReq].onSnoop(invalidateTrans);
+ if (doUpgrades) {
+ tt[Invalid][P::UpgradeReq].onSnoop(nullTransition);
+ tt[Shared][P::UpgradeReq].onSnoop(invalidateTrans);
+ }
+ tt[Modified][P::ReadExReq].onSnoop(supplyAndInvalidateTrans);
+ tt[Modified][P::ReadReq].onSnoop(hasOwned
+ ? supplyAndGotoOwnedTrans
+ : supplyAndGotoSharedTrans);
+ tt[Modified][P::InvalidateReq].onSnoop(invalidateTrans);
+ tt[Modified][P::WriteInvalidateReq].onSnoop(invalidateTrans);
+
+ if (hasExclusive) {
+ tt[Exclusive][P::ReadReq].onSnoop(assertShared);
+ tt[Exclusive][P::ReadExReq].onSnoop(invalidateTrans);
+ tt[Exclusive][P::InvalidateReq].onSnoop(invalidateTrans);
+ tt[Exclusive][P::WriteInvalidateReq].onSnoop(invalidateTrans);
}
- else {
- cerr << "CoherenceProtocol: unrecognized protocol " << protocol
- << endl;
- fatal("");
+ if (hasOwned) {
+ tt[Owned][P::ReadReq].onSnoop(supplyAndGotoOwnedTrans);
+ tt[Owned][P::ReadExReq].onSnoop(supplyAndInvalidateTrans);
+ tt[Owned][P::UpgradeReq].onSnoop(invalidateTrans);
+ tt[Owned][P::InvalidateReq].onSnoop(invalidateTrans);
+ tt[Owned][P::WriteInvalidateReq].onSnoop(invalidateTrans);
}
+
+ // @todo add in hardware prefetch to this list
}
@@ -463,7 +386,7 @@ CoherenceProtocol::getBusCmd(Packet::Command cmdIn, CacheBlk::State state,
CacheBlk::State
-CoherenceProtocol::getNewState(Packet * &pkt, CacheBlk::State oldState)
+CoherenceProtocol::getNewState(PacketPtr &pkt, CacheBlk::State oldState)
{
CacheBlk::State state = oldState & stateMask;
int cmd_idx = pkt->cmdToIndex();
@@ -488,7 +411,7 @@ CoherenceProtocol::getNewState(Packet * &pkt, CacheBlk::State oldState)
bool
-CoherenceProtocol::handleBusRequest(BaseCache *cache, Packet * &pkt,
+CoherenceProtocol::handleBusRequest(BaseCache *cache, PacketPtr &pkt,
CacheBlk *blk,
MSHR *mshr,
CacheBlk::State & new_state)
@@ -518,7 +441,7 @@ CoherenceProtocol::handleBusRequest(BaseCache *cache, Packet * &pkt,
}
bool
-CoherenceProtocol::nullTransition(BaseCache *cache, Packet * &pkt,
+CoherenceProtocol::nullTransition(BaseCache *cache, PacketPtr &pkt,
CacheBlk *blk, MSHR *mshr,
CacheBlk::State & new_state)
{
@@ -530,7 +453,7 @@ CoherenceProtocol::nullTransition(BaseCache *cache, Packet * &pkt,
bool
-CoherenceProtocol::invalidTransition(BaseCache *cache, Packet * &pkt,
+CoherenceProtocol::invalidTransition(BaseCache *cache, PacketPtr &pkt,
CacheBlk *blk, MSHR *mshr,
CacheBlk::State & new_state)
{
diff --git a/src/mem/cache/coherence/coherence_protocol.hh b/src/mem/cache/coherence/coherence_protocol.hh
index b5d7d80aa..481277523 100644
--- a/src/mem/cache/coherence/coherence_protocol.hh
+++ b/src/mem/cache/coherence/coherence_protocol.hh
@@ -89,7 +89,7 @@ class CoherenceProtocol : public SimObject
* @param oldState The current block state.
* @return The new state.
*/
- CacheBlk::State getNewState(Packet * &pkt,
+ CacheBlk::State getNewState(PacketPtr &pkt,
CacheBlk::State oldState);
/**
@@ -101,12 +101,12 @@ class CoherenceProtocol : public SimObject
* @param new_state The new coherence state of the block.
* @return True if the request should be satisfied locally.
*/
- bool handleBusRequest(BaseCache *cache, Packet * &pkt, CacheBlk *blk,
+ bool handleBusRequest(BaseCache *cache, PacketPtr &pkt, CacheBlk *blk,
MSHR *mshr, CacheBlk::State &new_state);
protected:
/** Snoop function type. */
- typedef bool (*SnoopFuncType)(BaseCache *, Packet *&, CacheBlk *,
+ typedef bool (*SnoopFuncType)(BaseCache *, PacketPtr &, CacheBlk *,
MSHR *, CacheBlk::State&);
//
@@ -116,49 +116,49 @@ class CoherenceProtocol : public SimObject
/**
* Do nothing transition.
*/
- static bool nullTransition(BaseCache *, Packet *&, CacheBlk *,
+ static bool nullTransition(BaseCache *, PacketPtr &, CacheBlk *,
MSHR *, CacheBlk::State&);
/**
* Invalid transition, basically panic.
*/
- static bool invalidTransition(BaseCache *, Packet *&, CacheBlk *,
+ static bool invalidTransition(BaseCache *, PacketPtr &, CacheBlk *,
MSHR *, CacheBlk::State&);
/**
* Invalidate block, move to Invalid state.
*/
- static bool invalidateTrans(BaseCache *, Packet *&, CacheBlk *,
+ static bool invalidateTrans(BaseCache *, PacketPtr &, CacheBlk *,
MSHR *, CacheBlk::State&);
/**
* Supply data, no state transition.
*/
- static bool supplyTrans(BaseCache *, Packet *&, CacheBlk *,
+ static bool supplyTrans(BaseCache *, PacketPtr &, CacheBlk *,
MSHR *, CacheBlk::State&);
/**
* Supply data and go to Shared state.
*/
- static bool supplyAndGotoSharedTrans(BaseCache *, Packet *&, CacheBlk *,
+ static bool supplyAndGotoSharedTrans(BaseCache *, PacketPtr &, CacheBlk *,
MSHR *, CacheBlk::State&);
/**
* Supply data and go to Owned state.
*/
- static bool supplyAndGotoOwnedTrans(BaseCache *, Packet *&, CacheBlk *,
+ static bool supplyAndGotoOwnedTrans(BaseCache *, PacketPtr &, CacheBlk *,
MSHR *, CacheBlk::State&);
/**
* Invalidate block, supply data, and go to Invalid state.
*/
- static bool supplyAndInvalidateTrans(BaseCache *, Packet *&, CacheBlk *,
+ static bool supplyAndInvalidateTrans(BaseCache *, PacketPtr &, CacheBlk *,
MSHR *, CacheBlk::State&);
/**
* Assert the shared line for a block that is shared/exclusive.
*/
- static bool assertShared(BaseCache *, Packet *&, CacheBlk *,
+ static bool assertShared(BaseCache *, PacketPtr &, CacheBlk *,
MSHR *, CacheBlk::State&);
/**
@@ -211,31 +211,25 @@ class CoherenceProtocol : public SimObject
friend class CoherenceProtocol::StateTransition;
/** Mask to select status bits relevant to coherence protocol. */
- const static CacheBlk::State
- stateMask = BlkValid | BlkWritable | BlkDirty;
+ static const int stateMask = BlkValid | BlkWritable | BlkDirty;
/** The Modified (M) state. */
- const static CacheBlk::State
- Modified = BlkValid | BlkWritable | BlkDirty;
+ static const int Modified = BlkValid | BlkWritable | BlkDirty;
/** The Owned (O) state. */
- const static CacheBlk::State
- Owned = BlkValid | BlkDirty;
+ static const int Owned = BlkValid | BlkDirty;
/** The Exclusive (E) state. */
- const static CacheBlk::State
- Exclusive = BlkValid | BlkWritable;
+ static const int Exclusive = BlkValid | BlkWritable;
/** The Shared (S) state. */
- const static CacheBlk::State
- Shared = BlkValid;
+ static const int Shared = BlkValid;
/** The Invalid (I) state. */
- const static CacheBlk::State
- Invalid = 0;
+ static const int Invalid = 0;
/**
* Maximum state encoding value (used to size transition lookup
* table). Could be more than number of states, depends on
* encoding of status bits.
*/
- const static int stateMax = stateMask;
+ static const int stateMax = stateMask;
/**
* The table of all possible transitions, organized by starting state and
diff --git a/src/mem/cache/coherence/simple_coherence.hh b/src/mem/cache/coherence/simple_coherence.hh
index a356b3ecc..5316e64b9 100644
--- a/src/mem/cache/coherence/simple_coherence.hh
+++ b/src/mem/cache/coherence/simple_coherence.hh
@@ -89,7 +89,7 @@ class SimpleCoherence
* This policy does not forward invalidates, return NULL.
* @return NULL.
*/
- Packet * getPacket()
+ PacketPtr getPacket()
{
return NULL;
}
@@ -99,7 +99,7 @@ class SimpleCoherence
* @param pkt The request.
* @param success True if the request was sent successfully.
*/
- void sendResult(Packet * &pkt, MSHR* cshr, bool success)
+ void sendResult(PacketPtr &pkt, MSHR* cshr, bool success)
{
//Don't do coherence
return;
@@ -112,7 +112,7 @@ class SimpleCoherence
* @param current The current block state.
* @return The new state.
*/
- CacheBlk::State getNewState(Packet * &pkt, CacheBlk::State current)
+ CacheBlk::State getNewState(PacketPtr &pkt, CacheBlk::State current)
{
return protocol->getNewState(pkt, current);
}
@@ -124,7 +124,7 @@ class SimpleCoherence
* @param mshr The MSHR corresponding to the request, if any.
* @param new_state Return the new state for the block.
*/
- bool handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr,
+ bool handleBusRequest(PacketPtr &pkt, CacheBlk *blk, MSHR *mshr,
CacheBlk::State &new_state)
{
// assert(mshr == NULL);
@@ -160,6 +160,12 @@ class SimpleCoherence
bool allowFastWrites() { return false; }
bool hasProtocol() { return true; }
+
+ void propogateInvalidate(PacketPtr pkt, bool isTiming)
+ {
+ //For now we do nothing, asssumes simple coherence is top level of cache
+ return;
+ }
};
#endif //__SIMPLE_COHERENCE_HH__
diff --git a/src/mem/cache/coherence/uni_coherence.cc b/src/mem/cache/coherence/uni_coherence.cc
index 751de4801..19230e35b 100644
--- a/src/mem/cache/coherence/uni_coherence.cc
+++ b/src/mem/cache/coherence/uni_coherence.cc
@@ -40,24 +40,24 @@ UniCoherence::UniCoherence()
{
}
-Packet *
+PacketPtr
UniCoherence::getPacket()
{
- Packet* pkt = cshrs.getReq();
+ PacketPtr pkt = cshrs.getReq();
return pkt;
}
void
-UniCoherence::sendResult(Packet * &pkt, MSHR* cshr, bool success)
+UniCoherence::sendResult(PacketPtr &pkt, MSHR* cshr, bool success)
{
if (success)
{
bool unblock = cshrs.isFull();
- cshrs.markInService(cshr);
+// cshrs.markInService(cshr);
+ cshrs.deallocate(cshr);
if (!cshrs.havePending()) {
cache->clearSlaveRequest(Request_Coherence);
}
- cshrs.deallocate(cshr);
if (unblock) {
//since CSHRs are always used as buffers, should always get rid of one
assert(!cshrs.isFull());
@@ -71,24 +71,36 @@ UniCoherence::sendResult(Packet * &pkt, MSHR* cshr, bool success)
* @todo add support for returning slave requests, not doing them here.
*/
bool
-UniCoherence::handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr,
+UniCoherence::handleBusRequest(PacketPtr &pkt, CacheBlk *blk, MSHR *mshr,
CacheBlk::State &new_state)
{
new_state = 0;
if (pkt->isInvalidate()) {
- DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n",
- pkt->getAddr(), blk);
- // Forward to other caches
- Packet * tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
- cshrs.allocate(tmp);
- cache->setSlaveRequest(Request_Coherence, curTick);
- if (cshrs.isFull()) {
- cache->setBlockedForSnoop(Blocked_Coherence);
+ DPRINTF(Cache, "snoop inval on blk %x (blk ptr %x)\n",
+ pkt->getAddr(), blk);
+ }
+ else if (blk) {
+ new_state = blk->status;
+ }
+ return false;
+}
+
+void
+UniCoherence::propogateInvalidate(PacketPtr pkt, bool isTiming)
+{
+ if (pkt->isInvalidate()) {
+ if (isTiming) {
+ // Forward to other caches
+ PacketPtr tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
+ cshrs.allocate(tmp);
+ cache->setSlaveRequest(Request_Coherence, curTick);
+ if (cshrs.isFull())
+ cache->setBlockedForSnoop(Blocked_Coherence);
}
- } else {
- if (blk) {
- new_state = blk->status;
+ else {
+ PacketPtr tmp = new Packet(pkt->req, Packet::InvalidateReq, -1);
+ cache->cpuSidePort->sendAtomic(tmp);
+ delete tmp;
}
}
- return false;
}
diff --git a/src/mem/cache/coherence/uni_coherence.hh b/src/mem/cache/coherence/uni_coherence.hh
index 60da7a36e..44c752088 100644
--- a/src/mem/cache/coherence/uni_coherence.hh
+++ b/src/mem/cache/coherence/uni_coherence.hh
@@ -92,7 +92,7 @@ class UniCoherence
* @param current The current block state.
* @return The new state.
*/
- CacheBlk::State getNewState(Packet * &pkt, CacheBlk::State current)
+ CacheBlk::State getNewState(PacketPtr &pkt, CacheBlk::State current)
{
if (pkt->senderState) //Blocking Buffers don't get mshrs
{
@@ -113,14 +113,14 @@ class UniCoherence
* Return outstanding invalidate to forward.
* @return The next invalidate to forward to lower levels of cache.
*/
- Packet * getPacket();
+ PacketPtr getPacket();
/**
* Was the CSHR request was sent successfully?
* @param pkt The request.
* @param success True if the request was sent successfully.
*/
- void sendResult(Packet * &pkt, MSHR* cshr, bool success);
+ void sendResult(PacketPtr &pkt, MSHR* cshr, bool success);
/**
* Handle snooped bus requests.
@@ -130,7 +130,7 @@ class UniCoherence
* @param new_state The new coherence state of the block.
* @return True if the request should be satisfied locally.
*/
- bool handleBusRequest(Packet * &pkt, CacheBlk *blk, MSHR *mshr,
+ bool handleBusRequest(PacketPtr &pkt, CacheBlk *blk, MSHR *mshr,
CacheBlk::State &new_state);
/**
@@ -139,6 +139,8 @@ class UniCoherence
bool allowFastWrites() { return true; }
bool hasProtocol() { return false; }
+
+ void propogateInvalidate(PacketPtr pkt, bool isTiming);
};
#endif //__UNI_COHERENCE_HH__
diff --git a/src/mem/cache/miss/blocking_buffer.cc b/src/mem/cache/miss/blocking_buffer.cc
index f7aacff89..bf741e547 100644
--- a/src/mem/cache/miss/blocking_buffer.cc
+++ b/src/mem/cache/miss/blocking_buffer.cc
@@ -68,7 +68,7 @@ BlockingBuffer::setPrefetcher(BasePrefetcher *_prefetcher)
prefetcher = _prefetcher;
}
void
-BlockingBuffer::handleMiss(Packet * &pkt, int blk_size, Tick time)
+BlockingBuffer::handleMiss(PacketPtr &pkt, int blk_size, Tick time)
{
Addr blk_addr = pkt->getAddr() & ~(Addr)(blk_size - 1);
if (pkt->isWrite() && (pkt->req->isUncacheable() || !writeAllocate ||
@@ -98,7 +98,7 @@ BlockingBuffer::handleMiss(Packet * &pkt, int blk_size, Tick time)
cache->setMasterRequest(Request_MSHR, time);
}
-Packet *
+PacketPtr
BlockingBuffer::getPacket()
{
if (miss.pkt && !miss.inService) {
@@ -108,7 +108,7 @@ BlockingBuffer::getPacket()
}
void
-BlockingBuffer::setBusCmd(Packet * &pkt, Packet::Command cmd)
+BlockingBuffer::setBusCmd(PacketPtr &pkt, Packet::Command cmd)
{
MSHR *mshr = (MSHR*) pkt->senderState;
mshr->originalCmd = pkt->cmd;
@@ -117,13 +117,13 @@ BlockingBuffer::setBusCmd(Packet * &pkt, Packet::Command cmd)
}
void
-BlockingBuffer::restoreOrigCmd(Packet * &pkt)
+BlockingBuffer::restoreOrigCmd(PacketPtr &pkt)
{
pkt->cmdOverride(((MSHR*)(pkt->senderState))->originalCmd);
}
void
-BlockingBuffer::markInService(Packet * &pkt, MSHR* mshr)
+BlockingBuffer::markInService(PacketPtr &pkt, MSHR* mshr)
{
if (!pkt->isCacheFill() && pkt->isWrite()) {
// Forwarding a write/ writeback, don't need to change
@@ -152,7 +152,7 @@ BlockingBuffer::markInService(Packet * &pkt, MSHR* mshr)
}
void
-BlockingBuffer::handleResponse(Packet * &pkt, Tick time)
+BlockingBuffer::handleResponse(PacketPtr &pkt, Tick time)
{
if (pkt->isCacheFill()) {
// targets were handled in the cache tags
@@ -163,7 +163,7 @@ BlockingBuffer::handleResponse(Packet * &pkt, Tick time)
if (((MSHR*)(pkt->senderState))->hasTargets()) {
// Should only have 1 target if we had any
assert(((MSHR*)(pkt->senderState))->getNumTargets() == 1);
- Packet * target = ((MSHR*)(pkt->senderState))->getTarget();
+ PacketPtr target = ((MSHR*)(pkt->senderState))->getTarget();
((MSHR*)(pkt->senderState))->popTarget();
if (pkt->isRead()) {
memcpy(target->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(), target->getSize());
@@ -187,7 +187,7 @@ void
BlockingBuffer::squash(int threadNum)
{
if (miss.threadNum == threadNum) {
- Packet * target = miss.getTarget();
+ PacketPtr target = miss.getTarget();
miss.popTarget();
assert(0/*target->req->getThreadNum()*/ == threadNum);
target = NULL;
@@ -207,7 +207,7 @@ BlockingBuffer::doWriteback(Addr addr,
{
// Generate request
Request * req = new Request(addr, size, 0);
- Packet * pkt = new Packet(req, Packet::Writeback, -1);
+ PacketPtr pkt = new Packet(req, Packet::Writeback, -1);
pkt->allocate();
if (data) {
memcpy(pkt->getPtr<uint8_t>(), data, size);
@@ -228,7 +228,7 @@ BlockingBuffer::doWriteback(Addr addr,
void
-BlockingBuffer::doWriteback(Packet * &pkt)
+BlockingBuffer::doWriteback(PacketPtr &pkt)
{
writebacks[0/*pkt->req->getThreadNum()*/]++;
diff --git a/src/mem/cache/miss/blocking_buffer.hh b/src/mem/cache/miss/blocking_buffer.hh
index f7069696c..4408cfc4f 100644
--- a/src/mem/cache/miss/blocking_buffer.hh
+++ b/src/mem/cache/miss/blocking_buffer.hh
@@ -111,7 +111,7 @@ public:
* @param blk_size The block size of the cache.
* @param time The time the miss is detected.
*/
- void handleMiss(Packet * &pkt, int blk_size, Tick time);
+ void handleMiss(PacketPtr &pkt, int blk_size, Tick time);
/**
* Fetch the block for the given address and buffer the given target.
@@ -122,7 +122,7 @@ public:
* @param target The target for the fetch.
*/
MSHR* fetchBlock(Addr addr, int blk_size, Tick time,
- Packet * &target)
+ PacketPtr &target)
{
fatal("Unimplemented");
}
@@ -131,20 +131,20 @@ public:
* Selects a outstanding pktuest to service.
* @return The pktuest to service, NULL if none found.
*/
- Packet * getPacket();
+ PacketPtr getPacket();
/**
* Set the command to the given bus command.
* @param pkt The request to update.
* @param cmd The bus command to use.
*/
- void setBusCmd(Packet * &pkt, Packet::Command cmd);
+ void setBusCmd(PacketPtr &pkt, Packet::Command cmd);
/**
* Restore the original command in case of a bus transmission error.
* @param pkt The request to reset.
*/
- void restoreOrigCmd(Packet * &pkt);
+ void restoreOrigCmd(PacketPtr &pkt);
/**
* Marks a pktuest as in service (sent on the bus). This can have side
@@ -152,14 +152,14 @@ public:
* are successfully sent.
* @param pkt The request that was sent on the bus.
*/
- void markInService(Packet * &pkt, MSHR* mshr);
+ void markInService(PacketPtr &pkt, MSHR* mshr);
/**
* Frees the resources of the pktuest and unblock the cache.
* @param pkt The request that has been satisfied.
* @param time The time when the pktuest is satisfied.
*/
- void handleResponse(Packet * &pkt, Tick time);
+ void handleResponse(PacketPtr &pkt, Tick time);
/**
* Removes all outstanding pktuests for a given thread number. If a request
@@ -223,7 +223,7 @@ public:
* Perform a writeback pktuest.
* @param pkt The writeback request.
*/
- void doWriteback(Packet * &pkt);
+ void doWriteback(PacketPtr &pkt);
/**
* Returns true if there are outstanding pktuests.
@@ -239,7 +239,7 @@ public:
* @param mshr The mshr to add a target to.
* @param pkt The target to add.
*/
- void addTarget(MSHR *mshr, Packet * &pkt)
+ void addTarget(MSHR *mshr, PacketPtr &pkt)
{
fatal("Shouldn't call this on a blocking buffer.");
}
diff --git a/src/mem/cache/miss/miss_queue.cc b/src/mem/cache/miss/miss_queue.cc
index c23b542f5..fe467a8ea 100644
--- a/src/mem/cache/miss/miss_queue.cc
+++ b/src/mem/cache/miss/miss_queue.cc
@@ -350,7 +350,7 @@ MissQueue::setPrefetcher(BasePrefetcher *_prefetcher)
}
MSHR*
-MissQueue::allocateMiss(Packet * &pkt, int size, Tick time)
+MissQueue::allocateMiss(PacketPtr &pkt, int size, Tick time)
{
MSHR* mshr = mq.allocate(pkt, size);
mshr->order = order++;
@@ -370,7 +370,7 @@ MissQueue::allocateMiss(Packet * &pkt, int size, Tick time)
MSHR*
-MissQueue::allocateWrite(Packet * &pkt, int size, Tick time)
+MissQueue::allocateWrite(PacketPtr &pkt, int size, Tick time)
{
MSHR* mshr = wb.allocate(pkt,size);
mshr->order = order++;
@@ -401,7 +401,7 @@ MissQueue::allocateWrite(Packet * &pkt, int size, Tick time)
* @todo Remove SW prefetches on mshr hits.
*/
void
-MissQueue::handleMiss(Packet * &pkt, int blkSize, Tick time)
+MissQueue::handleMiss(PacketPtr &pkt, int blkSize, Tick time)
{
// if (!cache->isTopLevel())
if (prefetchMiss) prefetcher->handleMiss(pkt, time);
@@ -455,7 +455,7 @@ MissQueue::handleMiss(Packet * &pkt, int blkSize, Tick time)
MSHR*
MissQueue::fetchBlock(Addr addr, int blk_size, Tick time,
- Packet * &target)
+ PacketPtr &target)
{
Addr blkAddr = addr & ~(Addr)(blk_size - 1);
assert(mq.findMatch(addr) == NULL);
@@ -469,10 +469,10 @@ MissQueue::fetchBlock(Addr addr, int blk_size, Tick time,
return mshr;
}
-Packet *
+PacketPtr
MissQueue::getPacket()
{
- Packet * pkt = mq.getReq();
+ PacketPtr pkt = mq.getReq();
if (((wb.isFull() && wb.inServiceMSHRs == 0) || !pkt ||
pkt->time > curTick) && wb.havePending()) {
pkt = wb.getReq();
@@ -510,7 +510,7 @@ MissQueue::getPacket()
}
void
-MissQueue::setBusCmd(Packet * &pkt, Packet::Command cmd)
+MissQueue::setBusCmd(PacketPtr &pkt, Packet::Command cmd)
{
assert(pkt->senderState != 0);
MSHR * mshr = (MSHR*)pkt->senderState;
@@ -528,13 +528,13 @@ MissQueue::setBusCmd(Packet * &pkt, Packet::Command cmd)
}
void
-MissQueue::restoreOrigCmd(Packet * &pkt)
+MissQueue::restoreOrigCmd(PacketPtr &pkt)
{
pkt->cmd = ((MSHR*)(pkt->senderState))->originalCmd;
}
void
-MissQueue::markInService(Packet * &pkt, MSHR* mshr)
+MissQueue::markInService(PacketPtr &pkt, MSHR* mshr)
{
bool unblock = false;
BlockedCause cause = NUM_BLOCKED_CAUSES;
@@ -583,7 +583,7 @@ MissQueue::markInService(Packet * &pkt, MSHR* mshr)
void
-MissQueue::handleResponse(Packet * &pkt, Tick time)
+MissQueue::handleResponse(PacketPtr &pkt, Tick time)
{
MSHR* mshr = (MSHR*)pkt->senderState;
if (((MSHR*)(pkt->senderState))->originalCmd == Packet::HardPFReq) {
@@ -632,7 +632,7 @@ MissQueue::handleResponse(Packet * &pkt, Tick time)
if (mshr->hasTargets() && pkt->req->isUncacheable()) {
// Should only have 1 target if we had any
assert(num_targets == 1);
- Packet * target = mshr->getTarget();
+ PacketPtr target = mshr->getTarget();
mshr->popTarget();
if (pkt->isRead()) {
memcpy(target->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(),
@@ -645,7 +645,7 @@ MissQueue::handleResponse(Packet * &pkt, Tick time)
//Must be a no_allocate with possibly more than one target
assert(mshr->pkt->isNoAllocate());
while (mshr->hasTargets()) {
- Packet * target = mshr->getTarget();
+ PacketPtr target = mshr->getTarget();
mshr->popTarget();
if (pkt->isRead()) {
memcpy(target->getPtr<uint8_t>(), pkt->getPtr<uint8_t>(),
@@ -721,7 +721,7 @@ MissQueue::doWriteback(Addr addr,
{
// Generate request
Request * req = new Request(addr, size, 0);
- Packet * pkt = new Packet(req, Packet::Writeback, -1);
+ PacketPtr pkt = new Packet(req, Packet::Writeback, -1);
pkt->allocate();
if (data) {
memcpy(pkt->getPtr<uint8_t>(), data, size);
@@ -739,7 +739,7 @@ MissQueue::doWriteback(Addr addr,
void
-MissQueue::doWriteback(Packet * &pkt)
+MissQueue::doWriteback(PacketPtr &pkt)
{
writebacks[0/*pkt->req->getThreadNum()*/]++;
allocateWrite(pkt, 0, curTick);
diff --git a/src/mem/cache/miss/miss_queue.hh b/src/mem/cache/miss/miss_queue.hh
index 179638d2b..2e04802fb 100644
--- a/src/mem/cache/miss/miss_queue.hh
+++ b/src/mem/cache/miss/miss_queue.hh
@@ -169,7 +169,7 @@ class MissQueue
* @param time The time the miss occurs.
* @return A pointer to the new MSHR.
*/
- MSHR* allocateMiss(Packet * &pkt, int size, Tick time);
+ MSHR* allocateMiss(PacketPtr &pkt, int size, Tick time);
/**
* Allocate a new WriteBuffer to handle the provided write.
@@ -178,7 +178,7 @@ class MissQueue
* @param time The time the write occurs.
* @return A pointer to the new write buffer.
*/
- MSHR* allocateWrite(Packet * &pkt, int size, Tick time);
+ MSHR* allocateWrite(PacketPtr &pkt, int size, Tick time);
public:
/**
@@ -218,7 +218,7 @@ class MissQueue
* @param blk_size The block size of the cache.
* @param time The time the miss is detected.
*/
- void handleMiss(Packet * &pkt, int blk_size, Tick time);
+ void handleMiss(PacketPtr &pkt, int blk_size, Tick time);
/**
* Fetch the block for the given address and buffer the given target.
@@ -229,26 +229,26 @@ class MissQueue
* @param target The target for the fetch.
*/
MSHR* fetchBlock(Addr addr, int blk_size, Tick time,
- Packet * &target);
+ PacketPtr &target);
/**
* Selects a outstanding pktuest to service.
* @return The pktuest to service, NULL if none found.
*/
- Packet * getPacket();
+ PacketPtr getPacket();
/**
* Set the command to the given bus command.
* @param pkt The request to update.
* @param cmd The bus command to use.
*/
- void setBusCmd(Packet * &pkt, Packet::Command cmd);
+ void setBusCmd(PacketPtr &pkt, Packet::Command cmd);
/**
* Restore the original command in case of a bus transmission error.
* @param pkt The request to reset.
*/
- void restoreOrigCmd(Packet * &pkt);
+ void restoreOrigCmd(PacketPtr &pkt);
/**
* Marks a pktuest as in service (sent on the bus). This can have side
@@ -256,14 +256,14 @@ class MissQueue
* are successfully sent.
* @param pkt The request that was sent on the bus.
*/
- void markInService(Packet * &pkt, MSHR* mshr);
+ void markInService(PacketPtr &pkt, MSHR* mshr);
/**
* Collect statistics and free resources of a satisfied pktuest.
* @param pkt The request that has been satisfied.
* @param time The time when the pktuest is satisfied.
*/
- void handleResponse(Packet * &pkt, Tick time);
+ void handleResponse(PacketPtr &pkt, Tick time);
/**
* Removes all outstanding pktuests for a given thread number. If a request
@@ -316,7 +316,7 @@ class MissQueue
* Perform the given writeback pktuest.
* @param pkt The writeback request.
*/
- void doWriteback(Packet * &pkt);
+ void doWriteback(PacketPtr &pkt);
/**
* Returns true if there are outstanding pktuests.
@@ -329,7 +329,7 @@ class MissQueue
* @param mshr The mshr to add a target to.
* @param pkt The target to add.
*/
- void addTarget(MSHR *mshr, Packet * &pkt)
+ void addTarget(MSHR *mshr, PacketPtr &pkt)
{
mq.allocateTarget(mshr, pkt);
}
diff --git a/src/mem/cache/miss/mshr.cc b/src/mem/cache/miss/mshr.cc
index 455798f15..fc520b4b4 100644
--- a/src/mem/cache/miss/mshr.cc
+++ b/src/mem/cache/miss/mshr.cc
@@ -55,7 +55,7 @@ MSHR::MSHR()
void
MSHR::allocate(Packet::Command cmd, Addr _addr, int size,
- Packet * &target)
+ PacketPtr &target)
{
addr = _addr;
if (target)
@@ -85,7 +85,7 @@ MSHR::allocate(Packet::Command cmd, Addr _addr, int size,
* @todo When we have a "global" data flag, might want to copy data here.
*/
void
-MSHR::allocateAsBuffer(Packet * &target)
+MSHR::allocateAsBuffer(PacketPtr &target)
{
addr = target->getAddr();
threadNum = 0/*target->req->getThreadNum()*/;
@@ -111,13 +111,13 @@ MSHR::deallocate()
* Adds a target to an MSHR
*/
void
-MSHR::allocateTarget(Packet * &target)
+MSHR::allocateTarget(PacketPtr &target)
{
//If we append an invalidate and we issued a read to the bus,
//but now have some pending writes, we need to move
//the invalidate to before the first non-read
if (inService && pkt->isRead() && target->isInvalidate()) {
- std::list<Packet *> temp;
+ std::list<PacketPtr> temp;
while (!targets.empty()) {
if (!targets.front()->isRead()) break;
diff --git a/src/mem/cache/miss/mshr.hh b/src/mem/cache/miss/mshr.hh
index 028259b35..d92aa8a85 100644
--- a/src/mem/cache/miss/mshr.hh
+++ b/src/mem/cache/miss/mshr.hh
@@ -49,9 +49,9 @@ class MSHR;
class MSHR {
public:
/** Defines the Data structure of the MSHR targetlist. */
- typedef std::list<Packet *> TargetList;
+ typedef std::list<PacketPtr> TargetList;
/** Target list iterator. */
- typedef std::list<Packet *>::iterator TargetListIterator;
+ typedef std::list<PacketPtr>::iterator TargetListIterator;
/** A list of MSHRs. */
typedef std::list<MSHR *> List;
/** MSHR list iterator. */
@@ -68,7 +68,7 @@ class MSHR {
/** Thread number of the miss. */
int threadNum;
/** The pktuest that is forwarded to the next level of the hierarchy. */
- Packet * pkt;
+ PacketPtr pkt;
/** The number of currently allocated targets. */
short ntargets;
/** The original pktuesting command. */
@@ -101,13 +101,13 @@ public:
* @param pkt The original miss.
*/
void allocate(Packet::Command cmd, Addr addr, int size,
- Packet * &pkt);
+ PacketPtr &pkt);
/**
* Allocate this MSHR as a buffer for the given pktuest.
* @param target The memory pktuest to buffer.
*/
- void allocateAsBuffer(Packet * &target);
+ void allocateAsBuffer(PacketPtr &target);
/**
* Mark this MSHR as free.
@@ -118,7 +118,7 @@ public:
* Add a pktuest to the list of targets.
* @param target The target.
*/
- void allocateTarget(Packet * &target);
+ void allocateTarget(PacketPtr &target);
/** A simple constructor. */
MSHR();
@@ -147,7 +147,7 @@ public:
* Returns a reference to the first target.
* @return A pointer to the first target.
*/
- Packet * getTarget()
+ PacketPtr getTarget()
{
return targets.front();
}
diff --git a/src/mem/cache/miss/mshr_queue.cc b/src/mem/cache/miss/mshr_queue.cc
index 777443e5f..d3a7a7933 100644
--- a/src/mem/cache/miss/mshr_queue.cc
+++ b/src/mem/cache/miss/mshr_queue.cc
@@ -88,7 +88,7 @@ MSHRQueue::findMatches(Addr addr, vector<MSHR*>& matches) const
}
MSHR*
-MSHRQueue::findPending(Packet * &pkt) const
+MSHRQueue::findPending(PacketPtr &pkt) const
{
MSHR::ConstIterator i = pendingList.begin();
MSHR::ConstIterator end = pendingList.end();
@@ -108,7 +108,7 @@ MSHRQueue::findPending(Packet * &pkt) const
}
MSHR*
-MSHRQueue::allocate(Packet * &pkt, int size)
+MSHRQueue::allocate(PacketPtr &pkt, int size)
{
Addr aligned_addr = pkt->getAddr() & ~((Addr)size - 1);
assert(!freeList.empty());
@@ -131,7 +131,7 @@ MSHRQueue::allocate(Packet * &pkt, int size)
}
MSHR*
-MSHRQueue::allocateFetch(Addr addr, int size, Packet * &target)
+MSHRQueue::allocateFetch(Addr addr, int size, PacketPtr &target)
{
MSHR *mshr = freeList.front();
assert(mshr->getNumTargets() == 0);
@@ -150,7 +150,7 @@ MSHRQueue::allocateTargetList(Addr addr, int size)
MSHR *mshr = freeList.front();
assert(mshr->getNumTargets() == 0);
freeList.pop_front();
- Packet * dummy;
+ PacketPtr dummy;
mshr->allocate(Packet::ReadReq, addr, size, dummy);
mshr->allocIter = allocatedList.insert(allocatedList.end(), mshr);
mshr->inService = true;
@@ -237,7 +237,7 @@ MSHRQueue::squash(int threadNum)
MSHR *mshr = *i;
if (mshr->threadNum == threadNum) {
while (mshr->hasTargets()) {
- Packet * target = mshr->getTarget();
+ PacketPtr target = mshr->getTarget();
mshr->popTarget();
assert(0/*target->req->getThreadNum()*/ == threadNum);
diff --git a/src/mem/cache/miss/mshr_queue.hh b/src/mem/cache/miss/mshr_queue.hh
index ea5f101b7..30397d9a0 100644
--- a/src/mem/cache/miss/mshr_queue.hh
+++ b/src/mem/cache/miss/mshr_queue.hh
@@ -107,7 +107,7 @@ class MSHRQueue {
* @param pkt The request to find.
* @return A pointer to the earliest matching MSHR.
*/
- MSHR* findPending(Packet * &pkt) const;
+ MSHR* findPending(PacketPtr &pkt) const;
/**
* Allocates a new MSHR for the pktuest and size. This places the request
@@ -118,7 +118,7 @@ class MSHRQueue {
*
* @pre There are free MSHRs.
*/
- MSHR* allocate(Packet * &pkt, int size = 0);
+ MSHR* allocate(PacketPtr &pkt, int size = 0);
/**
* Allocate a read pktuest for the given address, and places the given
@@ -129,7 +129,7 @@ class MSHRQueue {
* @param target The first target for the pktuest.
* @return Pointer to the new MSHR.
*/
- MSHR* allocateFetch(Addr addr, int size, Packet * &target);
+ MSHR* allocateFetch(Addr addr, int size, PacketPtr &target);
/**
* Allocate a target list for the given address.
@@ -153,7 +153,7 @@ class MSHRQueue {
* @param mshr The MSHR to allocate the target to.
* @param pkt The target request.
*/
- void allocateTarget(MSHR* mshr, Packet * &pkt)
+ void allocateTarget(MSHR* mshr, PacketPtr &pkt)
{
mshr->allocateTarget(pkt);
allocatedTargets += 1;
@@ -216,7 +216,7 @@ class MSHRQueue {
* Returns the pktuest at the head of the pendingList.
* @return The next pktuest to service.
*/
- Packet * getReq() const
+ PacketPtr getReq() const
{
if (pendingList.empty()) {
return NULL;
diff --git a/src/mem/cache/prefetch/base_prefetcher.cc b/src/mem/cache/prefetch/base_prefetcher.cc
index 5e50c48bd..a1388fad6 100644
--- a/src/mem/cache/prefetch/base_prefetcher.cc
+++ b/src/mem/cache/prefetch/base_prefetcher.cc
@@ -102,7 +102,7 @@ BasePrefetcher::regStats(const std::string &name)
;
}
-Packet *
+PacketPtr
BasePrefetcher::getPacket()
{
DPRINTF(HWPrefetch, "%s:Requesting a hw_pf to issue\n", cache->name());
@@ -112,7 +112,7 @@ BasePrefetcher::getPacket()
return NULL;
}
- Packet * pkt;
+ PacketPtr pkt;
bool keepTrying = false;
do {
pkt = *pf.begin();
@@ -131,7 +131,7 @@ BasePrefetcher::getPacket()
}
void
-BasePrefetcher::handleMiss(Packet * &pkt, Tick time)
+BasePrefetcher::handleMiss(PacketPtr &pkt, Tick time)
{
if (!pkt->req->isUncacheable() && !(pkt->req->isInstRead() && only_data))
{
@@ -139,7 +139,7 @@ BasePrefetcher::handleMiss(Packet * &pkt, Tick time)
Addr blkAddr = pkt->getAddr() & ~(Addr)(blkSize-1);
//Check if miss is in pfq, if so remove it
- std::list<Packet *>::iterator iter = inPrefetch(blkAddr);
+ std::list<PacketPtr>::iterator iter = inPrefetch(blkAddr);
if (iter != pf.end()) {
DPRINTF(HWPrefetch, "%s:Saw a miss to a queued prefetch, removing it\n", cache->name());
pfRemovedMSHR++;
@@ -179,7 +179,7 @@ BasePrefetcher::handleMiss(Packet * &pkt, Tick time)
pfIdentified++;
//create a prefetch memreq
Request * prefetchReq = new Request(*addr, blkSize, 0);
- Packet * prefetch;
+ PacketPtr prefetch;
prefetch = new Packet(prefetchReq, Packet::HardPFReq, -1);
prefetch->allocate();
prefetch->req->setThreadContext(pkt->req->getCpuNum(),
@@ -233,11 +233,11 @@ BasePrefetcher::handleMiss(Packet * &pkt, Tick time)
}
}
-std::list<Packet *>::iterator
+std::list<PacketPtr>::iterator
BasePrefetcher::inPrefetch(Addr address)
{
//Guaranteed to only be one match, we always check before inserting
- std::list<Packet *>::iterator iter;
+ std::list<PacketPtr>::iterator iter;
for (iter=pf.begin(); iter != pf.end(); iter++) {
if (((*iter)->getAddr() & ~(Addr)(blkSize-1)) == address) {
return iter;
diff --git a/src/mem/cache/prefetch/base_prefetcher.hh b/src/mem/cache/prefetch/base_prefetcher.hh
index d7ea41961..781d3ab09 100644
--- a/src/mem/cache/prefetch/base_prefetcher.hh
+++ b/src/mem/cache/prefetch/base_prefetcher.hh
@@ -45,7 +45,7 @@ class BasePrefetcher
protected:
/** The Prefetch Queue. */
- std::list<Packet *> pf;
+ std::list<PacketPtr> pf;
// PARAMETERS
@@ -93,24 +93,24 @@ class BasePrefetcher
void setCache(BaseCache *_cache);
- void handleMiss(Packet * &pkt, Tick time);
+ void handleMiss(PacketPtr &pkt, Tick time);
- Packet * getPacket();
+ PacketPtr getPacket();
bool havePending()
{
return !pf.empty();
}
- virtual void calculatePrefetch(Packet * &pkt,
+ virtual void calculatePrefetch(PacketPtr &pkt,
std::list<Addr> &addresses,
std::list<Tick> &delays) = 0;
- virtual bool inCache(Packet * &pkt) = 0;
+ virtual bool inCache(PacketPtr &pkt) = 0;
virtual bool inMissQueue(Addr address) = 0;
- std::list<Packet *>::iterator inPrefetch(Addr address);
+ std::list<PacketPtr>::iterator inPrefetch(Addr address);
};
diff --git a/src/mem/cache/prefetch/ghb_prefetcher.hh b/src/mem/cache/prefetch/ghb_prefetcher.hh
index c22b763d1..14f5747df 100644
--- a/src/mem/cache/prefetch/ghb_prefetcher.hh
+++ b/src/mem/cache/prefetch/ghb_prefetcher.hh
@@ -75,7 +75,7 @@ class GHBPrefetcher : public Prefetcher<TagStore, Buffering>
~GHBPrefetcher() {}
- void calculatePrefetch(Packet * &pkt, std::list<Addr> &addresses,
+ void calculatePrefetch(PacketPtr &pkt, std::list<Addr> &addresses,
std::list<Tick> &delays)
{
Addr blkAddr = pkt->getAddr() & ~(Addr)(this->blkSize-1);
diff --git a/src/mem/cache/prefetch/stride_prefetcher.hh b/src/mem/cache/prefetch/stride_prefetcher.hh
index 4a8ee7de4..d6fb8ab66 100644
--- a/src/mem/cache/prefetch/stride_prefetcher.hh
+++ b/src/mem/cache/prefetch/stride_prefetcher.hh
@@ -92,7 +92,7 @@ class StridePrefetcher : public Prefetcher<TagStore, Buffering>
~StridePrefetcher() {}
- void calculatePrefetch(Packet * &pkt, std::list<Addr> &addresses,
+ void calculatePrefetch(PacketPtr &pkt, std::list<Addr> &addresses,
std::list<Tick> &delays)
{
// Addr blkAddr = pkt->paddr & ~(Addr)(this->blkSize-1);
diff --git a/src/mem/cache/prefetch/tagged_prefetcher.hh b/src/mem/cache/prefetch/tagged_prefetcher.hh
index 17f500dd8..b61e57dcc 100644
--- a/src/mem/cache/prefetch/tagged_prefetcher.hh
+++ b/src/mem/cache/prefetch/tagged_prefetcher.hh
@@ -64,7 +64,7 @@ class TaggedPrefetcher : public Prefetcher<TagStore, Buffering>
~TaggedPrefetcher() {}
- void calculatePrefetch(Packet * &pkt, std::list<Addr> &addresses,
+ void calculatePrefetch(PacketPtr &pkt, std::list<Addr> &addresses,
std::list<Tick> &delays);
};
diff --git a/src/mem/cache/prefetch/tagged_prefetcher_impl.hh b/src/mem/cache/prefetch/tagged_prefetcher_impl.hh
index e554b3cec..a18de4571 100644
--- a/src/mem/cache/prefetch/tagged_prefetcher_impl.hh
+++ b/src/mem/cache/prefetch/tagged_prefetcher_impl.hh
@@ -50,7 +50,7 @@ TaggedPrefetcher(int size, bool pageStop, bool serialSquash,
template <class TagStore, class Buffering>
void
TaggedPrefetcher<TagStore, Buffering>::
-calculatePrefetch(Packet * &pkt, std::list<Addr> &addresses,
+calculatePrefetch(PacketPtr &pkt, std::list<Addr> &addresses,
std::list<Tick> &delays)
{
Addr blkAddr = pkt->getAddr() & ~(Addr)(this->blkSize-1);
diff --git a/src/mem/cache/tags/fa_lru.cc b/src/mem/cache/tags/fa_lru.cc
index 784ba1311..a58ddaff8 100644
--- a/src/mem/cache/tags/fa_lru.cc
+++ b/src/mem/cache/tags/fa_lru.cc
@@ -203,7 +203,7 @@ FALRU::findBlock(Addr addr, int &lat, int *inCache)
}
FALRUBlk*
-FALRU::findBlock(Packet * &pkt, int &lat, int *inCache)
+FALRU::findBlock(PacketPtr &pkt, int &lat, int *inCache)
{
Addr addr = pkt->getAddr();
@@ -256,7 +256,7 @@ FALRU::findBlock(Addr addr) const
}
FALRUBlk*
-FALRU::findReplacement(Packet * &pkt, PacketList &writebacks,
+FALRU::findReplacement(PacketPtr &pkt, PacketList &writebacks,
BlkList &compress_blocks)
{
FALRUBlk * blk = tail;
diff --git a/src/mem/cache/tags/fa_lru.hh b/src/mem/cache/tags/fa_lru.hh
index 0fc54902b..2db89d603 100644
--- a/src/mem/cache/tags/fa_lru.hh
+++ b/src/mem/cache/tags/fa_lru.hh
@@ -198,7 +198,7 @@ public:
* @param inCache The FALRUBlk::inCache flags.
* @return Pointer to the cache block.
*/
- FALRUBlk* findBlock(Packet * &pkt, int &lat, int *inCache = 0);
+ FALRUBlk* findBlock(PacketPtr &pkt, int &lat, int *inCache = 0);
/**
* Find the block in the cache, do not update the replacement data.
@@ -215,7 +215,7 @@ public:
* @param compress_blocks List of blocks to compress, for adaptive comp.
* @return The block to place the replacement in.
*/
- FALRUBlk* findReplacement(Packet * &pkt, PacketList & writebacks,
+ FALRUBlk* findReplacement(PacketPtr &pkt, PacketList & writebacks,
BlkList &compress_blocks);
/**
diff --git a/src/mem/cache/tags/iic.cc b/src/mem/cache/tags/iic.cc
index bf1d9ece4..f4e870659 100644
--- a/src/mem/cache/tags/iic.cc
+++ b/src/mem/cache/tags/iic.cc
@@ -285,7 +285,7 @@ IIC::findBlock(Addr addr, int &lat)
}
IICTag*
-IIC::findBlock(Packet * &pkt, int &lat)
+IIC::findBlock(PacketPtr &pkt, int &lat)
{
Addr addr = pkt->getAddr();
@@ -362,7 +362,7 @@ IIC::findBlock(Addr addr) const
IICTag*
-IIC::findReplacement(Packet * &pkt, PacketList &writebacks,
+IIC::findReplacement(PacketPtr &pkt, PacketList &writebacks,
BlkList &compress_blocks)
{
DPRINTF(IIC, "Finding Replacement for %x\n", pkt->getAddr());
@@ -423,7 +423,7 @@ IIC::freeReplacementBlock(PacketList & writebacks)
tag_ptr->refCount = 0;
if (tag_ptr->isModified()) {
-/* Packet * writeback =
+/* PacketPtr writeback =
buildWritebackReq(regenerateBlkAddr(tag_ptr->tag, 0),
tag_ptr->req->asid, tag_ptr->xc, blkSize,
tag_ptr->data,
@@ -431,7 +431,7 @@ IIC::freeReplacementBlock(PacketList & writebacks)
*/
Request *writebackReq = new Request(regenerateBlkAddr(tag_ptr->tag, 0),
blkSize, 0);
- Packet *writeback = new Packet(writebackReq, Packet::Writeback, -1);
+ PacketPtr writeback = new Packet(writebackReq, Packet::Writeback, -1);
writeback->allocate();
memcpy(writeback->getPtr<uint8_t>(), tag_ptr->data, blkSize);
diff --git a/src/mem/cache/tags/iic.hh b/src/mem/cache/tags/iic.hh
index 905d480c5..92bd6da1d 100644
--- a/src/mem/cache/tags/iic.hh
+++ b/src/mem/cache/tags/iic.hh
@@ -458,7 +458,7 @@ class IIC : public BaseTags
* @param lat The access latency.
* @return A pointer to the block found, if any.
*/
- IICTag* findBlock(Packet * &pkt, int &lat);
+ IICTag* findBlock(PacketPtr &pkt, int &lat);
/**
* Find the block, do not update the replacement data.
@@ -475,7 +475,7 @@ class IIC : public BaseTags
* @param compress_blocks List of blocks to compress, for adaptive comp.
* @return The block to place the replacement in.
*/
- IICTag* findReplacement(Packet * &pkt, PacketList &writebacks,
+ IICTag* findReplacement(PacketPtr &pkt, PacketList &writebacks,
BlkList &compress_blocks);
/**
diff --git a/src/mem/cache/tags/lru.cc b/src/mem/cache/tags/lru.cc
index a9ae049c3..31d29aae6 100644
--- a/src/mem/cache/tags/lru.cc
+++ b/src/mem/cache/tags/lru.cc
@@ -184,7 +184,7 @@ LRU::findBlock(Addr addr, int &lat)
}
LRUBlk*
-LRU::findBlock(Packet * &pkt, int &lat)
+LRU::findBlock(PacketPtr &pkt, int &lat)
{
Addr addr = pkt->getAddr();
@@ -215,7 +215,7 @@ LRU::findBlock(Addr addr) const
}
LRUBlk*
-LRU::findReplacement(Packet * &pkt, PacketList &writebacks,
+LRU::findReplacement(PacketPtr &pkt, PacketList &writebacks,
BlkList &compress_blocks)
{
unsigned set = extractSet(pkt->getAddr());
@@ -246,6 +246,7 @@ LRU::invalidateBlk(Addr addr)
if (blk) {
blk->status = 0;
blk->isTouched = false;
+ blk->clearLoadLocks();
tagsInUse--;
}
}
diff --git a/src/mem/cache/tags/lru.hh b/src/mem/cache/tags/lru.hh
index 9f0a05ee8..fed688283 100644
--- a/src/mem/cache/tags/lru.hh
+++ b/src/mem/cache/tags/lru.hh
@@ -174,7 +174,7 @@ public:
* @param lat The access latency.
* @return Pointer to the cache block if found.
*/
- LRUBlk* findBlock(Packet * &pkt, int &lat);
+ LRUBlk* findBlock(PacketPtr &pkt, int &lat);
/**
* Finds the given address in the cache and update replacement data.
@@ -201,7 +201,7 @@ public:
* @param compress_blocks List of blocks to compress, for adaptive comp.
* @return The block to place the replacement in.
*/
- LRUBlk* findReplacement(Packet * &pkt, PacketList &writebacks,
+ LRUBlk* findReplacement(PacketPtr &pkt, PacketList &writebacks,
BlkList &compress_blocks);
/**
diff --git a/src/mem/cache/tags/split.cc b/src/mem/cache/tags/split.cc
index cad18e885..bc74f0e0f 100644
--- a/src/mem/cache/tags/split.cc
+++ b/src/mem/cache/tags/split.cc
@@ -267,7 +267,7 @@ Split::probe(Addr addr) const
}
SplitBlk*
-Split::findBlock(Packet * &pkt, int &lat)
+Split::findBlock(PacketPtr &pkt, int &lat)
{
Addr aligned = blkAlign(pkt->getAddr());
@@ -350,7 +350,7 @@ Split::findBlock(Addr addr) const
}
SplitBlk*
-Split::findReplacement(Packet * &pkt, PacketList &writebacks,
+Split::findReplacement(PacketPtr &pkt, PacketList &writebacks,
BlkList &compress_blocks)
{
SplitBlk *blk;
diff --git a/src/mem/cache/tags/split.hh b/src/mem/cache/tags/split.hh
index 708058e96..748f6fb25 100644
--- a/src/mem/cache/tags/split.hh
+++ b/src/mem/cache/tags/split.hh
@@ -207,7 +207,7 @@ class Split : public BaseTags
* @param lat The access latency.
* @return Pointer to the cache block if found.
*/
- SplitBlk* findBlock(Packet * &pkt, int &lat);
+ SplitBlk* findBlock(PacketPtr &pkt, int &lat);
/**
* Finds the given address in the cache, do not update replacement data.
@@ -224,7 +224,7 @@ class Split : public BaseTags
* @param compress_blocks List of blocks to compress, for adaptive comp.
* @return The block to place the replacement in.
*/
- SplitBlk* findReplacement(Packet * &pkt, PacketList &writebacks,
+ SplitBlk* findReplacement(PacketPtr &pkt, PacketList &writebacks,
BlkList &compress_blocks);
diff --git a/src/mem/cache/tags/split_lifo.cc b/src/mem/cache/tags/split_lifo.cc
index 4e9375070..302e2aaeb 100644
--- a/src/mem/cache/tags/split_lifo.cc
+++ b/src/mem/cache/tags/split_lifo.cc
@@ -255,7 +255,7 @@ SplitLIFO::findBlock(Addr addr, int &lat)
}
SplitBlk*
-SplitLIFO::findBlock(Packet * &pkt, int &lat)
+SplitLIFO::findBlock(PacketPtr &pkt, int &lat)
{
Addr addr = pkt->getAddr();
@@ -291,7 +291,7 @@ SplitLIFO::findBlock(Addr addr) const
}
SplitBlk*
-SplitLIFO::findReplacement(Packet * &pkt, PacketList &writebacks,
+SplitLIFO::findReplacement(PacketPtr &pkt, PacketList &writebacks,
BlkList &compress_blocks)
{
unsigned set = extractSet(pkt->getAddr());
diff --git a/src/mem/cache/tags/split_lifo.hh b/src/mem/cache/tags/split_lifo.hh
index ddc7fdeec..6c3befe37 100644
--- a/src/mem/cache/tags/split_lifo.hh
+++ b/src/mem/cache/tags/split_lifo.hh
@@ -207,7 +207,7 @@ public:
* @param lat The access latency.
* @return Pointer to the cache block if found.
*/
- SplitBlk* findBlock(Packet * &pkt, int &lat);
+ SplitBlk* findBlock(PacketPtr &pkt, int &lat);
/**
* Finds the given address in the cache, do not update replacement data.
@@ -224,7 +224,7 @@ public:
* @param compress_blocks List of blocks to compress, for adaptive comp.
* @return The block to place the replacement in.
*/
- SplitBlk* findReplacement(Packet * &pkt, PacketList &writebacks,
+ SplitBlk* findReplacement(PacketPtr &pkt, PacketList &writebacks,
BlkList &compress_blocks);
/**
diff --git a/src/mem/cache/tags/split_lru.cc b/src/mem/cache/tags/split_lru.cc
index 4aba1c37f..11c9a5d64 100644
--- a/src/mem/cache/tags/split_lru.cc
+++ b/src/mem/cache/tags/split_lru.cc
@@ -203,7 +203,7 @@ SplitLRU::findBlock(Addr addr, int &lat)
}
SplitBlk*
-SplitLRU::findBlock(Packet * &pkt, int &lat)
+SplitLRU::findBlock(PacketPtr &pkt, int &lat)
{
Addr addr = pkt->getAddr();
@@ -234,7 +234,7 @@ SplitLRU::findBlock(Addr addr) const
}
SplitBlk*
-SplitLRU::findReplacement(Packet * &pkt, PacketList &writebacks,
+SplitLRU::findReplacement(PacketPtr &pkt, PacketList &writebacks,
BlkList &compress_blocks)
{
unsigned set = extractSet(pkt->getAddr());
diff --git a/src/mem/cache/tags/split_lru.hh b/src/mem/cache/tags/split_lru.hh
index 71f921177..6160d59e5 100644
--- a/src/mem/cache/tags/split_lru.hh
+++ b/src/mem/cache/tags/split_lru.hh
@@ -190,7 +190,7 @@ public:
* @param lat The access latency.
* @return Pointer to the cache block if found.
*/
- SplitBlk* findBlock(Packet * &pkt, int &lat);
+ SplitBlk* findBlock(PacketPtr &pkt, int &lat);
/**
* Finds the given address in the cache, do not update replacement data.
@@ -207,7 +207,7 @@ public:
* @param compress_blocks List of blocks to compress, for adaptive comp.
* @return The block to place the replacement in.
*/
- SplitBlk* findReplacement(Packet * &pkt, PacketList &writebacks,
+ SplitBlk* findReplacement(PacketPtr &pkt, PacketList &writebacks,
BlkList &compress_blocks);
/**
diff --git a/src/mem/dram.cc b/src/mem/dram.cc
index d7b955975..873ca5b97 100644
--- a/src/mem/dram.cc
+++ b/src/mem/dram.cc
@@ -359,7 +359,7 @@ DRAMMemory::regStats()
static char *mem_access_output=NULL;
/* latency of access [CPU cycles]*/
Tick
-DRAMMemory::calculateLatency(Packet *pkt)
+DRAMMemory::calculateLatency(PacketPtr pkt)
{
bool cmdIsRead = pkt->isRead();
diff --git a/src/mem/dram.hh b/src/mem/dram.hh
index 32d117596..9d2f60ee8 100644
--- a/src/mem/dram.hh
+++ b/src/mem/dram.hh
@@ -140,7 +140,7 @@ class DRAMMemory : public PhysicalMemory
protected:
- Tick calculateLatency(Packet *pkt);
+ Tick calculateLatency(PacketPtr pkt);
int prechargeBanksAround(int bank);
public:
diff --git a/src/mem/packet.cc b/src/mem/packet.cc
index 64c65dcca..fa8d82c46 100644
--- a/src/mem/packet.cc
+++ b/src/mem/packet.cc
@@ -36,9 +36,10 @@
*/
#include <iostream>
+
#include "base/misc.hh"
-#include "mem/packet.hh"
#include "base/trace.hh"
+#include "mem/packet.hh"
static const std::string ReadReqString("ReadReq");
static const std::string WriteReqString("WriteReq");
@@ -51,6 +52,7 @@ static const std::string HardPFReqString("HardPFReq");
static const std::string HardPFRespString("HardPFResp");
static const std::string InvalidateReqString("InvalidateReq");
static const std::string WriteInvalidateReqString("WriteInvalidateReq");
+static const std::string WriteInvalidateRespString("WriteInvalidateResp");
static const std::string UpgradeReqString("UpgradeReq");
static const std::string ReadExReqString("ReadExReq");
static const std::string ReadExRespString("ReadExResp");
@@ -71,6 +73,7 @@ Packet::cmdString() const
case HardPFResp: return HardPFRespString;
case InvalidateReq: return InvalidateReqString;
case WriteInvalidateReq:return WriteInvalidateReqString;
+ case WriteInvalidateResp:return WriteInvalidateRespString;
case UpgradeReq: return UpgradeReqString;
case ReadExReq: return ReadExReqString;
case ReadExResp: return ReadExRespString;
@@ -93,6 +96,7 @@ Packet::cmdIdxToString(Packet::Command idx)
case HardPFResp: return HardPFRespString;
case InvalidateReq: return InvalidateReqString;
case WriteInvalidateReq:return WriteInvalidateReqString;
+ case WriteInvalidateResp:return WriteInvalidateRespString;
case UpgradeReq: return UpgradeReqString;
case ReadExReq: return ReadExReqString;
case ReadExResp: return ReadExRespString;
@@ -129,7 +133,7 @@ Packet::allocate()
/** Do the packet modify the same addresses. */
bool
-Packet::intersect(Packet *p)
+Packet::intersect(PacketPtr p)
{
Addr s1 = getAddr();
Addr e1 = getAddr() + getSize() - 1;
@@ -140,14 +144,14 @@ Packet::intersect(Packet *p)
}
bool
-fixPacket(Packet *func, Packet *timing)
+fixPacket(PacketPtr func, PacketPtr timing)
{
Addr funcStart = func->getAddr();
Addr funcEnd = func->getAddr() + func->getSize() - 1;
Addr timingStart = timing->getAddr();
Addr timingEnd = timing->getAddr() + timing->getSize() - 1;
- assert(!(funcStart > timingEnd || timingStart < funcEnd));
+ assert(!(funcStart > timingEnd || timingStart > funcEnd));
if (DTRACE(FunctionalAccess)) {
DebugOut() << func;
diff --git a/src/mem/packet.hh b/src/mem/packet.hh
index 319a4e534..cb97dd036 100644
--- a/src/mem/packet.hh
+++ b/src/mem/packet.hh
@@ -38,28 +38,29 @@
#ifndef __MEM_PACKET_HH__
#define __MEM_PACKET_HH__
+#include <cassert>
+#include <list>
+
#include "mem/request.hh"
#include "sim/host.hh"
#include "sim/root.hh"
-#include <list>
-#include <cassert>
struct Packet;
-typedef Packet* PacketPtr;
+typedef Packet *PacketPtr;
typedef uint8_t* PacketDataPtr;
typedef std::list<PacketPtr> PacketList;
//Coherence Flags
-#define NACKED_LINE 1 << 0
-#define SATISFIED 1 << 1
-#define SHARED_LINE 1 << 2
-#define CACHE_LINE_FILL 1 << 3
-#define COMPRESSED 1 << 4
-#define NO_ALLOCATE 1 << 5
-#define SNOOP_COMMIT 1 << 6
+#define NACKED_LINE (1 << 0)
+#define SATISFIED (1 << 1)
+#define SHARED_LINE (1 << 2)
+#define CACHE_LINE_FILL (1 << 3)
+#define COMPRESSED (1 << 4)
+#define NO_ALLOCATE (1 << 5)
+#define SNOOP_COMMIT (1 << 6)
//for now. @todo fix later
-#define NUM_MEM_CMDS 1 << 11
+#define NUM_MEM_CMDS (1 << 11)
/**
* A Packet is used to encapsulate a transfer between two objects in
* the memory system (e.g., the L1 and L2 cache). (In contrast, a
@@ -102,7 +103,7 @@ class Packet
/** Device address (e.g., bus ID) of the source of the
* transaction. The source is not responsible for setting this
* field; it is set implicitly by the interconnect when the
- * packet * is first sent. */
+ * packet is first sent. */
short src;
/** Device address (e.g., bus ID) of the destination of the
@@ -171,17 +172,17 @@ class Packet
// as well.
enum CommandAttribute
{
- IsRead = 1 << 0,
- IsWrite = 1 << 1,
- IsPrefetch = 1 << 2,
- IsInvalidate = 1 << 3,
- IsRequest = 1 << 4,
- IsResponse = 1 << 5,
- NeedsResponse = 1 << 6,
+ IsRead = 1 << 0,
+ IsWrite = 1 << 1,
+ IsPrefetch = 1 << 2,
+ IsInvalidate = 1 << 3,
+ IsRequest = 1 << 4,
+ IsResponse = 1 << 5,
+ NeedsResponse = 1 << 6,
IsSWPrefetch = 1 << 7,
IsHWPrefetch = 1 << 8,
IsUpgrade = 1 << 9,
- HasData = 1 << 10
+ HasData = 1 << 10
};
public:
@@ -189,26 +190,27 @@ class Packet
enum Command
{
InvalidCmd = 0,
- ReadReq = IsRead | IsRequest | NeedsResponse,
+ ReadReq = IsRead | IsRequest | NeedsResponse,
WriteReq = IsWrite | IsRequest | NeedsResponse | HasData,
- WriteReqNoAck = IsWrite | IsRequest | HasData,
+ WriteReqNoAck = IsWrite | IsRequest | HasData,
ReadResp = IsRead | IsResponse | NeedsResponse | HasData,
- WriteResp = IsWrite | IsResponse | NeedsResponse,
+ WriteResp = IsWrite | IsResponse | NeedsResponse,
Writeback = IsWrite | IsRequest | HasData,
SoftPFReq = IsRead | IsRequest | IsSWPrefetch | NeedsResponse,
HardPFReq = IsRead | IsRequest | IsHWPrefetch | NeedsResponse,
SoftPFResp = IsRead | IsResponse | IsSWPrefetch
- | NeedsResponse | HasData,
+ | NeedsResponse | HasData,
HardPFResp = IsRead | IsResponse | IsHWPrefetch
- | NeedsResponse | HasData,
+ | NeedsResponse | HasData,
InvalidateReq = IsInvalidate | IsRequest,
- WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest
- | HasData | NeedsResponse,
- WriteInvalidateResp = IsWrite | IsInvalidate | IsRequest | NeedsResponse,
+ WriteInvalidateReq = IsWrite | IsInvalidate | IsRequest
+ | HasData | NeedsResponse,
+ WriteInvalidateResp = IsWrite | IsInvalidate | IsRequest
+ | NeedsResponse | IsResponse,
UpgradeReq = IsInvalidate | IsRequest | IsUpgrade,
ReadExReq = IsRead | IsInvalidate | IsRequest | NeedsResponse,
ReadExResp = IsRead | IsInvalidate | IsResponse
- | NeedsResponse | HasData
+ | NeedsResponse | HasData
};
/** Return the string name of the cmd field (for debugging and
@@ -308,6 +310,7 @@ class Packet
* multiple transactions. */
void reinitFromRequest() {
assert(req->validPaddr);
+ flags = 0;
addr = req->paddr;
size = req->size;
time = req->time;
@@ -341,10 +344,12 @@ class Packet
srcValid = false;
}
- /** Take a request packet and modify it in place to be suitable
- * for returning as a response to that request.
+ /**
+ * Take a request packet and modify it in place to be suitable for
+ * returning as a response to that request.
*/
- void makeAtomicResponse() {
+ void makeAtomicResponse()
+ {
assert(needsResponse());
assert(isRequest());
int icmd = (int)cmd;
@@ -357,50 +362,90 @@ class Packet
cmd = (Command)icmd;
}
- /** Take a request packet that has been returned as NACKED and modify it so
- * that it can be sent out again. Only packets that need a response can be
- * NACKED, so verify that that is true. */
- void reinitNacked() {
+ /**
+ * Take a request packet that has been returned as NACKED and
+ * modify it so that it can be sent out again. Only packets that
+ * need a response can be NACKED, so verify that that is true.
+ */
+ void
+ reinitNacked()
+ {
assert(needsResponse() && result == Nacked);
dest = Broadcast;
result = Unknown;
}
- /** Set the data pointer to the following value that should not be freed. */
+ /**
+ * Set the data pointer to the following value that should not be
+ * freed.
+ */
+ template <typename T>
+ void
+ dataStatic(T *p)
+ {
+ if(dynamicData)
+ dynamicData = false;
+ data = (PacketDataPtr)p;
+ staticData = true;
+ }
+
+ /**
+ * Set the data pointer to a value that should have delete []
+ * called on it.
+ */
template <typename T>
- void dataStatic(T *p);
+ void
+ dataDynamicArray(T *p)
+ {
+ assert(!staticData && !dynamicData);
+ data = (PacketDataPtr)p;
+ dynamicData = true;
+ arrayData = true;
+ }
- /** Set the data pointer to a value that should have delete [] called on it.
+ /**
+ * set the data pointer to a value that should have delete called
+ * on it.
*/
template <typename T>
- void dataDynamicArray(T *p);
+ void
+ dataDynamic(T *p)
+ {
+ assert(!staticData && !dynamicData);
+ data = (PacketDataPtr)p;
+ dynamicData = true;
+ arrayData = false;
+ }
- /** set the data pointer to a value that should have delete called on it. */
+ /** get a pointer to the data ptr. */
template <typename T>
- void dataDynamic(T *p);
+ T*
+ getPtr()
+ {
+ assert(staticData || dynamicData);
+ return (T*)data;
+ }
/** return the value of what is pointed to in the packet. */
template <typename T>
T get();
- /** get a pointer to the data ptr. */
- template <typename T>
- T* getPtr();
-
/** set the value in the data pointer to v. */
template <typename T>
void set(T v);
- /** delete the data pointed to in the data pointer. Ok to call to matter how
- * data was allocted. */
+ /**
+ * delete the data pointed to in the data pointer. Ok to call to
+ * matter how data was allocted.
+ */
void deleteData();
/** If there isn't data in the packet, allocate some. */
void allocate();
/** Do the packet modify the same addresses. */
- bool intersect(Packet *p);
+ bool intersect(PacketPtr p);
};
@@ -409,7 +454,7 @@ class Packet
* in the timing packet. It returns if the functional packet should continue to
* traverse the memory hierarchy or not.
*/
-bool fixPacket(Packet *func, Packet *timing);
+bool fixPacket(PacketPtr func, PacketPtr timing);
std::ostream & operator<<(std::ostream &o, const Packet &p);
diff --git a/src/mem/packet_access.hh b/src/mem/packet_access.hh
new file mode 100644
index 000000000..aac0c3ae5
--- /dev/null
+++ b/src/mem/packet_access.hh
@@ -0,0 +1,62 @@
+/*
+ * 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
+ * Nathan Binkert
+ */
+
+#include "arch/isa_traits.hh"
+#include "mem/packet.hh"
+#include "sim/byteswap.hh"
+
+#ifndef __MEM_PACKET_ACCESS_HH__
+#define __MEM_PACKET_ACCESS_HH__
+// The memory system needs to have an endianness. This is the easiest
+// way to deal with it for now. At some point, we will have to remove
+// these functions and make the users do their own byte swapping since
+// the memory system does not in fact have an endianness.
+
+/** return the value of what is pointed to in the packet. */
+template <typename T>
+inline T
+Packet::get()
+{
+ assert(staticData || dynamicData);
+ assert(sizeof(T) <= size);
+ return TheISA::gtoh(*(T*)data);
+}
+
+/** set the value in the data pointer to v. */
+template <typename T>
+inline void
+Packet::set(T v)
+{
+ assert(sizeof(T) <= size);
+ *(T*)data = TheISA::htog(v);
+}
+
+#endif //__MEM_PACKET_ACCESS_HH__
diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc
index fa6d5ddfb..fe8094b88 100644
--- a/src/mem/page_table.cc
+++ b/src/mem/page_table.cc
@@ -170,11 +170,14 @@ PageTable::serialize(std::ostream &os)
int count = 0;
- m5::hash_map<Addr,Addr>::iterator iter;
- m5::hash_map<Addr,Addr>::iterator end;
- for (iter = pTable.begin(); iter != end; ++iter,++count) {
- paramOut(os, csprintf("ptable.entry%dvaddr", count),iter->first);
- paramOut(os, csprintf("ptable.entry%dpaddr", count),iter->second);
+ m5::hash_map<Addr,Addr>::iterator iter = pTable.begin();
+ m5::hash_map<Addr,Addr>::iterator end = pTable.end();
+ while (iter != end) {
+ paramOut(os, csprintf("ptable.entry%dvaddr", count), iter->first);
+ paramOut(os, csprintf("ptable.entry%dpaddr", count), iter->second);
+
+ ++iter;
+ ++count;
}
assert(count == pTable.size());
}
diff --git a/src/mem/physical.cc b/src/mem/physical.cc
index f5a0ade15..0302f7351 100644
--- a/src/mem/physical.cc
+++ b/src/mem/physical.cc
@@ -39,21 +39,17 @@
#include <iostream>
#include <string>
-
+#include "arch/isa_traits.hh"
#include "base/misc.hh"
#include "config/full_system.hh"
-#include "mem/packet_impl.hh"
#include "mem/physical.hh"
-#include "sim/host.hh"
#include "sim/builder.hh"
#include "sim/eventq.hh"
-#include "arch/isa_traits.hh"
-
+#include "sim/host.hh"
using namespace std;
using namespace TheISA;
-
PhysicalMemory::PhysicalMemory(Params *p)
: MemObject(p->name), pmemAddr(NULL), port(NULL), lat(p->latency), _params(p)
{
@@ -105,7 +101,7 @@ PhysicalMemory::deviceBlockSize()
}
Tick
-PhysicalMemory::calculateLatency(Packet *pkt)
+PhysicalMemory::calculateLatency(PacketPtr pkt)
{
return lat;
}
@@ -193,7 +189,7 @@ PhysicalMemory::checkLockedAddrList(Request *req)
}
void
-PhysicalMemory::doFunctionalAccess(Packet *pkt)
+PhysicalMemory::doFunctionalAccess(PacketPtr pkt)
{
assert(pkt->getAddr() + pkt->getSize() <= params()->addrRange.size());
@@ -281,14 +277,14 @@ PhysicalMemory::MemoryPort::deviceBlockSize()
}
Tick
-PhysicalMemory::MemoryPort::recvAtomic(Packet *pkt)
+PhysicalMemory::MemoryPort::recvAtomic(PacketPtr pkt)
{
memory->doFunctionalAccess(pkt);
return memory->calculateLatency(pkt);
}
void
-PhysicalMemory::MemoryPort::recvFunctional(Packet *pkt)
+PhysicalMemory::MemoryPort::recvFunctional(PacketPtr pkt)
{
// Default implementation of SimpleTimingPort::recvFunctional()
// calls recvAtomic() and throws away the latency; we can save a
diff --git a/src/mem/physical.hh b/src/mem/physical.hh
index 97bea2ec4..045e61612 100644
--- a/src/mem/physical.hh
+++ b/src/mem/physical.hh
@@ -57,9 +57,9 @@ class PhysicalMemory : public MemObject
protected:
- virtual Tick recvAtomic(Packet *pkt);
+ virtual Tick recvAtomic(PacketPtr pkt);
- virtual void recvFunctional(Packet *pkt);
+ virtual void recvFunctional(PacketPtr pkt);
virtual void recvStatusChange(Status status);
@@ -172,8 +172,8 @@ class PhysicalMemory : public MemObject
unsigned int drain(Event *de);
protected:
- void doFunctionalAccess(Packet *pkt);
- virtual Tick calculateLatency(Packet *pkt);
+ void doFunctionalAccess(PacketPtr pkt);
+ virtual Tick calculateLatency(PacketPtr pkt);
void recvStatusChange(Port::Status status);
public:
diff --git a/src/mem/port.cc b/src/mem/port.cc
index 17924b759..bbc98c160 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -35,7 +35,6 @@
#include "base/chunk_generator.hh"
#include "base/trace.hh"
-#include "mem/packet_impl.hh"
#include "mem/port.hh"
void
diff --git a/src/mem/port.hh b/src/mem/port.hh
index bb3bc1b1b..b6eeb9db3 100644
--- a/src/mem/port.hh
+++ b/src/mem/port.hh
@@ -128,13 +128,13 @@ class Port
* called by a peer port, never directly by any outside object. */
/** Called to recive a timing call from the peer port. */
- virtual bool recvTiming(Packet *pkt) = 0;
+ virtual bool recvTiming(PacketPtr pkt) = 0;
/** Called to recive a atomic call from the peer port. */
- virtual Tick recvAtomic(Packet *pkt) = 0;
+ virtual Tick recvAtomic(PacketPtr pkt) = 0;
/** Called to recive a functional call from the peer port. */
- virtual void recvFunctional(Packet *pkt) = 0;
+ virtual void recvFunctional(PacketPtr pkt) = 0;
/** Called to recieve a status change from the peer port. */
virtual void recvStatusChange(Status status) = 0;
@@ -172,14 +172,14 @@ class Port
case a cache has a higher priority request come in while waiting for
the bus to arbitrate.
*/
- bool sendTiming(Packet *pkt) { return peer->recvTiming(pkt); }
+ bool sendTiming(PacketPtr pkt) { return peer->recvTiming(pkt); }
/** Function called by the associated device to send an atomic
* access, an access in which the data is moved and the state is
* updated in one cycle, without interleaving with other memory
* accesses. Returns estimated latency of access.
*/
- Tick sendAtomic(Packet *pkt)
+ Tick sendAtomic(PacketPtr pkt)
{ return peer->recvAtomic(pkt); }
/** Function called by the associated device to send a functional access,
@@ -187,7 +187,7 @@ class Port
memory system, without affecting the current state of any block or
moving the block.
*/
- void sendFunctional(Packet *pkt)
+ void sendFunctional(PacketPtr pkt)
{ return peer->recvFunctional(pkt); }
/** Called by the associated device to send a status change to the device
@@ -252,9 +252,9 @@ class FunctionalPort : public Port
{}
protected:
- virtual bool recvTiming(Packet *pkt) { panic("FuncPort is UniDir"); }
- virtual Tick recvAtomic(Packet *pkt) { panic("FuncPort is UniDir"); }
- virtual void recvFunctional(Packet *pkt) { panic("FuncPort is UniDir"); }
+ virtual bool recvTiming(PacketPtr pkt) { panic("FuncPort is UniDir"); }
+ virtual Tick recvAtomic(PacketPtr pkt) { panic("FuncPort is UniDir"); }
+ virtual void recvFunctional(PacketPtr pkt) { panic("FuncPort is UniDir"); }
virtual void recvStatusChange(Status status) {}
public:
diff --git a/src/mem/tport.cc b/src/mem/tport.cc
index 2d8e7dba4..55a461a8b 100644
--- a/src/mem/tport.cc
+++ b/src/mem/tport.cc
@@ -31,28 +31,27 @@
#include "mem/tport.hh"
void
-SimpleTimingPort::recvFunctional(Packet *pkt)
+SimpleTimingPort::recvFunctional(PacketPtr pkt)
{
- //First check queued events
- std::list<Packet *>::iterator i = transmitList.begin();
- std::list<Packet *>::iterator end = transmitList.end();
- bool cont = true;
+ std::list<PacketPtr>::iterator i = transmitList.begin();
+ std::list<PacketPtr>::iterator end = transmitList.end();
- while (i != end && cont) {
- Packet * target = *i;
+ while (i != end) {
+ PacketPtr target = *i;
// If the target contains data, and it overlaps the
// probed request, need to update data
if (target->intersect(pkt))
fixPacket(pkt, target);
}
+
//Then just do an atomic access and throw away the returned latency
- if (cont)
+ if (pkt->result != Packet::Success)
recvAtomic(pkt);
}
bool
-SimpleTimingPort::recvTiming(Packet *pkt)
+SimpleTimingPort::recvTiming(PacketPtr pkt)
{
// If the device is only a slave, it should only be sending
// responses, which should never get nacked. There used to be
diff --git a/src/mem/tport.hh b/src/mem/tport.hh
index df6d48196..fbe81c443 100644
--- a/src/mem/tport.hh
+++ b/src/mem/tport.hh
@@ -60,7 +60,7 @@ class SimpleTimingPort : public Port
protected:
/** A list of outgoing timing response packets that haven't been
* serviced yet. */
- std::list<Packet*> transmitList;
+ std::list<PacketPtr> transmitList;
/**
* This class is used to implemented sendTiming() with a delay. When
@@ -71,10 +71,10 @@ class SimpleTimingPort : public Port
class SendEvent : public Event
{
SimpleTimingPort *port;
- Packet *packet;
+ PacketPtr packet;
public:
- SendEvent(SimpleTimingPort *p, Packet *pkt, Tick t)
+ SendEvent(SimpleTimingPort *p, PacketPtr pkt, Tick t)
: Event(&mainEventQueue), port(p), packet(pkt)
{ setFlags(AutoDelete); schedule(curTick + t); }
@@ -95,7 +95,7 @@ class SimpleTimingPort : public Port
Event *drainEvent;
/** Schedule a sendTiming() event to be called in the future. */
- void sendTimingLater(Packet *pkt, Tick time)
+ void sendTimingLater(PacketPtr pkt, Tick time)
{ outTiming++; new SendEvent(this, pkt, time); }
/** This function is notification that the device should attempt to send a
@@ -103,10 +103,10 @@ class SimpleTimingPort : public Port
virtual void recvRetry();
/** Implemented using recvAtomic(). */
- void recvFunctional(Packet *pkt);
+ void recvFunctional(PacketPtr pkt);
/** Implemented using recvAtomic(). */
- bool recvTiming(Packet *pkt);
+ bool recvTiming(PacketPtr pkt);
/**
* Simple ports generally don't care about any status
diff --git a/src/python/m5/objects/MemTest.py b/src/python/m5/objects/MemTest.py
index 83399be80..1219ddd4d 100644
--- a/src/python/m5/objects/MemTest.py
+++ b/src/python/m5/objects/MemTest.py
@@ -13,6 +13,7 @@ class MemTest(SimObject):
percent_reads = Param.Percent(65, "target read percentage")
percent_source_unaligned = Param.Percent(50,
"percent of copy source address that are unaligned")
+ percent_functional = Param.Percent(50, "percent of access that are functional")
percent_uncacheable = Param.Percent(10,
"target uncacheable percentage")
progress_interval = Param.Counter(1000000,
diff --git a/src/sim/eventq.hh b/src/sim/eventq.hh
index 537bfb918..fa65b08af 100644
--- a/src/sim/eventq.hh
+++ b/src/sim/eventq.hh
@@ -120,10 +120,22 @@ class Event : public Serializable, public FastAlloc
/// priority; these values are used to control events that need to
/// be ordered within a cycle.
enum Priority {
- /// Breakpoints should happen before anything else, so we
- /// don't miss any action when debugging.
+ /// If we enable tracing on a particular cycle, do that as the
+ /// very first thing so we don't miss any of the events on
+ /// that cycle (even if we enter the debugger).
+ Trace_Enable_Pri = -101,
+
+ /// Breakpoints should happen before anything else (except
+ /// enabling trace output), so we don't miss any action when
+ /// debugging.
Debug_Break_Pri = -100,
+ /// CPU switches schedule the new CPU's tick event for the
+ /// same cycle (after unscheduling the old CPU's tick event).
+ /// The switch needs to come before any tick events to make
+ /// sure we don't tick both CPUs in the same cycle.
+ CPU_Switch_Pri = -31,
+
/// For some reason "delayed" inter-cluster writebacks are
/// scheduled before regular writebacks (which have default
/// priority). Steve?
@@ -132,12 +144,6 @@ class Event : public Serializable, public FastAlloc
/// Default is zero for historical reasons.
Default_Pri = 0,
- /// CPU switches schedule the new CPU's tick event for the
- /// same cycle (after unscheduling the old CPU's tick event).
- /// The switch needs to come before any tick events to make
- /// sure we don't tick both CPUs in the same cycle.
- CPU_Switch_Pri = -31,
-
/// Serailization needs to occur before tick events also, so
/// that a serialize/unserialize is identical to an on-line
/// CPU switch.
diff --git a/src/sim/faults.cc b/src/sim/faults.cc
index 650b728f7..cea35482a 100644
--- a/src/sim/faults.cc
+++ b/src/sim/faults.cc
@@ -37,7 +37,7 @@
#if !FULL_SYSTEM
void FaultBase::invoke(ThreadContext * tc)
{
- fatal("fault (%s) detected @ PC 0x%08p", name(), tc->readPC());
+ fatal("fault (%s) detected @ PC %p", name(), tc->readPC());
}
#else
void FaultBase::invoke(ThreadContext * tc)
diff --git a/src/sim/main.cc b/src/sim/main.cc
index 8bb0d7aaa..133141e57 100644
--- a/src/sim/main.cc
+++ b/src/sim/main.cc
@@ -55,6 +55,7 @@
#include "base/statistics.hh"
#include "base/str.hh"
#include "base/time.hh"
+#include "config/pythonhome.hh"
#include "cpu/base.hh"
#include "cpu/smt.hh"
#include "mem/mem_object.hh"
@@ -145,6 +146,11 @@ main(int argc, char **argv)
if (setenv("PYTHONPATH", pythonpath.c_str(), true) == -1)
fatal("setenv: %s\n", strerror(errno));
+ char *python_home = getenv("PYTHONHOME");
+ if (!python_home)
+ python_home = PYTHONHOME;
+ Py_SetPythonHome(python_home);
+
// initialize embedded Python interpreter
Py_Initialize();
PySys_SetArgv(argc, argv);
diff --git a/src/sim/pseudo_inst.cc b/src/sim/pseudo_inst.cc
index addf897c6..4eb0866a5 100644
--- a/src/sim/pseudo_inst.cc
+++ b/src/sim/pseudo_inst.cc
@@ -87,10 +87,15 @@ namespace AlphaPseudo
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
+ Tick resume = curTick + Clock::Int::ns * ns;
+
if (quiesceEvent->scheduled())
- quiesceEvent->reschedule(curTick + Clock::Int::ns * ns);
+ quiesceEvent->reschedule(resume);
else
- quiesceEvent->schedule(curTick + Clock::Int::ns * ns);
+ quiesceEvent->schedule(resume);
+
+ DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
+ tc->getCpuPtr()->name(), ns, resume);
tc->suspend();
if (tc->getKernelStats())
@@ -105,12 +110,15 @@ namespace AlphaPseudo
EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
+ Tick resume = curTick + tc->getCpuPtr()->cycles(cycles);
+
if (quiesceEvent->scheduled())
- quiesceEvent->reschedule(curTick +
- tc->getCpuPtr()->cycles(cycles));
+ quiesceEvent->reschedule(resume);
else
- quiesceEvent->schedule(curTick +
- tc->getCpuPtr()->cycles(cycles));
+ quiesceEvent->schedule(resume);
+
+ DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
+ tc->getCpuPtr()->name(), cycles, resume);
tc->suspend();
if (tc->getKernelStats())
diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh
index edd4e331d..e79712a19 100644
--- a/src/sim/syscall_emul.hh
+++ b/src/sim/syscall_emul.hh
@@ -356,6 +356,14 @@ convertStatBuf(target_stat &tgt, host_stat *host, bool fakeTTY = false)
tgt->st_dev = htog(tgt->st_dev);
tgt->st_ino = host->st_ino;
tgt->st_ino = htog(tgt->st_ino);
+ tgt->st_mode = host->st_mode;
+ tgt->st_mode = htog(tgt->st_mode);
+ tgt->st_nlink = host->st_nlink;
+ tgt->st_nlink = htog(tgt->st_nlink);
+ tgt->st_uid = host->st_uid;
+ tgt->st_uid = htog(tgt->st_uid);
+ tgt->st_gid = host->st_gid;
+ tgt->st_gid = htog(tgt->st_gid);
if (fakeTTY)
tgt->st_rdev = 0x880d;
else
diff --git a/tests/configs/memtest.py b/tests/configs/memtest.py
index 116e71af6..2b990418c 100644
--- a/tests/configs/memtest.py
+++ b/tests/configs/memtest.py
@@ -53,7 +53,7 @@ class L2(BaseCache):
#MAX CORES IS 8 with the fals sharing method
nb_cores = 8
-cpus = [ MemTest(max_loads=1e12, percent_uncacheable=0, progress_interval=1000) for i in xrange(nb_cores) ]
+cpus = [ MemTest(atomic=False, max_loads=1e12, percent_uncacheable=10, progress_interval=1000) for i in xrange(nb_cores) ]
# system simulated
system = System(cpu = cpus, funcmem = PhysicalMemory(),
@@ -90,6 +90,6 @@ system.physmem.port = system.membus.port
root = Root( system = system )
root.system.mem_mode = 'timing'
-#root.trace.flags="Cache CachePort Bus"
-#root.trace.cycle=3810800
+#root.trace.flags="Cache CachePort MemoryAccess"
+#root.trace.cycle=1
diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-timing/config.ini b/tests/quick/00.hello/ref/sparc/linux/simple-timing/config.ini
new file mode 100644
index 000000000..982973385
--- /dev/null
+++ b/tests/quick/00.hello/ref/sparc/linux/simple-timing/config.ini
@@ -0,0 +1,236 @@
+[root]
+type=Root
+children=system
+checkpoint=
+clock=1000000000000
+max_tick=0
+output_file=cout
+progress_interval=0
+
+[debug]
+break_cycles=
+
+[exetrace]
+intel_format=false
+pc_symbol=true
+print_cpseq=false
+print_cycle=true
+print_data=true
+print_effaddr=true
+print_fetchseq=false
+print_iregs=false
+print_opclass=true
+print_reg_delta=false
+print_thread=true
+speculative=true
+trace_system=client
+
+[serialize]
+count=10
+cycle=0
+dir=cpt.%012d
+period=0
+
+[stats]
+descriptions=true
+dump_cycle=0
+dump_period=0
+dump_reset=false
+ignore_events=
+mysql_db=
+mysql_host=
+mysql_password=
+mysql_user=
+project_name=test
+simulation_name=test
+simulation_sample=0
+text_compat=true
+text_file=m5stats.txt
+
+[system]
+type=System
+children=cpu membus physmem
+mem_mode=atomic
+physmem=system.physmem
+
+[system.cpu]
+type=TimingSimpleCPU
+children=dcache icache l2cache toL2Bus workload
+clock=1
+cpu_id=0
+defer_registration=false
+function_trace=false
+function_trace_start=0
+max_insts_all_threads=0
+max_insts_any_thread=0
+max_loads_all_threads=0
+max_loads_any_thread=0
+mem=system.cpu.dcache
+progress_interval=0
+system=system
+workload=system.cpu.workload
+dcache_port=system.cpu.dcache.cpu_side
+icache_port=system.cpu.icache.cpu_side
+
+[system.cpu.dcache]
+type=BaseCache
+adaptive_compression=false
+assoc=2
+block_size=64
+compressed_bus=false
+compression_latency=0
+hash_delay=1
+hit_latency=1
+latency=1
+lifo=false
+max_miss_count=0
+mshrs=10
+prefetch_access=false
+prefetch_cache_check_push=true
+prefetch_data_accesses_only=false
+prefetch_degree=1
+prefetch_latency=10
+prefetch_miss=false
+prefetch_past_page=false
+prefetch_policy=none
+prefetch_serial_squash=false
+prefetch_use_cpu_id=true
+prefetcher_size=100
+prioritizeRequests=false
+protocol=Null
+repl=Null
+size=262144
+split=false
+split_size=0
+store_compressed=false
+subblock_size=0
+tgts_per_mshr=5
+trace_addr=0
+two_queue=false
+write_buffers=8
+cpu_side=system.cpu.dcache_port
+mem_side=system.cpu.toL2Bus.port[1]
+
+[system.cpu.icache]
+type=BaseCache
+adaptive_compression=false
+assoc=2
+block_size=64
+compressed_bus=false
+compression_latency=0
+hash_delay=1
+hit_latency=1
+latency=1
+lifo=false
+max_miss_count=0
+mshrs=10
+prefetch_access=false
+prefetch_cache_check_push=true
+prefetch_data_accesses_only=false
+prefetch_degree=1
+prefetch_latency=10
+prefetch_miss=false
+prefetch_past_page=false
+prefetch_policy=none
+prefetch_serial_squash=false
+prefetch_use_cpu_id=true
+prefetcher_size=100
+prioritizeRequests=false
+protocol=Null
+repl=Null
+size=131072
+split=false
+split_size=0
+store_compressed=false
+subblock_size=0
+tgts_per_mshr=5
+trace_addr=0
+two_queue=false
+write_buffers=8
+cpu_side=system.cpu.icache_port
+mem_side=system.cpu.toL2Bus.port[0]
+
+[system.cpu.l2cache]
+type=BaseCache
+adaptive_compression=false
+assoc=2
+block_size=64
+compressed_bus=false
+compression_latency=0
+hash_delay=1
+hit_latency=1
+latency=1
+lifo=false
+max_miss_count=0
+mshrs=10
+prefetch_access=false
+prefetch_cache_check_push=true
+prefetch_data_accesses_only=false
+prefetch_degree=1
+prefetch_latency=10
+prefetch_miss=false
+prefetch_past_page=false
+prefetch_policy=none
+prefetch_serial_squash=false
+prefetch_use_cpu_id=true
+prefetcher_size=100
+prioritizeRequests=false
+protocol=Null
+repl=Null
+size=2097152
+split=false
+split_size=0
+store_compressed=false
+subblock_size=0
+tgts_per_mshr=5
+trace_addr=0
+two_queue=false
+write_buffers=8
+cpu_side=system.cpu.toL2Bus.port[2]
+mem_side=system.membus.port[1]
+
+[system.cpu.toL2Bus]
+type=Bus
+bus_id=0
+clock=1000
+width=64
+port=system.cpu.icache.mem_side system.cpu.dcache.mem_side system.cpu.l2cache.cpu_side
+
+[system.cpu.workload]
+type=LiveProcess
+cmd=hello
+egid=100
+env=
+euid=100
+executable=tests/test-progs/hello/bin/sparc/linux/hello
+gid=100
+input=cin
+output=cout
+pid=100
+ppid=99
+system=system
+uid=100
+
+[system.membus]
+type=Bus
+bus_id=0
+clock=1000
+width=64
+port=system.physmem.port system.cpu.l2cache.mem_side
+
+[system.physmem]
+type=PhysicalMemory
+file=
+latency=1
+range=0:134217727
+port=system.membus.port[0]
+
+[trace]
+bufsize=0
+cycle=0
+dump_on_exit=false
+file=cout
+flags=
+ignore=
+start=0
+
diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-timing/config.out b/tests/quick/00.hello/ref/sparc/linux/simple-timing/config.out
new file mode 100644
index 000000000..5210081b3
--- /dev/null
+++ b/tests/quick/00.hello/ref/sparc/linux/simple-timing/config.out
@@ -0,0 +1,227 @@
+[root]
+type=Root
+clock=1000000000000
+max_tick=0
+progress_interval=0
+output_file=cout
+
+[system.physmem]
+type=PhysicalMemory
+file=
+range=[0,134217727]
+latency=1
+
+[system]
+type=System
+physmem=system.physmem
+mem_mode=atomic
+
+[system.membus]
+type=Bus
+bus_id=0
+clock=1000
+width=64
+
+[system.cpu.dcache]
+type=BaseCache
+size=262144
+assoc=2
+block_size=64
+latency=1
+mshrs=10
+tgts_per_mshr=5
+write_buffers=8
+prioritizeRequests=false
+protocol=null
+trace_addr=0
+hash_delay=1
+repl=null
+compressed_bus=false
+store_compressed=false
+adaptive_compression=false
+compression_latency=0
+block_size=64
+max_miss_count=0
+addr_range=[0,18446744073709551615]
+split=false
+split_size=0
+lifo=false
+two_queue=false
+prefetch_miss=false
+prefetch_access=false
+prefetcher_size=100
+prefetch_past_page=false
+prefetch_serial_squash=false
+prefetch_latency=10
+prefetch_degree=1
+prefetch_policy=none
+prefetch_cache_check_push=true
+prefetch_use_cpu_id=true
+prefetch_data_accesses_only=false
+hit_latency=1
+
+[system.cpu.workload]
+type=LiveProcess
+cmd=hello
+executable=tests/test-progs/hello/bin/sparc/linux/hello
+input=cin
+output=cout
+env=
+system=system
+uid=100
+euid=100
+gid=100
+egid=100
+pid=100
+ppid=99
+
+[system.cpu]
+type=TimingSimpleCPU
+max_insts_any_thread=0
+max_insts_all_threads=0
+max_loads_any_thread=0
+max_loads_all_threads=0
+progress_interval=0
+mem=system.cpu.dcache
+system=system
+cpu_id=0
+workload=system.cpu.workload
+clock=1
+defer_registration=false
+// width not specified
+function_trace=false
+function_trace_start=0
+// simulate_stalls not specified
+
+[system.cpu.toL2Bus]
+type=Bus
+bus_id=0
+clock=1000
+width=64
+
+[system.cpu.icache]
+type=BaseCache
+size=131072
+assoc=2
+block_size=64
+latency=1
+mshrs=10
+tgts_per_mshr=5
+write_buffers=8
+prioritizeRequests=false
+protocol=null
+trace_addr=0
+hash_delay=1
+repl=null
+compressed_bus=false
+store_compressed=false
+adaptive_compression=false
+compression_latency=0
+block_size=64
+max_miss_count=0
+addr_range=[0,18446744073709551615]
+split=false
+split_size=0
+lifo=false
+two_queue=false
+prefetch_miss=false
+prefetch_access=false
+prefetcher_size=100
+prefetch_past_page=false
+prefetch_serial_squash=false
+prefetch_latency=10
+prefetch_degree=1
+prefetch_policy=none
+prefetch_cache_check_push=true
+prefetch_use_cpu_id=true
+prefetch_data_accesses_only=false
+hit_latency=1
+
+[system.cpu.l2cache]
+type=BaseCache
+size=2097152
+assoc=2
+block_size=64
+latency=1
+mshrs=10
+tgts_per_mshr=5
+write_buffers=8
+prioritizeRequests=false
+protocol=null
+trace_addr=0
+hash_delay=1
+repl=null
+compressed_bus=false
+store_compressed=false
+adaptive_compression=false
+compression_latency=0
+block_size=64
+max_miss_count=0
+addr_range=[0,18446744073709551615]
+split=false
+split_size=0
+lifo=false
+two_queue=false
+prefetch_miss=false
+prefetch_access=false
+prefetcher_size=100
+prefetch_past_page=false
+prefetch_serial_squash=false
+prefetch_latency=10
+prefetch_degree=1
+prefetch_policy=none
+prefetch_cache_check_push=true
+prefetch_use_cpu_id=true
+prefetch_data_accesses_only=false
+hit_latency=1
+
+[trace]
+flags=
+start=0
+cycle=0
+bufsize=0
+file=cout
+dump_on_exit=false
+ignore=
+
+[stats]
+descriptions=true
+project_name=test
+simulation_name=test
+simulation_sample=0
+text_file=m5stats.txt
+text_compat=true
+mysql_db=
+mysql_user=
+mysql_password=
+mysql_host=
+events_start=-1
+dump_reset=false
+dump_cycle=0
+dump_period=0
+ignore_events=
+
+[random]
+seed=1
+
+[exetrace]
+speculative=true
+print_cycle=true
+print_opclass=true
+print_thread=true
+print_effaddr=true
+print_data=true
+print_iregs=false
+print_fetchseq=false
+print_cpseq=false
+print_reg_delta=false
+pc_symbol=true
+intel_format=false
+trace_system=client
+
+[debug]
+break_cycles=
+
+[statsreset]
+reset_cycle=0
+
diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-timing/m5stats.txt b/tests/quick/00.hello/ref/sparc/linux/simple-timing/m5stats.txt
new file mode 100644
index 000000000..c4dc22855
--- /dev/null
+++ b/tests/quick/00.hello/ref/sparc/linux/simple-timing/m5stats.txt
@@ -0,0 +1,214 @@
+
+---------- Begin Simulation Statistics ----------
+host_inst_rate 53689 # Simulator instruction rate (inst/s)
+host_mem_usage 177104 # Number of bytes of host memory used
+host_seconds 0.08 # Real time elapsed on the host
+host_tick_rate 17808084 # Simulator tick rate (ticks/s)
+sim_freq 1000000000000 # Frequency of simulated ticks
+sim_insts 4483 # Number of instructions simulated
+sim_seconds 0.000001 # Number of seconds simulated
+sim_ticks 1497001 # Number of ticks simulated
+system.cpu.dcache.ReadReq_accesses 464 # number of ReadReq accesses(hits+misses)
+system.cpu.dcache.ReadReq_avg_miss_latency 3972.166667 # average ReadReq miss latency
+system.cpu.dcache.ReadReq_avg_mshr_miss_latency 2972.166667 # average ReadReq mshr miss latency
+system.cpu.dcache.ReadReq_hits 410 # number of ReadReq hits
+system.cpu.dcache.ReadReq_miss_latency 214497 # number of ReadReq miss cycles
+system.cpu.dcache.ReadReq_miss_rate 0.116379 # miss rate for ReadReq accesses
+system.cpu.dcache.ReadReq_misses 54 # number of ReadReq misses
+system.cpu.dcache.ReadReq_mshr_miss_latency 160497 # number of ReadReq MSHR miss cycles
+system.cpu.dcache.ReadReq_mshr_miss_rate 0.116379 # mshr miss rate for ReadReq accesses
+system.cpu.dcache.ReadReq_mshr_misses 54 # number of ReadReq MSHR misses
+system.cpu.dcache.WriteReq_accesses 501 # number of WriteReq accesses(hits+misses)
+system.cpu.dcache.WriteReq_avg_miss_latency 3980.840580 # average WriteReq miss latency
+system.cpu.dcache.WriteReq_avg_mshr_miss_latency 2980.840580 # average WriteReq mshr miss latency
+system.cpu.dcache.WriteReq_hits 432 # number of WriteReq hits
+system.cpu.dcache.WriteReq_miss_latency 274678 # number of WriteReq miss cycles
+system.cpu.dcache.WriteReq_miss_rate 0.137725 # miss rate for WriteReq accesses
+system.cpu.dcache.WriteReq_misses 69 # number of WriteReq misses
+system.cpu.dcache.WriteReq_mshr_miss_latency 205678 # number of WriteReq MSHR miss cycles
+system.cpu.dcache.WriteReq_mshr_miss_rate 0.137725 # mshr miss rate for WriteReq accesses
+system.cpu.dcache.WriteReq_mshr_misses 69 # number of WriteReq MSHR misses
+system.cpu.dcache.avg_blocked_cycles_no_mshrs <err: div-0> # average number of cycles each access was blocked
+system.cpu.dcache.avg_blocked_cycles_no_targets <err: div-0> # average number of cycles each access was blocked
+system.cpu.dcache.avg_refs 6.845528 # Average number of references to valid blocks.
+system.cpu.dcache.blocked_no_mshrs 0 # number of cycles access was blocked
+system.cpu.dcache.blocked_no_targets 0 # number of cycles access was blocked
+system.cpu.dcache.blocked_cycles_no_mshrs 0 # number of cycles access was blocked
+system.cpu.dcache.blocked_cycles_no_targets 0 # number of cycles access was blocked
+system.cpu.dcache.cache_copies 0 # number of cache copies performed
+system.cpu.dcache.demand_accesses 965 # number of demand (read+write) accesses
+system.cpu.dcache.demand_avg_miss_latency 3977.032520 # average overall miss latency
+system.cpu.dcache.demand_avg_mshr_miss_latency 2977.032520 # average overall mshr miss latency
+system.cpu.dcache.demand_hits 842 # number of demand (read+write) hits
+system.cpu.dcache.demand_miss_latency 489175 # number of demand (read+write) miss cycles
+system.cpu.dcache.demand_miss_rate 0.127461 # miss rate for demand accesses
+system.cpu.dcache.demand_misses 123 # number of demand (read+write) misses
+system.cpu.dcache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits
+system.cpu.dcache.demand_mshr_miss_latency 366175 # number of demand (read+write) MSHR miss cycles
+system.cpu.dcache.demand_mshr_miss_rate 0.127461 # mshr miss rate for demand accesses
+system.cpu.dcache.demand_mshr_misses 123 # number of demand (read+write) MSHR misses
+system.cpu.dcache.fast_writes 0 # number of fast writes performed
+system.cpu.dcache.mshr_cap_events 0 # number of times MSHR cap was activated
+system.cpu.dcache.no_allocate_misses 0 # Number of misses that were no-allocate
+system.cpu.dcache.overall_accesses 965 # number of overall (read+write) accesses
+system.cpu.dcache.overall_avg_miss_latency 3977.032520 # average overall miss latency
+system.cpu.dcache.overall_avg_mshr_miss_latency 2977.032520 # average overall mshr miss latency
+system.cpu.dcache.overall_avg_mshr_uncacheable_latency no value # average overall mshr uncacheable latency
+system.cpu.dcache.overall_hits 842 # number of overall hits
+system.cpu.dcache.overall_miss_latency 489175 # number of overall miss cycles
+system.cpu.dcache.overall_miss_rate 0.127461 # miss rate for overall accesses
+system.cpu.dcache.overall_misses 123 # number of overall misses
+system.cpu.dcache.overall_mshr_hits 0 # number of overall MSHR hits
+system.cpu.dcache.overall_mshr_miss_latency 366175 # number of overall MSHR miss cycles
+system.cpu.dcache.overall_mshr_miss_rate 0.127461 # mshr miss rate for overall accesses
+system.cpu.dcache.overall_mshr_misses 123 # number of overall MSHR misses
+system.cpu.dcache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles
+system.cpu.dcache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses
+system.cpu.dcache.prefetcher.num_hwpf_already_in_cache 0 # number of hwpf that were already in the cache
+system.cpu.dcache.prefetcher.num_hwpf_already_in_mshr 0 # number of hwpf that were already in mshr
+system.cpu.dcache.prefetcher.num_hwpf_already_in_prefetcher 0 # number of hwpf that were already in the prefetch queue
+system.cpu.dcache.prefetcher.num_hwpf_evicted 0 # number of hwpf removed due to no buffer left
+system.cpu.dcache.prefetcher.num_hwpf_identified 0 # number of hwpf identified
+system.cpu.dcache.prefetcher.num_hwpf_issued 0 # number of hwpf issued
+system.cpu.dcache.prefetcher.num_hwpf_removed_MSHR_hit 0 # number of hwpf removed because MSHR allocated
+system.cpu.dcache.prefetcher.num_hwpf_span_page 0 # number of hwpf spanning a virtual page
+system.cpu.dcache.prefetcher.num_hwpf_squashed_from_miss 0 # number of hwpf that got squashed due to a miss aborting calculation time
+system.cpu.dcache.replacements 0 # number of replacements
+system.cpu.dcache.sampled_refs 123 # Sample count of references to valid blocks.
+system.cpu.dcache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions
+system.cpu.dcache.tagsinuse 71.370810 # Cycle average of tags in use
+system.cpu.dcache.total_refs 842 # Total number of references to valid blocks.
+system.cpu.dcache.warmup_cycle 0 # Cycle when the warmup percentage was hit.
+system.cpu.dcache.writebacks 0 # number of writebacks
+system.cpu.icache.ReadReq_accesses 4484 # number of ReadReq accesses(hits+misses)
+system.cpu.icache.ReadReq_avg_miss_latency 3979.178571 # average ReadReq miss latency
+system.cpu.icache.ReadReq_avg_mshr_miss_latency 2979.178571 # average ReadReq mshr miss latency
+system.cpu.icache.ReadReq_hits 4232 # number of ReadReq hits
+system.cpu.icache.ReadReq_miss_latency 1002753 # number of ReadReq miss cycles
+system.cpu.icache.ReadReq_miss_rate 0.056200 # miss rate for ReadReq accesses
+system.cpu.icache.ReadReq_misses 252 # number of ReadReq misses
+system.cpu.icache.ReadReq_mshr_miss_latency 750753 # number of ReadReq MSHR miss cycles
+system.cpu.icache.ReadReq_mshr_miss_rate 0.056200 # mshr miss rate for ReadReq accesses
+system.cpu.icache.ReadReq_mshr_misses 252 # number of ReadReq MSHR misses
+system.cpu.icache.avg_blocked_cycles_no_mshrs <err: div-0> # average number of cycles each access was blocked
+system.cpu.icache.avg_blocked_cycles_no_targets <err: div-0> # average number of cycles each access was blocked
+system.cpu.icache.avg_refs 16.793651 # Average number of references to valid blocks.
+system.cpu.icache.blocked_no_mshrs 0 # number of cycles access was blocked
+system.cpu.icache.blocked_no_targets 0 # number of cycles access was blocked
+system.cpu.icache.blocked_cycles_no_mshrs 0 # number of cycles access was blocked
+system.cpu.icache.blocked_cycles_no_targets 0 # number of cycles access was blocked
+system.cpu.icache.cache_copies 0 # number of cache copies performed
+system.cpu.icache.demand_accesses 4484 # number of demand (read+write) accesses
+system.cpu.icache.demand_avg_miss_latency 3979.178571 # average overall miss latency
+system.cpu.icache.demand_avg_mshr_miss_latency 2979.178571 # average overall mshr miss latency
+system.cpu.icache.demand_hits 4232 # number of demand (read+write) hits
+system.cpu.icache.demand_miss_latency 1002753 # number of demand (read+write) miss cycles
+system.cpu.icache.demand_miss_rate 0.056200 # miss rate for demand accesses
+system.cpu.icache.demand_misses 252 # number of demand (read+write) misses
+system.cpu.icache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits
+system.cpu.icache.demand_mshr_miss_latency 750753 # number of demand (read+write) MSHR miss cycles
+system.cpu.icache.demand_mshr_miss_rate 0.056200 # mshr miss rate for demand accesses
+system.cpu.icache.demand_mshr_misses 252 # number of demand (read+write) MSHR misses
+system.cpu.icache.fast_writes 0 # number of fast writes performed
+system.cpu.icache.mshr_cap_events 0 # number of times MSHR cap was activated
+system.cpu.icache.no_allocate_misses 0 # Number of misses that were no-allocate
+system.cpu.icache.overall_accesses 4484 # number of overall (read+write) accesses
+system.cpu.icache.overall_avg_miss_latency 3979.178571 # average overall miss latency
+system.cpu.icache.overall_avg_mshr_miss_latency 2979.178571 # average overall mshr miss latency
+system.cpu.icache.overall_avg_mshr_uncacheable_latency no value # average overall mshr uncacheable latency
+system.cpu.icache.overall_hits 4232 # number of overall hits
+system.cpu.icache.overall_miss_latency 1002753 # number of overall miss cycles
+system.cpu.icache.overall_miss_rate 0.056200 # miss rate for overall accesses
+system.cpu.icache.overall_misses 252 # number of overall misses
+system.cpu.icache.overall_mshr_hits 0 # number of overall MSHR hits
+system.cpu.icache.overall_mshr_miss_latency 750753 # number of overall MSHR miss cycles
+system.cpu.icache.overall_mshr_miss_rate 0.056200 # mshr miss rate for overall accesses
+system.cpu.icache.overall_mshr_misses 252 # number of overall MSHR misses
+system.cpu.icache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles
+system.cpu.icache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses
+system.cpu.icache.prefetcher.num_hwpf_already_in_cache 0 # number of hwpf that were already in the cache
+system.cpu.icache.prefetcher.num_hwpf_already_in_mshr 0 # number of hwpf that were already in mshr
+system.cpu.icache.prefetcher.num_hwpf_already_in_prefetcher 0 # number of hwpf that were already in the prefetch queue
+system.cpu.icache.prefetcher.num_hwpf_evicted 0 # number of hwpf removed due to no buffer left
+system.cpu.icache.prefetcher.num_hwpf_identified 0 # number of hwpf identified
+system.cpu.icache.prefetcher.num_hwpf_issued 0 # number of hwpf issued
+system.cpu.icache.prefetcher.num_hwpf_removed_MSHR_hit 0 # number of hwpf removed because MSHR allocated
+system.cpu.icache.prefetcher.num_hwpf_span_page 0 # number of hwpf spanning a virtual page
+system.cpu.icache.prefetcher.num_hwpf_squashed_from_miss 0 # number of hwpf that got squashed due to a miss aborting calculation time
+system.cpu.icache.replacements 0 # number of replacements
+system.cpu.icache.sampled_refs 252 # Sample count of references to valid blocks.
+system.cpu.icache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions
+system.cpu.icache.tagsinuse 115.914677 # Cycle average of tags in use
+system.cpu.icache.total_refs 4232 # Total number of references to valid blocks.
+system.cpu.icache.warmup_cycle 0 # Cycle when the warmup percentage was hit.
+system.cpu.icache.writebacks 0 # number of writebacks
+system.cpu.idle_fraction 0 # Percentage of idle cycles
+system.cpu.l2cache.ReadReq_accesses 375 # number of ReadReq accesses(hits+misses)
+system.cpu.l2cache.ReadReq_avg_miss_latency 2986.473118 # average ReadReq miss latency
+system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 1985.473118 # average ReadReq mshr miss latency
+system.cpu.l2cache.ReadReq_hits 3 # number of ReadReq hits
+system.cpu.l2cache.ReadReq_miss_latency 1110968 # number of ReadReq miss cycles
+system.cpu.l2cache.ReadReq_miss_rate 0.992000 # miss rate for ReadReq accesses
+system.cpu.l2cache.ReadReq_misses 372 # number of ReadReq misses
+system.cpu.l2cache.ReadReq_mshr_miss_latency 738596 # number of ReadReq MSHR miss cycles
+system.cpu.l2cache.ReadReq_mshr_miss_rate 0.992000 # mshr miss rate for ReadReq accesses
+system.cpu.l2cache.ReadReq_mshr_misses 372 # number of ReadReq MSHR misses
+system.cpu.l2cache.avg_blocked_cycles_no_mshrs <err: div-0> # average number of cycles each access was blocked
+system.cpu.l2cache.avg_blocked_cycles_no_targets <err: div-0> # average number of cycles each access was blocked
+system.cpu.l2cache.avg_refs 0.008065 # Average number of references to valid blocks.
+system.cpu.l2cache.blocked_no_mshrs 0 # number of cycles access was blocked
+system.cpu.l2cache.blocked_no_targets 0 # number of cycles access was blocked
+system.cpu.l2cache.blocked_cycles_no_mshrs 0 # number of cycles access was blocked
+system.cpu.l2cache.blocked_cycles_no_targets 0 # number of cycles access was blocked
+system.cpu.l2cache.cache_copies 0 # number of cache copies performed
+system.cpu.l2cache.demand_accesses 375 # number of demand (read+write) accesses
+system.cpu.l2cache.demand_avg_miss_latency 2986.473118 # average overall miss latency
+system.cpu.l2cache.demand_avg_mshr_miss_latency 1985.473118 # average overall mshr miss latency
+system.cpu.l2cache.demand_hits 3 # number of demand (read+write) hits
+system.cpu.l2cache.demand_miss_latency 1110968 # number of demand (read+write) miss cycles
+system.cpu.l2cache.demand_miss_rate 0.992000 # miss rate for demand accesses
+system.cpu.l2cache.demand_misses 372 # number of demand (read+write) misses
+system.cpu.l2cache.demand_mshr_hits 0 # number of demand (read+write) MSHR hits
+system.cpu.l2cache.demand_mshr_miss_latency 738596 # number of demand (read+write) MSHR miss cycles
+system.cpu.l2cache.demand_mshr_miss_rate 0.992000 # mshr miss rate for demand accesses
+system.cpu.l2cache.demand_mshr_misses 372 # number of demand (read+write) MSHR misses
+system.cpu.l2cache.fast_writes 0 # number of fast writes performed
+system.cpu.l2cache.mshr_cap_events 0 # number of times MSHR cap was activated
+system.cpu.l2cache.no_allocate_misses 0 # Number of misses that were no-allocate
+system.cpu.l2cache.overall_accesses 375 # number of overall (read+write) accesses
+system.cpu.l2cache.overall_avg_miss_latency 2986.473118 # average overall miss latency
+system.cpu.l2cache.overall_avg_mshr_miss_latency 1985.473118 # average overall mshr miss latency
+system.cpu.l2cache.overall_avg_mshr_uncacheable_latency no value # average overall mshr uncacheable latency
+system.cpu.l2cache.overall_hits 3 # number of overall hits
+system.cpu.l2cache.overall_miss_latency 1110968 # number of overall miss cycles
+system.cpu.l2cache.overall_miss_rate 0.992000 # miss rate for overall accesses
+system.cpu.l2cache.overall_misses 372 # number of overall misses
+system.cpu.l2cache.overall_mshr_hits 0 # number of overall MSHR hits
+system.cpu.l2cache.overall_mshr_miss_latency 738596 # number of overall MSHR miss cycles
+system.cpu.l2cache.overall_mshr_miss_rate 0.992000 # mshr miss rate for overall accesses
+system.cpu.l2cache.overall_mshr_misses 372 # number of overall MSHR misses
+system.cpu.l2cache.overall_mshr_uncacheable_latency 0 # number of overall MSHR uncacheable cycles
+system.cpu.l2cache.overall_mshr_uncacheable_misses 0 # number of overall MSHR uncacheable misses
+system.cpu.l2cache.prefetcher.num_hwpf_already_in_cache 0 # number of hwpf that were already in the cache
+system.cpu.l2cache.prefetcher.num_hwpf_already_in_mshr 0 # number of hwpf that were already in mshr
+system.cpu.l2cache.prefetcher.num_hwpf_already_in_prefetcher 0 # number of hwpf that were already in the prefetch queue
+system.cpu.l2cache.prefetcher.num_hwpf_evicted 0 # number of hwpf removed due to no buffer left
+system.cpu.l2cache.prefetcher.num_hwpf_identified 0 # number of hwpf identified
+system.cpu.l2cache.prefetcher.num_hwpf_issued 0 # number of hwpf issued
+system.cpu.l2cache.prefetcher.num_hwpf_removed_MSHR_hit 0 # number of hwpf removed because MSHR allocated
+system.cpu.l2cache.prefetcher.num_hwpf_span_page 0 # number of hwpf spanning a virtual page
+system.cpu.l2cache.prefetcher.num_hwpf_squashed_from_miss 0 # number of hwpf that got squashed due to a miss aborting calculation time
+system.cpu.l2cache.replacements 0 # number of replacements
+system.cpu.l2cache.sampled_refs 372 # Sample count of references to valid blocks.
+system.cpu.l2cache.soft_prefetch_mshr_full 0 # number of mshr full events for SW prefetching instrutions
+system.cpu.l2cache.tagsinuse 185.896040 # Cycle average of tags in use
+system.cpu.l2cache.total_refs 3 # Total number of references to valid blocks.
+system.cpu.l2cache.warmup_cycle 0 # Cycle when the warmup percentage was hit.
+system.cpu.l2cache.writebacks 0 # number of writebacks
+system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles
+system.cpu.numCycles 1497001 # number of cpu cycles simulated
+system.cpu.num_insts 4483 # Number of instructions executed
+system.cpu.num_refs 965 # Number of memory references
+system.cpu.workload.PROG:num_syscalls 11 # Number of system calls
+
+---------- End Simulation Statistics ----------
diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-timing/stderr b/tests/quick/00.hello/ref/sparc/linux/simple-timing/stderr
new file mode 100644
index 000000000..7873672f2
--- /dev/null
+++ b/tests/quick/00.hello/ref/sparc/linux/simple-timing/stderr
@@ -0,0 +1,3 @@
+warn: More than two loadable segments in ELF object.
+warn: Ignoring segment @ 0x0 length 0x0.
+warn: Entering event queue @ 0. Starting simulation...
diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-timing/stdout b/tests/quick/00.hello/ref/sparc/linux/simple-timing/stdout
new file mode 100644
index 000000000..3c17ee40b
--- /dev/null
+++ b/tests/quick/00.hello/ref/sparc/linux/simple-timing/stdout
@@ -0,0 +1,12 @@
+Hello World!M5 Simulator System
+
+Copyright (c) 2001-2006
+The Regents of The University of Michigan
+All Rights Reserved
+
+
+M5 compiled Oct 23 2006 07:47:36
+M5 started Mon Oct 23 07:47:41 2006
+M5 executing on zeep
+command line: build/SPARC_SE/m5.debug -d build/SPARC_SE/tests/debug/quick/00.hello/sparc/linux/simple-timing tests/run.py quick/00.hello/sparc/linux/simple-timing
+Exiting @ tick 1497001 because target called exit()
diff --git a/util/statetrace/arch/tracechild_sparc.cc b/util/statetrace/arch/tracechild_sparc.cc
index 378de0865..bad81b647 100644
--- a/util/statetrace/arch/tracechild_sparc.cc
+++ b/util/statetrace/arch/tracechild_sparc.cc
@@ -47,10 +47,10 @@ string SparcTraceChild::regNames[numregs] = {
//Input registers
"i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
//Floating point
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+ "f0", "f2", "f4", "f6", "f8", "f10", "f12", "f14",
+ "f16", "f18", "f20", "f22", "f24", "f26", "f28", "f30",
+ "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46",
+ "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",
//Miscelaneous
"fsr", "fprs", "pc", "npc", "y", "cwp", "pstate", "asi", "ccr"};
@@ -98,37 +98,37 @@ int64_t getRegs(regs & myregs, fpu & myfpu,
case SparcTraceChild::I7: return inputs[7];
//Floating point
case SparcTraceChild::F0: return myfpu.f_fpstatus.fpu_fr[0];
- case SparcTraceChild::F1: return myfpu.f_fpstatus.fpu_fr[1];
- case SparcTraceChild::F2: return myfpu.f_fpstatus.fpu_fr[2];
- case SparcTraceChild::F3: return myfpu.f_fpstatus.fpu_fr[3];
- case SparcTraceChild::F4: return myfpu.f_fpstatus.fpu_fr[4];
- case SparcTraceChild::F5: return myfpu.f_fpstatus.fpu_fr[5];
- case SparcTraceChild::F6: return myfpu.f_fpstatus.fpu_fr[6];
- case SparcTraceChild::F7: return myfpu.f_fpstatus.fpu_fr[7];
- case SparcTraceChild::F8: return myfpu.f_fpstatus.fpu_fr[8];
- case SparcTraceChild::F9: return myfpu.f_fpstatus.fpu_fr[9];
- case SparcTraceChild::F10: return myfpu.f_fpstatus.fpu_fr[10];
- case SparcTraceChild::F11: return myfpu.f_fpstatus.fpu_fr[11];
- case SparcTraceChild::F12: return myfpu.f_fpstatus.fpu_fr[12];
- case SparcTraceChild::F13: return myfpu.f_fpstatus.fpu_fr[13];
- case SparcTraceChild::F14: return myfpu.f_fpstatus.fpu_fr[14];
- case SparcTraceChild::F15: return myfpu.f_fpstatus.fpu_fr[15];
- case SparcTraceChild::F16: return myfpu.f_fpstatus.fpu_fr[16];
- case SparcTraceChild::F17: return myfpu.f_fpstatus.fpu_fr[17];
- case SparcTraceChild::F18: return myfpu.f_fpstatus.fpu_fr[18];
- case SparcTraceChild::F19: return myfpu.f_fpstatus.fpu_fr[19];
- case SparcTraceChild::F20: return myfpu.f_fpstatus.fpu_fr[20];
- case SparcTraceChild::F21: return myfpu.f_fpstatus.fpu_fr[21];
- case SparcTraceChild::F22: return myfpu.f_fpstatus.fpu_fr[22];
- case SparcTraceChild::F23: return myfpu.f_fpstatus.fpu_fr[23];
- case SparcTraceChild::F24: return myfpu.f_fpstatus.fpu_fr[24];
- case SparcTraceChild::F25: return myfpu.f_fpstatus.fpu_fr[25];
- case SparcTraceChild::F26: return myfpu.f_fpstatus.fpu_fr[26];
- case SparcTraceChild::F27: return myfpu.f_fpstatus.fpu_fr[27];
- case SparcTraceChild::F28: return myfpu.f_fpstatus.fpu_fr[28];
- case SparcTraceChild::F29: return myfpu.f_fpstatus.fpu_fr[29];
- case SparcTraceChild::F30: return myfpu.f_fpstatus.fpu_fr[30];
- case SparcTraceChild::F31: return myfpu.f_fpstatus.fpu_fr[31];
+ case SparcTraceChild::F2: return myfpu.f_fpstatus.fpu_fr[1];
+ case SparcTraceChild::F4: return myfpu.f_fpstatus.fpu_fr[2];
+ case SparcTraceChild::F6: return myfpu.f_fpstatus.fpu_fr[3];
+ case SparcTraceChild::F8: return myfpu.f_fpstatus.fpu_fr[4];
+ case SparcTraceChild::F10: return myfpu.f_fpstatus.fpu_fr[5];
+ case SparcTraceChild::F12: return myfpu.f_fpstatus.fpu_fr[6];
+ case SparcTraceChild::F14: return myfpu.f_fpstatus.fpu_fr[7];
+ case SparcTraceChild::F16: return myfpu.f_fpstatus.fpu_fr[8];
+ case SparcTraceChild::F18: return myfpu.f_fpstatus.fpu_fr[9];
+ case SparcTraceChild::F20: return myfpu.f_fpstatus.fpu_fr[10];
+ case SparcTraceChild::F22: return myfpu.f_fpstatus.fpu_fr[11];
+ case SparcTraceChild::F24: return myfpu.f_fpstatus.fpu_fr[12];
+ case SparcTraceChild::F26: return myfpu.f_fpstatus.fpu_fr[13];
+ case SparcTraceChild::F28: return myfpu.f_fpstatus.fpu_fr[14];
+ case SparcTraceChild::F30: return myfpu.f_fpstatus.fpu_fr[15];
+ case SparcTraceChild::F32: return myfpu.f_fpstatus.fpu_fr[16];
+ case SparcTraceChild::F34: return myfpu.f_fpstatus.fpu_fr[17];
+ case SparcTraceChild::F36: return myfpu.f_fpstatus.fpu_fr[18];
+ case SparcTraceChild::F38: return myfpu.f_fpstatus.fpu_fr[19];
+ case SparcTraceChild::F40: return myfpu.f_fpstatus.fpu_fr[20];
+ case SparcTraceChild::F42: return myfpu.f_fpstatus.fpu_fr[21];
+ case SparcTraceChild::F44: return myfpu.f_fpstatus.fpu_fr[22];
+ case SparcTraceChild::F46: return myfpu.f_fpstatus.fpu_fr[23];
+ case SparcTraceChild::F48: return myfpu.f_fpstatus.fpu_fr[24];
+ case SparcTraceChild::F50: return myfpu.f_fpstatus.fpu_fr[25];
+ case SparcTraceChild::F52: return myfpu.f_fpstatus.fpu_fr[26];
+ case SparcTraceChild::F54: return myfpu.f_fpstatus.fpu_fr[27];
+ case SparcTraceChild::F56: return myfpu.f_fpstatus.fpu_fr[28];
+ case SparcTraceChild::F58: return myfpu.f_fpstatus.fpu_fr[29];
+ case SparcTraceChild::F60: return myfpu.f_fpstatus.fpu_fr[30];
+ case SparcTraceChild::F62: return myfpu.f_fpstatus.fpu_fr[31];
//Miscelaneous
case SparcTraceChild::FSR: return myfpu.f_fpstatus.Fpu_fsr;
case SparcTraceChild::FPRS: return myregs.r_fprs;
@@ -188,46 +188,110 @@ bool SparcTraceChild::step()
//being breakpointed should be word (64bit) aligned, and that both the
//next instruction and the instruction after that need to be breakpointed
//so that annulled branches will still stop as well.
+
+ /*
+ * Useful constants
+ */
const static uint64_t breakInst = 0x91d02001;
const static uint64_t breakWord = breakInst | (breakInst << 32);
- const static uint64_t lowMask = (uint64_t)(0xFFFFFFFF);
+ const static uint64_t lowMask = 0xFFFFFFFFULL;
const static uint64_t highMask = lowMask << 32;
+
+ /*
+ * storage for the original contents of the child process's memory
+ */
uint64_t originalInst, originalAnnulInst;
+
+ /*
+ * Get information about where the process is and is headed next.
+ */
+ uint64_t currentPC = getRegVal(PC);
+ bool unalignedPC = currentPC & 7;
+ uint64_t alignedPC = currentPC & (~7);
uint64_t nextPC = getRegVal(NPC);
- bool unaligned = nextPC & 7;
- uint64_t alignedPC = nextPC & (~7);
- originalInst = ptrace(PTRACE_PEEKTEXT, pid, alignedPC, 0);
- if(unaligned)
+ bool unalignedNPC = nextPC & 7;
+ uint64_t alignedNPC = nextPC & (~7);
+
+ /*
+ * Store the original contents of the child process's memory
+ */
+ originalInst = ptrace(PTRACE_PEEKTEXT, pid, alignedNPC, 0);
+ //Save a ptrace call if we can
+ if(unalignedNPC)
{
- originalAnnulInst = ptrace(PTRACE_PEEKTEXT, pid, alignedPC+8, 0);
+ originalAnnulInst = ptrace(PTRACE_PEEKTEXT, pid, alignedNPC+8, 0);
}
- uint64_t newInst;
- if(unaligned)
+
+ /*
+ * Prepare breakpointed copies of child processes memory
+ */
+ uint64_t newInst, newAnnulInst;
+ //If the current instruction is in the same word as the npc
+ if(alignedPC == alignedNPC)
{
- newInst = (originalInst & highMask) | (breakInst << 0);
- if(ptrace(PTRACE_POKETEXT, pid, alignedPC, newInst) != 0)
- cerr << "Poke failed" << endl;
- newInst = (originalAnnulInst & lowMask) | (breakInst << 32);
- if(ptrace(PTRACE_POKETEXT, pid, alignedPC+8, newInst) != 0)
- cerr << "Poke failed" << endl;
+ //Make sure we only replace the other part
+ if(unalignedPC)
+ newInst = (originalInst & lowMask) | (breakWord & highMask);
+ else
+ newInst = (originalInst & highMask) | (breakWord & lowMask);
+ }
+ else
+ {
+ //otherwise replace the whole thing
+ newInst = breakWord;
+ }
+ //If the current instruction is in the same word as the word after
+ //the npc
+ if(alignedPC == alignedNPC+8)
+ {
+ //Make sure we only replace the other part
+ if(unalignedPC)
+ newAnnulInst = (originalAnnulInst & lowMask) | (breakWord & highMask);
+ else
+ newAnnulInst = (originalAnnulInst & highMask) | (breakWord & lowMask);
}
else
{
- if(ptrace(PTRACE_POKETEXT, pid, alignedPC, breakWord) != 0)
+ //otherwise replace the whole thing
+ newAnnulInst = breakWord;
+ }
+
+ /*
+ * Stuff the breakpoint instructions into the child's address space.
+ */
+ //Replace the word at npc
+ if(ptrace(PTRACE_POKETEXT, pid, alignedNPC, newInst) != 0)
+ cerr << "Poke failed" << endl;
+ //Replace the next word, if necessary
+ if(unalignedNPC)
+ {
+ if(ptrace(PTRACE_POKETEXT, pid, alignedNPC+8, newAnnulInst) != 0)
cerr << "Poke failed" << endl;
}
+
+ /*
+ * Restart the child process
+ */
//Note that the "addr" parameter is supposed to be ignored, but in at
//least one version of the kernel, it must be 1 or it will set what
//pc to continue from
- if(ptrace(PTRACE_CONT, pid, /*nextPC - 4*/ 1, 0) != 0)
+ if(ptrace(PTRACE_CONT, pid, 1, 0) != 0)
cerr << "Cont failed" << endl;
doWait();
+
+ /*
+ * Update our record of the child's state
+ */
update(pid);
- if(ptrace(PTRACE_POKETEXT, pid, alignedPC, originalInst) != 0)
+
+ /*
+ * Put back the original contents of the childs address space
+ */
+ if(ptrace(PTRACE_POKETEXT, pid, alignedNPC, originalInst) != 0)
cerr << "Repoke failed" << endl;
- if(unaligned)
+ if(unalignedNPC)
{
- if(ptrace(PTRACE_POKETEXT, pid, alignedPC+8, originalAnnulInst) != 0)
+ if(ptrace(PTRACE_POKETEXT, pid, alignedNPC+8, originalAnnulInst) != 0)
cerr << "Repoke failed" << endl;
}
return true;
diff --git a/util/statetrace/arch/tracechild_sparc.hh b/util/statetrace/arch/tracechild_sparc.hh
index d177d5941..80770211a 100644
--- a/util/statetrace/arch/tracechild_sparc.hh
+++ b/util/statetrace/arch/tracechild_sparc.hh
@@ -57,10 +57,10 @@ public:
//Input registers
I0, I1, I2, I3, I4, I5, I6, I7,
//Floating point
- F0, F1, F2, F3, F4, F5, F6, F7,
- F8, F9, F10, F11, F12, F13, F14, F15,
- F16, F17, F18, F19, F20, F21, F22, F23,
- F24, F25, F26, F27, F28, F29, F30, F31,
+ F0, F2, F4, F6, F8, F10, F12, F14,
+ F16, F18, F20, F22, F24, F26, F28, F30,
+ F32, F34, F36, F38, F40, F42, F44, F46,
+ F48, F50, F52, F54, F56, F58, F60, F62,
//Miscelaneous
FSR, FPRS, PC, NPC, Y, CWP, PSTATE, ASI, CCR,
numregs
diff --git a/util/term/term.c b/util/term/term.c
index 8a95480b1..597966159 100644
--- a/util/term/term.c
+++ b/util/term/term.c
@@ -60,46 +60,49 @@ void usage(int);
int
main(int argc, char *argv[])
{
- int ch, s, ret;
- char *host, *port, *endp;
- struct addrinfo hints;
- socklen_t len;
-
- ret = 1;
- s = 0;
- host = NULL;
- port = NULL;
- endp = NULL;
-
- strncpy(progname, argv[0], sizeof progname);
-
- /* Cruft to make sure options are clean, and used properly. */
- if (argc != 3 || !argv[1] || !argv[2])
- usage(1);
-
+ int ch, s, ret;
+ char *host, *port, *endp;
+ struct addrinfo hints;
+ socklen_t len;
+
+ ret = 1;
+ s = 0;
+ host = NULL;
+ port = NULL;
+ endp = NULL;
+
+ strncpy(progname, argv[0], sizeof progname);
+
+ /* Cruft to make sure options are clean, and used properly. */
+ if (argc == 2) {
+ host = "localhost";
+ port = argv[1];
+ } else if (argc == 3) {
host = argv[1];
port = argv[2];
+ } else {
+ usage(1);
+ }
+ if (!isatty(STDIN_FILENO))
+ errx(1, "not attached to a terminal");
- if (!isatty(STDIN_FILENO))
- errx(1, "not attached to a terminal");
+ raw_term();
- raw_term();
+ /* Initialize addrinfo structure */
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
- /* Initialize addrinfo structure */
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
+ s = remote_connect(host, port, hints);
+ ret = 0;
+ readwrite(s);
- s = remote_connect(host, port, hints);
- ret = 0;
- readwrite(s);
+ if (s)
+ close(s);
- if (s)
- close(s);
-
- exit(ret);
+ exit(ret);
}
/*
@@ -110,28 +113,28 @@ main(int argc, char *argv[])
int
remote_connect(char *host, char *port, struct addrinfo hints)
{
- struct addrinfo *res, *res0;
- int s, error;
+ struct addrinfo *res, *res0;
+ int s, error;
- if ((error = getaddrinfo(host, port, &hints, &res)))
- errx(1, "getaddrinfo: %s", gai_strerror(error));
+ if ((error = getaddrinfo(host, port, &hints, &res)))
+ errx(1, "getaddrinfo: %s", gai_strerror(error));
- res0 = res;
- do {
- if ((s = socket(res0->ai_family, res0->ai_socktype,
- res0->ai_protocol)) < 0)
- continue;
+ res0 = res;
+ do {
+ if ((s = socket(res0->ai_family, res0->ai_socktype,
+ res0->ai_protocol)) < 0)
+ continue;
- if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
- break;
+ if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0)
+ break;
- close(s);
- s = -1;
- } while ((res0 = res0->ai_next) != NULL);
+ close(s);
+ s = -1;
+ } while ((res0 = res0->ai_next) != NULL);
- freeaddrinfo(res);
+ freeaddrinfo(res);
- return (s);
+ return (s);
}
/*
@@ -141,79 +144,79 @@ remote_connect(char *host, char *port, struct addrinfo hints)
void
readwrite(int nfd)
{
- struct pollfd pfd[2];
- char buf[BUFSIZ];
- int wfd = fileno(stdin), n, ret;
- int lfd = fileno(stdout);
- int escape = 0;
-
- /* Setup Network FD */
- pfd[0].fd = nfd;
- pfd[0].events = POLLIN;
-
- /* Setup STDIN FD */
- pfd[1].fd = wfd;
- pfd[1].events = POLLIN;
-
- while (pfd[0].fd != -1) {
- if ((n = poll(pfd, 2, -1)) < 0) {
- close(nfd);
- err(1, "Polling Error");
- }
+ struct pollfd pfd[2];
+ char buf[BUFSIZ];
+ int wfd = fileno(stdin), n, ret;
+ int lfd = fileno(stdout);
+ int escape = 0;
+
+ /* Setup Network FD */
+ pfd[0].fd = nfd;
+ pfd[0].events = POLLIN;
+
+ /* Setup STDIN FD */
+ pfd[1].fd = wfd;
+ pfd[1].events = POLLIN;
+
+ while (pfd[0].fd != -1) {
+ if ((n = poll(pfd, 2, -1)) < 0) {
+ close(nfd);
+ err(1, "Polling Error");
+ }
- if (n == 0)
- return;
+ if (n == 0)
+ return;
+
+ if (pfd[0].revents & POLLIN) {
+ if ((n = read(nfd, buf, sizeof(buf))) < 0)
+ return;
+ else if (n == 0) {
+ shutdown(nfd, SHUT_RD);
+ pfd[0].fd = -1;
+ pfd[0].events = 0;
+ } else {
+ if ((ret = atomicio(write, lfd, buf, n)) != n)
+ return;
+ }
+ }
- if (pfd[0].revents & POLLIN) {
- if ((n = read(nfd, buf, sizeof(buf))) < 0)
- return;
- else if (n == 0) {
- shutdown(nfd, SHUT_RD);
- pfd[0].fd = -1;
- pfd[0].events = 0;
- } else {
- if ((ret = atomicio(write, lfd, buf, n)) != n)
- return;
- }
+ if (pfd[1].revents & POLLIN) {
+ if ((n = read(wfd, buf, sizeof(buf))) < 0)
+ return;
+ else if (n == 0) {
+ shutdown(nfd, SHUT_WR);
+ pfd[1].fd = -1;
+ pfd[1].events = 0;
+ } else {
+ if (escape) {
+ char buf2[] = "~";
+ if (*buf == '.') {
+ printf("quit!\n");
+ return;
+ }
+ escape = 0;
+ if (*buf != '~' &&
+ (ret = atomicio(write, nfd, buf2, 1)) != n)
+ return;
+ } else {
+ escape = (*buf == '~');
+ if (escape)
+ continue;
}
- if (pfd[1].revents & POLLIN) {
- if ((n = read(wfd, buf, sizeof(buf))) < 0)
- return;
- else if (n == 0) {
- shutdown(nfd, SHUT_WR);
- pfd[1].fd = -1;
- pfd[1].events = 0;
- } else {
- if (escape) {
- char buf2[] = "~";
- if (*buf == '.') {
- printf("quit!\n");
- return;
- }
- escape = 0;
- if (*buf != '~' &&
- (ret = atomicio(write, nfd, buf2, 1)) != n)
- return;
- } else {
- escape = (*buf == '~');
- if (escape)
- continue;
- }
-
- if ((ret = atomicio(write, nfd, buf, n)) != n)
- return;
- }
- }
+ if ((ret = atomicio(write, nfd, buf, n)) != n)
+ return;
+ }
}
+ }
}
void
usage(int ret)
{
- fprintf(stderr, "usage: %s hostname port\n", progname);
- if (ret)
- exit(1);
+ fprintf(stderr, "usage: %s hostname port\n", progname);
+ if (ret)
+ exit(1);
}
/*
@@ -247,22 +250,22 @@ usage(int ret)
ssize_t
atomicio(ssize_t (*f) (), int fd, void *_s, size_t n)
{
- char *s = _s;
- ssize_t res, pos = 0;
-
- while (n > pos) {
- res = (f) (fd, s + pos, n - pos);
- switch (res) {
- case -1:
- if (errno == EINTR || errno == EAGAIN)
- continue;
- case 0:
- return (res);
- default:
- pos += res;
- }
+ char *s = _s;
+ ssize_t res, pos = 0;
+
+ while (n > pos) {
+ res = (f) (fd, s + pos, n - pos);
+ switch (res) {
+ case -1:
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ case 0:
+ return (res);
+ default:
+ pos += res;
}
- return (pos);
+ }
+ return (pos);
}
/*
@@ -284,28 +287,28 @@ atomicio(ssize_t (*f) (), int fd, void *_s, size_t n)
void
raw_term()
{
- struct termios ios;
+ struct termios ios;
- if (tcgetattr(STDIN_FILENO, &ios) < 0)
- errx(1, "tcgetagttr\n");
+ if (tcgetattr(STDIN_FILENO, &ios) < 0)
+ errx(1, "tcgetagttr\n");
- memcpy(&saved_ios, &ios, sizeof(struct termios));
+ memcpy(&saved_ios, &ios, sizeof(struct termios));
- ios.c_iflag &= ~(ISTRIP|ICRNL|IGNCR|ICRNL|IXOFF|IXON);
- ios.c_oflag &= ~(OPOST);
- ios.c_oflag &= (ONLCR);
- ios.c_lflag &= ~(ISIG|ICANON|ECHO);
- ios.c_cc[VMIN] = 1;
- ios.c_cc[VTIME] = 0;
+ ios.c_iflag &= ~(ISTRIP|ICRNL|IGNCR|ICRNL|IXOFF|IXON);
+ ios.c_oflag &= ~(OPOST);
+ ios.c_oflag &= (ONLCR);
+ ios.c_lflag &= ~(ISIG|ICANON|ECHO);
+ ios.c_cc[VMIN] = 1;
+ ios.c_cc[VTIME] = 0;
- if (tcsetattr(STDIN_FILENO, TCSANOW, &ios) < 0)
- errx(1, "tcsetattr\n");
+ if (tcsetattr(STDIN_FILENO, TCSANOW, &ios) < 0)
+ errx(1, "tcsetattr\n");
- atexit(restore_term);
+ atexit(restore_term);
}
void
restore_term()
{
- tcsetattr(STDIN_FILENO, TCSANOW, &saved_ios);
+ tcsetattr(STDIN_FILENO, TCSANOW, &saved_ios);
}
diff --git a/util/tracediff b/util/tracediff
index f2377a999..b25efe9b2 100755
--- a/util/tracediff
+++ b/util/tracediff
@@ -33,23 +33,63 @@
# ******Note that you need to enable some trace flags in the args in order
# to do anything useful!******
#
-# If you want to pass different arguments to the two instances of m5,
-# you can embed them in the simulator arguments like this:
+# Script arguments are handled uniformly as follows:
+# - If the argument does not contain a '|' character, it is appended
+# to both command lines.
+# - If the argument has a '|' character in it, the text on either side
+# of the '|' is appended to the respective command lines. Note that
+# you'll have to quote the arg or escape the '|' with a backslash
+# so that the shell doesn't think you're doing a pipe.
#
-# % tracediff "m5.opt --option1" "m5.opt --option2" [common args]
+# In other words, the arguments should look like the command line you
+# want to run, with "|" used to list the alternatives for the parts
+# that you want to differ between the two runs.
+#
+# For example:
+#
+# % tracediff m5.opt --opt1 "--opt2|--opt3" --opt4
+# would compare these two runs:
+# m5.opt --opt1 --opt2 --opt4
+# m5.opt --opt1 --opt3 --opt4
+#
+# If you want to compare two different simulator binaries, put a '|'
+# in the first script argument ("path1/m5.opt|path2/m5.opt"). If you
+# want to add arguments to one run only, just put a '|' in with text
+# only on one side ("--onlyOn1|"). You can do this with multiple
+# arguments together too ("|-a -b -c" adds three args to the second
+# run only).
#
if (@ARGV < 2) {
- die "Usage: tracediff sim1 sim2 [--root.trace.flags=X args...]\n";
+ die "Usage: tracediff \"sim1|sim2\" [common-arg \"arg1|arg2\" ...]\n";
+}
+
+foreach $arg (@ARGV) {
+ @pair = split('\|', $arg, -1); # -1 enables null trailing fields
+ if ($#pair > 0) {
+ push @cmd1, $pair[0];
+ push @cmd2, $pair[1];
+ } else {
+ push @cmd1, $arg;
+ push @cmd2, $arg;
+ }
}
# First two args are the two simulator binaries to compare
-$sim1 = shift;
-$sim2 = shift;
+$sim1 = shift @cmd1;
+$sim2 = shift @cmd2;
+
+# Everything else is a simulator arg.
+$args1 = join(' ', @cmd1);
+$args2 = join(' ', @cmd2);
-# Everything else on the command line is taken to be an m5 argument to
-# be given to both invocations
-$simargs = '"' . join('" "', @ARGV) . '"';
+# Common mistake: if you don't set any traceflags this often isn't
+# doing what you want.
+if ($args1 !~ /--trace-flags/) {
+ print "****\n";
+ print "**** WARNING: no trace flags set... you may not be diffing much!\n";
+ print "****\n";
+}
# Run individual invocations in separate dirs so output and intermediate
# files (particularly config.py and config.ini) don't conflict.
@@ -58,8 +98,8 @@ $dir2 = "tracediff-$$-2";
mkdir($dir1) or die "Can't create dir $dir1\n";
mkdir($dir2) or die "Can't create dir $dir2\n";
-$cmd1 = "$sim1 -d $dir1 $simargs 2>&1 |";
-$cmd2 = "$sim2 -d $dir2 $simargs 2>&1 |";
+$cmd1 = "$sim1 -d $dir1 $args1 2>&1 |";
+$cmd2 = "$sim2 -d $dir2 $args2 2>&1 |";
# This only works if you have rundiff in your path. I just edit it
# with an explicit path if necessary.