diff options
35 files changed, 1059 insertions, 140 deletions
diff --git a/configs/common/FSConfig.py b/configs/common/FSConfig.py index 6d7634106..44c13ef78 100644 --- a/configs/common/FSConfig.py +++ b/configs/common/FSConfig.py @@ -156,7 +156,7 @@ def makeLinuxMipsSystem(mem_mode, mdesc = None): return self def x86IOAddress(port): - IO_address_space_base = 0x1000000000000000 + IO_address_space_base = 0x8000000000000000 return IO_address_space_base + port; def makeLinuxX86System(mem_mode, mdesc = None): @@ -189,6 +189,7 @@ def makeLinuxX86System(mem_mode, mdesc = None): # Platform self.opteron = Opteron() + self.opteron.attachIO(self.iobus) self.intrctrl = IntrControl() diff --git a/configs/common/Options.py b/configs/common/Options.py index 3cd3342b8..34833e799 100644 --- a/configs/common/Options.py +++ b/configs/common/Options.py @@ -29,7 +29,7 @@ # 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("-n", "--num-cpus", type="int", default=1) parser.add_option("--caches", action="store_true") parser.add_option("--l2cache", action="store_true") parser.add_option("--fastmem", action="store_true") @@ -41,26 +41,38 @@ 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>") +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("-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) -parser.add_option("-f", "--fast_forward", type="int", action="store", - help="fast_forward count in instructions: use alone to checkpoint or with -s and -max_inst") -parser.add_option("--max_inst", type="int", action="store", - help="max_insts_any_thread value") + help="if -s, then this is the warmup period. else, this is ignored", + default=5000000000) + +# Fastforwarding and simpoint related materials +parser.add_option("-W", "--warmup-insts", action="store", type="int", + default=None, + help="Warmup period in total instructions (requires --standard-switch)") +parser.add_option("-I", "--max-inst", action="store", type="int", default=None, + help="Total number of instructions to simulate (default: run forever)") +parser.add_option("--bench", action="store", type="string", default=None, + help="base names for --take-checkpoint and --checkpoint-restore") +parser.add_option("-F", "--fast-forward", action="store", type="string", + default=None, + help="Number of instructions to fast forward before switching") +parser.add_option("-S", "--simpoint", action="store_true", default=False, + help="""Use workload simpoints as an instruction offset for +--checkpoint-restore or --take-checkpoint.""") +parser.add_option("--at-instruction", action="store_true", default=False, + help="""Treate value of --checkpoint-restore or --take-checkpoint as a +number of instructions.""") diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py index f6b289fb5..9f3bf0cd9 100644 --- a/configs/common/Simulation.py +++ b/configs/common/Simulation.py @@ -51,7 +51,7 @@ def setCPUClass(options): test_mem_mode = 'atomic' if not atomic: - if options.checkpoint_restore: + if options.checkpoint_restore or options.fast_forward: CPUClass = TmpClass class TmpClass(AtomicSimpleCPU): pass else: @@ -86,6 +86,8 @@ def run(options, root, testsys, cpu_class): for i in xrange(np)] for i in xrange(np): + if options.fast_forward: + testsys.cpu[i].max_insts_any_thread = options.fast_forward switch_cpus[i].system = testsys if not m5.build_env['FULL_SYSTEM']: switch_cpus[i].workload = testsys.cpu[i].workload @@ -95,9 +97,6 @@ def run(options, root, testsys, cpu_class): switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] if options.standard_switch: - if (options.fast_forward and options.warmup): - m5.panic("Must specify either warmup OR fast-forward with -s!") - switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i)) for i in xrange(np)] switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i)) @@ -112,8 +111,27 @@ def run(options, root, testsys, cpu_class): switch_cpus[i].clock = testsys.cpu[0].clock switch_cpus_1[i].clock = testsys.cpu[0].clock - if options.fast_forward: - switch_cpus[i].max_insts_any_thread = options.fast_forward + # if restoring, make atomic cpu simulate only a few instructions + if options.checkpoint_restore: + testsys.cpu[i].max_insts_any_thread = 1 + # Fast forward to specified location if we are not restoring + elif options.fast_forward: + testsys.cpu[i].max_insts_any_thread = options.fast_forward + # Fast forward to a simpoint (warning: time consuming) + elif options.simpoint: + if testsys.cpu[i].workload[0].simpoint == None: + m5.panic('simpoint not found') + testsys.cpu[i].max_insts_any_thread = \ + testsys.cpu[i].workload[0].simpoint + # No distance specified, just switch + else: + testsys.cpu[i].max_insts_any_thread = 1 + + # warmup period + if options.warmup_insts: + switch_cpus[i].max_insts_any_thread = options.warmup_insts + + # simulation period if options.max_inst: switch_cpus_1[i].max_insts_any_thread = options.max_inst @@ -123,136 +141,209 @@ def run(options, root, testsys, cpu_class): L1Cache(size = '64kB')) switch_cpus_1[i].connectMemPorts(testsys.membus) - testsys.switch_cpus = switch_cpus testsys.switch_cpus_1 = switch_cpus_1 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)] - elif options.fast_forward: - for i in xrange(np): - testsys.cpu[i].max_insts_any_thread = options.fast_forward + # set the checkpoint in the cpu before m5.instantiate is called + if options.take_checkpoints and \ + (options.simpoint or options.at_instruction): + offset = int(options.take_checkpoints) + # Set an instruction break point + if options.simpoint: + for i in xrange(np): + if testsys.cpu[i].workload[0].simpoint == None: + m5.panic('no simpoint for testsys.cpu[%d].workload[0]' % i) + checkpoint_inst = testsys.cpu[i].workload[0].simpoint + offset + testsys.cpu[i].max_insts_any_thread = checkpoint_inst + # used for output below + options.take_checkpoints = checkpoint_inst + else: + options.take_checkpoints = offset + # Set all test cpus with the right number of instructions + # for the upcoming simulation + for i in xrange(np): + testsys.cpu[i].max_insts_any_thread = offset + + testsys.cpu_switch_list = cpu_switch_list m5.instantiate(root) if options.checkpoint_restore: - from os.path import isdir + from os.path import isdir, exists 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)) + if options.at_instruction: + checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % \ + (options.bench, options.checkpoint_restore)) + if not exists(checkpoint_dir): + m5.panic("Unable to find checkpoint directory %s" % \ + checkpoint_dir) + + print "Restoring checkpoint ..." + m5.restoreCheckpoint(root, checkpoint_dir) + print "Done." + elif options.simpoint: + # assume workload 0 has the simpoint + if testsys.cpu[i].workload[0].simpoint == None: + m5.panic('Unable to find simpoint') + + options.checkpoint_restore += \ + testsys.cpu[0].workload[0].simpoint + + checkpoint_dir = joinpath(cptdir, "cpt.%s.%d" % \ + (options.bench, options.checkpoint_restore)) + if not exists(checkpoint_dir): + m5.panic("Unable to find checkpoint directory %s.%s" % \ + (options.bench, options.checkpoint_restore)) + + print "Restoring checkpoint ..." + m5.restoreCheckpoint(root,checkpoint_dir) + print "Done." + else: + 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))) + cpts.sort(lambda a,b: cmp(long(a), long(b))) - cpt_num = options.checkpoint_restore + cpt_num = options.checkpoint_restore - if cpt_num > len(cpts): - m5.panic('Checkpoint %d not found' % cpt_num) + if cpt_num > len(cpts): + m5.panic('Checkpoint %d not found' % cpt_num) - ## Adjust max tick based on our starting tick - maxtick = maxtick - int(cpts[cpt_num - 1]) + ## Adjust max tick based on our starting tick + maxtick = maxtick - int(cpts[cpt_num - 1]) - ## Restore the checkpoint - m5.restoreCheckpoint(root, - joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1])) + ## Restore the checkpoint + m5.restoreCheckpoint(root, + joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1])) if options.standard_switch or cpu_class: - exit_event = m5.simulate(10000) + if options.standard_switch: + print "Switch at instruction count:%s" % \ + str(testsys.cpu[0].max_insts_any_thread) + exit_event = m5.simulate() + elif cpu_class and options.fast_forward: + print "Switch at instruction count:%s" % \ + str(testsys.cpu[0].max_insts_any_thread) + exit_event = m5.simulate() + else: + print "Switch at curTick count:%s" % str(10000) + exit_event = m5.simulate(10000) + print "Switched CPUS @ cycle = %s" % (m5.curTick()) - ## 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. + # 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) if options.standard_switch: - if (options.warmup): - exit_event = m5.simulate(options.warmup) - if options.fast_forward: + print "Switch at instruction count:%d" % \ + (testsys.switch_cpus[0].max_insts_any_thread) + + #warmup instruction count may have already been set + if options.warmup_insts: exit_event = m5.simulate() + else: + exit_event = m5.simulate(options.warmup) + print "Switching CPUS @ cycle = %s" % (m5.curTick()) + print "Simulation ends instruction count:%d" % \ + (testsys.switch_cpus_1[0].max_insts_any_thread) m5.drain(testsys) m5.switchCpus(switch_cpu_list1) m5.resume(testsys) - # This should *only* be used by itself to take a checkpoint! - # Otherwise, use standard_switch - elif options.fast_forward: - exit_event = m5.simulate() - - while exit_event.getCause() != "a thread reached the max instruction count": - if exit_event.getCause() == "user interrupt received": - print "User interrupt! Switching to simulation mode" - break - else: - m5.simulate(True) - - if exit_event.getCause() == "a thread reached the max instruction count": - print "Reached fast_forward count %d; starting simulation at cycle %d" % (options.fast_forward, m5.curTick()) - - m5.checkpoint(root, joinpath(cptdir, "cpt.%d")) - return - 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. + # 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, 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 options.at_instruction or options.simpoint: + checkpoint_inst = when - if exit_event.getCause() == "simulate() limit reached": - m5.checkpoint(root, joinpath(cptdir, "cpt.%d")) - num_checkpoints += 1 + # maintain correct offset if we restored from some instruction + if options.checkpoint_restore: + checkpoint_inst += options.checkpoint_restore - sim_ticks = when - exit_cause = "maximum %d checkpoints dropped" % max_checkpoints - while num_checkpoints < max_checkpoints and \ - exit_event.getCause() == "simulate() limit reached": - if (sim_ticks + period) > maxtick: - 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, joinpath(cptdir, "cpt.%d")) - num_checkpoints += 1 + print "Creating checkpoint at inst:%d" % (checkpoint_inst) + exit_event = m5.simulate() + print "exit cause = %s" % (exit_event.getCause()) - if exit_event.getCause() != "simulate() limit reached": - exit_cause = exit_event.getCause(); + # skip checkpoint instructions should they exist + while exit_event.getCause() == "checkpoint": + exit_event = m5.simulate() + if exit_event.getCause() == \ + "a thread reached the max instruction count": + m5.checkpoint(root, joinpath(cptdir, "cpt.%s.%d" % \ + (options.bench, checkpoint_inst))) + print "Checkpoint written." + num_checkpoints += 1 - else: #no checkpoints being taken via this script + if exit_event.getCause() == "user interrupt received": + exit_cause = exit_event.getCause(); + else: + 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, joinpath(cptdir, "cpt.%d")) + num_checkpoints += 1 + + sim_ticks = when + exit_cause = "maximum %d checkpoints dropped" % max_checkpoints + while num_checkpoints < max_checkpoints and \ + exit_event.getCause() == "simulate() limit reached": + if (sim_ticks + period) > maxtick: + 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, joinpath(cptdir, "cpt.%d")) + num_checkpoints += 1 + + if exit_event.getCause() != "simulate() limit reached": + exit_cause = exit_event.getCause(); + + else: # no checkpoints being taken via this script + if options.fast_forward: + m5.stats.reset() + print "**** REAL SIMULATION ****" exit_event = m5.simulate(maxtick) while exit_event.getCause() == "checkpoint": m5.checkpoint(root, joinpath(cptdir, "cpt.%d")) num_checkpoints += 1 if num_checkpoints == max_checkpoints: - exit_cause = "maximum %d checkpoints dropped" % max_checkpoints + exit_cause = "maximum %d checkpoints dropped" % max_checkpoints break exit_event = m5.simulate(maxtick - m5.curTick()) diff --git a/configs/common/cpu2000.py b/configs/common/cpu2000.py index 2f5844dc6..7fe15b577 100644 --- a/configs/common/cpu2000.py +++ b/configs/common/cpu2000.py @@ -1,4 +1,4 @@ -# Copyright (c) 2006-2007 The Regents of The University of Michigan +# Copyright (c) 2006-2008 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -85,6 +85,9 @@ class Benchmark(object): if not hasattr(self.__class__, 'output'): self.output = '%s.out' % self.name + if not hasattr(self.__class__, 'simpoint'): + self.simpoint = None + try: func = getattr(self.__class__, input_set) except AttributeError: @@ -137,7 +140,7 @@ class Benchmark(object): process_args['input'] = self.stdin if self.stdout: process_args['output'] = self.stdout - + process_args['simpoint'] = self.simpoint # explicit keywords override defaults process_args.update(kwargs) @@ -149,6 +152,7 @@ class Benchmark(object): # figure out working directory: use m5's outdir unless # overridden by LiveProcess's cwd param cwd = process_args.get('cwd') + if not cwd: from m5.main import options cwd = options.outdir @@ -179,16 +183,19 @@ class ammp(MinneDefaultBenchmark): name = 'ammp' number = 188 lang = 'C' + simpoint = 108*100E6 class applu(MinneDefaultBenchmark): name = 'applu' number = 173 lang = 'F77' + simpoint = 2179*100E6 class apsi(MinneDefaultBenchmark): name = 'apsi' number = 301 lang = 'F77' + simpoint = 3408*100E6 class art(DefaultBenchmark): name = 'art' @@ -241,6 +248,7 @@ class art110(art): '-endy', '240', '-objects', '10' ] self.output = 'ref.1.out' + self.simpoint = 340*100E6 class art470(art): def ref(self, isa, os): @@ -254,11 +262,13 @@ class art470(art): '-endy', '180', '-objects', '10' ] self.output = 'ref.2.out' + self.simpoint = 365*100E6 class equake(DefaultBenchmark): name = 'equake' number = 183 lang = 'C' + simpoint = 812*100E6 def lgred(self, isa, os): pass @@ -266,21 +276,25 @@ class facerec(MinneDefaultBenchmark): name = 'facerec' number = 187 lang = 'F' + simpoint = 375*100E6 class fma3d(MinneDefaultBenchmark): name = 'fma3d' number = 191 lang = 'F' + simpoint = 2541*100E6 class galgel(MinneDefaultBenchmark): name = 'galgel' number = 178 lang = 'F' + simpoint = 2491*100E6 class lucas(MinneDefaultBenchmark): name = 'lucas' number = 189 lang = 'F' + simpoint = 545*100E6 class mesa(Benchmark): name = 'mesa' @@ -300,6 +314,7 @@ class mesa(Benchmark): def ref(self, isa, os): self.__set_args('1000') + self.simpoint = 1135*100E6 def lgred(self, isa, os): self.__set_args('1') @@ -308,11 +323,13 @@ class mgrid(MinneDefaultBenchmark): name = 'mgrid' number = 172 lang = 'F77' + simpoint = 3292*100E6 class sixtrack(DefaultBenchmark): name = 'sixtrack' number = 200 lang = 'F77' + simpoint = 3043*100E6 def lgred(self, isa, os): pass @@ -320,11 +337,13 @@ class swim(MinneDefaultBenchmark): name = 'swim' number = 171 lang = 'F77' + simpoint = 2079*100E6 class wupwise(DefaultBenchmark): name = 'wupwise' number = 168 lang = 'F77' + simpoint = 3237*100E6 def lgred(self, isa, os): pass @@ -341,6 +360,7 @@ class bzip2(DefaultBenchmark): class bzip2_source(bzip2): def ref(self, isa, os): + self.simpoint = 977*100E6 self.args = [ 'input.source', '58' ] def lgred(self, isa, os): @@ -348,6 +368,7 @@ class bzip2_source(bzip2): class bzip2_graphic(bzip2): def ref(self, isa, os): + self.simpoint = 718*100E6 self.args = [ 'input.graphic', '58' ] def lgred(self, isa, os): @@ -355,6 +376,7 @@ class bzip2_graphic(bzip2): class bzip2_program(bzip2): def ref(self, isa, os): + self.simpoint = 458*100E6 self.args = [ 'input.program', '58' ] def lgred(self, isa, os): @@ -364,6 +386,7 @@ class crafty(MinneDefaultBenchmark): name = 'crafty' number = 186 lang = 'C' + simpoint = 774*100E6 class eon(MinneDefaultBenchmark): name = 'eon' @@ -386,6 +409,7 @@ class eon_rushmeier(eon): args = [ 'chair.control.rushmeier', 'chair.camera', 'chair.surfaces', 'chair.rushmeier.ppm', 'ppm', 'pixels_out.rushmeier' ] output = 'rushmeier_log.out' + simpoint = 403*100E6 class gap(DefaultBenchmark): name = 'gap' @@ -403,6 +427,7 @@ class gap(DefaultBenchmark): def ref(self, isa, os): self.__set_args('192M') + self.simpoint = 674*100E6 def lgred(self, isa, os): self.__set_args('64M') @@ -435,22 +460,27 @@ class gcc(DefaultBenchmark): class gcc_166(gcc): def ref(self, isa, os): + self.simpoint = 389*100E6 self.args = [ '166.i', '-o', '166.s' ] class gcc_200(gcc): def ref(self, isa, os): + self.simpoint = 736*100E6 self.args = [ '200.i', '-o', '200.s' ] class gcc_expr(gcc): def ref(self, isa, os): + self.simpoint = 36*100E6 self.args = [ 'expr.i', '-o', 'expr.s' ] class gcc_integrate(gcc): def ref(self, isa, os): + self.simpoint = 4*100E6 self.args = [ 'integrate.i', '-o', 'integrate.s' ] class gcc_scilab(gcc): def ref(self, isa, os): + self.simpoint = 207*100E6 self.args = [ 'scilab.i', '-o', 'scilab.s' ] class gzip(DefaultBenchmark): @@ -466,6 +496,7 @@ class gzip(DefaultBenchmark): class gzip_source(gzip): def ref(self, isa, os): + self.simpoint = 334*100E6 self.args = [ 'input.source', '1' ] def smred(self, isa, os): self.args = [ 'input.source', '1' ] @@ -476,6 +507,7 @@ class gzip_source(gzip): class gzip_log(gzip): def ref(self, isa, os): + self.simpoint = 265*100E6 self.args = [ 'input.log', '60' ] def smred(self, isa, os): self.args = [ 'input.log', '1' ] @@ -486,6 +518,7 @@ class gzip_log(gzip): class gzip_graphic(gzip): def ref(self, isa, os): + self.simpoint = 653*100E6 self.args = [ 'input.graphic', '60' ] def smred(self, isa, os): self.args = [ 'input.graphic', '1' ] @@ -496,6 +529,7 @@ class gzip_graphic(gzip): class gzip_random(gzip): def ref(self, isa, os): + self.simpoint = 623*100E6 self.args = [ 'input.random', '60' ] def smred(self, isa, os): self.args = [ 'input.random', '1' ] @@ -506,6 +540,7 @@ class gzip_random(gzip): class gzip_program(gzip): def ref(self, isa, os): + self.simpoint = 1189*100E6 self.args = [ 'input.program', '60' ] def smred(self, isa, os): self.args = [ 'input.program', '1' ] @@ -519,12 +554,14 @@ class mcf(MinneDefaultBenchmark): number = 181 lang = 'C' args = [ 'mcf.in' ] + simpoint = 553*100E6 class parser(MinneDefaultBenchmark): name = 'parser' number = 197 lang = 'C' args = [ '2.1.dict', '-batch' ] + simpoint = 1146*100E6 class perlbmk(DefaultBenchmark): name = 'perlbmk' @@ -537,6 +574,7 @@ class perlbmk(DefaultBenchmark): class perlbmk_diffmail(perlbmk): def ref(self, isa, os): + self.simpoint = 141*100E6 self.args = [ '-I', 'lib', 'diffmail.pl', '2', '550', '15', '24', '23', '100' ] @@ -551,6 +589,7 @@ class perlbmk_scrabbl(perlbmk): class perlbmk_makerand(perlbmk): def ref(self, isa, os): + self.simpoint = 11*100E6 self.args = [ '-I', 'lib', 'makerand.pl' ] def lgred(self, isa, os): @@ -564,6 +603,7 @@ class perlbmk_makerand(perlbmk): class perlbmk_perfect(perlbmk): def ref(self, isa, os): + self.simpoint = 5*100E6 self.args = [ '-I', 'lib', 'perfect.pl', 'b', '3', 'm', '4' ] def train(self, isa, os): @@ -571,6 +611,7 @@ class perlbmk_perfect(perlbmk): class perlbmk_splitmail1(perlbmk): def ref(self, isa, os): + self.simpoint = 405*100E6 self.args = [ '-I', 'lib', 'splitmail.pl', '850', '5', '19', '18', '1500' ] @@ -602,6 +643,7 @@ class twolf(Benchmark): self.args = [ 'train' ] def ref(self, isa, os): + self.simpoint = 1066*100E6 self.args = [ 'ref' ] def smred(self, isa, os): @@ -653,15 +695,18 @@ class vortex1(vortex): def ref(self, isa, os): self.args = [ '%s1.raw' % self.endian ] self.output = 'vortex1.out' + self.simpoint = 271*100E6 class vortex2(vortex): def ref(self, isa, os): + self.simpoint = 1024*100E6 self.args = [ '%s2.raw' % self.endian ] self.output = 'vortex2.out' class vortex3(vortex): def ref(self, isa, os): + self.simpoint = 564*100E6 self.args = [ '%s3.raw' % self.endian ] self.output = 'vortex3.out' @@ -678,6 +723,7 @@ class vpr_place(vpr): output = 'place_log.out' class vpr_route(vpr): + simpoint = 476*100E6 args = [ 'net.in', 'arch.in', 'place.in', 'route.out', '-nodisp', '-route_only', '-route_chan_width', '15', '-pres_fac_mult', '2', '-acc_fac', '1', diff --git a/src/arch/alpha/tlb.cc b/src/arch/alpha/tlb.cc index 2e974effe..77bf5e285 100644 --- a/src/arch/alpha/tlb.cc +++ b/src/arch/alpha/tlb.cc @@ -58,7 +58,7 @@ bool uncacheBit40 = false; #define MODE2MASK(X) (1 << (X)) TLB::TLB(const Params *p) - : SimObject(p), size(p->size), nlu(0) + : BaseTLB(p), size(p->size), nlu(0) { table = new TlbEntry[size]; memset(table, 0, sizeof(TlbEntry[size])); diff --git a/src/arch/alpha/tlb.hh b/src/arch/alpha/tlb.hh index 69a33f32d..e61ae5c6d 100644 --- a/src/arch/alpha/tlb.hh +++ b/src/arch/alpha/tlb.hh @@ -44,7 +44,7 @@ #include "params/AlphaDTB.hh" #include "params/AlphaITB.hh" #include "sim/faults.hh" -#include "sim/sim_object.hh" +#include "sim/tlb.hh" class ThreadContext; @@ -52,7 +52,7 @@ namespace AlphaISA { class TlbEntry; - class TLB : public SimObject + class TLB : public BaseTLB { protected: typedef std::multimap<Addr, int> PageTable; @@ -79,6 +79,12 @@ namespace AlphaISA void flushProcesses(); void flushAddr(Addr addr, uint8_t asn); + void demapPage(Addr vaddr, uint64_t asn) + { + assert(asn < (1 << 8)); + flushAddr(vaddr, asn); + } + // static helper functions... really EV5 VM traits static bool validVirtualAddress(Addr vaddr) { // unimplemented bits must be all 0 or all 1 diff --git a/src/arch/mips/tlb.cc b/src/arch/mips/tlb.cc index 4923e3e3a..d78aefab4 100644 --- a/src/arch/mips/tlb.cc +++ b/src/arch/mips/tlb.cc @@ -62,7 +62,7 @@ using namespace MipsISA; #define MODE2MASK(X) (1 << (X)) TLB::TLB(const Params *p) - : SimObject(p), size(p->size), nlu(0) + : BaseTLB(p), size(p->size), nlu(0) { table = new MipsISA::PTE[size]; memset(table, 0, sizeof(MipsISA::PTE[size])); diff --git a/src/arch/mips/tlb.hh b/src/arch/mips/tlb.hh index d6f9ac101..4333777ff 100644 --- a/src/arch/mips/tlb.hh +++ b/src/arch/mips/tlb.hh @@ -80,7 +80,7 @@ struct TlbEntry }; -class TLB : public SimObject +class TLB : public BaseTLB { protected: typedef std::multimap<Addr, int> PageTable; @@ -120,6 +120,10 @@ class TLB : public SimObject void insert(Addr vaddr, MipsISA::PTE &pte); void insertAt(MipsISA::PTE &pte, unsigned Index, int _smallPages); void flushAll(); + void demapPage(Addr vaddr, uint64_t asn) + { + panic("demapPage unimplemented.\n"); + } // static helper functions... really static bool validVirtualAddress(Addr vaddr); diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 740da37ab..22df44908 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -46,7 +46,7 @@ namespace SparcISA { TLB::TLB(const Params *p) - : SimObject(p), size(p->size), usedEntries(0), lastReplaced(0), + : BaseTLB(p), size(p->size), usedEntries(0), lastReplaced(0), cacheValid(false) { // To make this work you'll have to change the hypervisor and OS diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh index b38ee15dc..2f7d08320 100644 --- a/src/arch/sparc/tlb.hh +++ b/src/arch/sparc/tlb.hh @@ -39,7 +39,7 @@ #include "params/SparcDTB.hh" #include "params/SparcITB.hh" #include "sim/faults.hh" -#include "sim/sim_object.hh" +#include "sim/tlb.hh" class ThreadContext; class Packet; @@ -47,7 +47,7 @@ class Packet; namespace SparcISA { -class TLB : public SimObject +class TLB : public BaseTLB { #if !FULL_SYSTEM //These faults need to be able to populate the tlb in SE mode. @@ -152,6 +152,11 @@ class TLB : public SimObject typedef SparcTLBParams Params; TLB(const Params *p); + void demapPage(Addr vaddr, uint64_t asn) + { + panic("demapPage(Addr) is not implemented.\n"); + } + void dumpAll(); // Checkpointing diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript index 1b589268d..674cd54c2 100644 --- a/src/arch/x86/SConscript +++ b/src/arch/x86/SConscript @@ -184,6 +184,7 @@ if env['TARGET_ISA'] == 'x86': 'general_purpose/system_calls.py', 'system/__init__.py', 'system/halt.py', + 'system/invlpg.py', 'system/undefined_operation.py', 'system/msrs.py', 'system/segmentation.py', diff --git a/src/arch/x86/isa/decoder/two_byte_opcodes.isa b/src/arch/x86/isa/decoder/two_byte_opcodes.isa index d90df6f45..8135a1fdb 100644 --- a/src/arch/x86/isa/decoder/two_byte_opcodes.isa +++ b/src/arch/x86/isa/decoder/two_byte_opcodes.isa @@ -157,7 +157,7 @@ } 0x4: smsw_Mw(); 0x6: lmsw_Mw(); - 0x7: invlpg_M(); + 0x7: Inst::INVLPG(M); default: Inst::UD2(); } } diff --git a/src/arch/x86/isa/insts/system/__init__.py b/src/arch/x86/isa/insts/system/__init__.py index 5984761a6..409a929f5 100644 --- a/src/arch/x86/isa/insts/system/__init__.py +++ b/src/arch/x86/isa/insts/system/__init__.py @@ -1,4 +1,32 @@ -# Copyright (c) 2007 The Hewlett-Packard Development Company +# Copyright (c) 2008 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company # All rights reserved. # # Redistribution and use of this software in source and binary forms, @@ -54,6 +82,7 @@ # Authors: Gabe Black categories = ["halt", + "invlpg", "undefined_operation", "msrs", "segmentation"] diff --git a/src/arch/x86/isa/insts/system/invlpg.py b/src/arch/x86/isa/insts/system/invlpg.py new file mode 100644 index 000000000..e4241e826 --- /dev/null +++ b/src/arch/x86/isa/insts/system/invlpg.py @@ -0,0 +1,93 @@ +# Copyright (c) 2008 The Regents of The University of Michigan +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +# Copyright (c) 2007-2008 The Hewlett-Packard Development Company +# All rights reserved. +# +# Redistribution and use of this software in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# +# The software must be used only for Non-Commercial Use which means any +# use which is NOT directed to receiving any direct monetary +# compensation for, or commercial advantage from such use. Illustrative +# examples of non-commercial use are academic research, personal study, +# teaching, education and corporate research & development. +# Illustrative examples of commercial use are distributing products for +# commercial advantage and providing services using the software for +# commercial advantage. +# +# If you wish to use this software or functionality therein that may be +# covered by patents for commercial use, please contact: +# Director of Intellectual Property Licensing +# Office of Strategy and Technology +# Hewlett-Packard Company +# 1501 Page Mill Road +# Palo Alto, California 94304 +# +# 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. No right of +# sublicense is granted herewith. Derivatives of the software and +# output created using the software may be prepared, but only for +# Non-Commercial Uses. Derivatives of the software may be shared with +# others provided: (i) the others agree to abide by the list of +# conditions herein which includes the Non-Commercial Use restrictions; +# and (ii) such Derivatives of the software include the above copyright +# notice to acknowledge the contribution from this software where +# applicable, this list of conditions and the disclaimer below. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# Authors: Gabe Black + +microcode = ''' +def macroop INVLPG_M { + tia seg, sib, disp +}; + +def macroop INVLPG_P { + rdip t7 + tia seg, riprel, disp +}; +''' diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index 77152a190..cb63e7cd9 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -1,4 +1,32 @@ -// Copyright (c) 2007 The Hewlett-Packard Development Company +// Copyright (c) 2008 The Regents of The University of Michigan +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer; +// redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution; +// neither the name of the copyright holders nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Gabe Black + +// Copyright (c) 2007-2008 The Hewlett-Packard Development Company // All rights reserved. // // Redistribution and use of this software in source and binary forms, @@ -447,6 +475,24 @@ let {{ microopClasses["lea"] = LeaOp + iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp', + {"code": "xc->demapPage(EA, 0);", + "ea_code": calculateEA, + "mem_flags": 0}) + header_output += MicroLeaDeclare.subst(iop) + decoder_output += MicroLdStOpConstructor.subst(iop) + exec_output += MicroLeaExecute.subst(iop) + + class TiaOp(LdStOp): + def __init__(self, segment, addr, disp = 0, + dataSize="env.dataSize", addressSize="env.addressSize"): + super(TiaOp, self).__init__("NUM_INTREGS", segment, + addr, disp, dataSize, addressSize) + self.className = "Tia" + self.mnemonic = "tia" + + microopClasses["tia"] = TiaOp + iop = InstObjParams("cda", "Cda", 'X86ISA::LdStOp', {"code": ''' Addr paddr; diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc index 153610e44..3b4dc3407 100644 --- a/src/arch/x86/miscregfile.cc +++ b/src/arch/x86/miscregfile.cc @@ -123,6 +123,84 @@ MiscReg MiscRegFile::readRegNoEffect(int miscReg) MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) { + if (miscReg >= MISCREG_APIC_START && miscReg <= MISCREG_APIC_END) { + if (miscReg >= MISCREG_APIC_IN_SERVICE(0) && + miscReg <= MISCREG_APIC_IN_SERVICE(15)) { + panic("Local APIC In-Service registers are unimplemented.\n"); + } + if (miscReg >= MISCREG_APIC_TRIGGER_MODE(0) && + miscReg <= MISCREG_APIC_TRIGGER_MODE(15)) { + panic("Local APIC Trigger Mode registers are unimplemented.\n"); + } + if (miscReg >= MISCREG_APIC_INTERRUPT_REQUEST(0) && + miscReg <= MISCREG_APIC_INTERRUPT_REQUEST(15)) { + panic("Local APIC Interrupt Request registers " + "are unimplemented.\n"); + } + switch (miscReg) { + case MISCREG_APIC_TASK_PRIORITY: + panic("Local APIC Task Priority register unimplemented.\n"); + break; + case MISCREG_APIC_ARBITRATION_PRIORITY: + panic("Local APIC Arbitration Priority register unimplemented.\n"); + break; + case MISCREG_APIC_PROCESSOR_PRIORITY: + panic("Local APIC Processor Priority register unimplemented.\n"); + break; + case MISCREG_APIC_EOI: + panic("Local APIC EOI register unimplemented.\n"); + break; + case MISCREG_APIC_LOGICAL_DESTINATION: + panic("Local APIC Logical Destination register unimplemented.\n"); + break; + case MISCREG_APIC_DESTINATION_FORMAT: + panic("Local APIC Destination Format register unimplemented.\n"); + break; + case MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR: + panic("Local APIC Spurious Interrupt Vector" + " register unimplemented.\n"); + break; + case MISCREG_APIC_ERROR_STATUS: + panic("Local APIC Error Status register unimplemented.\n"); + break; + case MISCREG_APIC_INTERRUPT_COMMAND_LOW: + panic("Local APIC Interrupt Command low" + " register unimplemented.\n"); + break; + case MISCREG_APIC_INTERRUPT_COMMAND_HIGH: + panic("Local APIC Interrupt Command high" + " register unimplemented.\n"); + break; + case MISCREG_APIC_LVT_TIMER: + panic("Local APIC LVT Timer register unimplemented.\n"); + break; + case MISCREG_APIC_LVT_THERMAL_SENSOR: + panic("Local APIC LVT Thermal Sensor register unimplemented.\n"); + break; + case MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS: + panic("Local APIC LVT Performance Monitoring Counters" + " register unimplemented.\n"); + break; + case MISCREG_APIC_LVT_LINT0: + panic("Local APIC LVT LINT0 register unimplemented.\n"); + break; + case MISCREG_APIC_LVT_LINT1: + panic("Local APIC LVT LINT1 register unimplemented.\n"); + break; + case MISCREG_APIC_LVT_ERROR: + panic("Local APIC LVT Error register unimplemented.\n"); + break; + case MISCREG_APIC_INITIAL_COUNT: + panic("Local APIC Initial Count register unimplemented.\n"); + break; + case MISCREG_APIC_CURRENT_COUNT: + panic("Local APIC Current Count register unimplemented.\n"); + break; + case MISCREG_APIC_DIVIDE_COUNT: + panic("Local APIC Divide Count register unimplemented.\n"); + break; + } + } return readRegNoEffect(miscReg); } @@ -143,6 +221,92 @@ void MiscRegFile::setReg(int miscReg, const MiscReg &val, ThreadContext * tc) { MiscReg newVal = val; + if (miscReg >= MISCREG_APIC_START && miscReg <= MISCREG_APIC_END) { + if (miscReg >= MISCREG_APIC_IN_SERVICE(0) && + miscReg <= MISCREG_APIC_IN_SERVICE(15)) { + panic("Local APIC In-Service registers are unimplemented.\n"); + } + if (miscReg >= MISCREG_APIC_TRIGGER_MODE(0) && + miscReg <= MISCREG_APIC_TRIGGER_MODE(15)) { + panic("Local APIC Trigger Mode registers are unimplemented.\n"); + } + if (miscReg >= MISCREG_APIC_INTERRUPT_REQUEST(0) && + miscReg <= MISCREG_APIC_INTERRUPT_REQUEST(15)) { + panic("Local APIC Interrupt Request registers " + "are unimplemented.\n"); + } + switch (miscReg) { + case MISCREG_APIC_ID: + panic("Local APIC ID register unimplemented.\n"); + break; + case MISCREG_APIC_VERSION: + panic("Local APIC Version register is read only.\n"); + break; + case MISCREG_APIC_TASK_PRIORITY: + panic("Local APIC Task Priority register unimplemented.\n"); + break; + case MISCREG_APIC_ARBITRATION_PRIORITY: + panic("Local APIC Arbitration Priority register unimplemented.\n"); + break; + case MISCREG_APIC_PROCESSOR_PRIORITY: + panic("Local APIC Processor Priority register unimplemented.\n"); + break; + case MISCREG_APIC_EOI: + panic("Local APIC EOI register unimplemented.\n"); + break; + case MISCREG_APIC_LOGICAL_DESTINATION: + panic("Local APIC Logical Destination register unimplemented.\n"); + break; + case MISCREG_APIC_DESTINATION_FORMAT: + panic("Local APIC Destination Format register unimplemented.\n"); + break; + case MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR: + panic("Local APIC Spurious Interrupt Vector" + " register unimplemented.\n"); + break; + case MISCREG_APIC_ERROR_STATUS: + panic("Local APIC Error Status register unimplemented.\n"); + break; + case MISCREG_APIC_INTERRUPT_COMMAND_LOW: + panic("Local APIC Interrupt Command low" + " register unimplemented.\n"); + break; + case MISCREG_APIC_INTERRUPT_COMMAND_HIGH: + panic("Local APIC Interrupt Command high" + " register unimplemented.\n"); + break; + case MISCREG_APIC_LVT_TIMER: + panic("Local APIC LVT Timer register unimplemented.\n"); + break; + case MISCREG_APIC_LVT_THERMAL_SENSOR: + panic("Local APIC LVT Thermal Sensor register unimplemented.\n"); + break; + case MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS: + panic("Local APIC LVT Performance Monitoring Counters" + " register unimplemented.\n"); + break; + case MISCREG_APIC_LVT_LINT0: + panic("Local APIC LVT LINT0 register unimplemented.\n"); + break; + case MISCREG_APIC_LVT_LINT1: + panic("Local APIC LVT LINT1 register unimplemented.\n"); + break; + case MISCREG_APIC_LVT_ERROR: + panic("Local APIC LVT Error register unimplemented.\n"); + break; + case MISCREG_APIC_INITIAL_COUNT: + panic("Local APIC Initial Count register unimplemented.\n"); + break; + case MISCREG_APIC_CURRENT_COUNT: + panic("Local APIC Current Count register unimplemented.\n"); + break; + case MISCREG_APIC_DIVIDE_COUNT: + panic("Local APIC Divide Count register unimplemented.\n"); + break; + } + setRegNoEffect(miscReg, newVal); + return; + } switch(miscReg) { case MISCREG_CR0: diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh index 36b953526..d1016d2a9 100644 --- a/src/arch/x86/miscregs.hh +++ b/src/arch/x86/miscregs.hh @@ -339,6 +339,43 @@ namespace X86ISA //XXX Add "Model-Specific Registers" + MISCREG_APIC_BASE, + + MISCREG_APIC_START, + MISCREG_APIC_ID = MISCREG_APIC_START, + MISCREG_APIC_VERSION, + MISCREG_APIC_TASK_PRIORITY, + MISCREG_APIC_ARBITRATION_PRIORITY, + MISCREG_APIC_PROCESSOR_PRIORITY, + MISCREG_APIC_EOI, + MISCREG_APIC_LOGICAL_DESTINATION, + MISCREG_APIC_DESTINATION_FORMAT, + MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR, + + MISCREG_APIC_IN_SERVICE_BASE, + + MISCREG_APIC_TRIGGER_MODE_BASE = MISCREG_APIC_IN_SERVICE_BASE + 16, + + MISCREG_APIC_INTERRUPT_REQUEST_BASE = + MISCREG_APIC_TRIGGER_MODE_BASE + 16, + + MISCREG_APIC_ERROR_STATUS = MISCREG_APIC_INTERRUPT_REQUEST_BASE + 16, + MISCREG_APIC_INTERRUPT_COMMAND_LOW, + MISCREG_APIC_INTERRUPT_COMMAND_HIGH, + MISCREG_APIC_LVT_TIMER, + MISCREG_APIC_LVT_THERMAL_SENSOR, + MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS, + MISCREG_APIC_LVT_LINT0, + MISCREG_APIC_LVT_LINT1, + MISCREG_APIC_LVT_ERROR, + MISCREG_APIC_INITIAL_COUNT, + MISCREG_APIC_CURRENT_COUNT, + MISCREG_APIC_DIVIDE_COUNT, + MISCREG_APIC_END = MISCREG_APIC_DIVIDE_COUNT, + + // "Fake" MSRs for internally implemented devices + MISCREG_PCI_CONFIG_ADDRESS, + NUM_MISCREGS }; @@ -444,6 +481,24 @@ namespace X86ISA return (MiscRegIndex)(MISCREG_SEG_ATTR_BASE + index); } + static inline MiscRegIndex + MISCREG_APIC_IN_SERVICE(int index) + { + return (MiscRegIndex)(MISCREG_APIC_IN_SERVICE_BASE + index); + } + + static inline MiscRegIndex + MISCREG_APIC_TRIGGER_MODE(int index) + { + return (MiscRegIndex)(MISCREG_APIC_TRIGGER_MODE_BASE + index); + } + + static inline MiscRegIndex + MISCREG_APIC_INTERRUPT_REQUEST(int index) + { + return (MiscRegIndex)(MISCREG_APIC_INTERRUPT_REQUEST_BASE + index); + } + /** * A type to describe the condition code bits of the RFLAGS register, * plus two flags, EZF and ECF, which are only visible to microcode. @@ -792,6 +847,16 @@ namespace X86ISA */ BitUnion64(TR) EndBitUnion(TR) + + + /** + * Local APIC Base Register + */ + BitUnion64(LocalApicBase) + Bitfield<51, 12> base; + Bitfield<11> enable; + Bitfield<8> bsp; + EndBitUnion(LocalApicBase) }; #endif // __ARCH_X86_INTREGS_HH__ diff --git a/src/arch/x86/mmaped_ipr.hh b/src/arch/x86/mmaped_ipr.hh index 9184ec4dc..eda85c084 100644 --- a/src/arch/x86/mmaped_ipr.hh +++ b/src/arch/x86/mmaped_ipr.hh @@ -64,6 +64,7 @@ * ISA-specific helper functions for memory mapped IPR accesses. */ +#include "arch/x86/miscregs.hh" #include "config/full_system.hh" #include "cpu/base.hh" #include "cpu/thread_context.hh" @@ -77,7 +78,15 @@ namespace X86ISA #if !FULL_SYSTEM panic("Shouldn't have a memory mapped register in SE\n"); #else - pkt->set(xc->readMiscReg(pkt->getAddr() / sizeof(MiscReg))); + MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg)); + if (index == MISCREG_PCI_CONFIG_ADDRESS || + (index >= MISCREG_APIC_START && + index <= MISCREG_APIC_END)) { + pkt->set((uint32_t)(xc->readMiscReg(pkt->getAddr() / + sizeof(MiscReg)))); + } else { + pkt->set(xc->readMiscReg(pkt->getAddr() / sizeof(MiscReg))); + } #endif return xc->getCpuPtr()->ticks(1); } @@ -88,8 +97,15 @@ namespace X86ISA #if !FULL_SYSTEM panic("Shouldn't have a memory mapped register in SE\n"); #else - xc->setMiscReg(pkt->getAddr() / sizeof(MiscReg), - gtoh(pkt->get<uint64_t>())); + MiscRegIndex index = (MiscRegIndex)(pkt->getAddr() / sizeof(MiscReg)); + if (index == MISCREG_PCI_CONFIG_ADDRESS || + (index >= MISCREG_APIC_START && + index <= MISCREG_APIC_END)) { + xc->setMiscReg(index, gtoh(pkt->get<uint32_t>())); + } else { + xc->setMiscReg(pkt->getAddr() / sizeof(MiscReg), + gtoh(pkt->get<uint64_t>())); + } #endif return xc->getCpuPtr()->ticks(1); } diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc index 2e6ea4a22..a87abf212 100644 --- a/src/arch/x86/tlb.cc +++ b/src/arch/x86/tlb.cc @@ -76,7 +76,7 @@ namespace X86ISA { -TLB::TLB(const Params *p) : SimObject(p), size(p->size) +TLB::TLB(const Params *p) : BaseTLB(p), configAddress(0), size(p->size) { tlb = new TlbEntry[size]; std::memset(tlb, 0, sizeof(TlbEntry) * size); @@ -108,8 +108,8 @@ TLB::insert(Addr vpn, TlbEntry &entry) entryList.push_front(newEntry); } -TlbEntry * -TLB::lookup(Addr va, bool update_lru) +TLB::EntryList::iterator +TLB::lookupIt(Addr va, bool update_lru) { //TODO make this smarter at some point EntryList::iterator entry; @@ -117,15 +117,25 @@ TLB::lookup(Addr va, bool update_lru) if ((*entry)->vaddr <= va && (*entry)->vaddr + (*entry)->size > va) { DPRINTF(TLB, "Matched vaddr %#x to entry starting at %#x " "with size %#x.\n", va, (*entry)->vaddr, (*entry)->size); - TlbEntry *e = *entry; if (update_lru) { + entryList.push_front(*entry); entryList.erase(entry); - entryList.push_front(e); + entry = entryList.begin(); } - return e; + break; } } - return NULL; + return entry; +} + +TlbEntry * +TLB::lookup(Addr va, bool update_lru) +{ + EntryList::iterator entry = lookupIt(va, update_lru); + if (entry == entryList.end()) + return NULL; + else + return *entry; } #if FULL_SYSTEM @@ -148,6 +158,12 @@ TLB::invalidateAll() } void +TLB::setConfigAddress(uint32_t addr) +{ + configAddress = addr; +} + +void TLB::invalidateNonGlobal() { DPRINTF(TLB, "Invalidating all non global entries.\n"); @@ -163,8 +179,13 @@ TLB::invalidateNonGlobal() } void -TLB::demapPage(Addr va) +TLB::demapPage(Addr va, uint64_t asn) { + EntryList::iterator entry = lookupIt(va, false); + if (entry != entryList.end()) { + freeList.push_back(*entry); + entryList.erase(entry); + } } template<class TlbFault> @@ -195,6 +216,9 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) case 0x10: regNum = MISCREG_TSC; break; + case 0x1B: + regNum = MISCREG_APIC_BASE; + break; case 0xFE: regNum = MISCREG_MTRRCAP; break; @@ -478,7 +502,19 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) // Make sure the address fits in the expected 16 bit IO address // space. assert(!(IOPort & ~0xFFFF)); - req->setPaddr(PhysAddrPrefixIO | IOPort); + if (IOPort == 0xCF8 && req->getSize() == 4) { + req->setMmapedIpr(true); + req->setPaddr(MISCREG_PCI_CONFIG_ADDRESS * sizeof(MiscReg)); + } else if ((IOPort & ~mask(2)) == 0xCFC) { + Addr configAddress = + tc->readMiscRegNoEffect(MISCREG_PCI_CONFIG_ADDRESS); + if (bits(configAddress, 31, 31)) { + req->setPaddr(PhysAddrPrefixPciConfig | + bits(configAddress, 30, 0)); + } + } else { + req->setPaddr(PhysAddrPrefixIO | IOPort); + } return NoFault; } else { panic("Access to unrecognized internal address space %#x.\n", @@ -555,6 +591,148 @@ TLB::translate(RequestPtr &req, ThreadContext *tc, bool write, bool execute) DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, vaddr); req->setPaddr(vaddr); } + // Check for an access to the local APIC + LocalApicBase localApicBase = tc->readMiscRegNoEffect(MISCREG_APIC_BASE); + Addr baseAddr = localApicBase.base << 12; + Addr paddr = req->getPaddr(); + if (baseAddr <= paddr && baseAddr + (1 << 12) > paddr) { + req->setMmapedIpr(true); + // Check alignment + if (paddr & ((32/8) - 1)) + return new GeneralProtection(0); + // Check access size + if (req->getSize() != (32/8)) + return new GeneralProtection(0); + MiscReg regNum; + switch (paddr - baseAddr) + { + case 0x20: + regNum = MISCREG_APIC_ID; + break; + case 0x30: + regNum = MISCREG_APIC_VERSION; + break; + case 0x80: + regNum = MISCREG_APIC_TASK_PRIORITY; + break; + case 0x90: + regNum = MISCREG_APIC_ARBITRATION_PRIORITY; + break; + case 0xA0: + regNum = MISCREG_APIC_PROCESSOR_PRIORITY; + break; + case 0xB0: + regNum = MISCREG_APIC_EOI; + break; + case 0xD0: + regNum = MISCREG_APIC_LOGICAL_DESTINATION; + break; + case 0xE0: + regNum = MISCREG_APIC_DESTINATION_FORMAT; + break; + case 0xF0: + regNum = MISCREG_APIC_SPURIOUS_INTERRUPT_VECTOR; + break; + case 0x100: + case 0x108: + case 0x110: + case 0x118: + case 0x120: + case 0x128: + case 0x130: + case 0x138: + case 0x140: + case 0x148: + case 0x150: + case 0x158: + case 0x160: + case 0x168: + case 0x170: + case 0x178: + regNum = MISCREG_APIC_IN_SERVICE( + (paddr - baseAddr - 0x100) / 0x8); + break; + case 0x180: + case 0x188: + case 0x190: + case 0x198: + case 0x1A0: + case 0x1A8: + case 0x1B0: + case 0x1B8: + case 0x1C0: + case 0x1C8: + case 0x1D0: + case 0x1D8: + case 0x1E0: + case 0x1E8: + case 0x1F0: + case 0x1F8: + regNum = MISCREG_APIC_TRIGGER_MODE( + (paddr - baseAddr - 0x180) / 0x8); + break; + case 0x200: + case 0x208: + case 0x210: + case 0x218: + case 0x220: + case 0x228: + case 0x230: + case 0x238: + case 0x240: + case 0x248: + case 0x250: + case 0x258: + case 0x260: + case 0x268: + case 0x270: + case 0x278: + regNum = MISCREG_APIC_INTERRUPT_REQUEST( + (paddr - baseAddr - 0x200) / 0x8); + break; + case 0x280: + regNum = MISCREG_APIC_ERROR_STATUS; + break; + case 0x300: + regNum = MISCREG_APIC_INTERRUPT_COMMAND_LOW; + break; + case 0x310: + regNum = MISCREG_APIC_INTERRUPT_COMMAND_HIGH; + break; + case 0x320: + regNum = MISCREG_APIC_LVT_TIMER; + break; + case 0x330: + regNum = MISCREG_APIC_LVT_THERMAL_SENSOR; + break; + case 0x340: + regNum = MISCREG_APIC_LVT_PERFORMANCE_MONITORING_COUNTERS; + break; + case 0x350: + regNum = MISCREG_APIC_LVT_LINT0; + break; + case 0x360: + regNum = MISCREG_APIC_LVT_LINT1; + break; + case 0x370: + regNum = MISCREG_APIC_LVT_ERROR; + break; + case 0x380: + regNum = MISCREG_APIC_INITIAL_COUNT; + break; + case 0x390: + regNum = MISCREG_APIC_CURRENT_COUNT; + break; + case 0x3E0: + regNum = MISCREG_APIC_DIVIDE_COUNT; + break; + default: + // A reserved register field. + return new GeneralProtection(0); + break; + } + req->setPaddr(regNum * sizeof(MiscReg)); + } return NoFault; }; diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh index a361c2291..89b965e97 100644 --- a/src/arch/x86/tlb.hh +++ b/src/arch/x86/tlb.hh @@ -70,6 +70,7 @@ #include "params/X86DTB.hh" #include "params/X86ITB.hh" #include "sim/faults.hh" +#include "sim/tlb.hh" #include "sim/sim_object.hh" class ThreadContext; @@ -83,13 +84,16 @@ namespace X86ISA class TLB; - class TLB : public SimObject + class TLB : public BaseTLB { protected: friend class FakeITLBFault; friend class FakeDTLBFault; + typedef std::list<TlbEntry *> EntryList; + bool _allowNX; + uint32_t configAddress; public: bool allowNX() const @@ -104,6 +108,12 @@ namespace X86ISA TlbEntry *lookup(Addr va, bool update_lru = true); + void setConfigAddress(uint32_t addr); + + protected: + + EntryList::iterator lookupIt(Addr va, bool update_lru = true); + #if FULL_SYSTEM protected: @@ -117,14 +127,13 @@ namespace X86ISA void invalidateNonGlobal(); - void demapPage(Addr va); + void demapPage(Addr va, uint64_t asn); protected: int size; TlbEntry * tlb; - typedef std::list<TlbEntry *> EntryList; EntryList freeList; EntryList entryList; diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc index f5e87b860..5fe5bf8c3 100644 --- a/src/arch/x86/utility.cc +++ b/src/arch/x86/utility.cc @@ -248,6 +248,16 @@ void initCPU(ThreadContext *tc, int cpuId) // TODO Turn on the APIC. This should be handled elsewhere but it isn't // currently being handled at all. + LocalApicBase lApicBase = 0; + lApicBase.base = 0xFEE00000 >> 12; + lApicBase.enable = 1; + lApicBase.bsp = (cpuId == 0); + tc->setMiscReg(MISCREG_APIC_BASE, lApicBase); + + tc->setMiscRegNoEffect(MISCREG_APIC_ID, cpuId << 24); + + tc->setMiscRegNoEffect(MISCREG_APIC_VERSION, (5 << 16) | 0x14); + // TODO Set the SMRAM base address (SMBASE) to 0x00030000 tc->setMiscReg(MISCREG_VM_CR, 0); diff --git a/src/arch/x86/x86_traits.hh b/src/arch/x86/x86_traits.hh index dc71de500..d605ce218 100644 --- a/src/arch/x86/x86_traits.hh +++ b/src/arch/x86/x86_traits.hh @@ -88,7 +88,8 @@ namespace X86ISA const Addr IntAddrPrefixMSR = ULL(0x200000000); const Addr IntAddrPrefixIO = ULL(0x300000000); - const Addr PhysAddrPrefixIO = ULL(0x1000000000000000); + const Addr PhysAddrPrefixIO = ULL(0x8000000000000000); + const Addr PhysAddrPrefixPciConfig = ULL(0xC000000000000000); } #endif //__ARCH_X86_X86TRAITS_HH__ diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 74b250207..bea680fac 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -92,6 +92,19 @@ class BaseDynInst : public FastAlloc, public RefCounted /** InstRecord that tracks this instructions. */ Trace::InstRecord *traceData; + void demapPage(Addr vaddr, uint64_t asn) + { + cpu->demapPage(vaddr, asn); + } + void demapInstPage(Addr vaddr, uint64_t asn) + { + cpu->demapPage(vaddr, asn); + } + void demapDataPage(Addr vaddr, uint64_t asn) + { + cpu->demapPage(vaddr, asn); + } + /** * Does a read to a given address. * @param addr The address to read. diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh index 7b3628986..35dc59ff4 100644 --- a/src/cpu/checker/cpu.hh +++ b/src/cpu/checker/cpu.hh @@ -324,6 +324,22 @@ class CheckerCPU : public BaseCPU void recordPCChange(uint64_t val) { changedPC = true; newPC = val; } void recordNextPCChange(uint64_t val) { changedNextPC = true; } + void demapPage(Addr vaddr, uint64_t asn) + { + this->itb->demapPage(vaddr, asn); + this->dtb->demapPage(vaddr, asn); + } + + void demapInstPage(Addr vaddr, uint64_t asn) + { + this->itb->demapPage(vaddr, asn); + } + + void demapDataPage(Addr vaddr, uint64_t asn) + { + this->dtb->demapPage(vaddr, asn); + } + bool translateInstReq(Request *req); void translateDataWriteReq(Request *req); void translateDataReadReq(Request *req); diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 8eb17d23b..c75a08213 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -671,7 +671,12 @@ FullO3CPU<Impl>::removeThread(unsigned tid) // Copy Thread Data From RegFile // If thread is suspended, it might be re-allocated - //this->copyToTC(tid); + // this->copyToTC(tid); + + + // @todo: 2-27-2008: Fix how we free up rename mappings + // here to alleviate the case for double-freeing registers + // in SMT workloads. // Unbind Int Regs from Rename Map for (int ireg = 0; ireg < TheISA::NumIntRegs; ireg++) { @@ -682,7 +687,7 @@ FullO3CPU<Impl>::removeThread(unsigned tid) } // Unbind Float Regs from Rename Map - for (int freg = 0; freg < TheISA::NumFloatRegs; freg++) { + for (int freg = TheISA::NumIntRegs; freg < TheISA::NumFloatRegs; freg++) { PhysRegIndex phys_reg = renameMap[tid].lookup(freg); scoreboard.unsetReg(phys_reg); @@ -695,8 +700,11 @@ FullO3CPU<Impl>::removeThread(unsigned tid) decode.squash(tid); rename.squash(squash_seq_num, tid); iew.squash(tid); + iew.ldstQueue.squash(squash_seq_num, tid); commit.rob->squash(squash_seq_num, tid); + + assert(iew.instQueue.getCount(tid) == 0); assert(iew.ldstQueue.getCount(tid) == 0); // Reset ROB/IQ/LSQ Entries diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index e902968c1..61d7dcf22 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -263,6 +263,22 @@ class FullO3CPU : public BaseO3CPU /** Registers statistics. */ void fullCPURegStats(); + void demapPage(Addr vaddr, uint64_t asn) + { + this->itb->demapPage(vaddr, asn); + this->dtb->demapPage(vaddr, asn); + } + + void demapInstPage(Addr vaddr, uint64_t asn) + { + this->itb->demapPage(vaddr, asn); + } + + void demapDataPage(Addr vaddr, uint64_t asn) + { + this->dtb->demapPage(vaddr, asn); + } + /** Translates instruction requestion. */ Fault translateInstReq(RequestPtr &req, Thread *thread) { diff --git a/src/cpu/o3/free_list.hh b/src/cpu/o3/free_list.hh index 42fc0c533..97b56909e 100644 --- a/src/cpu/o3/free_list.hh +++ b/src/cpu/o3/free_list.hh @@ -173,6 +173,18 @@ SimpleFreeList::addReg(PhysRegIndex freed_reg) #endif freeFloatRegs.push(freed_reg); } + + // These assert conditions ensure that the number of free + // registers are not more than the # of total Physical Registers. + // If this were false, it would mean that registers + // have been freed twice, overflowing the free register + // pool and potentially crashing SMT workloads. + // ---- + // Comment out for now so as to not potentially break + // CMP and single-threaded workloads + // ---- + // assert(freeIntRegs.size() <= numPhysicalIntRegs); + // assert(freeFloatRegs.size() <= numPhysicalFloatRegs); } inline void diff --git a/src/cpu/ozone/cpu.hh b/src/cpu/ozone/cpu.hh index 61abae807..b0ea2cba9 100644 --- a/src/cpu/ozone/cpu.hh +++ b/src/cpu/ozone/cpu.hh @@ -423,6 +423,22 @@ class OzoneCPU : public BaseCPU virtual void serialize(std::ostream &os); virtual void unserialize(Checkpoint *cp, const std::string §ion); + void demapPage(Addr vaddr, uint64_t asn) + { + itb->demap(vaddr, asn); + dtb->demap(vaddr, asn); + } + + void demapInstPage(Addr vaddr, uint64_t asn) + { + itb->demap(vaddr, asn); + } + + void demapDataPage(Addr vaddr, uint64_t asn) + { + dtb->demap(vaddr, asn); + } + #if FULL_SYSTEM /** Translates instruction requestion. */ Fault translateInstReq(RequestPtr &req, OzoneThreadState<Impl> *thread) diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index 8c162a846..918965fdb 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -367,6 +367,21 @@ class BaseSimpleCPU : public BaseCPU return thread->setMiscReg(reg_idx, val); } + void demapPage(Addr vaddr, uint64_t asn) + { + thread->demapPage(vaddr, asn); + } + + void demapInstPage(Addr vaddr, uint64_t asn) + { + thread->demapInstPage(vaddr, asn); + } + + void demapDataPage(Addr vaddr, uint64_t asn) + { + thread->demapDataPage(vaddr, asn); + } + unsigned readStCondFailures() { return thread->readStCondFailures(); } diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index 2b79c9708..fa80a283a 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -163,6 +163,22 @@ class SimpleThread : public ThreadState return dtb->translate(req, tc, true); } + void demapPage(Addr vaddr, uint64_t asn) + { + itb->demapPage(vaddr, asn); + dtb->demapPage(vaddr, asn); + } + + void demapInstPage(Addr vaddr, uint64_t asn) + { + itb->demapPage(vaddr, asn); + } + + void demapDataPage(Addr vaddr, uint64_t asn) + { + dtb->demapPage(vaddr, asn); + } + #if FULL_SYSTEM int getInstAsid() { return regs.instAsid(); } int getDataAsid() { return regs.dataAsid(); } diff --git a/src/dev/x86/Opteron.py b/src/dev/x86/Opteron.py index 435ecccb6..cb015e2e7 100644 --- a/src/dev/x86/Opteron.py +++ b/src/dev/x86/Opteron.py @@ -3,8 +3,16 @@ from m5.proxy import * from Device import BasicPioDevice, PioDevice, IsaFake, BadAddr from Uart import Uart8250 from Platform import Platform +from Pci import PciConfigAll from SimConsole import SimConsole class Opteron(Platform): type = 'Opteron' system = Param.System(Parent.any, "system") + + pciconfig = PciConfigAll() + + def attachIO(self, bus): + self.pciconfig.pio = bus.default + bus.responder_set = True + bus.responder = self.pciconfig diff --git a/src/dev/x86/opteron.cc b/src/dev/x86/opteron.cc index df28e58de..ba46f2dfa 100644 --- a/src/dev/x86/opteron.cc +++ b/src/dev/x86/opteron.cc @@ -36,6 +36,7 @@ #include <string> #include <vector> +#include "arch/x86/x86_traits.hh" #include "cpu/intr_control.hh" #include "dev/simconsole.hh" #include "dev/x86/opteron.hh" @@ -95,8 +96,10 @@ Opteron::pciToDma(Addr pciAddr) const Addr Opteron::calcConfigAddr(int bus, int dev, int func) { - panic("Need implementation\n"); - M5_DUMMY_RETURN + assert(func < 8); + assert(dev < 32); + assert(bus == 0); + return (PhysAddrPrefixPciConfig | (func << 8) | (dev << 11)); } Opteron * diff --git a/src/sim/Process.py b/src/sim/Process.py index 07ed2c692..37a27bf3b 100644 --- a/src/sim/Process.py +++ b/src/sim/Process.py @@ -1,4 +1,4 @@ -# Copyright (c) 2005-2007 The Regents of The University of Michigan +# Copyright (c) 2005-2008 The Regents of The University of Michigan # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -50,3 +50,4 @@ class LiveProcess(Process): egid = Param.Int(100, 'effective group id') pid = Param.Int(100, 'process id') ppid = Param.Int(99, 'parent process id') + simpoint = Param.UInt64(0, 'simulation point at which to start simulation') diff --git a/src/sim/tlb.cc b/src/sim/tlb.cc index de6779839..7292a69e0 100644 --- a/src/sim/tlb.cc +++ b/src/sim/tlb.cc @@ -48,3 +48,9 @@ GenericTLB::translate(RequestPtr req, ThreadContext * tc, bool) return NoFault; #endif } + +void +GenericTLB::demapPage(Addr vaddr, uint64_t asn) +{ + warn("Demapping pages in the generic TLB is unnecessary.\n"); +} diff --git a/src/sim/tlb.hh b/src/sim/tlb.hh index b5e341185..011cc1144 100644 --- a/src/sim/tlb.hh +++ b/src/sim/tlb.hh @@ -39,13 +39,25 @@ class ThreadContext; class Packet; -class GenericTLB : public SimObject +class BaseTLB : public SimObject { protected: - GenericTLB(const Params *p) : SimObject(p) + BaseTLB(const Params *p) : SimObject(p) {} public: + virtual void demapPage(Addr vaddr, uint64_t asn) = 0; +}; + +class GenericTLB : public BaseTLB +{ + protected: + GenericTLB(const Params *p) : BaseTLB(p) + {} + + public: + void demapPage(Addr vaddr, uint64_t asn); + Fault translate(RequestPtr req, ThreadContext *tc, bool=false); }; |