diff options
author | Kevin Lim <ktlim@umich.edu> | 2006-10-31 14:44:23 -0500 |
---|---|---|
committer | Kevin Lim <ktlim@umich.edu> | 2006-10-31 14:44:23 -0500 |
commit | 2fa535f7407ad2a7e1e2ec807b72d11a81fa25aa (patch) | |
tree | 29a33ada141edad37b9304227f411a0195520869 | |
parent | e912080d12666482a942eae354e783c3d666c6c9 (diff) | |
parent | 7f39644609e19ada9e94c9bbb09c3e625fa6e8ed (diff) | |
download | gem5-2fa535f7407ad2a7e1e2ec807b72d11a81fa25aa.tar.xz |
Merge ktlim@zizzer:/bk/newmem
into zamp.eecs.umich.edu:/z/ktlim2/clean/o3-merge/newmem
--HG--
extra : convert_revision : 88fa7ae5cc32be068787ee381fae9d8de0e9bd0f
49 files changed, 1188 insertions, 975 deletions
diff --git a/configs/common/Caches.py b/configs/common/Caches.py new file mode 100644 index 000000000..d86fba246 --- /dev/null +++ b/configs/common/Caches.py @@ -0,0 +1,39 @@ +# 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: Lisa Hsu + +import m5 +from m5.objects import * + +class L1Cache(BaseCache): + assoc = 2 + block_size = 64 + latency = 1 + mshrs = 10 + tgts_per_mshr = 5 + protocol = CoherenceProtocol(protocol='moesi') + diff --git a/configs/common/Options.py b/configs/common/Options.py new file mode 100644 index 000000000..69f48dc3b --- /dev/null +++ b/configs/common/Options.py @@ -0,0 +1,60 @@ +# 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: Lisa Hsu + +# system options +parser.add_option("-d", "--detailed", action="store_true") +parser.add_option("-t", "--timing", action="store_true") +parser.add_option("-n", "--num_cpus", type="int", default=1) +parser.add_option("--caches", action="store_true") + +# Run duration options +parser.add_option("-m", "--maxtick", type="int") +parser.add_option("--maxtime", type="float") + +# Checkpointing options +###Note that performing checkpointing via python script files will override +###checkpoint instructions built into binaries. +parser.add_option("--take_checkpoints", action="store", type="string", + help="<M,N> will take checkpoint at cycle M and every N cycles \ + thereafter") +parser.add_option("--max_checkpoints", action="store", type="int", + help="the maximum number of checkpoints to drop", + default=5) +parser.add_option("--checkpoint_dir", action="store", type="string", + help="Place all checkpoints in this absolute directory") +parser.add_option("-r", "--checkpoint_restore", action="store", type="int", + help="restore from checkpoint <N>") + +# CPU Switching - default switch model goes from a checkpoint +# to a timing simple CPU with caches to warm up, then to detailed CPU for +# data measurement +parser.add_option("-s", "--standard_switch", action="store_true", + help="switch from timing CPU to Detailed CPU") +parser.add_option("-w", "--warmup", action="store", type="int", + help="if -s, then this is the warmup period. else, this is ignored", + default=5000000000) diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py new file mode 100644 index 000000000..5e9c1d339 --- /dev/null +++ b/configs/common/Simulation.py @@ -0,0 +1,177 @@ +# 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: Lisa Hsu + +from os import getcwd +import m5 +from m5.objects import * +m5.AddToPath('../common') +from Caches import L1Cache + +def run(options, root, testsys): + if options.maxtick: + maxtick = options.maxtick + elif options.maxtime: + simtime = int(options.maxtime * root.clock.value) + print "simulating for: ", simtime + maxtick = simtime + else: + maxtick = -1 + + if options.checkpoint_dir: + cptdir = options.checkpoint_dir + else: + cptdir = getcwd() + + np = options.num_cpus + max_checkpoints = options.max_checkpoints + + if options.standard_switch: + switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i)) + for i in xrange(np)] + switch_cpus1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i)) + for i in xrange(np)] + for i in xrange(np): + switch_cpus[i].system = testsys + switch_cpus1[i].system = testsys + if not m5.build_env['FULL_SYSTEM']: + switch_cpus[i].workload = testsys.cpu[i].workload + switch_cpus1[i].workload = testsys.cpu[i].workload + switch_cpus[i].clock = testsys.cpu[0].clock + switch_cpus1[i].clock = testsys.cpu[0].clock + if options.caches: + switch_cpus[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'), + L1Cache(size = '64kB')) + + switch_cpus[i].mem = testsys.physmem + switch_cpus1[i].mem = testsys.physmem + switch_cpus[i].connectMemPorts(testsys.membus) + root.switch_cpus = switch_cpus + root.switch_cpus1 = switch_cpus1 + switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] + switch_cpu_list1 = [(switch_cpus[i], switch_cpus1[i]) for i in xrange(np)] + + m5.instantiate(root) + + if options.checkpoint_restore: + from os.path import isdir + from os import listdir + import re + + if not isdir(cptdir): + m5.panic("checkpoint dir %s does not exist!" % cptdir) + + dirs = listdir(cptdir) + expr = re.compile('cpt.([0-9]*)') + cpts = [] + for dir in dirs: + match = expr.match(dir) + if match: + cpts.append(match.group(1)) + + cpts.sort(lambda a,b: cmp(long(a), long(b))) + + cpt_num = options.checkpoint_restore + + if cpt_num > len(cpts): + m5.panic('Checkpoint %d not found' % cpt_num) + + m5.restoreCheckpoint(root, + "/".join([cptdir, "cpt.%s" % cpts[cpt_num - 1]])) + + if options.standard_switch: + exit_event = m5.simulate(10000) + + ## when you change to Timing (or Atomic), you halt the system given + ## as argument. When you are finished with the system changes + ## (including switchCpus), you must resume the system manually. + ## You DON'T need to resume after just switching CPUs if you haven't + ## changed anything on the system level. + + m5.changeToTiming(testsys) + m5.switchCpus(switch_cpu_list) + m5.resume(testsys) + + exit_event = m5.simulate(options.warmup) + m5.switchCpus(switch_cpu_list1) + + num_checkpoints = 0 + exit_cause = '' + + ## Checkpoints being taken via the command line at <when> and at subsequent + ## periods of <period>. Checkpoint instructions received from the benchmark running + ## are ignored and skipped in favor of command line checkpoint instructions. + if options.take_checkpoints: + [when, period] = options.take_checkpoints.split(",", 1) + when = int(when) + period = int(period) + + exit_event = m5.simulate(when) + while exit_event.getCause() == "checkpoint": + exit_event = m5.simulate(when - m5.curTick()) + + if exit_event.getCause() == "simulate() limit reached": + m5.checkpoint(root, "/".join([cptdir,"cpt.%d"])) + num_checkpoints += 1 + + sim_ticks = when + exit_cause = "maximum %d checkpoints dropped" % max_checkpoints + while num_checkpoints < max_checkpoints: + if (sim_ticks + period) > maxtick and maxtick != -1: + exit_event = m5.simulate(maxtick - sim_ticks) + exit_cause = exit_event.getCause() + break + else: + exit_event = m5.simulate(period) + sim_ticks += period + while exit_event.getCause() == "checkpoint": + exit_event = m5.simulate(sim_ticks - m5.curTick()) + if exit_event.getCause() == "simulate() limit reached": + m5.checkpoint(root, "/".join([cptdir,"cpt.%d"])) + num_checkpoints += 1 + + else: #no checkpoints being taken via this script + exit_event = m5.simulate(maxtick) + + while exit_event.getCause() == "checkpoint": + m5.checkpoint(root, "/".join([cptdir,"cpt.%d"])) + num_checkpoints += 1 + if num_checkpoints == max_checkpoints: + exit_cause = "maximum %d checkpoints dropped" % max_checkpoints + break + + if maxtick == -1: + exit_event = m5.simulate(maxtick) + else: + exit_event = m5.simulate(maxtick - m5.curTick()) + + exit_cause = exit_event.getCause() + + if exit_cause == '': + exit_cause = exit_event.getCause() + print 'Exiting @ cycle', m5.curTick(), 'because ', exit_cause + diff --git a/configs/example/fs.py b/configs/example/fs.py index 76b62a066..3ce463879 100644 --- a/configs/example/fs.py +++ b/configs/example/fs.py @@ -34,10 +34,16 @@ m5.AddToPath('../common') from FSConfig import * from SysPaths import * from Benchmarks import * +import Simulation +from Caches import * if not m5.build_env['FULL_SYSTEM']: m5.panic("This script requires full-system mode (ALPHA_FS).") +# Get paths we might need. It's expected this file is in m5/configs/example. +config_path = os.path.dirname(os.path.abspath(__file__)) +config_root = os.path.dirname(config_path) + parser = optparse.OptionParser() # Benchmark options @@ -48,40 +54,12 @@ parser.add_option("-b", "--benchmark", action="store", type="string", help="Specify the benchmark to run. Available benchmarks: %s"\ % DefinedBenchmarks) -# system options -parser.add_option("-d", "--detailed", action="store_true") -parser.add_option("-t", "--timing", action="store_true") -parser.add_option("-n", "--num_cpus", type="int", default=1) -parser.add_option("--caches", action="store_true") - -# Run duration options -parser.add_option("-m", "--maxtick", type="int") -parser.add_option("--maxtime", type="float") - # Metafile options parser.add_option("--etherdump", action="store", type="string", dest="etherdump", help="Specify the filename to dump a pcap capture of the" \ "ethernet traffic") -# Checkpointing options -###Note that performing checkpointing via python script files will override -###checkpoint instructions built into binaries. -parser.add_option("--take_checkpoints", action="store", type="string", - help="<M,N> will take checkpoint at cycle M and every N cycles \ - thereafter") -parser.add_option("--max_checkpoints", action="store", type="int", - help="the maximum number of checkpoints to drop", - default=5) -parser.add_option("--checkpoint_dir", action="store", type="string", - help="Place all checkpoints in this absolute directory") -parser.add_option("-r", "--checkpoint_restore", action="store", type="int", - help="restore from checkpoint <N>") - -# CPU Switching - default switch model goes from a checkpoint -# to a timing simple CPU with caches to warm up, then to detailed CPU for -# data measurement -parser.add_option("-s", "--standard_switch", action="store_true", - help="switch from one cpu mode to another") +execfile(os.path.join(config_root, "common", "Options.py")) (options, args) = parser.parse_args() @@ -89,14 +67,6 @@ if args: print "Error: script doesn't take any positional arguments" sys.exit(1) -class MyCache(BaseCache): - assoc = 2 - block_size = 64 - 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. DriveCPUClass = AtomicSimpleCPU @@ -134,8 +104,8 @@ np = options.num_cpus test_sys.cpu = [TestCPUClass(cpu_id=i) for i in xrange(np)] for i in xrange(np): if options.caches and not options.standard_switch: - test_sys.cpu[i].addPrivateSplitL1Caches(MyCache(size = '32kB'), - MyCache(size = '64kB')) + test_sys.cpu[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'), + L1Cache(size = '64kB')) test_sys.cpu[i].connectMemPorts(test_sys.membus) test_sys.cpu[i].mem = test_sys.physmem @@ -151,129 +121,4 @@ else: print "Error I don't know how to create more than 2 systems." sys.exit(1) -if options.standard_switch: - switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i)) for i in xrange(np)] - switch_cpus1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i)) for i in xrange(np)] - for i in xrange(np): - switch_cpus[i].system = test_sys - switch_cpus1[i].system = test_sys - switch_cpus[i].clock = TestCPUClass.clock - switch_cpus1[i].clock = TestCPUClass.clock - if options.caches: - switch_cpus[i].addPrivateSplitL1Caches(MyCache(size = '32kB'), - MyCache(size = '64kB')) - - switch_cpus[i].mem = test_sys.physmem - switch_cpus1[i].mem = test_sys.physmem - switch_cpus[i].connectMemPorts(test_sys.membus) - root.switch_cpus = switch_cpus - root.switch_cpus1 = switch_cpus1 - switch_cpu_list = [(test_sys.cpu[i], switch_cpus[i]) for i in xrange(np)] - switch_cpu_list1 = [(switch_cpus[i], switch_cpus1[i]) for i in xrange(np)] - -m5.instantiate(root) - -if options.checkpoint_dir: - cptdir = options.checkpoint_dir -else: - cptdir = os.getcwd() - -if options.checkpoint_restore: - from os.path import isdir - from os import listdir, getcwd - import re - - if not isdir(cptdir): - m5.panic("checkpoint dir %s does not exist!" % cptdir) - - dirs = listdir(cptdir) - expr = re.compile('cpt.([0-9]*)') - cpts = [] - for dir in dirs: - match = expr.match(dir) - if match: - cpts.append(match.group(1)) - - cpts.sort(lambda a,b: cmp(long(a), long(b))) - - if options.checkpoint_restore > len(cpts): - m5.panic('Checkpoint %d not found' % options.checkpoint_restore) - - m5.restoreCheckpoint(root, "/".join([cptdir, "cpt.%s" % cpts[options.checkpoint_restore - 1]])) - -if options.standard_switch: - exit_event = m5.simulate(1000) - ## when you change to Timing (or Atomic), you halt the system given - ## as argument. When you are finished with the system changes - ## (including switchCpus), you must resume the system manually. - ## You DON'T need to resume after just switching CPUs if you haven't - ## changed anything on the system level. - m5.changeToTiming(test_sys) - m5.switchCpus(switch_cpu_list) - m5.resume(test_sys) - - exit_event = m5.simulate(500000000000) - m5.switchCpus(switch_cpu_list1) - -if options.maxtick: - maxtick = options.maxtick -elif options.maxtime: - simtime = int(options.maxtime * root.clock.value) - print "simulating for: ", simtime - maxtick = simtime -else: - maxtick = -1 - -num_checkpoints = 0 - -exit_cause = '' - -if options.take_checkpoints: - [when, period] = options.take_checkpoints.split(",", 1) - when = int(when) - period = int(period) - - exit_event = m5.simulate(when) - while exit_event.getCause() == "checkpoint": - exit_event = m5.simulate(when - m5.curTick()) - - if exit_event.getCause() == "simulate() limit reached": - m5.checkpoint(root, cptdir + "cpt.%d") - num_checkpoints += 1 - - sim_ticks = when - exit_cause = "maximum %d checkpoints dropped" % options.max_checkpoints - while num_checkpoints < options.max_checkpoints: - if (sim_ticks + period) > maxtick and maxtick != -1: - exit_event = m5.simulate(maxtick - sim_ticks) - exit_cause = exit_event.getCause() - break - else: - exit_event = m5.simulate(period) - sim_ticks += period - while exit_event.getCause() == "checkpoint": - exit_event = m5.simulate(period - m5.curTick()) - if exit_event.getCause() == "simulate() limit reached": - m5.checkpoint(root, cptdir + "cpt.%d") - num_checkpoints += 1 - -else: #no checkpoints being taken via this script - exit_event = m5.simulate(maxtick) - - while exit_event.getCause() == "checkpoint": - m5.checkpoint(root, cptdir + "cpt.%d") - num_checkpoints += 1 - if num_checkpoints == options.max_checkpoints: - exit_cause = "maximum %d checkpoints dropped" % options.max_checkpoints - break - - if maxtick == -1: - exit_event = m5.simulate(maxtick) - else: - exit_event = m5.simulate(maxtick - m5.curTick()) - - exit_cause = exit_event.getCause() - -if exit_cause == '': - exit_cause = exit_event.getCause() -print 'Exiting @ cycle', m5.curTick(), 'because ', exit_cause +Simulation.run(options, root, test_sys) diff --git a/configs/example/se.py b/configs/example/se.py index 2e63e27da..83c2b1f8d 100644 --- a/configs/example/se.py +++ b/configs/example/se.py @@ -34,12 +34,23 @@ import m5 from m5.objects import * import os, optparse, sys m5.AddToPath('../common') +import Simulation +from Caches import * + +# Get paths we might need. It's expected this file is in m5/configs/example. +config_path = os.path.dirname(os.path.abspath(__file__)) +config_root = os.path.dirname(config_path) +m5_root = os.path.dirname(config_root) +print m5_root +print config_path +print config_root + parser = optparse.OptionParser() # Benchmark options parser.add_option("-c", "--cmd", - default="../../tests/test-progs/hello/bin/alpha/linux/hello", + default=os.path.join(m5_root, "tests/test-progs/hello/bin/alpha/linux/hello"), help="The binary to run in syscall emulation mode.") parser.add_option("-o", "--options", default="", help="The options to pass to the binary, use \" \" around the entire\ @@ -47,34 +58,7 @@ parser.add_option("-o", "--options", default="", parser.add_option("-i", "--input", default="", help="A file of input to give to the binary.") -# System options -parser.add_option("-d", "--detailed", action="store_true") -parser.add_option("-t", "--timing", action="store_true") -parser.add_option("--caches", action="store_true") - -# Run duration options -parser.add_option("-m", "--maxtick", type="int") -parser.add_option("--maxtime", type="float") - -#Checkpointing options -###Note that performing checkpointing via python script files will override -###checkpoint instructions built into binaries. -parser.add_option("--take_checkpoints", action="store", type="string", - help="<M,N> will take checkpoint at cycle M and every N cycles \ - thereafter") -parser.add_option("--max_checkpoints", action="store", type="int", - help="the maximum number of checkpoints to drop", - default=5) -parser.add_option("--checkpoint_dir", action="store", type="string", - help="Place all checkpoints in this absolute directory") -parser.add_option("-r", "--checkpoint_restore", action="store", type="int", - help="restore from checkpoint <N>") - -#CPU Switching - default switch model generally goes from a checkpoint -#to a timing simple CPU with caches to warm up, then to detailed CPU for -#data measurement -parser.add_option("-s", "--standard_switch", action="store_true", - help="switch from one cpu mode to another") +execfile(os.path.join(config_root, "common", "Options.py")) (options, args) = parser.parse_args() @@ -82,13 +66,6 @@ if args: print "Error: script doesn't take any positional arguments" sys.exit(1) -class MyCache(BaseCache): - assoc = 2 - block_size = 64 - latency = 1 - mshrs = 10 - tgts_per_mshr = 5 - process = LiveProcess() process.executable = options.cmd process.cmd = options.cmd + " " + options.options @@ -117,159 +94,33 @@ if options.detailed: if options.timing: - cpu = TimingSimpleCPU() + CPUClass = TimingSimpleCPU + test_mem_mode = 'timing' elif options.detailed: - cpu = DerivO3CPU() + CPUClass = DerivO3CPU + test_mem_mode = 'timing' else: - cpu = AtomicSimpleCPU() - -cpu.workload = process -cpu.cpu_id = 0 - -system = System(cpu = cpu, - physmem = PhysicalMemory(range=AddrRange("512MB")), - membus = Bus()) -system.physmem.port = system.membus.port -system.cpu.connectMemPorts(system.membus) -system.cpu.mem = system.physmem -system.cpu.clock = '2GHz' -if options.caches and not options.standard_switch: - system.cpu.addPrivateSplitL1Caches(MyCache(size = '32kB'), - MyCache(size = '64kB')) - -root = Root(system = system) - -if options.timing or options.detailed: - root.system.mem_mode = 'timing' - -if options.standard_switch: - switch_cpu = TimingSimpleCPU(defer_registration=True, cpu_id=1) - switch_cpu1 = DerivO3CPU(defer_registration=True, cpu_id=2) - switch_cpu.system = system - switch_cpu1.system = system - switch_cpu.clock = cpu.clock - switch_cpu1.clock = cpu.clock - if options.caches: - switch_cpu.addPrivateSplitL1Caches(MyCache(size = '32kB'), - MyCache(size = '64kB')) - - switch_cpu.workload = process - switch_cpu1.workload = process - switch_cpu.mem = system.physmem - switch_cpu1.mem = system.physmem - switch_cpu.connectMemPorts(system.membus) - root.switch_cpu = switch_cpu - root.switch_cpu1 = switch_cpu1 - switch_cpu_list = [(system.cpu, switch_cpu)] - switch_cpu_list1 = [(switch_cpu, switch_cpu1)] - -# instantiate configuration -m5.instantiate(root) - -if options.checkpoint_dir: - cptdir = options.checkpoint_dir -else: - cptdir = getcwd() - -if options.checkpoint_restore: - from os.path import isdir - from os import listdir, getcwd - import re + CPUClass = AtomicSimpleCPU + test_mem_mode = 'atomic' - if not isdir(cptdir): - m5.panic("checkpoint dir %s does not exist!" % cptdir) +CPUClass.clock = '2GHz' - dirs = listdir(cptdir) - expr = re.compile('cpt.([0-9]*)') - cpts = [] - for dir in dirs: - match = expr.match(dir) - if match: - cpts.append(match.group(1)) +np = options.num_cpus - cpts.sort(lambda a,b: cmp(long(a), long(b))) - - if options.checkpoint_restore > len(cpts): - m5.panic('Checkpoint %d not found' % options.checkpoint_restore) - - print "restoring checkpoint from ","/".join([cptdir, "cpt.%s" % cpts[options.checkpoint_restore - 1]]) - m5.restoreCheckpoint(root, "/".join([cptdir, "cpt.%s" % cpts[options.checkpoint_restore - 1]])) - -if options.standard_switch: - exit_event = m5.simulate(10000) - ## when you change to Timing (or Atomic), you halt the system given - ## as argument. When you are finished with the system changes - ## (including switchCpus), you must resume the system manually. - ## You DON'T need to resume after just switching CPUs if you haven't - ## changed anything on the system level. - m5.changeToTiming(system) - m5.switchCpus(switch_cpu_list) - m5.resume(system) - - exit_event = m5.simulate(500000000000) - m5.switchCpus(switch_cpu_list1) - -if options.maxtick: - maxtick = options.maxtick -elif options.maxtime: - simtime = int(options.maxtime * root.clock.value) - print "simulating for: ", simtime - maxtick = simtime -else: - maxtick = -1 - -num_checkpoints = 0 - -exit_cause = '' - -if options.take_checkpoints: - [when, period] = options.take_checkpoints.split(",", 1) - when = int(when) - period = int(period) - - exit_event = m5.simulate(when) - while exit_event.getCause() == "checkpoint": - exit_event = m5.simulate(when - m5.curTick()) - - if exit_event.getCause() == "simulate() limit reached": - m5.checkpoint(root, cptdir + "cpt.%d") - num_checkpoints += 1 - - sim_ticks = when - exit_cause = "maximum %d checkpoints dropped" % options.max_checkpoints - while num_checkpoints < options.max_checkpoints: - if (sim_ticks + period) > maxtick and maxtick != -1: - exit_event = m5.simulate(maxtick - sim_ticks) - exit_cause = exit_event.getCause() - break - else: - exit_event = m5.simulate(period) - sim_ticks += period - while exit_event.getCause() == "checkpoint": - exit_event = m5.simulate(period - m5.curTick()) - if exit_event.getCause() == "simulate() limit reached": - m5.checkpoint(root, cptdir + "cpt.%d") - num_checkpoints += 1 - -else: #no checkpoints being taken via this script - exit_event = m5.simulate(maxtick) - - while exit_event.getCause() == "checkpoint": - m5.checkpoint(root, cptdir + "cpt.%d") - num_checkpoints += 1 - if num_checkpoints == options.max_checkpoints: - exit_cause = "maximum %d checkpoints dropped" % options.max_checkpoints - break - - if maxtick == -1: - exit_event = m5.simulate(maxtick) - else: - exit_event = m5.simulate(maxtick - m5.curTick()) +system = System(cpu = [CPUClass(cpu_id=i) for i in xrange(np)], + physmem = PhysicalMemory(range=AddrRange("512MB")), + membus = Bus(), mem_mode = test_mem_mode) - exit_cause = exit_event.getCause() +system.physmem.port = system.membus.port -if exit_cause == '': - exit_cause = exit_event.getCause() -print 'Exiting @ cycle', m5.curTick(), 'because ', exit_cause +for i in xrange(np): + if options.caches and not options.standard_switch: + system.cpu[i].addPrivateSplitL1Caches(L1Cache(size = '32kB'), + L1Cache(size = '64kB')) + system.cpu[i].connectMemPorts(system.membus) + system.cpu[i].mem = system.physmem + system.cpu[i].workload = process +root = Root(system = system) +Simulation.run(options, root, system) diff --git a/src/SConscript b/src/SConscript index 9f88bbeea..28f39bc29 100644 --- a/src/SConscript +++ b/src/SConscript @@ -220,7 +220,6 @@ full_system_sources = Split(''' dev/etherlink.cc dev/etherpkt.cc dev/ethertap.cc - dev/i8254xGBe.cc dev/ide_ctrl.cc dev/ide_disk.cc dev/io_device.cc @@ -253,6 +252,7 @@ full_system_sources = Split(''' sim/pseudo_inst.cc ''') #dev/sinic.cc + #dev/i8254xGBe.cc if env['TARGET_ISA'] == 'alpha': diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index b235398f1..6504c7b32 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -1316,7 +1316,7 @@ class ControlRegOperand(Operand): def makeWrite(self): if (self.ctype == 'float' or self.ctype == 'double'): error(0, 'Attempt to write control register as FP') - wb = 'xc->setMiscReg(%s, %s);\n' % (self.reg_spec, self.base_name) + wb = 'xc->setMiscRegWithEffect(%s, %s);\n' % (self.reg_spec, self.base_name) wb += 'if (traceData) { traceData->setData(%s); }' % \ self.base_name return wb diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index 7b7765935..2c8da44c5 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -29,15 +29,22 @@ * Kevin Lim */ +#include <algorithm> + #include "arch/sparc/faults.hh" -#include "cpu/thread_context.hh" -#include "cpu/base.hh" +#include "arch/sparc/isa_traits.hh" +#include "arch/sparc/process.hh" +#include "base/bitfield.hh" #include "base/trace.hh" +#include "cpu/base.hh" +#include "cpu/thread_context.hh" #if !FULL_SYSTEM -#include "sim/process.hh" #include "mem/page_table.hh" +#include "sim/process.hh" #endif +using namespace std; + namespace SparcISA { @@ -229,6 +236,121 @@ FaultPriority PageTableFault::_priority = 0; FaultStat PageTableFault::_count; #endif +/** + * This sets everything up for a normal trap except for actually jumping to + * the handler. It will need to be expanded to include the state machine in + * the manual. Right now it assumes that traps will always be to the + * privileged level. + */ + +void doNormalFault(ThreadContext *tc, TrapType tt) +{ + uint64_t TL = tc->readMiscReg(MISCREG_TL); + uint64_t TSTATE = tc->readMiscReg(MISCREG_TSTATE); + uint64_t PSTATE = tc->readMiscReg(MISCREG_PSTATE); + uint64_t HPSTATE = tc->readMiscReg(MISCREG_HPSTATE); + uint64_t CCR = tc->readMiscReg(MISCREG_CCR); + uint64_t ASI = tc->readMiscReg(MISCREG_ASI); + uint64_t CWP = tc->readMiscReg(MISCREG_CWP); + uint64_t CANSAVE = tc->readMiscReg(MISCREG_CANSAVE); + uint64_t GL = tc->readMiscReg(MISCREG_GL); + uint64_t PC = tc->readPC(); + uint64_t NPC = tc->readNextPC(); + + //Increment the trap level + TL++; + tc->setMiscReg(MISCREG_TL, TL); + + //Save off state + + //set TSTATE.gl to gl + replaceBits(TSTATE, 42, 40, GL); + //set TSTATE.ccr to ccr + replaceBits(TSTATE, 39, 32, CCR); + //set TSTATE.asi to asi + replaceBits(TSTATE, 31, 24, ASI); + //set TSTATE.pstate to pstate + replaceBits(TSTATE, 20, 8, PSTATE); + //set TSTATE.cwp to cwp + replaceBits(TSTATE, 4, 0, CWP); + + //Write back TSTATE + tc->setMiscReg(MISCREG_TSTATE, TSTATE); + + //set TPC to PC + tc->setMiscReg(MISCREG_TPC, PC); + //set TNPC to NPC + tc->setMiscReg(MISCREG_TNPC, NPC); + + //set HTSTATE.hpstate to hpstate + tc->setMiscReg(MISCREG_HTSTATE, HPSTATE); + + //TT = trap type; + tc->setMiscReg(MISCREG_TT, tt); + + //Update the global register level + if(1/*We're delivering the trap in priveleged mode*/) + tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxGL)); + else + tc->setMiscReg(MISCREG_GL, max<int>(GL+1, MaxPGL)); + + //PSTATE.mm is unchanged + //PSTATE.pef = whether or not an fpu is present + //XXX We'll say there's one present, even though there aren't + //implementations for a decent number of the instructions + PSTATE |= (1 << 4); + //PSTATE.am = 0 + PSTATE &= ~(1 << 3); + if(1/*We're delivering the trap in priveleged mode*/) + { + //PSTATE.priv = 1 + PSTATE |= (1 << 2); + //PSTATE.cle = PSTATE.tle + replaceBits(PSTATE, 9, 9, PSTATE >> 8); + } + else + { + //PSTATE.priv = 0 + PSTATE &= ~(1 << 2); + //PSTATE.cle = 0 + PSTATE &= ~(1 << 9); + } + //PSTATE.ie = 0 + PSTATE &= ~(1 << 1); + //PSTATE.tle is unchanged + //PSTATE.tct = 0 + //XXX Where exactly is this field? + tc->setMiscReg(MISCREG_PSTATE, PSTATE); + + if(0/*We're delivering the trap in hyperprivileged mode*/) + { + //HPSTATE.red = 0 + HPSTATE &= ~(1 << 5); + //HPSTATE.hpriv = 1 + HPSTATE |= (1 << 2); + //HPSTATE.ibe = 0 + HPSTATE &= ~(1 << 10); + //HPSTATE.tlz is unchanged + tc->setMiscReg(MISCREG_HPSTATE, HPSTATE); + } + + bool changedCWP = true; + if(tt == 0x24) + CWP++; + else if(0x80 <= tt && tt <= 0xbf) + CWP += (CANSAVE + 2); + else if(0xc0 <= tt && tt <= 0xff) + CWP--; + else + changedCWP = false; + + if(changedCWP) + { + CWP = (CWP + NWindows) % NWindows; + tc->setMiscRegWithEffect(MISCREG_CWP, CWP); + } +} + #if FULL_SYSTEM void SparcFault::invoke(ThreadContext * tc) @@ -263,6 +385,40 @@ void TrapInstruction::invoke(ThreadContext * tc) // Should be handled in ISA. } +void SpillNNormal::invoke(ThreadContext *tc) +{ + doNormalFault(tc, trapType()); + + Process *p = tc->getProcessPtr(); + + //This will only work in faults from a SparcLiveProcess + SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); + assert(lp); + + //Then adjust the PC and NPC + Addr spillStart = lp->readSpillStart(); + tc->setPC(spillStart); + tc->setNextPC(spillStart + sizeof(MachInst)); + tc->setNextNPC(spillStart + 2*sizeof(MachInst)); +} + +void FillNNormal::invoke(ThreadContext *tc) +{ + doNormalFault(tc, trapType()); + + Process * p = tc->getProcessPtr(); + + //This will only work in faults from a SparcLiveProcess + SparcLiveProcess *lp = dynamic_cast<SparcLiveProcess *>(p); + assert(lp); + + //The adjust the PC and NPC + Addr fillStart = lp->readFillStart(); + tc->setPC(fillStart); + tc->setNextPC(fillStart + sizeof(MachInst)); + tc->setNextNPC(fillStart + 2*sizeof(MachInst)); +} + void PageTableFault::invoke(ThreadContext *tc) { Process *p = tc->getProcessPtr(); @@ -282,6 +438,7 @@ void PageTableFault::invoke(ThreadContext *tc) FaultBase::invoke(tc); } } + #endif } // namespace SparcISA diff --git a/src/arch/sparc/faults.hh b/src/arch/sparc/faults.hh index b279f4911..394a06294 100644 --- a/src/arch/sparc/faults.hh +++ b/src/arch/sparc/faults.hh @@ -39,8 +39,8 @@ namespace SparcISA { -typedef const uint32_t TrapType; -typedef const uint32_t FaultPriority; +typedef uint32_t TrapType; +typedef uint32_t FaultPriority; class SparcFault : public FaultBase { @@ -547,6 +547,7 @@ class SpillNNormal : public EnumeratedFault FaultName name() {return _name;} FaultPriority priority() {return _priority;} FaultStat & countStat() {return _count;} + void invoke(ThreadContext * tc); }; class SpillNOther : public EnumeratedFault @@ -577,6 +578,7 @@ class FillNNormal : public EnumeratedFault FaultName name() {return _name;} FaultPriority priority() {return _priority;} FaultStat & countStat() {return _count;} + void invoke(ThreadContext * tc); }; class FillNOther : public EnumeratedFault diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index bef62f6ae..164f194dd 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -75,8 +75,14 @@ IntRegFile::IntRegFile() IntReg IntRegFile::readReg(int intReg) { - IntReg val = - regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask]; + IntReg val; + if(intReg < NumRegularIntRegs) + val = regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask]; + else if((intReg -= NumRegularIntRegs) < NumMicroIntRegs) + val = microRegs[intReg]; + else + panic("Tried to read non-existant integer register\n"); + DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val); return val; } @@ -86,7 +92,12 @@ Fault IntRegFile::setReg(int intReg, const IntReg &val) if(intReg) { DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); - regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; + if(intReg < NumRegularIntRegs) + regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; + else if((intReg -= NumRegularIntRegs) < NumMicroIntRegs) + microRegs[intReg] = val; + else + panic("Tried to set non-existant integer register\n"); } return NoFault; } @@ -123,6 +134,7 @@ void IntRegFile::serialize(std::ostream &os) SERIALIZE_ARRAY(regGlobals[x], RegsPerFrame); for(x = 0; x < 2 * NWindows; x++) SERIALIZE_ARRAY(regSegments[x], RegsPerFrame); + SERIALIZE_ARRAY(microRegs, NumMicroIntRegs); } void IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) @@ -132,4 +144,5 @@ void IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_ARRAY(regGlobals[x], RegsPerFrame); for(unsigned int x = 0; x < 2 * NWindows; x++) UNSERIALIZE_ARRAY(regSegments[x], RegsPerFrame); + UNSERIALIZE_ARRAY(microRegs, NumMicroIntRegs); } diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh index d305c753b..223e3b34c 100644 --- a/src/arch/sparc/intregfile.hh +++ b/src/arch/sparc/intregfile.hh @@ -65,6 +65,7 @@ namespace SparcISA IntReg regGlobals[MaxGL][RegsPerFrame]; IntReg regSegments[2 * NWindows][RegsPerFrame]; + IntReg microRegs[NumMicroIntRegs]; enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames}; diff --git a/src/arch/sparc/isa/bitfields.isa b/src/arch/sparc/isa/bitfields.isa index 372f5c4ef..7e884866c 100644 --- a/src/arch/sparc/isa/bitfields.isa +++ b/src/arch/sparc/isa/bitfields.isa @@ -50,7 +50,7 @@ def bitfield D16LO <13:0>; def bitfield DISP19 <18:0>; def bitfield DISP22 <21:0>; def bitfield DISP30 <29:0>; -def bitfield FCN <29:26>; +def bitfield FCN <29:25>; def bitfield I <13>; def bitfield IMM_ASI <12:5>; def bitfield IMM22 <21:0>; diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index 45d3616d9..a64ff09bb 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -357,13 +357,9 @@ decode OP default Unknown::unknown() }}); } 0x29: HPriv::rdhpr({{ - // XXX Need to protect with format that traps non-priv/priv - // access Rd = xc->readMiscRegWithEffect(RS1 + HprStart, fault); }}); 0x2A: Priv::rdpr({{ - // XXX Need to protect with format that traps non-priv - // access Rd = xc->readMiscRegWithEffect(RS1 + PrStart, fault); }}); 0x2B: BasicOperate::flushw({{ @@ -425,18 +421,34 @@ decode OP default Unknown::unknown() xc->setMiscRegWithEffect(RD + AsrStart, Rs1 ^ Rs2_or_imm13); }}); 0x31: decode FCN { - 0x0: BasicOperate::saved({{/*Boogy Boogy*/}}); - 0x1: BasicOperate::restored({{/*Boogy Boogy*/}}); + 0x0: Priv::saved({{ + assert(Cansave < NWindows - 2); + assert(Otherwin || Canrestore); + Cansave = Cansave + 1; + if(Otherwin == 0) + Canrestore = Canrestore - 1; + else + Otherwin = Otherwin - 1; + }}); + 0x1: BasicOperate::restored({{ + assert(Cansave || Otherwin); + assert(Canrestore < NWindows - 2); + Canrestore = Canrestore + 1; + if(Otherwin == 0) + Cansave = Cansave - 1; + else + Otherwin = Otherwin - 1; + }}); } 0x32: Priv::wrpr({{ // XXX Need to protect with format that traps non-priv // access - fault = xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13); + xc->setMiscRegWithEffect(RD + PrStart, Rs1 ^ Rs2_or_imm13); }}); 0x33: HPriv::wrhpr({{ // XXX Need to protect with format that traps non-priv/priv // access - fault = xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13); + xc->setMiscRegWithEffect(RD + HprStart, Rs1 ^ Rs2_or_imm13); }}); 0x34: decode OPF{ format BasicOperate{ @@ -684,10 +696,6 @@ decode OP default Unknown::unknown() NNPC = target; if(fault == NoFault) { - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one - Cwp = (Cwp - 1 + NWindows) % NWindows; if(Canrestore == 0) { if(Otherwin) @@ -697,14 +705,17 @@ decode OP default Unknown::unknown() } else { - Rd = Rs1 + Rs2_or_imm13; + //CWP should be set directly so that it always happens + //Also, this will allow writing to the new window and + //reading from the old one + Cwp = (Cwp - 1 + NWindows) % NWindows; Cansave = Cansave + 1; Canrestore = Canrestore - 1; + //This is here to make sure the CWP is written + //no matter what. This ensures that the results + //are written in the new window as well. + xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } }}); 0x3A: decode CC @@ -747,11 +758,11 @@ decode OP default Unknown::unknown() fault = new SpillNOther(Wstate<5:3>); else fault = new SpillNNormal(Wstate<2:0>); - Cwp = (Cwp + 2) % NWindows; + //Cwp = (Cwp + 2) % NWindows; } else if(Cleanwin - Canrestore == 0) { - Cwp = (Cwp + 1) % NWindows; + //Cwp = (Cwp + 1) % NWindows; fault = new CleanWindow; } else @@ -760,17 +771,13 @@ decode OP default Unknown::unknown() Rd = Rs1 + Rs2_or_imm13; Cansave = Cansave - 1; Canrestore = Canrestore + 1; + //This is here to make sure the CWP is written + //no matter what. This ensures that the results + //are written in the new window as well. + xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); }}); 0x3D: restore({{ - //CWP should be set directly so that it always happens - //Also, this will allow writing to the new window and - //reading from the old one - Cwp = (Cwp - 1 + NWindows) % NWindows; if(Canrestore == 0) { if(Otherwin) @@ -780,14 +787,18 @@ decode OP default Unknown::unknown() } else { + //CWP should be set directly so that it always happens + //Also, this will allow writing to the new window and + //reading from the old one + Cwp = (Cwp - 1 + NWindows) % NWindows; Rd = Rs1 + Rs2_or_imm13; Cansave = Cansave + 1; Canrestore = Canrestore - 1; + //This is here to make sure the CWP is written + //no matter what. This ensures that the results + //are written in the new window as well. + xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); } - //This is here to make sure the CWP is written - //no matter what. This ensures that the results - //are written in the new window as well. - xc->setMiscRegWithEffect(MISCREG_CWP, Cwp); }}); 0x3E: decode FCN { 0x0: Priv::done({{ @@ -812,7 +823,7 @@ decode OP default Unknown::unknown() Ccr = Tstate<39:32>; Gl = Tstate<42:40>; NPC = Tpc; - NNPC = Tnpc + 4; + NNPC = Tnpc; Tl = Tl - 1; }}); } @@ -840,16 +851,15 @@ decode OP default Unknown::unknown() 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.ub; - Mem.ub = 0xFF; - }}); } + 0x0D: LoadStore::ldstub( + {{Rd = Mem.ub;}}, + {{Mem.ub = 0xFF;}}); 0x0E: Store::stx({{Mem.udw = Rd}}); 0x0F: LoadStore::swap( - {{*temp = Rd.uw; + {{uReg0 = Rd.uw; Rd.uw = Mem.uw;}}, - {{Mem.uw = *temp;}}); + {{Mem.uw = uReg0;}}); format Load { 0x10: lduwa({{Rd = Mem.uw;}}); 0x11: lduba({{Rd = Mem.ub;}}); @@ -877,9 +887,9 @@ decode OP default Unknown::unknown() {{Mem.ub = 0xFF}}); 0x1E: Store::stxa({{Mem.udw = Rd}}); 0x1F: LoadStore::swapa( - {{*temp = Rd.uw; + {{uReg0 = Rd.uw; Rd.uw = Mem.uw;}}, - {{Mem.uw = *temp;}}); + {{Mem.uw = uReg0;}}); format Trap { 0x20: Load::ldf({{Frd.uw = Mem.uw;}}); 0x21: decode X { @@ -1062,19 +1072,21 @@ decode OP default Unknown::unknown() {{fault = new DataAccessException;}}); } } - 0x3C: Cas::casa({{ - uint64_t val = Mem.uw; - if(Rs2.uw == val) + 0x3C: Cas::casa( + {{uReg0 = Mem.uw;}}, + {{if(Rs2.uw == uReg0) Mem.uw = Rd.uw; - Rd.uw = val; - }}); + else + storeCond = false; + Rd.uw = uReg0;}}); 0x3D: Nop::prefetcha({{ }}); - 0x3E: Cas::casxa({{ - uint64_t val = Mem.udw; - if(Rs2 == val) + 0x3E: Cas::casxa( + {{uReg0 = Mem.udw;}}, + {{if(Rs2 == uReg0) Mem.udw = Rd; - Rd = val; - }}); + else + storeCond = false; + Rd = uReg0;}}); } } } diff --git a/src/arch/sparc/isa/formats/formats.isa b/src/arch/sparc/isa/formats/formats.isa index 5b81a1ab1..8125e6349 100644 --- a/src/arch/sparc/isa/formats/formats.isa +++ b/src/arch/sparc/isa/formats/formats.isa @@ -42,9 +42,6 @@ //Include the memory formats ##include "mem/mem.isa" -//Include the compare and swap format -##include "cas.isa" - //Include the trap format ##include "trap.isa" diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa index c13194d0f..cb6c2f161 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -32,100 +32,6 @@ // Mem instructions // -output header {{ - /** - * Base class for memory operations. - */ - class Mem : public SparcStaticInst - { - protected: - - // Constructor - Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : - SparcStaticInst(mnem, _machInst, __opClass) - { - } - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - }; - - /** - * Class for memory operations which use an immediate offset. - */ - class MemImm : public Mem - { - protected: - - // Constructor - MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : - Mem(mnem, _machInst, __opClass), imm(sext<13>(SIMM13)) - {} - - std::string generateDisassembly(Addr pc, - const SymbolTable *symtab) const; - - const int32_t imm; - }; -}}; - -output decoder {{ - std::string Mem::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 MemImm::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]); - 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 MemDeclare {{ /** * Static instruction class for "%(mnemonic)s". @@ -156,7 +62,7 @@ let {{ 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 = doSplitExecute(code, addrCalcReg, addrCalcImm, execute, + exec_output = doDualSplitExecute(code, addrCalcReg, addrCalcImm, execute, faultCode, name, name + "Imm", Name, Name + "Imm", opt_flags) return (header_output, decoder_output, exec_output, decode_block) }}; diff --git a/src/arch/sparc/isa/formats/mem/blockmem.isa b/src/arch/sparc/isa/formats/mem/blockmem.isa index 93ad1b2b8..8b4aca473 100644 --- a/src/arch/sparc/isa/formats/mem/blockmem.isa +++ b/src/arch/sparc/isa/formats/mem/blockmem.isa @@ -56,14 +56,14 @@ output header {{ {} }; - class BlockMemMicro : public SparcDelayedMicroInst + class BlockMemMicro : public SparcMicroInst { protected: // Constructor BlockMemMicro(const char *mnem, ExtMachInst _machInst, OpClass __opClass, int8_t _offset) : - SparcDelayedMicroInst(mnem, _machInst, __opClass), + SparcMicroInst(mnem, _machInst, __opClass), offset(_offset) {} @@ -290,6 +290,8 @@ let {{ flag_code = '' if (microPc == 7): flag_code = "flags[IsLastMicroOp] = true;" + else: + flag_code = "flags[IsDelayedCommit] = true;" pcedCode = matcher.sub("Frd_%d" % microPc, code) iop = InstObjParams(name, Name, 'BlockMem', pcedCode, opt_flags, {"ea_code": addrCalcReg, @@ -301,7 +303,7 @@ let {{ "set_flags": flag_code}) decoder_output += BlockMemMicroConstructor.subst(iop) decoder_output += BlockMemMicroConstructor.subst(iop_imm) - exec_output += doSplitExecute( + exec_output += doDualSplitExecute( pcedCode, addrCalcReg, addrCalcImm, execute, faultCode, makeMicroName(name, microPc), makeMicroName(name + "Imm", microPc), diff --git a/src/arch/sparc/isa/formats/mem/mem.isa b/src/arch/sparc/isa/formats/mem/mem.isa index 20a22c45d..fedece2b8 100644 --- a/src/arch/sparc/isa/formats/mem/mem.isa +++ b/src/arch/sparc/isa/formats/mem/mem.isa @@ -41,5 +41,5 @@ //Include the block memory format ##include "blockmem.isa" -//Include the load/store memory format +//Include the load/store and cas 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 index 241a25d17..b9f7fde2d 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -33,6 +33,100 @@ // Mem utility templates and functions // +output header {{ + /** + * Base class for memory operations. + */ + class Mem : public SparcStaticInst + { + protected: + + // Constructor + Mem(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : + SparcStaticInst(mnem, _machInst, __opClass) + { + } + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + }; + + /** + * Class for memory operations which use an immediate offset. + */ + class MemImm : public Mem + { + protected: + + // Constructor + MemImm(const char *mnem, ExtMachInst _machInst, OpClass __opClass) : + Mem(mnem, _machInst, __opClass), imm(sext<13>(SIMM13)) + {} + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + + const int32_t imm; + }; +}}; + +output decoder {{ + std::string Mem::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 MemImm::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]); + 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(); + } +}}; + //This template provides the execute functions for a load def template LoadExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, @@ -102,6 +196,9 @@ def template StoreExecute {{ { Fault fault = NoFault; uint64_t write_result = 0; + //This is to support the conditional store in cas instructions. + //It should be optomized out in all the others + bool storeCond = true; Addr EA; %(op_decl)s; %(op_rd)s; @@ -112,7 +209,7 @@ def template StoreExecute {{ { %(code)s; } - if(fault == NoFault) + if(storeCond && fault == NoFault) { fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); } @@ -130,6 +227,7 @@ def template StoreExecute {{ { Fault fault = NoFault; uint64_t write_result = 0; + bool storeCond = true; Addr EA; %(op_decl)s; %(op_rd)s; @@ -140,7 +238,7 @@ def template StoreExecute {{ { %(code)s; } - if(fault == NoFault) + if(storeCond && fault == NoFault) { fault = xc->write((uint%(mem_acc_size)s_t)Mem, EA, 0, &write_result); } @@ -204,23 +302,29 @@ let {{ //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, + def doSplitExecute(code, eaCode, execute, + faultCode, name, Name, opt_flags): + codeIop = InstObjParams(name, Name, '', code, opt_flags) + 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) + return execute.subst(iop) + + + def doDualSplitExecute(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) + executeCode += doSplitExecute(code, eaCode, + execute, faultCode, name, Name, opt_flags) return executeCode }}; diff --git a/src/arch/sparc/isa/formats/priv.isa b/src/arch/sparc/isa/formats/priv.isa index 2a38422a7..04c67d332 100644 --- a/src/arch/sparc/isa/formats/priv.isa +++ b/src/arch/sparc/isa/formats/priv.isa @@ -121,15 +121,14 @@ let {{ // Primary format for integer operate instructions: def format Priv(code, *opt_flags) {{ - checkCode = '''((xc->readMiscReg(PrStart + MISCREG_PSTATE))<2:2>) || - ((xc->readMiscReg(HprStart + MISCREG_HPSTATE))<2:2>)''' + checkCode = "!(Pstate<2:2> || Hpstate<2:2>)" (header_output, decoder_output, exec_output, decode_block) = doPrivFormat(code, checkCode, name, Name, opt_flags + ('IprAccessOp',)) }}; def format HPriv(code, *opt_flags) {{ - checkCode = "((xc->readMiscReg(HprStart + MISCREG_HPSTATE))<2:2>)" + checkCode = "!Hpstate<2:2>" (header_output, decoder_output, exec_output, decode_block) = doPrivFormat(code, checkCode, name, Name, opt_flags + ('IprAccessOp',)) diff --git a/src/arch/sparc/isa/operands.isa b/src/arch/sparc/isa/operands.isa index b8b75170b..80b499b91 100644 --- a/src/arch/sparc/isa/operands.isa +++ b/src/arch/sparc/isa/operands.isa @@ -61,6 +61,7 @@ def operands {{ 'RdHigh': ('IntReg', 'udw', 'RD | 1', 'IsInteger', 3), 'Rs1': ('IntReg', 'udw', 'RS1', 'IsInteger', 4), 'Rs2': ('IntReg', 'udw', 'RS2', 'IsInteger', 5), + 'uReg0': ('IntReg', 'udw', 'NumRegularIntRegs+0', 'IsInteger', 6), '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. @@ -95,18 +96,19 @@ def operands {{ 'Tnpc': ('ControlReg', 'udw', 'MISCREG_TNPC', None, 44), 'Tstate': ('ControlReg', 'udw', 'MISCREG_TSTATE', None, 45), 'Pstate': ('ControlReg', 'udw', 'MISCREG_PSTATE', None, 46), - 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 47), + 'Hpstate': ('ControlReg', 'udw', 'MISCREG_HPSTATE', None, 47), + 'Tl': ('ControlReg', 'udw', 'MISCREG_TL', None, 48), - 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 48), - 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 49), - 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 50), - 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 51), - 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 52), - 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 53), - 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 54), + 'Cwp': ('ControlReg', 'udw', 'MISCREG_CWP', None, 49), + 'Cansave': ('ControlReg', 'udw', 'MISCREG_CANSAVE', None, 50), + 'Canrestore': ('ControlReg', 'udw', 'MISCREG_CANRESTORE', None, 51), + 'Cleanwin': ('ControlReg', 'udw', 'MISCREG_CLEANWIN', None, 52), + 'Otherwin': ('ControlReg', 'udw', 'MISCREG_OTHERWIN', None, 53), + 'Wstate': ('ControlReg', 'udw', 'MISCREG_WSTATE', None, 54), + 'Gl': ('ControlReg', 'udw', 'MISCREG_GL', None, 55), - 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 55), - 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 56), + 'Fsr': ('ControlReg', 'udw', 'MISCREG_FSR', None, 56), + 'Gsr': ('ControlReg', 'udw', 'MISCREG_GSR', None, 57), # Mem gets a large number so it's always last 'Mem': ('Mem', 'udw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 100) diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 6d5aa4251..46a0ebbfb 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -57,14 +57,17 @@ namespace SparcISA //This makes sure the big endian versions of certain functions are used. using namespace BigEndianGuest; - // Alpha Does NOT have a delay slot + // SPARC has a delay slot #define ISA_HAS_DELAY_SLOT 1 - //TODO this needs to be a SPARC Noop - // Alpha UNOP (ldq_u r31,0(r0)) - const MachInst NoopMachInst = 0x2ffe0000; + // SPARC NOP (sethi %(hi(0), g0) + const MachInst NoopMachInst = 0x01000000; - const int NumIntRegs = 32; + const int NumRegularIntRegs = 32; + const int NumMicroIntRegs = 1; + const int NumIntRegs = + NumRegularIntRegs + + NumMicroIntRegs; const int NumFloatRegs = 64; const int NumMiscRegs = 40; @@ -87,7 +90,7 @@ namespace SparcISA const int MaxPGL = 2; // NWINDOWS - number of register windows, can be 3 to 32 - const int NWindows = 32; + const int NWindows = 8; // semantically meaningful register indices const int ZeroReg = 0; // architecturally meaningful diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 8041e45c0..bf4572878 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -202,282 +202,164 @@ MiscReg MiscRegFile::readReg(int miscReg) } } -MiscReg MiscRegFile::readRegWithEffect(int miscReg, - Fault &fault, ThreadContext * tc) +MiscReg MiscRegFile::readRegWithEffect(int miscReg, ThreadContext * tc) { - fault = NoFault; switch (miscReg) { - case MISCREG_Y: - case MISCREG_CCR: - case MISCREG_ASI: - return readReg(miscReg); - case MISCREG_TICK: case MISCREG_PRIVTICK: - // Check for reading privilege - if (tickFields.npt && !isNonPriv()) { - fault = new PrivilegedAction; - return 0; - } return tc->getCpuPtr()->curCycle() - tickFields.counter | tickFields.npt << 63; - case MISCREG_PC: - return tc->readPC(); case MISCREG_FPRS: - fault = new UnimpFault("FPU not implemented\n"); - return 0; + panic("FPU not implemented\n"); case MISCREG_PCR: - fault = new UnimpFault("Performance Instrumentation not impl\n"); - return 0; case MISCREG_PIC: - fault = new UnimpFault("Performance Instrumentation not impl\n"); - return 0; - case MISCREG_GSR: - return readReg(miscReg); - - /** Privilged Registers */ - case MISCREG_TPC: - case MISCREG_TNPC: - case MISCREG_TSTATE: - case MISCREG_TT: - if (tl == 0) { - fault = new IllegalInstruction; - return 0; - } // NOTE THE FALL THROUGH! - case MISCREG_PSTATE: - case MISCREG_TL: - return readReg(miscReg); - - case MISCREG_TBA: - return readReg(miscReg) & ULL(~0x7FFF); - - case MISCREG_PIL: - - case MISCREG_CWP: - case MISCREG_CANSAVE: - case MISCREG_CANRESTORE: - case MISCREG_CLEANWIN: - case MISCREG_OTHERWIN: - case MISCREG_WSTATE: - case MISCREG_GL: - return readReg(miscReg); + panic("Performance Instrumentation not impl\n"); /** Floating Point Status Register */ case MISCREG_FSR: panic("Floating Point not implemented\n"); - default: -#if FULL_SYSTEM - return readFSRegWithEffect(miscReg, fault, tc); -#else - fault = new IllegalInstruction; - return 0; -#endif } + return readReg(miscReg); } -Fault MiscRegFile::setReg(int miscReg, const MiscReg &val) +void MiscRegFile::setReg(int miscReg, const MiscReg &val) { switch (miscReg) { case MISCREG_Y: y = val; - return NoFault; + break; case MISCREG_CCR: ccr = val; - return NoFault; + break; case MISCREG_ASI: asi = val; - return NoFault; + break; case MISCREG_FPRS: fprs = val; - return NoFault; + break; case MISCREG_TICK: - tick = val; - return NoFault; + tick = val; + break; case MISCREG_PCR: case MISCREG_PIC: panic("ASR number %d not implemented\n", miscReg - AsrStart); case MISCREG_GSR: gsr = val; + break; case MISCREG_SOFTINT: - softint = val; - return NoFault; + softint = val; + break; case MISCREG_TICK_CMPR: - tick_cmpr = val; - return NoFault; + tick_cmpr = val; + break; case MISCREG_STICK: - stick = val; - return NoFault; + stick = val; + break; case MISCREG_STICK_CMPR: - stick_cmpr = val; - return NoFault; + stick_cmpr = val; + break; /** Privilged Registers */ case MISCREG_TPC: tpc[tl-1] = val; - return NoFault; + break; case MISCREG_TNPC: tnpc[tl-1] = val; - return NoFault; + break; case MISCREG_TSTATE: tstate[tl-1] = val; - return NoFault; + break; case MISCREG_TT: tt[tl-1] = val; - return NoFault; + break; case MISCREG_PRIVTICK: panic("Priviliged access to tick regesiters not implemented\n"); case MISCREG_TBA: - tba = val; - return NoFault; + // clear lower 7 bits on writes. + tba = val & ULL(~0x7FFF); + break; case MISCREG_PSTATE: pstate = val; - return NoFault; + break; case MISCREG_TL: tl = val; - return NoFault; + break; case MISCREG_PIL: pil = val; - return NoFault; + break; case MISCREG_CWP: cwp = val; - return NoFault; + break; case MISCREG_CANSAVE: cansave = val; - return NoFault; + break; case MISCREG_CANRESTORE: canrestore = val; - return NoFault; + break; case MISCREG_CLEANWIN: cleanwin = val; - return NoFault; + break; case MISCREG_OTHERWIN: otherwin = val; - return NoFault; + break; case MISCREG_WSTATE: wstate = val; - return NoFault; + break; case MISCREG_GL: gl = val; - return NoFault; + break; /** Hyper privileged registers */ case MISCREG_HPSTATE: hpstate = val; - return NoFault; + break; case MISCREG_HTSTATE: htstate[tl-1] = val; - return NoFault; + break; case MISCREG_HINTP: panic("HINTP not implemented\n"); case MISCREG_HTBA: htba = val; - return NoFault; + break; case MISCREG_STRAND_STS_REG: strandStatusReg = val; - return NoFault; + break; case MISCREG_HSTICK_CMPR: hstick_cmpr = val; - return NoFault; + break; /** Floating Point Status Register */ case MISCREG_FSR: fsr = val; - return NoFault; + break; default: panic("Miscellaneous register %d not implemented\n", miscReg); } } -Fault MiscRegFile::setRegWithEffect(int miscReg, +void MiscRegFile::setRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc) { const uint64_t Bit64 = (1ULL << 63); switch (miscReg) { - case MISCREG_Y: - case MISCREG_CCR: - case MISCREG_ASI: - setReg(miscReg, val); - return NoFault; - case MISCREG_PRIVTICK: case MISCREG_TICK: - if (isNonPriv()) - return new PrivilegedOpcode; - if (isPriv()) - return new PrivilegedAction; tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64; tickFields.npt = val & Bit64 ? 1 : 0; - return NoFault; - case MISCREG_PC: - return new IllegalInstruction; + break; case MISCREG_FPRS: - return new UnimpFault("FPU not implemented\n"); + //Configure the fpu based on the fprs + break; case MISCREG_PCR: - return new UnimpFault("Performance Instrumentation not impl\n"); - case MISCREG_PIC: - return new UnimpFault("Performance Instrumentation not impl\n"); - case MISCREG_GSR: - return setReg(miscReg, val); - - /** Privilged Registers */ - case MISCREG_TPC: - case MISCREG_TNPC: - case MISCREG_TSTATE: - case MISCREG_TT: - if (tl == 0) - return new IllegalInstruction; - setReg(miscReg, val); - return NoFault; - - case MISCREG_TBA: - // clear lower 7 bits on writes. - setReg(miscReg, val & ULL(~0x7FFF)); - return NoFault; - - case MISCREG_PSTATE: - setReg(miscReg, val); - return NoFault; - - case MISCREG_TL: - if (isHyperPriv() && val > MaxTL) - setReg(miscReg, MaxTL); - else if (isPriv() && !isHyperPriv() && val > MaxPTL) - setReg(miscReg, MaxPTL); - else - setReg(miscReg, val); - return NoFault; - + //Set up performance counting based on pcr value + break; case MISCREG_CWP: tc->changeRegFileContext(CONTEXT_CWP, val); - case MISCREG_CANSAVE: - case MISCREG_CANRESTORE: - case MISCREG_CLEANWIN: - case MISCREG_OTHERWIN: - case MISCREG_WSTATE: - setReg(miscReg, val); - return NoFault; - + break; case MISCREG_GL: - int newval; - if (isHyperPriv() && val > MaxGL) - newval = MaxGL; - else if (isPriv() && !isHyperPriv() && val > MaxPGL) - newval = MaxPGL; - else - newval = val; - tc->changeRegFileContext(CONTEXT_GLOBALS, newval); - setReg(miscReg, newval); - return NoFault; - - /** Floating Point Status Register */ - case MISCREG_FSR: - panic("Floating Point not implemented\n"); - default: -#if FULL_SYSTEM - setFSRegWithEffect(miscReg, val, tc); -#else - return new IllegalInstruction; -#endif + tc->changeRegFileContext(CONTEXT_GLOBALS, val); + break; } + setReg(miscReg, val); } void MiscRegFile::serialize(std::ostream & os) diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index be143311f..771cb1ed6 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -56,7 +56,6 @@ namespace SparcISA MISCREG_CCR = AsrStart + 2, MISCREG_ASI = AsrStart + 3, MISCREG_TICK = AsrStart + 4, - MISCREG_PC = AsrStart + 5, MISCREG_FPRS = AsrStart + 6, MISCREG_PCR = AsrStart + 16, MISCREG_PIC = AsrStart + 17, @@ -366,31 +365,13 @@ namespace SparcISA reset(); } - /** read a value out of an either an SE or FS IPR. No checking is done - * about SE vs. FS as this is mostly used to copy the regfile. Thus more - * register are copied that are necessary for FS. However this prevents - * a bunch of ifdefs and is rarely called so is not performance - * criticial. */ MiscReg readReg(int miscReg); - /** Read a value from an IPR. Only the SE iprs are here and the rest - * are are readFSRegWithEffect (which is called by readRegWithEffect()). - * Checking is done for permission based on state bits in the miscreg - * file. */ - MiscReg readRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc); - - /** write a value into an either an SE or FS IPR. No checking is done - * about SE vs. FS as this is mostly used to copy the regfile. Thus more - * register are copied that are necessary for FS. However this prevents - * a bunch of ifdefs and is rarely called so is not performance - * criticial.*/ - Fault setReg(int miscReg, const MiscReg &val); - - /** Write a value into an IPR. Only the SE iprs are here and the rest - * are are setFSRegWithEffect (which is called by setRegWithEffect()). - * Checking is done for permission based on state bits in the miscreg - * file. */ - Fault setRegWithEffect(int miscReg, + MiscReg readRegWithEffect(int miscReg, ThreadContext *tc); + + void setReg(int miscReg, const MiscReg &val); + + void setRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc); void serialize(std::ostream & os); diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 3323ba7a0..a3b7dde7c 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -66,6 +66,10 @@ SparcLiveProcess::SparcLiveProcess(const std::string &nm, ObjectFile *objFile, // Set pointer for next thread stack. Reserve 8M for main stack. next_thread_stack_base = stack_base - (8 * 1024 * 1024); + + //Initialize these to 0s + fillStart = 0; + spillStart = 0; } void @@ -88,15 +92,19 @@ SparcLiveProcess::startup() */ //No windows contain info from other programs - threadContexts[0]->setMiscRegWithEffect(MISCREG_OTHERWIN, 0); + threadContexts[0]->setMiscReg(MISCREG_OTHERWIN, 0); //There are no windows to pop - threadContexts[0]->setMiscRegWithEffect(MISCREG_CANRESTORE, 0); + threadContexts[0]->setMiscReg(MISCREG_CANRESTORE, 0); //All windows are available to save into - threadContexts[0]->setMiscRegWithEffect(MISCREG_CANSAVE, NWindows - 2); + threadContexts[0]->setMiscReg(MISCREG_CANSAVE, NWindows - 2); //All windows are "clean" - threadContexts[0]->setMiscRegWithEffect(MISCREG_CLEANWIN, NWindows); + threadContexts[0]->setMiscReg(MISCREG_CLEANWIN, NWindows); //Start with register window 0 - threadContexts[0]->setMiscRegWithEffect(MISCREG_CWP, 0); + threadContexts[0]->setMiscReg(MISCREG_CWP, 0); + //Always use spill and fill traps 0 + threadContexts[0]->setMiscReg(MISCREG_WSTATE, 0); + //Set the trap level to 0 + threadContexts[0]->setMiscReg(MISCREG_TL, 0); } m5_auxv_t buildAuxVect(int64_t type, int64_t val) @@ -107,6 +115,83 @@ m5_auxv_t buildAuxVect(int64_t type, int64_t val) return result; } +//We only use 19 instructions for the trap handlers, but there would be +//space for 32 in a real SPARC trap table. +const int numFillInsts = 32; +const int numSpillInsts = 32; + +MachInst fillHandler[numFillInsts] = +{ + htog(0x87802018), //wr %g0, ASI_AIUP, %asi + htog(0xe0dba7ff), //ldxa [%sp + BIAS + (0*8)] %asi, %l0 + htog(0xe2dba807), //ldxa [%sp + BIAS + (1*8)] %asi, %l1 + htog(0xe4dba80f), //ldxa [%sp + BIAS + (2*8)] %asi, %l2 + htog(0xe6dba817), //ldxa [%sp + BIAS + (3*8)] %asi, %l3 + htog(0xe8dba81f), //ldxa [%sp + BIAS + (4*8)] %asi, %l4 + htog(0xeadba827), //ldxa [%sp + BIAS + (5*8)] %asi, %l5 + htog(0xecdba82f), //ldxa [%sp + BIAS + (6*8)] %asi, %l6 + htog(0xeedba837), //ldxa [%sp + BIAS + (7*8)] %asi, %l7 + htog(0xf0dba83f), //ldxa [%sp + BIAS + (8*8)] %asi, %i0 + htog(0xf2dba847), //ldxa [%sp + BIAS + (9*8)] %asi, %i1 + htog(0xf4dba84f), //ldxa [%sp + BIAS + (10*8)] %asi, %i2 + htog(0xf6dba857), //ldxa [%sp + BIAS + (11*8)] %asi, %i3 + htog(0xf8dba85f), //ldxa [%sp + BIAS + (12*8)] %asi, %i4 + htog(0xfadba867), //ldxa [%sp + BIAS + (13*8)] %asi, %i5 + htog(0xfcdba86f), //ldxa [%sp + BIAS + (14*8)] %asi, %i6 + htog(0xfedba877), //ldxa [%sp + BIAS + (15*8)] %asi, %i7 + htog(0x83880000), //restored + htog(0x83F00000), //retry + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000) //illtrap +}; + +MachInst spillHandler[numSpillInsts] = +{ + htog(0x87802018), //wr %g0, ASI_AIUP, %asi + htog(0xe0f3a7ff), //stxa %l0, [%sp + BIAS + (0*8)] %asi + htog(0xe2f3a807), //stxa %l1, [%sp + BIAS + (1*8)] %asi + htog(0xe4f3a80f), //stxa %l2, [%sp + BIAS + (2*8)] %asi + htog(0xe6f3a817), //stxa %l3, [%sp + BIAS + (3*8)] %asi + htog(0xe8f3a81f), //stxa %l4, [%sp + BIAS + (4*8)] %asi + htog(0xeaf3a827), //stxa %l5, [%sp + BIAS + (5*8)] %asi + htog(0xecf3a82f), //stxa %l6, [%sp + BIAS + (6*8)] %asi + htog(0xeef3a837), //stxa %l7, [%sp + BIAS + (7*8)] %asi + htog(0xf0f3a83f), //stxa %i0, [%sp + BIAS + (8*8)] %asi + htog(0xf2f3a847), //stxa %i1, [%sp + BIAS + (9*8)] %asi + htog(0xf4f3a84f), //stxa %i2, [%sp + BIAS + (10*8)] %asi + htog(0xf6f3a857), //stxa %i3, [%sp + BIAS + (11*8)] %asi + htog(0xf8f3a85f), //stxa %i4, [%sp + BIAS + (12*8)] %asi + htog(0xfaf3a867), //stxa %i5, [%sp + BIAS + (13*8)] %asi + htog(0xfcf3a86f), //stxa %i6, [%sp + BIAS + (14*8)] %asi + htog(0xfef3a877), //stxa %i7, [%sp + BIAS + (15*8)] %asi + htog(0x81880000), //saved + htog(0x83F00000), //retry + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000), //illtrap + htog(0x00000000) //illtrap +}; + void SparcLiveProcess::argsInit(int intSize, int pageSize) { @@ -317,6 +402,17 @@ SparcLiveProcess::argsInit(int intSize, int pageSize) initVirtMem->writeBlob(argc_base, (uint8_t*)&guestArgc, intSize); + //Stuff the trap handlers into the processes address space. + //Since the stack grows down and is the highest area in the processes + //address space, we can put stuff above it and stay out of the way. + int fillSize = sizeof(MachInst) * numFillInsts; + int spillSize = sizeof(MachInst) * numSpillInsts; + fillStart = stack_base; + spillStart = fillStart + fillSize; + initVirtMem->writeBlob(fillStart, (uint8_t*)fillHandler, fillSize); + initVirtMem->writeBlob(spillStart, (uint8_t*)spillHandler, spillSize); + + //Set up the thread context to start running the process threadContexts[0]->setIntReg(ArgumentReg0, argc); threadContexts[0]->setIntReg(ArgumentReg1, argv_array_base); threadContexts[0]->setIntReg(StackPointerReg, stack_min - StackBias); diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh index 7cc52e241..2320810c7 100644 --- a/src/arch/sparc/process.hh +++ b/src/arch/sparc/process.hh @@ -55,6 +55,9 @@ class SparcLiveProcess : public LiveProcess static const Addr StackBias = 2047; + //The locations of the fill and spill handlers + Addr fillStart, spillStart; + std::vector<m5_auxv_t> auxv; SparcLiveProcess(const std::string &nm, ObjectFile *objFile, @@ -71,6 +74,12 @@ class SparcLiveProcess : public LiveProcess void argsInit(int intSize, int pageSize); + Addr readFillStart() + { return fillStart; } + + Addr readSpillStart() + { return spillStart; } + }; #endif // __SPARC_PROCESS_HH__ diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index 747426781..5eb874d39 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -82,18 +82,21 @@ MiscReg RegFile::readMiscReg(int miscReg) MiscReg RegFile::readMiscRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc) { - return miscRegFile.readRegWithEffect(miscReg, fault, tc); + fault = NoFault; + return miscRegFile.readRegWithEffect(miscReg, tc); } Fault RegFile::setMiscReg(int miscReg, const MiscReg &val) { - return miscRegFile.setReg(miscReg, val); + miscRegFile.setReg(miscReg, val); + return NoFault; } Fault RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc) { - return miscRegFile.setRegWithEffect(miscReg, val, tc); + miscRegFile.setRegWithEffect(miscReg, val, tc); + return NoFault; } FloatReg RegFile::readFloatReg(int floatReg, int width) diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh index 879780d56..177279678 100644 --- a/src/base/bitfield.hh +++ b/src/base/bitfield.hh @@ -69,4 +69,28 @@ sext(uint64_t val) return sign_bit ? (val | ~mask(N)) : val; } +/** + * Return val with bits first to last set to bit_val + */ +template <class T, class B> +inline +T +insertBits(T val, int first, int last, B bit_val) +{ + T bmask = mask(first - last + 1) << last; + return ((bit_val << last) & bmask) | (val & ~bmask); +} + +/** + * A convenience function to replace bits first to last of val with bit_val + * in place. + */ +template <class T, class B> +inline +void +replaceBits(T& val, int first, int last, B bit_val) +{ + val = insertBits(val, first, last, bit_val); +} + #endif // __BASE_BITFIELD_HH__ diff --git a/src/cpu/ozone/back_end.hh b/src/cpu/ozone/back_end.hh index 8debd277d..992f55c6e 100644 --- a/src/cpu/ozone/back_end.hh +++ b/src/cpu/ozone/back_end.hh @@ -35,7 +35,7 @@ #include <queue> #include <string> -#include "arch/faults.hh" +#include "sim/faults.hh" #include "base/timebuf.hh" #include "cpu/inst_seq.hh" #include "cpu/ozone/rename_table.hh" diff --git a/src/cpu/ozone/dyn_inst_impl.hh b/src/cpu/ozone/dyn_inst_impl.hh index 0a1e1c139..9d42ab05b 100644 --- a/src/cpu/ozone/dyn_inst_impl.hh +++ b/src/cpu/ozone/dyn_inst_impl.hh @@ -28,7 +28,7 @@ * Authors: Kevin Lim */ -#include "arch/faults.hh" +#include "sim/faults.hh" #include "config/full_system.hh" #include "cpu/ozone/dyn_inst.hh" #include "kern/kernel_stats.hh" diff --git a/src/cpu/ozone/front_end_impl.hh b/src/cpu/ozone/front_end_impl.hh index 36e87ec9c..60c954517 100644 --- a/src/cpu/ozone/front_end_impl.hh +++ b/src/cpu/ozone/front_end_impl.hh @@ -30,7 +30,7 @@ #include "config/use_checker.hh" -#include "arch/faults.hh" +#include "sim/faults.hh" #include "arch/isa_traits.hh" #include "arch/utility.hh" #include "base/statistics.hh" diff --git a/src/cpu/ozone/inorder_back_end.hh b/src/cpu/ozone/inorder_back_end.hh index 76eef6fad..b2522bdc8 100644 --- a/src/cpu/ozone/inorder_back_end.hh +++ b/src/cpu/ozone/inorder_back_end.hh @@ -33,7 +33,7 @@ #include <list> -#include "arch/faults.hh" +#include "sim/faults.hh" #include "base/timebuf.hh" #include "cpu/thread_context.hh" #include "cpu/inst_seq.hh" diff --git a/src/cpu/ozone/inorder_back_end_impl.hh b/src/cpu/ozone/inorder_back_end_impl.hh index 16ebac163..8aef9c074 100644 --- a/src/cpu/ozone/inorder_back_end_impl.hh +++ b/src/cpu/ozone/inorder_back_end_impl.hh @@ -28,7 +28,7 @@ * Authors: Kevin Lim */ -#include "arch/faults.hh" +#include "sim/faults.hh" #include "arch/types.hh" #include "cpu/ozone/inorder_back_end.hh" #include "cpu/ozone/thread_state.hh" diff --git a/src/cpu/ozone/lw_back_end.hh b/src/cpu/ozone/lw_back_end.hh index 49c6a1ae2..08a6863d0 100644 --- a/src/cpu/ozone/lw_back_end.hh +++ b/src/cpu/ozone/lw_back_end.hh @@ -36,7 +36,7 @@ #include <set> #include <string> -#include "arch/faults.hh" +#include "sim/faults.hh" #include "base/timebuf.hh" #include "cpu/inst_seq.hh" #include "cpu/ozone/rename_table.hh" diff --git a/src/cpu/ozone/thread_state.hh b/src/cpu/ozone/thread_state.hh index c86f3552e..985e09b52 100644 --- a/src/cpu/ozone/thread_state.hh +++ b/src/cpu/ozone/thread_state.hh @@ -31,7 +31,7 @@ #ifndef __CPU_OZONE_THREAD_STATE_HH__ #define __CPU_OZONE_THREAD_STATE_HH__ -#include "arch/faults.hh" +#include "sim/faults.hh" #include "arch/types.hh" #include "arch/regfile.hh" #include "base/callback.hh" diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index edba55b0d..11e4d2acb 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -188,8 +188,11 @@ AtomicSimpleCPU::resume() changeState(SimObject::Running); if (thread->status() == ThreadContext::Active) { - if (!tickEvent.scheduled()) - tickEvent.schedule(curTick); + if (!tickEvent.scheduled()) { + Tick nextTick = curTick + cycles(1) - 1; + nextTick -= (nextTick % (cycles(1))); + tickEvent.schedule(nextTick); + } } } } @@ -217,7 +220,9 @@ AtomicSimpleCPU::takeOverFrom(BaseCPU *oldCPU) ThreadContext *tc = threadContexts[i]; if (tc->status() == ThreadContext::Active && _status != Running) { _status = Running; - tickEvent.schedule(curTick); + Tick nextTick = curTick + cycles(1) - 1; + nextTick -= (nextTick % (cycles(1))); + tickEvent.schedule(nextTick); break; } } @@ -234,7 +239,10 @@ AtomicSimpleCPU::activateContext(int thread_num, int delay) assert(!tickEvent.scheduled()); notIdleFraction++; - tickEvent.schedule(curTick + cycles(delay)); + //Make sure ticks are still on multiples of cycles + Tick nextTick = curTick + cycles(delay + 1) - 1; + nextTick -= (nextTick % (cycles(1))); + tickEvent.schedule(nextTick); _status = Running; } diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index cbb3980cb..253d33243 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -401,13 +401,15 @@ BaseSimpleCPU::preExecute() StaticInstPtr instPtr = StaticInst::decode(makeExtMI(inst, thread->getTC())); if (instPtr->isMacroOp()) { curMacroStaticInst = instPtr; - curStaticInst = curMacroStaticInst->fetchMicroOp(0); + curStaticInst = curMacroStaticInst-> + fetchMicroOp(thread->readMicroPC()); } else { curStaticInst = instPtr; } } else { //Read the next micro op from the macro op - curStaticInst = curMacroStaticInst->fetchMicroOp(thread->readMicroPC()); + curStaticInst = curMacroStaticInst-> + fetchMicroOp(thread->readMicroPC()); } diff --git a/src/cpu/thread_state.cc b/src/cpu/thread_state.cc index c644ae8d7..e6ebcc525 100644 --- a/src/cpu/thread_state.cc +++ b/src/cpu/thread_state.cc @@ -62,6 +62,8 @@ ThreadState::serialize(std::ostream &os) // thread_num and cpu_id are deterministic from the config SERIALIZE_SCALAR(funcExeInst); SERIALIZE_SCALAR(inst); + SERIALIZE_SCALAR(microPC); + SERIALIZE_SCALAR(nextMicroPC); #if FULL_SYSTEM Tick quiesceEndTick = 0; @@ -81,6 +83,8 @@ ThreadState::unserialize(Checkpoint *cp, const std::string §ion) // thread_num and cpu_id are deterministic from the config UNSERIALIZE_SCALAR(funcExeInst); UNSERIALIZE_SCALAR(inst); + UNSERIALIZE_SCALAR(microPC); + UNSERIALIZE_SCALAR(nextMicroPC); #if FULL_SYSTEM Tick quiesceEndTick; diff --git a/src/dev/i8254xGBe.cc b/src/dev/i8254xGBe.cc index e52a3e73d..7fc68f4e7 100644 --- a/src/dev/i8254xGBe.cc +++ b/src/dev/i8254xGBe.cc @@ -38,6 +38,7 @@ #include "base/inet.hh" #include "dev/i8254xGBe.hh" #include "mem/packet.hh" +#include "mem/packet_access.hh" #include "sim/builder.hh" #include "sim/stats.hh" #include "sim/system.hh" @@ -66,12 +67,17 @@ IGbE::IGbE(Params *p) regs.tctl.reg = 0; regs.manc.reg = 0; + regs.pba.rxa = 0x30; + regs.pba.txa = 0x10; + eeOpBits = 0; eeAddrBits = 0; eeDataBits = 0; eeOpcode = 0; - memset(&flash, 0, EEPROM_SIZE); + // clear all 64 16 bit words of the eeprom + memset(&flash, 0, EEPROM_SIZE*2); + // Magic happy checksum value flash[0] = 0xBABA; } @@ -108,7 +114,7 @@ IGbE::read(PacketPtr pkt) // Only 32bit accesses allowed assert(pkt->getSize() == 4); - DPRINTF(Ethernet, "Read device register %#X\n", daddr); + //DPRINTF(Ethernet, "Read device register %#X\n", daddr); pkt->allocate(); @@ -116,6 +122,7 @@ IGbE::read(PacketPtr pkt) /// Handle read of register here /// + switch (daddr) { case CTRL: pkt->set<uint32_t>(regs.ctrl.reg); @@ -141,11 +148,23 @@ IGbE::read(PacketPtr pkt) case TCTL: pkt->set<uint32_t>(regs.tctl.reg); break; + case PBA: + pkt->set<uint32_t>(regs.pba.reg); + break; + case WUC: + case LEDCTL: + pkt->set<uint32_t>(0); // We don't care, so just return 0 + break; case MANC: pkt->set<uint32_t>(regs.manc.reg); break; default: - panic("Read request to unknown register number: %#x\n", daddr); + if (!(daddr >= VFTA && daddr < (VFTA + VLAN_FILTER_TABLE_SIZE)*4) && + !(daddr >= RAL && daddr < (RAL + RCV_ADDRESS_TABLE_SIZE)*4) && + !(daddr >= MTA && daddr < (MTA + MULTICAST_TABLE_SIZE)*4)) + pkt->set<uint32_t>(0); + else + panic("Read request to unknown register number: %#x\n", daddr); }; pkt->result = Packet::Success; @@ -168,7 +187,7 @@ IGbE::write(PacketPtr pkt) // Only 32bit accesses allowed assert(pkt->getSize() == sizeof(uint32_t)); - DPRINTF(Ethernet, "Wrote device register %#X value %#X\n", daddr, pkt->get<uint32_t>()); + //DPRINTF(Ethernet, "Wrote device register %#X value %#X\n", daddr, pkt->get<uint32_t>()); /// /// Handle write of register here @@ -195,10 +214,10 @@ IGbE::write(PacketPtr pkt) eeAddr = eeAddr << 1 | regs.eecd.din; eeAddrBits++; } else if (eeDataBits < 16 && eeOpcode == EEPROM_READ_OPCODE_SPI) { - assert(eeAddr < EEPROM_SIZE); - DPRINTF(Ethernet, "EEPROM bit read: %d word: %#X\n", - flash[eeAddr] >> eeDataBits & 0x1, flash[eeAddr]); - regs.eecd.dout = (flash[eeAddr] >> eeDataBits) & 0x1; + assert(eeAddr>>1 < EEPROM_SIZE); + DPRINTF(EthernetEEPROM, "EEPROM bit read: %d word: %#X\n", + flash[eeAddr>>1] >> eeDataBits & 0x1, flash[eeAddr>>1]); + regs.eecd.dout = (flash[eeAddr>>1] >> (15-eeDataBits)) & 0x1; eeDataBits++; } else if (eeDataBits < 8 && eeOpcode == EEPROM_RDSR_OPCODE_SPI) { regs.eecd.dout = 0; @@ -219,8 +238,9 @@ IGbE::write(PacketPtr pkt) eeAddr = 0; } - DPRINTF(Ethernet, "EEPROM: opcode: %#X:%d\n", - (uint32_t)eeOpcode, (uint32_t) eeOpBits); + DPRINTF(EthernetEEPROM, "EEPROM: opcode: %#X:%d addr: %#X:%d\n", + (uint32_t)eeOpcode, (uint32_t) eeOpBits, + (uint32_t)eeAddr>>1, (uint32_t)eeAddrBits); if (eeOpBits == 8 && !(eeOpcode == EEPROM_READ_OPCODE_SPI || eeOpcode == EEPROM_RDSR_OPCODE_SPI )) panic("Unknown eeprom opcode: %#X:%d\n", (uint32_t)eeOpcode, @@ -246,11 +266,22 @@ IGbE::write(PacketPtr pkt) case TCTL: regs.tctl.reg = val; break; + case PBA: + regs.pba.rxa = val; + regs.pba.txa = 64 - regs.pba.rxa; + break; + case WUC: + case LEDCTL: + ; // We don't care, so don't store anything + break; case MANC: regs.manc.reg = val; break; default: - panic("Write request to unknown register number: %#x\n", daddr); + if (!(daddr >= VFTA && daddr < (VFTA + VLAN_FILTER_TABLE_SIZE)*4) && + !(daddr >= RAL && daddr < (RAL + RCV_ADDRESS_TABLE_SIZE)*4) && + !(daddr >= MTA && daddr < (MTA + MULTICAST_TABLE_SIZE)*4)) + panic("Write request to unknown register number: %#x\n", daddr); }; pkt->result = Packet::Success; diff --git a/src/mem/tport.cc b/src/mem/tport.cc index 55a461a8b..086d91279 100644 --- a/src/mem/tport.cc +++ b/src/mem/tport.cc @@ -33,16 +33,18 @@ void SimpleTimingPort::recvFunctional(PacketPtr pkt) { - std::list<PacketPtr>::iterator i = transmitList.begin(); - std::list<PacketPtr>::iterator end = transmitList.end(); + std::list<std::pair<Tick,PacketPtr> >::iterator i = transmitList.begin(); + std::list<std::pair<Tick,PacketPtr> >::iterator end = transmitList.end(); + bool done = false; - while (i != end) { - PacketPtr target = *i; + while (i != end && !done) { + PacketPtr target = i->second; // If the target contains data, and it overlaps the // probed request, need to update data if (target->intersect(pkt)) - fixPacket(pkt, target); + done = fixPacket(pkt, target); + i++; } //Then just do an atomic access and throw away the returned latency @@ -63,7 +65,7 @@ SimpleTimingPort::recvTiming(PacketPtr pkt) // turn packet around to go back to requester if response expected if (pkt->needsResponse()) { pkt->makeTimingResponse(); - sendTimingLater(pkt, latency); + sendTiming(pkt, latency); } else { if (pkt->cmd != Packet::UpgradeReq) @@ -78,14 +80,14 @@ SimpleTimingPort::recvTiming(PacketPtr pkt) void SimpleTimingPort::recvRetry() { - assert(outTiming > 0); assert(!transmitList.empty()); - if (sendTiming(transmitList.front())) { + if (Port::sendTiming(transmitList.front().second)) { transmitList.pop_front(); - outTiming--; DPRINTF(Bus, "No Longer waiting on retry\n"); - if (!transmitList.empty()) - sendTimingLater(transmitList.front(), 1); + if (!transmitList.empty()) { + Tick time = transmitList.front().first; + sendEvent.schedule(time <= curTick ? curTick+1 : time); + } } if (transmitList.empty() && drainEvent) { @@ -95,38 +97,61 @@ SimpleTimingPort::recvRetry() } void +SimpleTimingPort::sendTiming(PacketPtr pkt, Tick time) +{ + // Nothing is on the list: add it and schedule an event + if (transmitList.empty()) { + assert(!sendEvent.scheduled()); + sendEvent.schedule(curTick+time); + transmitList.push_back(std::pair<Tick,PacketPtr>(time+curTick,pkt)); + return; + } + + // something is on the list and this belongs at the end + if (time+curTick >= transmitList.back().first) { + transmitList.push_back(std::pair<Tick,PacketPtr>(time+curTick,pkt)); + return; + } + // Something is on the list and this belongs somewhere else + std::list<std::pair<Tick,PacketPtr> >::iterator i = transmitList.begin(); + std::list<std::pair<Tick,PacketPtr> >::iterator end = transmitList.end(); + bool done = false; + + while (i != end && !done) { + if (time+curTick < i->first) + transmitList.insert(i,std::pair<Tick,PacketPtr>(time+curTick,pkt)); + i++; + } +} + +void SimpleTimingPort::SendEvent::process() { - assert(port->outTiming > 0); - if (!port->transmitList.empty() && port->transmitList.front() != packet) { - //We are not the head of the list - port->transmitList.push_back(packet); - } else if (port->sendTiming(packet)) { - // send successful - if (port->transmitList.size()) { - port->transmitList.pop_front(); - port->outTiming--; - if (!port->transmitList.empty()) - port->sendTimingLater(port->transmitList.front(), 1); + assert(port->transmitList.size()); + assert(port->transmitList.front().first <= curTick); + if (port->Port::sendTiming(port->transmitList.front().second)) { + //send successful, remove packet + port->transmitList.pop_front(); + if (!port->transmitList.empty()) { + Tick time = port->transmitList.front().first; + schedule(time <= curTick ? curTick+1 : time); } if (port->transmitList.empty() && port->drainEvent) { port->drainEvent->process(); port->drainEvent = NULL; } - } else { - // send unsuccessful (due to flow control). Will get retry - // callback later; save for then if not already - DPRINTF(Bus, "Waiting on retry\n"); - if (!(port->transmitList.front() == packet)) - port->transmitList.push_back(packet); + return; } + // send unsuccessful (due to flow control). Will get retry + // callback later; save for then if not already + DPRINTF(Bus, "Waiting on retry\n"); } unsigned int SimpleTimingPort::drain(Event *de) { - if (outTiming == 0 && transmitList.size() == 0) + if (transmitList.size() == 0) return 0; drainEvent = de; return 1; diff --git a/src/mem/tport.hh b/src/mem/tport.hh index fbe81c443..438ec56dc 100644 --- a/src/mem/tport.hh +++ b/src/mem/tport.hh @@ -60,23 +60,22 @@ class SimpleTimingPort : public Port protected: /** A list of outgoing timing response packets that haven't been * serviced yet. */ - std::list<PacketPtr> transmitList; + std::list<std::pair<Tick,PacketPtr> > transmitList; /** * This class is used to implemented sendTiming() with a delay. When - * a delay is requested a new event is created. When the event time - * expires it attempts to send the packet. If it cannot, the packet - * is pushed onto the transmit list to be sent when recvRetry() is - * called. */ + * a delay is requested a the event is scheduled if it isn't already. + * When the event time expires it attempts to send the packet. + * If it cannot, the packet sent when recvRetry() is called. + **/ class SendEvent : public Event { SimpleTimingPort *port; - PacketPtr packet; public: - SendEvent(SimpleTimingPort *p, PacketPtr pkt, Tick t) - : Event(&mainEventQueue), port(p), packet(pkt) - { setFlags(AutoDelete); schedule(curTick + t); } + SendEvent(SimpleTimingPort *p) + : Event(&mainEventQueue), port(p) + { } virtual void process(); @@ -84,19 +83,17 @@ class SimpleTimingPort : public Port { return "Future scheduled sendTiming event"; } }; - - /** Number of timing requests that are emulating the device timing before - * attempting to end up on the bus. - */ - int outTiming; + SendEvent sendEvent; /** If we need to drain, keep the drain event around until we're done * here.*/ Event *drainEvent; - /** Schedule a sendTiming() event to be called in the future. */ - void sendTimingLater(PacketPtr pkt, Tick time) - { outTiming++; new SendEvent(this, pkt, time); } + /** Schedule a sendTiming() event to be called in the future. + * @param pkt packet to send + * @param time increment from now (in ticks) to send packet + */ + void sendTiming(PacketPtr pkt, Tick time); /** This function is notification that the device should attempt to send a * packet again. */ @@ -118,7 +115,7 @@ class SimpleTimingPort : public Port public: SimpleTimingPort(std::string pname) - : Port(pname), outTiming(0), drainEvent(NULL) + : Port(pname), sendEvent(this), drainEvent(NULL) {} /** Hook for draining timing accesses from the system. The diff --git a/src/sim/sim_object.cc b/src/sim/sim_object.cc index d12b06b7a..8fc8fe58f 100644 --- a/src/sim/sim_object.cc +++ b/src/sim/sim_object.cc @@ -92,11 +92,6 @@ SimObject::SimObject(const string &_name) } void -SimObject::connect() -{ -} - -void SimObject::init() { } @@ -160,21 +155,6 @@ SimObject::regAllStats() } // -// static function: call connect() on all SimObjects. -// -void -SimObject::connectAll() -{ - SimObjectList::iterator i = simObjectList.begin(); - SimObjectList::iterator end = simObjectList.end(); - - for (; i != end; ++i) { - SimObject *obj = *i; - obj->connect(); - } -} - -// // static function: call init() on all SimObjects. // void diff --git a/src/sim/sim_object.hh b/src/sim/sim_object.hh index 32807b69d..93802e247 100644 --- a/src/sim/sim_object.hh +++ b/src/sim/sim_object.hh @@ -101,9 +101,7 @@ class SimObject : public Serializable, protected StartupCallback // initialization pass of all objects. // Gets invoked after construction, before unserialize. virtual void init(); - virtual void connect(); static void initAll(); - static void connectAll(); // register statistics for this object virtual void regStats(); diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.ini b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.ini index 21028fa63..9da46d74f 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.ini +++ b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.ini @@ -91,6 +91,8 @@ uid=100 [system.membus] type=Bus bus_id=0 +clock=1000 +width=64 port=system.physmem.port system.cpu.icache_port system.cpu.dcache_port [system.physmem] diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.out b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.out index f5be4e3bd..fc125a624 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.out +++ b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/config.out @@ -19,6 +19,8 @@ mem_mode=atomic [system.membus] type=Bus bus_id=0 +clock=1000 +width=64 [system.cpu.workload] type=LiveProcess diff --git a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/m5stats.txt b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/m5stats.txt index e87e77b8f..5c79f4d62 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/m5stats.txt +++ b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/m5stats.txt @@ -1,18 +1,18 @@ ---------- Begin Simulation Statistics ---------- -host_inst_rate 2175 # Simulator instruction rate (inst/s) -host_mem_usage 147292 # Number of bytes of host memory used -host_seconds 2.06 # Real time elapsed on the host -host_tick_rate 2174 # Simulator tick rate (ticks/s) +host_inst_rate 58121 # Simulator instruction rate (inst/s) +host_mem_usage 148396 # Number of bytes of host memory used +host_seconds 0.08 # Real time elapsed on the host +host_tick_rate 57840 # Simulator tick rate (ticks/s) sim_freq 1000000000000 # Frequency of simulated ticks -sim_insts 4483 # Number of instructions simulated +sim_insts 4863 # Number of instructions simulated sim_seconds 0.000000 # Number of seconds simulated -sim_ticks 4482 # Number of ticks simulated +sim_ticks 4862 # Number of ticks simulated system.cpu.idle_fraction 0 # Percentage of idle cycles system.cpu.not_idle_fraction 1 # Percentage of non-idle cycles -system.cpu.numCycles 4483 # 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.numCycles 4863 # number of cpu cycles simulated +system.cpu.num_insts 4863 # Number of instructions executed +system.cpu.num_refs 1269 # 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-atomic/stdout b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/stdout index c9df3a17c..1d76c6089 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-atomic/stdout +++ b/tests/quick/00.hello/ref/sparc/linux/simple-atomic/stdout @@ -5,8 +5,8 @@ The Regents of The University of Michigan All Rights Reserved -M5 compiled Oct 8 2006 14:19:59 -M5 started Sun Oct 8 14:20:03 2006 +M5 compiled Oct 27 2006 02:07:29 +M5 started Fri Oct 27 02:08:08 2006 M5 executing on zizzer.eecs.umich.edu -command line: build/SPARC_SE/m5.opt -d build/SPARC_SE/tests/opt/quick/00.hello/sparc/linux/simple-atomic tests/run.py quick/00.hello/sparc/linux/simple-atomic -Exiting @ tick 4482 because target called exit() +command line: build/SPARC_SE/m5.debug -d build/SPARC_SE/tests/debug/quick/00.hello/sparc/linux/simple-atomic tests/run.py quick/00.hello/sparc/linux/simple-atomic +Exiting @ tick 4862 because target called exit() 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 index 982973385..da87d03a1 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-timing/config.ini +++ b/tests/quick/00.hello/ref/sparc/linux/simple-timing/config.ini @@ -20,7 +20,6 @@ print_effaddr=true print_fetchseq=false print_iregs=false print_opclass=true -print_reg_delta=false print_thread=true speculative=true trace_system=client 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 index c4dc22855..3645207b1 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-timing/m5stats.txt +++ b/tests/quick/00.hello/ref/sparc/linux/simple-timing/m5stats.txt @@ -1,67 +1,67 @@ ---------- 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) +host_inst_rate 48159 # Simulator instruction rate (inst/s) +host_mem_usage 179620 # Number of bytes of host memory used +host_seconds 0.10 # Real time elapsed on the host +host_tick_rate 15510230 # 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 +sim_insts 4863 # Number of instructions simulated +sim_seconds 0.000002 # Number of seconds simulated +sim_ticks 1573001 # Number of ticks simulated +system.cpu.dcache.ReadReq_accesses 608 # number of ReadReq accesses(hits+misses) +system.cpu.dcache.ReadReq_avg_miss_latency 3971.370370 # average ReadReq miss latency +system.cpu.dcache.ReadReq_avg_mshr_miss_latency 2971.370370 # average ReadReq mshr miss latency +system.cpu.dcache.ReadReq_hits 554 # number of ReadReq hits +system.cpu.dcache.ReadReq_miss_latency 214454 # number of ReadReq miss cycles +system.cpu.dcache.ReadReq_miss_rate 0.088816 # 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_miss_latency 160454 # number of ReadReq MSHR miss cycles +system.cpu.dcache.ReadReq_mshr_miss_rate 0.088816 # 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.WriteReq_accesses 661 # number of WriteReq accesses(hits+misses) +system.cpu.dcache.WriteReq_avg_miss_latency 3981.559524 # average WriteReq miss latency +system.cpu.dcache.WriteReq_avg_mshr_miss_latency 2981.559524 # average WriteReq mshr miss latency +system.cpu.dcache.WriteReq_hits 577 # number of WriteReq hits +system.cpu.dcache.WriteReq_miss_latency 334451 # number of WriteReq miss cycles +system.cpu.dcache.WriteReq_miss_rate 0.127080 # miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_misses 84 # number of WriteReq misses +system.cpu.dcache.WriteReq_mshr_miss_latency 250451 # number of WriteReq MSHR miss cycles +system.cpu.dcache.WriteReq_mshr_miss_rate 0.127080 # mshr miss rate for WriteReq accesses +system.cpu.dcache.WriteReq_mshr_misses 84 # 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.avg_refs 8.195652 # 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_accesses 1269 # number of demand (read+write) accesses +system.cpu.dcache.demand_avg_miss_latency 3977.572464 # average overall miss latency +system.cpu.dcache.demand_avg_mshr_miss_latency 2977.572464 # average overall mshr miss latency +system.cpu.dcache.demand_hits 1131 # number of demand (read+write) hits +system.cpu.dcache.demand_miss_latency 548905 # number of demand (read+write) miss cycles +system.cpu.dcache.demand_miss_rate 0.108747 # miss rate for demand accesses +system.cpu.dcache.demand_misses 138 # 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.demand_mshr_miss_latency 410905 # number of demand (read+write) MSHR miss cycles +system.cpu.dcache.demand_mshr_miss_rate 0.108747 # mshr miss rate for demand accesses +system.cpu.dcache.demand_mshr_misses 138 # 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_accesses 1269 # number of overall (read+write) accesses +system.cpu.dcache.overall_avg_miss_latency 3977.572464 # average overall miss latency +system.cpu.dcache.overall_avg_mshr_miss_latency 2977.572464 # 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_hits 1131 # number of overall hits +system.cpu.dcache.overall_miss_latency 548905 # number of overall miss cycles +system.cpu.dcache.overall_miss_rate 0.108747 # miss rate for overall accesses +system.cpu.dcache.overall_misses 138 # 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_miss_latency 410905 # number of overall MSHR miss cycles +system.cpu.dcache.overall_mshr_miss_rate 0.108747 # mshr miss rate for overall accesses +system.cpu.dcache.overall_mshr_misses 138 # 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 @@ -74,56 +74,56 @@ system.cpu.dcache.prefetcher.num_hwpf_removed_MSHR_hit 0 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.sampled_refs 138 # 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.tagsinuse 81.997528 # Cycle average of tags in use +system.cpu.dcache.total_refs 1131 # 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.ReadReq_accesses 4864 # number of ReadReq accesses(hits+misses) +system.cpu.icache.ReadReq_avg_miss_latency 3977.960938 # average ReadReq miss latency +system.cpu.icache.ReadReq_avg_mshr_miss_latency 2977.960938 # average ReadReq mshr miss latency +system.cpu.icache.ReadReq_hits 4608 # number of ReadReq hits +system.cpu.icache.ReadReq_miss_latency 1018358 # number of ReadReq miss cycles +system.cpu.icache.ReadReq_miss_rate 0.052632 # miss rate for ReadReq accesses +system.cpu.icache.ReadReq_misses 256 # number of ReadReq misses +system.cpu.icache.ReadReq_mshr_miss_latency 762358 # number of ReadReq MSHR miss cycles +system.cpu.icache.ReadReq_mshr_miss_rate 0.052632 # mshr miss rate for ReadReq accesses +system.cpu.icache.ReadReq_mshr_misses 256 # 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.avg_refs 18 # 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_accesses 4864 # number of demand (read+write) accesses +system.cpu.icache.demand_avg_miss_latency 3977.960938 # average overall miss latency +system.cpu.icache.demand_avg_mshr_miss_latency 2977.960938 # average overall mshr miss latency +system.cpu.icache.demand_hits 4608 # number of demand (read+write) hits +system.cpu.icache.demand_miss_latency 1018358 # number of demand (read+write) miss cycles +system.cpu.icache.demand_miss_rate 0.052632 # miss rate for demand accesses +system.cpu.icache.demand_misses 256 # 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.demand_mshr_miss_latency 762358 # number of demand (read+write) MSHR miss cycles +system.cpu.icache.demand_mshr_miss_rate 0.052632 # mshr miss rate for demand accesses +system.cpu.icache.demand_mshr_misses 256 # 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_accesses 4864 # number of overall (read+write) accesses +system.cpu.icache.overall_avg_miss_latency 3977.960938 # average overall miss latency +system.cpu.icache.overall_avg_mshr_miss_latency 2977.960938 # 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_hits 4608 # number of overall hits +system.cpu.icache.overall_miss_latency 1018358 # number of overall miss cycles +system.cpu.icache.overall_miss_rate 0.052632 # miss rate for overall accesses +system.cpu.icache.overall_misses 256 # 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_miss_latency 762358 # number of overall MSHR miss cycles +system.cpu.icache.overall_mshr_miss_rate 0.052632 # mshr miss rate for overall accesses +system.cpu.icache.overall_mshr_misses 256 # 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 @@ -136,57 +136,57 @@ system.cpu.icache.prefetcher.num_hwpf_removed_MSHR_hit 0 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.sampled_refs 256 # 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.tagsinuse 114.778311 # Cycle average of tags in use +system.cpu.icache.total_refs 4608 # 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_accesses 394 # number of ReadReq accesses(hits+misses) +system.cpu.l2cache.ReadReq_avg_miss_latency 2985.429668 # average ReadReq miss latency +system.cpu.l2cache.ReadReq_avg_mshr_miss_latency 1984.429668 # 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.ReadReq_miss_latency 1167303 # number of ReadReq miss cycles +system.cpu.l2cache.ReadReq_miss_rate 0.992386 # miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_misses 391 # number of ReadReq misses +system.cpu.l2cache.ReadReq_mshr_miss_latency 775912 # number of ReadReq MSHR miss cycles +system.cpu.l2cache.ReadReq_mshr_miss_rate 0.992386 # mshr miss rate for ReadReq accesses +system.cpu.l2cache.ReadReq_mshr_misses 391 # 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.avg_refs 0.007673 # 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_accesses 394 # number of demand (read+write) accesses +system.cpu.l2cache.demand_avg_miss_latency 2985.429668 # average overall miss latency +system.cpu.l2cache.demand_avg_mshr_miss_latency 1984.429668 # 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_miss_latency 1167303 # number of demand (read+write) miss cycles +system.cpu.l2cache.demand_miss_rate 0.992386 # miss rate for demand accesses +system.cpu.l2cache.demand_misses 391 # 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.demand_mshr_miss_latency 775912 # number of demand (read+write) MSHR miss cycles +system.cpu.l2cache.demand_mshr_miss_rate 0.992386 # mshr miss rate for demand accesses +system.cpu.l2cache.demand_mshr_misses 391 # 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_accesses 394 # number of overall (read+write) accesses +system.cpu.l2cache.overall_avg_miss_latency 2985.429668 # average overall miss latency +system.cpu.l2cache.overall_avg_mshr_miss_latency 1984.429668 # 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_miss_latency 1167303 # number of overall miss cycles +system.cpu.l2cache.overall_miss_rate 0.992386 # miss rate for overall accesses +system.cpu.l2cache.overall_misses 391 # 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_miss_latency 775912 # number of overall MSHR miss cycles +system.cpu.l2cache.overall_mshr_miss_rate 0.992386 # mshr miss rate for overall accesses +system.cpu.l2cache.overall_mshr_misses 391 # 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 @@ -199,16 +199,16 @@ system.cpu.l2cache.prefetcher.num_hwpf_removed_MSHR_hit 0 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.sampled_refs 391 # 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.tagsinuse 195.424915 # 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.numCycles 1573001 # number of cpu cycles simulated +system.cpu.num_insts 4863 # Number of instructions executed +system.cpu.num_refs 1269 # 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/stdout b/tests/quick/00.hello/ref/sparc/linux/simple-timing/stdout index 3c17ee40b..b1da2e4ab 100644 --- a/tests/quick/00.hello/ref/sparc/linux/simple-timing/stdout +++ b/tests/quick/00.hello/ref/sparc/linux/simple-timing/stdout @@ -5,8 +5,8 @@ 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 +M5 compiled Oct 27 2006 02:07:29 +M5 started Fri Oct 27 02:08:11 2006 +M5 executing on zizzer.eecs.umich.edu 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() +Exiting @ tick 1573001 because target called exit() |