Automated merge with ssh://daystrom.m5sim.org//repo/m5
--HG-- extra : convert_revision : f4bcd342e7abb86ca83840b723e6ab0b861ecf5b
This commit is contained in:
@@ -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()
|
||||
|
||||
|
||||
@@ -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.""")
|
||||
|
||||
@@ -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)
|
||||
|
||||
cpts.sort(lambda a,b: cmp(long(a), long(b)))
|
||||
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')
|
||||
|
||||
cpt_num = options.checkpoint_restore
|
||||
options.checkpoint_restore += \
|
||||
testsys.cpu[0].workload[0].simpoint
|
||||
|
||||
if cpt_num > len(cpts):
|
||||
m5.panic('Checkpoint %d not found' % cpt_num)
|
||||
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))
|
||||
|
||||
## Adjust max tick based on our starting tick
|
||||
maxtick = maxtick - int(cpts[cpt_num - 1])
|
||||
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))
|
||||
|
||||
## Restore the checkpoint
|
||||
m5.restoreCheckpoint(root,
|
||||
joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 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)
|
||||
|
||||
## 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]))
|
||||
|
||||
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())
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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]));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
}
|
||||
0x4: smsw_Mw();
|
||||
0x6: lmsw_Mw();
|
||||
0x7: invlpg_M();
|
||||
0x7: Inst::INVLPG(M);
|
||||
default: Inst::UD2();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"]
|
||||
|
||||
93
src/arch/x86/isa/insts/system/invlpg.py
Normal file
93
src/arch/x86/isa/insts/system/invlpg.py
Normal file
@@ -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
|
||||
};
|
||||
'''
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -147,6 +157,12 @@ TLB::invalidateAll()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TLB::setConfigAddress(uint32_t addr)
|
||||
{
|
||||
configAddress = addr;
|
||||
}
|
||||
|
||||
void
|
||||
TLB::invalidateNonGlobal()
|
||||
{
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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(); }
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user