summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKorey Sewell <ksewell@umich.edu>2009-05-05 02:44:21 -0400
committerKorey Sewell <ksewell@umich.edu>2009-05-05 02:44:21 -0400
commitdb79945ad0fe6863dd05944b6d1d905aa55de3ef (patch)
treec1bf567e6e035f60835a2217ca283287f163e104
parent9f90291c54135acc42be0fcb8843ec4e67eab2fb (diff)
parentdc35d2f125de43fb2b2865e9211cccca8546b8cd (diff)
downloadgem5-db79945ad0fe6863dd05944b6d1d905aa55de3ef.tar.xz
merge code
-rw-r--r--SConstruct2
-rw-r--r--src/SConscript361
-rw-r--r--src/arch/x86/faults.cc10
-rw-r--r--src/arch/x86/miscregfile.cc114
-rw-r--r--src/arch/x86/miscregfile.hh2
-rw-r--r--src/arch/x86/miscregs.hh7
-rw-r--r--src/arch/x86/predecoder.cc78
-rw-r--r--src/arch/x86/predecoder.hh5
-rw-r--r--src/arch/x86/process.cc36
-rw-r--r--src/arch/x86/tlb.cc745
-rw-r--r--src/arch/x86/tlb.hh2
-rw-r--r--src/sim/SConscript2
12 files changed, 704 insertions, 660 deletions
diff --git a/SConstruct b/SConstruct
index bfd93f26f..7a0bf2794 100644
--- a/SConstruct
+++ b/SConstruct
@@ -394,7 +394,7 @@ if main['GCC'] + main['SUNCC'] + main['ICC'] > 1:
if main['GCC']:
main.Append(CCFLAGS='-pipe')
main.Append(CCFLAGS='-fno-strict-aliasing')
- main.Append(CCFLAGS=Split('-Wall -Wno-sign-compare -Werror -Wundef'))
+ main.Append(CCFLAGS=['-Wall', '-Wno-sign-compare', '-Wundef'])
main.Append(CXXFLAGS='-Wno-deprecated')
elif main['ICC']:
pass #Fix me... add warning flags once we clean up icc warnings
diff --git a/src/SConscript b/src/SConscript
index 20d454f03..d36f5f244 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -29,6 +29,7 @@
# Authors: Nathan Binkert
import array
+import bisect
import imp
import marshal
import os
@@ -50,122 +51,144 @@ Export('env')
build_env = dict([(opt, env[opt]) for opt in export_vars])
-def sort_list(_list):
- """return a sorted copy of '_list'"""
- if isinstance(_list, list):
- _list = _list[:]
- else:
- _list = list(_list)
- _list.sort()
- return _list
+########################################################################
+# Code for adding source files of various types
+#
+class SourceMeta(type):
+ def __init__(cls, name, bases, dict):
+ super(SourceMeta, cls).__init__(name, bases, dict)
+ cls.all = []
+
+ def get(cls, **kwargs):
+ for src in cls.all:
+ for attr,value in kwargs.iteritems():
+ if getattr(src, attr) != value:
+ break
+ else:
+ yield src
+
+class SourceFile(object):
+ __metaclass__ = SourceMeta
+ def __init__(self, source):
+ tnode = source
+ if not isinstance(source, SCons.Node.FS.File):
+ tnode = File(source)
-class PySourceFile(object):
+ self.tnode = tnode
+ self.snode = tnode.srcnode()
+ self.filename = str(tnode)
+ self.dirname = dirname(self.filename)
+ self.basename = basename(self.filename)
+ index = self.basename.rfind('.')
+ if index <= 0:
+ # dot files aren't extensions
+ self.extname = self.basename, None
+ else:
+ self.extname = self.basename[:index], self.basename[index+1:]
+
+ for base in type(self).__mro__:
+ if issubclass(base, SourceFile):
+ bisect.insort_right(base.all, self)
+
+ def __lt__(self, other): return self.filename < other.filename
+ def __le__(self, other): return self.filename <= other.filename
+ def __gt__(self, other): return self.filename > other.filename
+ def __ge__(self, other): return self.filename >= other.filename
+ def __eq__(self, other): return self.filename == other.filename
+ def __ne__(self, other): return self.filename != other.filename
+
+class Source(SourceFile):
+ '''Add a c/c++ source file to the build'''
+ def __init__(self, source, Werror=True, swig=False, bin_only=False,
+ skip_lib=False):
+ super(Source, self).__init__(source)
+
+ self.Werror = Werror
+ self.swig = swig
+ self.bin_only = bin_only
+ self.skip_lib = bin_only or skip_lib
+
+class PySource(SourceFile):
+ '''Add a python source file to the named package'''
invalid_sym_char = re.compile('[^A-z0-9_]')
- def __init__(self, package, tnode):
- snode = tnode.srcnode()
- filename = str(tnode)
- pyname = basename(filename)
- assert pyname.endswith('.py')
- name = pyname[:-3]
+ modules = {}
+ tnodes = {}
+ symnames = {}
+
+ def __init__(self, package, source):
+ super(PySource, self).__init__(source)
+
+ modname,ext = self.extname
+ assert ext == 'py'
+
if package:
path = package.split('.')
else:
path = []
modpath = path[:]
- if name != '__init__':
- modpath += [name]
+ if modname != '__init__':
+ modpath += [ modname ]
modpath = '.'.join(modpath)
- arcpath = path + [ pyname ]
- arcname = joinpath(*arcpath)
-
- debugname = snode.abspath
+ arcpath = path + [ self.basename ]
+ debugname = self.snode.abspath
if not exists(debugname):
- debugname = tnode.abspath
+ debugname = self.tnode.abspath
- self.tnode = tnode
- self.snode = snode
- self.pyname = pyname
self.package = package
+ self.modname = modname
self.modpath = modpath
- self.arcname = arcname
+ self.arcname = joinpath(*arcpath)
self.debugname = debugname
- self.compiled = File(filename + 'c')
- self.assembly = File(filename + '.s')
- self.symname = "PyEMB_" + self.invalid_sym_char.sub('_', modpath)
-
+ self.compiled = File(self.filename + 'c')
+ self.assembly = File(self.filename + '.s')
+ self.symname = "PyEMB_" + PySource.invalid_sym_char.sub('_', modpath)
-########################################################################
-# Code for adding source files of various types
-#
-cc_lib_sources = []
-def Source(source):
- '''Add a source file to the libm5 build'''
- if not isinstance(source, SCons.Node.FS.File):
- source = File(source)
+ PySource.modules[modpath] = self
+ PySource.tnodes[self.tnode] = self
+ PySource.symnames[self.symname] = self
- cc_lib_sources.append(source)
+class SimObject(PySource):
+ '''Add a SimObject python file as a python source object and add
+ it to a list of sim object modules'''
-cc_bin_sources = []
-def BinSource(source):
- '''Add a source file to the m5 binary build'''
- if not isinstance(source, SCons.Node.FS.File):
- source = File(source)
+ fixed = False
+ modnames = []
- cc_bin_sources.append(source)
+ def __init__(self, source):
+ super(SimObject, self).__init__('m5.objects', source)
+ if self.fixed:
+ raise AttributeError, "Too late to call SimObject now."
-py_sources = []
-def PySource(package, source):
- '''Add a python source file to the named package'''
- if not isinstance(source, SCons.Node.FS.File):
- source = File(source)
+ bisect.insort_right(SimObject.modnames, self.modname)
- source = PySourceFile(package, source)
- py_sources.append(source)
+class SwigSource(SourceFile):
+ '''Add a swig file to build'''
-sim_objects_fixed = False
-sim_object_modfiles = set()
-def SimObject(source):
- '''Add a SimObject python file as a python source object and add
- it to a list of sim object modules'''
+ def __init__(self, package, source):
+ super(SwigSource, self).__init__(source)
- if sim_objects_fixed:
- raise AttributeError, "Too late to call SimObject now."
+ modname,ext = self.extname
+ assert ext == 'i'
- if not isinstance(source, SCons.Node.FS.File):
- source = File(source)
+ self.module = modname
+ cc_file = joinpath(self.dirname, modname + '_wrap.cc')
+ py_file = joinpath(self.dirname, modname + '.py')
- PySource('m5.objects', source)
- modfile = basename(str(source))
- assert modfile.endswith('.py')
- modname = modfile[:-3]
- sim_object_modfiles.add(modname)
-
-swig_sources = []
-def SwigSource(package, source):
- '''Add a swig file to build'''
- if not isinstance(source, SCons.Node.FS.File):
- source = File(source)
- val = source,package
- swig_sources.append(val)
+ self.cc_source = Source(cc_file, swig=True)
+ self.py_source = PySource(package, py_file)
unit_tests = []
def UnitTest(target, sources):
if not isinstance(sources, (list, tuple)):
sources = [ sources ]
-
- srcs = []
- for source in sources:
- if not isinstance(source, SCons.Node.FS.File):
- source = File(source)
- srcs.append(source)
-
- unit_tests.append((target, srcs))
+
+ sources = [ Source(src, skip_lib=True) for src in sources ]
+ unit_tests.append((target, sources))
# Children should have access
Export('Source')
-Export('BinSource')
Export('PySource')
Export('SimObject')
Export('SwigSource')
@@ -276,7 +299,8 @@ class DictImporter(object):
if fullname.startswith('m5.internal'):
return None
- if fullname in self.modules and exists(self.modules[fullname]):
+ source = self.modules.get(fullname, None)
+ if source is not None and exists(source.snode.abspath):
return self
return None
@@ -295,34 +319,28 @@ class DictImporter(object):
mod.__dict__['buildEnv'] = build_env
return mod
- srcfile = self.modules[fullname]
- if basename(srcfile) == '__init__.py':
- mod.__path__ = fullname.split('.')
- mod.__file__ = srcfile
+ source = self.modules[fullname]
+ if source.modname == '__init__':
+ mod.__path__ = source.modpath
+ mod.__file__ = source.snode.abspath
- exec file(srcfile, 'r') in mod.__dict__
+ exec file(source.snode.abspath, 'r') in mod.__dict__
return mod
-py_modules = {}
-for source in py_sources:
- py_modules[source.modpath] = source.snode.abspath
-
# install the python importer so we can grab stuff from the source
# tree itself. We can't have SimObjects added after this point or
# else we won't know about them for the rest of the stuff.
-sim_objects_fixed = True
-importer = DictImporter(py_modules)
+SimObject.fixed = True
+importer = DictImporter(PySource.modules)
sys.meta_path[0:0] = [ importer ]
import m5
# import all sim objects so we can populate the all_objects list
# make sure that we're working with a list, then let's sort it
-sim_objects = list(sim_object_modfiles)
-sim_objects.sort()
-for simobj in sim_objects:
- exec('from m5.objects import %s' % simobj)
+for modname in SimObject.modnames:
+ exec('from m5.objects import %s' % modname)
# we need to unload all of the currently imported modules so that they
# will be re-imported the next time the sconscript is run
@@ -333,7 +351,7 @@ sim_objects = m5.SimObject.allClasses
all_enums = m5.params.allEnums
all_params = {}
-for name,obj in sim_objects.iteritems():
+for name,obj in sorted(sim_objects.iteritems()):
for param in obj._params.local.values():
if not hasattr(param, 'swig_decl'):
continue
@@ -346,7 +364,7 @@ for name,obj in sim_objects.iteritems():
# calculate extra dependencies
#
module_depends = ["m5", "m5.SimObject", "m5.params"]
-depends = [ File(py_modules[dep]) for dep in module_depends ]
+depends = [ PySource.modules[dep].tnode for dep in module_depends ]
########################################################################
#
@@ -392,7 +410,7 @@ def makeObjectsInitFile(target, source, env):
# Generate an __init__.py file for the objects package
env.Command('python/m5/objects/__init__.py',
- [ Value(o) for o in sort_list(sim_object_modfiles) ],
+ map(Value, SimObject.modnames),
makeObjectsInitFile)
PySource('m5.objects', 'python/m5/objects/__init__.py')
@@ -409,6 +427,7 @@ def createSimObjectParam(target, source, env):
obj = sim_objects[name]
print >>hh_file, obj.cxx_decl()
+ hh_file.close()
def createSwigParam(target, source, env):
assert len(target) == 1 and len(source) == 1
@@ -419,6 +438,7 @@ def createSwigParam(target, source, env):
for line in param.swig_decl():
print >>i_file, line
+ i_file.close()
def createEnumStrings(target, source, env):
assert len(target) == 1 and len(source) == 1
@@ -438,11 +458,13 @@ def createEnumParam(target, source, env):
obj = all_enums[name]
print >>hh_file, obj.cxx_decl()
+ hh_file.close()
# Generate all of the SimObject param struct header files
params_hh_files = []
-for name,simobj in sim_objects.iteritems():
- extra_deps = [ File(py_modules[simobj.__module__]) ]
+for name,simobj in sorted(sim_objects.iteritems()):
+ py_source = PySource.modules[simobj.__module__]
+ extra_deps = [ py_source.tnode ]
hh_file = File('params/%s.hh' % name)
params_hh_files.append(hh_file)
@@ -463,8 +485,9 @@ for name,param in all_params.iteritems():
env.Depends(i_file, depends)
# Generate all enum header files
-for name,enum in all_enums.iteritems():
- extra_deps = [ File(py_modules[enum.__module__]) ]
+for name,enum in sorted(all_enums.iteritems()):
+ py_source = PySource.modules[enum.__module__]
+ extra_deps = [ py_source.tnode ]
cc_file = File('enums/%s.cc' % name)
env.Command(cc_file, Value(name), createEnumStrings)
@@ -576,32 +599,18 @@ def buildParams(target, source, env):
print >>out, '%%include "params/%s.hh"' % obj
params_file = File('params/params.i')
-names = sort_list(sim_objects.keys())
-env.Command(params_file, [ Value(v) for v in names ], buildParams)
+names = sorted(sim_objects.keys())
+env.Command(params_file, map(Value, names), buildParams)
env.Depends(params_file, params_hh_files + params_i_files + depends)
SwigSource('m5.objects', params_file)
# Build all swig modules
-swig_modules = []
-cc_swig_sources = []
-for source,package in swig_sources:
- filename = str(source)
- assert filename.endswith('.i')
-
- base = '.'.join(filename.split('.')[:-1])
- module = basename(base)
- cc_file = base + '_wrap.cc'
- py_file = base + '.py'
-
- env.Command([cc_file, py_file], source,
+for swig in SwigSource.all:
+ env.Command([swig.cc_source.tnode, swig.py_source.tnode], swig.tnode,
'$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
'-o ${TARGETS[0]} $SOURCES')
- env.Depends(py_file, source)
- env.Depends(cc_file, source)
-
- swig_modules.append(Value(module))
- cc_swig_sources.append(File(cc_file))
- PySource(package, py_file)
+ env.Depends(swig.py_source.tnode, swig.tnode)
+ env.Depends(swig.cc_source.tnode, swig.tnode)
# Generate the main swig init file
def makeSwigInit(target, source, env):
@@ -616,7 +625,9 @@ def makeSwigInit(target, source, env):
print >>f, '}'
f.close()
-env.Command('python/swig/init.cc', swig_modules, makeSwigInit)
+env.Command('python/swig/init.cc',
+ map(Value, sorted(s.module for s in SwigSource.all)),
+ makeSwigInit)
Source('python/swig/init.cc')
# Generate traceflags.py
@@ -813,7 +824,7 @@ extern const Flags *compoundFlags[];
f.close()
-flags = [ Value(f) for f in trace_flags.values() ]
+flags = map(Value, trace_flags.values())
env.Command('base/traceflags.py', flags, traceFlagsPy)
PySource('m5', 'base/traceflags.py')
@@ -827,10 +838,6 @@ Source('base/traceflags.cc')
# byte code, compress it, and then generate an assembly file that
# inserts the result into the data section with symbols indicating the
# beginning, and end (and with the size at the end)
-py_sources_tnodes = {}
-for pysource in py_sources:
- py_sources_tnodes[pysource.tnode] = pysource
-
def objectifyPyFile(target, source, env):
'''Action function to compile a .py into a code object, marshal
it, compress it, and stick it into an asm file so the code appears
@@ -839,7 +846,7 @@ def objectifyPyFile(target, source, env):
src = file(str(source[0]), 'r').read()
dst = file(str(target[0]), 'w')
- pysource = py_sources_tnodes[source[0]]
+ pysource = PySource.tnodes[source[0]]
compiled = compile(src, pysource.debugname, 'exec')
marshalled = marshal.dumps(compiled)
compressed = zlib.compress(marshalled)
@@ -864,7 +871,7 @@ def objectifyPyFile(target, source, env):
print >>dst, "%s_end:" % sym
print >>dst, ".long %d" % len(marshalled)
-for source in py_sources:
+for source in PySource.all:
env.Command(source.assembly, source.tnode, objectifyPyFile)
Source(source.assembly)
@@ -873,14 +880,11 @@ for source in py_sources:
# contains information about the importer that python uses to get at
# the embedded files, and then there's a list of all of the rest that
# the importer uses to load the rest on demand.
-py_sources_symbols = {}
-for pysource in py_sources:
- py_sources_symbols[pysource.symname] = pysource
def pythonInit(target, source, env):
dst = file(str(target[0]), 'w')
def dump_mod(sym, endchar=','):
- pysource = py_sources_symbols[sym]
+ pysource = PySource.symnames[sym]
print >>dst, ' { "%s",' % pysource.arcname
print >>dst, ' "%s",' % pysource.modpath
print >>dst, ' %s_beg, %s_end,' % (sym, sym)
@@ -907,8 +911,10 @@ def pythonInit(target, source, env):
print >>dst, " { 0, 0, 0, 0, 0, 0 }"
print >>dst, "};"
-symbols = [Value(s.symname) for s in py_sources]
-env.Command('sim/init_python.cc', symbols, pythonInit)
+
+env.Command('sim/init_python.cc',
+ map(Value, (s.symname for s in PySource.all)),
+ pythonInit)
Source('sim/init_python.cc')
########################################################################
@@ -920,26 +926,7 @@ Source('sim/init_python.cc')
# List of constructed environments to pass back to SConstruct
envList = []
-# This function adds the specified sources to the given build
-# environment, and returns a list of all the corresponding SCons
-# Object nodes (including an extra one for date.cc). We explicitly
-# add the Object nodes so we can set up special dependencies for
-# date.cc.
-def make_objs(sources, env, static):
- if static:
- XObject = env.StaticObject
- else:
- XObject = env.SharedObject
-
- objs = [ XObject(s) for s in sources ]
-
- # make date.cc depend on all other objects so it always gets
- # recompiled whenever anything else does
- date_obj = XObject('base/date.cc')
-
- env.Depends(date_obj, objs)
- objs.append(date_obj)
- return objs
+date_source = Source('base/date.cc', skip_lib=True)
# Function to create a new build environment as clone of current
# environment 'env' with modified object suffix and optional stripped
@@ -956,15 +943,45 @@ def makeEnv(label, objsfx, strip = False, **kwargs):
new_env.Append(**kwargs)
swig_env = new_env.Clone()
+ swig_env.Append(CCFLAGS='-Werror')
if env['GCC']:
swig_env.Append(CCFLAGS='-Wno-uninitialized')
swig_env.Append(CCFLAGS='-Wno-sign-compare')
swig_env.Append(CCFLAGS='-Wno-parentheses')
- static_objs = make_objs(cc_lib_sources, new_env, static=True)
- shared_objs = make_objs(cc_lib_sources, new_env, static=False)
- static_objs += [ swig_env.StaticObject(s) for s in cc_swig_sources ]
- shared_objs += [ swig_env.SharedObject(s) for s in cc_swig_sources ]
+ werror_env = new_env.Clone()
+ werror_env.Append(CCFLAGS='-Werror')
+
+ def make_obj(source, static, extra_deps = None):
+ '''This function adds the specified source to the correct
+ build environment, and returns the corresponding SCons Object
+ nodes'''
+
+ if source.swig:
+ env = swig_env
+ elif source.Werror:
+ env = werror_env
+ else:
+ env = new_env
+
+ if static:
+ obj = env.StaticObject(source.tnode)
+ else:
+ obj = env.SharedObject(source.tnode)
+
+ if extra_deps:
+ env.Depends(obj, extra_deps)
+
+ return obj
+
+ static_objs = [ make_obj(s, True) for s in Source.get(skip_lib=False)]
+ shared_objs = [ make_obj(s, False) for s in Source.get(skip_lib=False)]
+
+ static_date = make_obj(date_source, static=True, extra_deps=static_objs)
+ static_objs.append(static_date)
+
+ shared_date = make_obj(date_source, static=False, extra_deps=shared_objs)
+ shared_objs.append(static_date)
# First make a library of everything but main() so other programs can
# link against m5.
@@ -972,21 +989,23 @@ def makeEnv(label, objsfx, strip = False, **kwargs):
shared_lib = new_env.SharedLibrary(libname, shared_objs)
for target, sources in unit_tests:
- objs = [ new_env.StaticObject(s) for s in sources ]
+ objs = [ make_obj(s, static=True) for s in sources ]
new_env.Program("unittest/%s.%s" % (target, label), objs + static_objs)
# Now link a stub with main() and the static library.
- objects = [new_env.Object(s) for s in cc_bin_sources] + static_objs
+ bin_objs = [make_obj(s, True) for s in Source.get(bin_only=True) ]
+ progname = exename
+ if strip:
+ progname += '.unstripped'
+
+ targets = new_env.Program(progname, bin_objs + static_objs)
+
if strip:
- unstripped_exe = exename + '.unstripped'
- new_env.Program(unstripped_exe, objects)
if sys.platform == 'sunos5':
cmd = 'cp $SOURCE $TARGET; strip $TARGET'
else:
cmd = 'strip $SOURCE -o $TARGET'
- targets = new_env.Command(exename, unstripped_exe, cmd)
- else:
- targets = new_env.Program(exename, objects)
+ targets = new_env.Command(exename, progname, cmd)
new_env.M5Binary = targets[0]
envList.append(new_env)
diff --git a/src/arch/x86/faults.cc b/src/arch/x86/faults.cc
index bef7e4414..10b539248 100644
--- a/src/arch/x86/faults.cc
+++ b/src/arch/x86/faults.cc
@@ -271,12 +271,8 @@ namespace X86ISA
tc->setMiscReg(MISCREG_DR6, 0x00000000ffff0ff0ULL);
tc->setMiscReg(MISCREG_DR7, 0x0000000000000400ULL);
- // We're now in real mode, effectively at CPL 0
- HandyM5Reg m5Reg = 0;
- m5Reg.mode = LegacyMode;
- m5Reg.submode = RealMode;
- m5Reg.cpl = 0;
- tc->setMiscReg(MISCREG_M5_REG, m5Reg);
+ // Update the handy M5 Reg.
+ tc->setMiscReg(MISCREG_M5_REG, 0);
MicroPC entry = X86ISAInst::RomLabels::extern_label_initIntHalt;
tc->setMicroPC(romMicroPC(entry));
tc->setNextMicroPC(romMicroPC(entry) + 1);
@@ -289,7 +285,7 @@ namespace X86ISA
HandyM5Reg m5Reg = tc->readMiscReg(MISCREG_M5_REG);
if (m5Reg.mode != LegacyMode || m5Reg.submode != RealMode) {
panic("Startup IPI recived outside of real mode. "
- "Don't know what to do.");
+ "Don't know what to do. %d, %d", m5Reg.mode, m5Reg.submode);
}
tc->setMiscReg(MISCREG_CS, vector << 8);
diff --git a/src/arch/x86/miscregfile.cc b/src/arch/x86/miscregfile.cc
index 0316603e5..317cdadc5 100644
--- a/src/arch/x86/miscregfile.cc
+++ b/src/arch/x86/miscregfile.cc
@@ -96,6 +96,64 @@ using namespace std;
class Checkpoint;
+void MiscRegFile::updateHandyM5Reg(Efer efer, CR0 cr0,
+ SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags)
+{
+ HandyM5Reg m5reg;
+ if (efer.lma) {
+ m5reg.mode = LongMode;
+ if (csAttr.longMode)
+ m5reg.submode = SixtyFourBitMode;
+ else
+ m5reg.submode = CompatabilityMode;
+ } else {
+ m5reg.mode = LegacyMode;
+ if (cr0.pe) {
+ if (rflags.vm)
+ m5reg.submode = Virtual8086Mode;
+ else
+ m5reg.submode = ProtectedMode;
+ } else {
+ m5reg.submode = RealMode;
+ }
+ }
+ m5reg.cpl = csAttr.dpl;
+ m5reg.paging = cr0.pg;
+ m5reg.prot = cr0.pe;
+
+ // Compute the default and alternate operand size.
+ if (m5reg.submode == SixtyFourBitMode || csAttr.defaultSize) {
+ m5reg.defOp = 2;
+ m5reg.altOp = 1;
+ } else {
+ m5reg.defOp = 1;
+ m5reg.altOp = 2;
+ }
+
+ // Compute the default and alternate address size.
+ if (m5reg.submode == SixtyFourBitMode) {
+ m5reg.defAddr = 3;
+ m5reg.altAddr = 2;
+ } else if (csAttr.defaultSize) {
+ m5reg.defAddr = 2;
+ m5reg.altAddr = 1;
+ } else {
+ m5reg.defAddr = 1;
+ m5reg.altAddr = 2;
+ }
+
+ // Compute the stack size
+ if (m5reg.submode == SixtyFourBitMode) {
+ m5reg.stack = 3;
+ } else if (ssAttr.defaultSize) {
+ m5reg.stack = 2;
+ } else {
+ m5reg.stack = 1;
+ }
+
+ regVal[MISCREG_M5_REG] = m5reg;
+}
+
void MiscRegFile::clear()
{
// Blank everything. 0 might not be an appropriate value for some things,
@@ -151,39 +209,17 @@ void MiscRegFile::setReg(MiscRegIndex miscReg,
CR0 toggled = regVal[miscReg] ^ val;
CR0 newCR0 = val;
Efer efer = regVal[MISCREG_EFER];
- HandyM5Reg m5reg = regVal[MISCREG_M5_REG];
if (toggled.pg && efer.lme) {
if (newCR0.pg) {
//Turning on long mode
efer.lma = 1;
- m5reg.mode = LongMode;
regVal[MISCREG_EFER] = efer;
} else {
//Turning off long mode
efer.lma = 0;
- m5reg.mode = LegacyMode;
regVal[MISCREG_EFER] = efer;
}
}
- // Figure out what submode we're in.
- if (m5reg.mode == LongMode) {
- SegAttr csAttr = regVal[MISCREG_CS_ATTR];
- if (csAttr.longMode)
- m5reg.submode = SixtyFourBitMode;
- else
- m5reg.submode = CompatabilityMode;
- } else {
- if (newCR0.pe) {
- RFLAGS rflags = regVal[MISCREG_RFLAGS];
- if (rflags.vm)
- m5reg.submode = Virtual8086Mode;
- else
- m5reg.submode = ProtectedMode;
- } else {
- m5reg.submode = RealMode;
- }
- }
- regVal[MISCREG_M5_REG] = m5reg;
if (toggled.pg) {
tc->getITBPtr()->invalidateAll();
tc->getDTBPtr()->invalidateAll();
@@ -191,6 +227,11 @@ void MiscRegFile::setReg(MiscRegIndex miscReg,
//This must always be 1.
newCR0.et = 1;
newVal = newCR0;
+ updateHandyM5Reg(regVal[MISCREG_EFER],
+ newCR0,
+ regVal[MISCREG_CS_ATTR],
+ regVal[MISCREG_SS_ATTR],
+ regVal[MISCREG_RFLAGS]);
}
break;
case MISCREG_CR2:
@@ -214,28 +255,33 @@ void MiscRegFile::setReg(MiscRegIndex miscReg,
{
SegAttr toggled = regVal[miscReg] ^ val;
SegAttr newCSAttr = val;
- HandyM5Reg m5reg = regVal[MISCREG_M5_REG];
if (toggled.longMode) {
if (newCSAttr.longMode) {
- if (m5reg.mode == LongMode)
- m5reg.submode = SixtyFourBitMode;
regVal[MISCREG_ES_EFF_BASE] = 0;
regVal[MISCREG_CS_EFF_BASE] = 0;
regVal[MISCREG_SS_EFF_BASE] = 0;
regVal[MISCREG_DS_EFF_BASE] = 0;
} else {
- if (m5reg.mode == LongMode)
- m5reg.submode = CompatabilityMode;
regVal[MISCREG_ES_EFF_BASE] = regVal[MISCREG_ES_BASE];
regVal[MISCREG_CS_EFF_BASE] = regVal[MISCREG_CS_BASE];
regVal[MISCREG_SS_EFF_BASE] = regVal[MISCREG_SS_BASE];
regVal[MISCREG_DS_EFF_BASE] = regVal[MISCREG_DS_BASE];
}
}
- m5reg.cpl = newCSAttr.dpl;
- regVal[MISCREG_M5_REG] = m5reg;
+ updateHandyM5Reg(regVal[MISCREG_EFER],
+ regVal[MISCREG_CR0],
+ newCSAttr,
+ regVal[MISCREG_SS_ATTR],
+ regVal[MISCREG_RFLAGS]);
}
break;
+ case MISCREG_SS_ATTR:
+ updateHandyM5Reg(regVal[MISCREG_EFER],
+ regVal[MISCREG_CR0],
+ regVal[MISCREG_CS_ATTR],
+ val,
+ regVal[MISCREG_RFLAGS]);
+ break;
// These segments always actually use their bases, or in other words
// their effective bases must stay equal to their actual bases.
case MISCREG_FS_BASE:
@@ -333,6 +379,16 @@ void MiscRegFile::setReg(MiscRegIndex miscReg,
dr7.len3 = newDR7.len3;
}
break;
+ case MISCREG_M5_REG:
+ // Writing anything to the m5reg with side effects makes it update
+ // based on the current values of the relevant registers. The actual
+ // value written is discarded.
+ updateHandyM5Reg(regVal[MISCREG_EFER],
+ regVal[MISCREG_CR0],
+ regVal[MISCREG_CS_ATTR],
+ regVal[MISCREG_SS_ATTR],
+ regVal[MISCREG_RFLAGS]);
+ return;
default:
break;
}
diff --git a/src/arch/x86/miscregfile.hh b/src/arch/x86/miscregfile.hh
index 6d3ae4e92..babc65b44 100644
--- a/src/arch/x86/miscregfile.hh
+++ b/src/arch/x86/miscregfile.hh
@@ -107,6 +107,8 @@ namespace X86ISA
{
protected:
MiscReg regVal[NumMiscRegs];
+ void updateHandyM5Reg(Efer efer, CR0 cr0,
+ SegAttr csAttr, SegAttr ssAttr, RFLAGS rflags);
public:
void clear();
diff --git a/src/arch/x86/miscregs.hh b/src/arch/x86/miscregs.hh
index af02e9422..088dbeace 100644
--- a/src/arch/x86/miscregs.hh
+++ b/src/arch/x86/miscregs.hh
@@ -518,6 +518,13 @@ namespace X86ISA
Bitfield<0> mode;
Bitfield<3, 1> submode;
Bitfield<5, 4> cpl;
+ Bitfield<6> paging;
+ Bitfield<7> prot;
+ Bitfield<9, 8> defOp;
+ Bitfield<11, 10> altOp;
+ Bitfield<13, 12> defAddr;
+ Bitfield<15, 14> altAddr;
+ Bitfield<17, 16> stack;
EndBitUnion(HandyM5Reg)
/**
diff --git a/src/arch/x86/predecoder.cc b/src/arch/x86/predecoder.cc
index 620ab89ea..5bac8e711 100644
--- a/src/arch/x86/predecoder.cc
+++ b/src/arch/x86/predecoder.cc
@@ -80,9 +80,9 @@ namespace X86ISA
emi.modRM = 0;
emi.sib = 0;
- HandyM5Reg m5reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
- emi.mode.mode = m5reg.mode;
- emi.mode.submode = m5reg.submode;
+ m5Reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
+ emi.mode.mode = m5Reg.mode;
+ emi.mode.submode = m5Reg.submode;
}
void Predecoder::process()
@@ -216,34 +216,15 @@ namespace X86ISA
DPRINTF(Predecoder, "Found opcode %#x.\n", nextByte);
emi.opcode.op = nextByte;
- SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
-
//Figure out the effective operand size. This can be overriden to
//a fixed value at the decoder level.
int logOpSize;
- if (emi.mode.submode == SixtyFourBitMode)
- {
- if(emi.rex.w)
- logOpSize = 3; // 64 bit operand size
- else if(emi.legacy.op)
- logOpSize = 1; // 16 bit operand size
- else
- logOpSize = 2; // 32 bit operand size
- }
- else if(csAttr.defaultSize)
- {
- if(emi.legacy.op)
- logOpSize = 1; // 16 bit operand size
- else
- logOpSize = 2; // 32 bit operand size
- }
- else // 16 bit default operand size
- {
- if(emi.legacy.op)
- logOpSize = 2; // 32 bit operand size
- else
- logOpSize = 1; // 16 bit operand size
- }
+ if (emi.rex.w)
+ logOpSize = 3; // 64 bit operand size
+ else if (emi.legacy.op)
+ logOpSize = m5Reg.altOp;
+ else
+ logOpSize = m5Reg.defOp;
//Set the actual op size
emi.opSize = 1 << logOpSize;
@@ -251,41 +232,18 @@ namespace X86ISA
//Figure out the effective address size. This can be overriden to
//a fixed value at the decoder level.
int logAddrSize;
- if(emi.mode.submode == SixtyFourBitMode)
- {
- if(emi.legacy.addr)
- logAddrSize = 2; // 32 bit address size
- else
- logAddrSize = 3; // 64 bit address size
- }
- else if(csAttr.defaultSize)
- {
- if(emi.legacy.addr)
- logAddrSize = 1; // 16 bit address size
- else
- logAddrSize = 2; // 32 bit address size
- }
- else // 16 bit default operand size
- {
- if(emi.legacy.addr)
- logAddrSize = 2; // 32 bit address size
- else
- logAddrSize = 1; // 16 bit address size
- }
-
- SegAttr ssAttr = tc->readMiscRegNoEffect(MISCREG_SS_ATTR);
- //Figure out the effective stack width. This can be overriden to
- //a fixed value at the decoder level.
- if(emi.mode.submode == SixtyFourBitMode)
- emi.stackSize = 8; // 64 bit stack width
- else if(ssAttr.defaultSize)
- emi.stackSize = 4; // 32 bit stack width
+ if(emi.legacy.addr)
+ logAddrSize = m5Reg.altAddr;
else
- emi.stackSize = 2; // 16 bit stack width
+ logAddrSize = m5Reg.defAddr;
//Set the actual address size
emi.addrSize = 1 << logAddrSize;
+ //Figure out the effective stack width. This can be overriden to
+ //a fixed value at the decoder level.
+ emi.stackSize = 1 << m5Reg.stack;
+
//Figure out how big of an immediate we'll retreive based
//on the opcode.
int immType = ImmediateType[emi.opcode.num - 1][nextByte];
@@ -318,9 +276,7 @@ namespace X86ISA
ModRM modRM;
modRM = nextByte;
DPRINTF(Predecoder, "Found modrm byte %#x.\n", nextByte);
- SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
- if (emi.mode.submode != SixtyFourBitMode &&
- !csAttr.defaultSize) {
+ if (m5Reg.defOp == 1) {
//figure out 16 bit displacement size
if ((modRM.mod == 0 && modRM.rm == 6) || modRM.mod == 2)
displacementSize = 2;
diff --git a/src/arch/x86/predecoder.hh b/src/arch/x86/predecoder.hh
index a16ce6fb8..4893f1de9 100644
--- a/src/arch/x86/predecoder.hh
+++ b/src/arch/x86/predecoder.hh
@@ -61,6 +61,7 @@
#include <cassert>
#include "arch/x86/types.hh"
+#include "arch/x86/miscregs.hh"
#include "base/bitfield.hh"
#include "base/misc.hh"
#include "base/trace.hh"
@@ -91,10 +92,11 @@ namespace X86ISA
int offset;
//The extended machine instruction being generated
ExtMachInst emi;
+ HandyM5Reg m5Reg;
inline uint8_t getNextByte()
{
- return (fetchChunk >> (offset * 8)) & 0xff;
+ return ((uint8_t *)&fetchChunk)[offset];
}
void getImmediate(int &collected, uint64_t &current, int size)
@@ -182,6 +184,7 @@ namespace X86ISA
{
emi.mode.mode = LongMode;
emi.mode.submode = SixtyFourBitMode;
+ m5Reg = 0;
}
void reset()
diff --git a/src/arch/x86/process.cc b/src/arch/x86/process.cc
index 43dd4a591..f7b5468b4 100644
--- a/src/arch/x86/process.cc
+++ b/src/arch/x86/process.cc
@@ -232,6 +232,15 @@ X86_64LiveProcess::startup()
tc->setMiscRegNoEffect(MISCREG_CS_ATTR, csAttr);
+ Efer efer = 0;
+ efer.sce = 1; // Enable system call extensions.
+ efer.lme = 1; // Enable long mode.
+ efer.lma = 1; // Activate long mode.
+ efer.nxe = 1; // Enable nx support.
+ efer.svme = 0; // Disable svm support for now. It isn't implemented.
+ efer.ffxsr = 1; // Turn on fast fxsave and fxrstor.
+ tc->setMiscReg(MISCREG_EFER, efer);
+
//Set up the registers that describe the operating mode.
CR0 cr0 = 0;
cr0.pg = 1; // Turn on paging.
@@ -248,15 +257,6 @@ X86_64LiveProcess::startup()
// setting it to one.
cr0.pe = 1; // We're definitely in protected mode.
tc->setMiscReg(MISCREG_CR0, cr0);
-
- Efer efer = 0;
- efer.sce = 1; // Enable system call extensions.
- efer.lme = 1; // Enable long mode.
- efer.lma = 1; // Activate long mode.
- efer.nxe = 1; // Enable nx support.
- efer.svme = 0; // Disable svm support for now. It isn't implemented.
- efer.ffxsr = 1; // Turn on fast fxsave and fxrstor.
- tc->setMiscReg(MISCREG_EFER, efer);
}
}
@@ -340,6 +340,15 @@ I386LiveProcess::startup()
// Set the LDT selector to 0 to deactivate it.
tc->setMiscRegNoEffect(MISCREG_TSL, 0);
+ Efer efer = 0;
+ efer.sce = 1; // Enable system call extensions.
+ efer.lme = 1; // Enable long mode.
+ efer.lma = 0; // Deactivate long mode.
+ efer.nxe = 1; // Enable nx support.
+ efer.svme = 0; // Disable svm support for now. It isn't implemented.
+ efer.ffxsr = 1; // Turn on fast fxsave and fxrstor.
+ tc->setMiscReg(MISCREG_EFER, efer);
+
//Set up the registers that describe the operating mode.
CR0 cr0 = 0;
cr0.pg = 1; // Turn on paging.
@@ -356,15 +365,6 @@ I386LiveProcess::startup()
// setting it to one.
cr0.pe = 1; // We're definitely in protected mode.
tc->setMiscReg(MISCREG_CR0, cr0);
-
- Efer efer = 0;
- efer.sce = 1; // Enable system call extensions.
- efer.lme = 1; // Enable long mode.
- efer.lma = 0; // Deactivate long mode.
- efer.nxe = 1; // Enable nx support.
- efer.svme = 0; // Disable svm support for now. It isn't implemented.
- efer.ffxsr = 1; // Turn on fast fxsave and fxrstor.
- tc->setMiscReg(MISCREG_EFER, efer);
}
}
diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc
index f8b5c3392..1478c3e66 100644
--- a/src/arch/x86/tlb.cc
+++ b/src/arch/x86/tlb.cc
@@ -186,391 +186,393 @@ TLB::demapPage(Addr va, uint64_t asn)
}
Fault
+TLB::translateInt(RequestPtr req, ThreadContext *tc)
+{
+ DPRINTF(TLB, "Addresses references internal memory.\n");
+ Addr vaddr = req->getVaddr();
+ Addr prefix = (vaddr >> 3) & IntAddrPrefixMask;
+ if (prefix == IntAddrPrefixCPUID) {
+ panic("CPUID memory space not yet implemented!\n");
+ } else if (prefix == IntAddrPrefixMSR) {
+ vaddr = vaddr >> 3;
+ req->setMmapedIpr(true);
+ Addr regNum = 0;
+ switch (vaddr & ~IntAddrPrefixMask) {
+ case 0x10:
+ regNum = MISCREG_TSC;
+ break;
+ case 0x1B:
+ regNum = MISCREG_APIC_BASE;
+ break;
+ case 0xFE:
+ regNum = MISCREG_MTRRCAP;
+ break;
+ case 0x174:
+ regNum = MISCREG_SYSENTER_CS;
+ break;
+ case 0x175:
+ regNum = MISCREG_SYSENTER_ESP;
+ break;
+ case 0x176:
+ regNum = MISCREG_SYSENTER_EIP;
+ break;
+ case 0x179:
+ regNum = MISCREG_MCG_CAP;
+ break;
+ case 0x17A:
+ regNum = MISCREG_MCG_STATUS;
+ break;
+ case 0x17B:
+ regNum = MISCREG_MCG_CTL;
+ break;
+ case 0x1D9:
+ regNum = MISCREG_DEBUG_CTL_MSR;
+ break;
+ case 0x1DB:
+ regNum = MISCREG_LAST_BRANCH_FROM_IP;
+ break;
+ case 0x1DC:
+ regNum = MISCREG_LAST_BRANCH_TO_IP;
+ break;
+ case 0x1DD:
+ regNum = MISCREG_LAST_EXCEPTION_FROM_IP;
+ break;
+ case 0x1DE:
+ regNum = MISCREG_LAST_EXCEPTION_TO_IP;
+ break;
+ case 0x200:
+ regNum = MISCREG_MTRR_PHYS_BASE_0;
+ break;
+ case 0x201:
+ regNum = MISCREG_MTRR_PHYS_MASK_0;
+ break;
+ case 0x202:
+ regNum = MISCREG_MTRR_PHYS_BASE_1;
+ break;
+ case 0x203:
+ regNum = MISCREG_MTRR_PHYS_MASK_1;
+ break;
+ case 0x204:
+ regNum = MISCREG_MTRR_PHYS_BASE_2;
+ break;
+ case 0x205:
+ regNum = MISCREG_MTRR_PHYS_MASK_2;
+ break;
+ case 0x206:
+ regNum = MISCREG_MTRR_PHYS_BASE_3;
+ break;
+ case 0x207:
+ regNum = MISCREG_MTRR_PHYS_MASK_3;
+ break;
+ case 0x208:
+ regNum = MISCREG_MTRR_PHYS_BASE_4;
+ break;
+ case 0x209:
+ regNum = MISCREG_MTRR_PHYS_MASK_4;
+ break;
+ case 0x20A:
+ regNum = MISCREG_MTRR_PHYS_BASE_5;
+ break;
+ case 0x20B:
+ regNum = MISCREG_MTRR_PHYS_MASK_5;
+ break;
+ case 0x20C:
+ regNum = MISCREG_MTRR_PHYS_BASE_6;
+ break;
+ case 0x20D:
+ regNum = MISCREG_MTRR_PHYS_MASK_6;
+ break;
+ case 0x20E:
+ regNum = MISCREG_MTRR_PHYS_BASE_7;
+ break;
+ case 0x20F:
+ regNum = MISCREG_MTRR_PHYS_MASK_7;
+ break;
+ case 0x250:
+ regNum = MISCREG_MTRR_FIX_64K_00000;
+ break;
+ case 0x258:
+ regNum = MISCREG_MTRR_FIX_16K_80000;
+ break;
+ case 0x259:
+ regNum = MISCREG_MTRR_FIX_16K_A0000;
+ break;
+ case 0x268:
+ regNum = MISCREG_MTRR_FIX_4K_C0000;
+ break;
+ case 0x269:
+ regNum = MISCREG_MTRR_FIX_4K_C8000;
+ break;
+ case 0x26A:
+ regNum = MISCREG_MTRR_FIX_4K_D0000;
+ break;
+ case 0x26B:
+ regNum = MISCREG_MTRR_FIX_4K_D8000;
+ break;
+ case 0x26C:
+ regNum = MISCREG_MTRR_FIX_4K_E0000;
+ break;
+ case 0x26D:
+ regNum = MISCREG_MTRR_FIX_4K_E8000;
+ break;
+ case 0x26E:
+ regNum = MISCREG_MTRR_FIX_4K_F0000;
+ break;
+ case 0x26F:
+ regNum = MISCREG_MTRR_FIX_4K_F8000;
+ break;
+ case 0x277:
+ regNum = MISCREG_PAT;
+ break;
+ case 0x2FF:
+ regNum = MISCREG_DEF_TYPE;
+ break;
+ case 0x400:
+ regNum = MISCREG_MC0_CTL;
+ break;
+ case 0x404:
+ regNum = MISCREG_MC1_CTL;
+ break;
+ case 0x408:
+ regNum = MISCREG_MC2_CTL;
+ break;
+ case 0x40C:
+ regNum = MISCREG_MC3_CTL;
+ break;
+ case 0x410:
+ regNum = MISCREG_MC4_CTL;
+ break;
+ case 0x414:
+ regNum = MISCREG_MC5_CTL;
+ break;
+ case 0x418:
+ regNum = MISCREG_MC6_CTL;
+ break;
+ case 0x41C:
+ regNum = MISCREG_MC7_CTL;
+ break;
+ case 0x401:
+ regNum = MISCREG_MC0_STATUS;
+ break;
+ case 0x405:
+ regNum = MISCREG_MC1_STATUS;
+ break;
+ case 0x409:
+ regNum = MISCREG_MC2_STATUS;
+ break;
+ case 0x40D:
+ regNum = MISCREG_MC3_STATUS;
+ break;
+ case 0x411:
+ regNum = MISCREG_MC4_STATUS;
+ break;
+ case 0x415:
+ regNum = MISCREG_MC5_STATUS;
+ break;
+ case 0x419:
+ regNum = MISCREG_MC6_STATUS;
+ break;
+ case 0x41D:
+ regNum = MISCREG_MC7_STATUS;
+ break;
+ case 0x402:
+ regNum = MISCREG_MC0_ADDR;
+ break;
+ case 0x406:
+ regNum = MISCREG_MC1_ADDR;
+ break;
+ case 0x40A:
+ regNum = MISCREG_MC2_ADDR;
+ break;
+ case 0x40E:
+ regNum = MISCREG_MC3_ADDR;
+ break;
+ case 0x412:
+ regNum = MISCREG_MC4_ADDR;
+ break;
+ case 0x416:
+ regNum = MISCREG_MC5_ADDR;
+ break;
+ case 0x41A:
+ regNum = MISCREG_MC6_ADDR;
+ break;
+ case 0x41E:
+ regNum = MISCREG_MC7_ADDR;
+ break;
+ case 0x403:
+ regNum = MISCREG_MC0_MISC;
+ break;
+ case 0x407:
+ regNum = MISCREG_MC1_MISC;
+ break;
+ case 0x40B:
+ regNum = MISCREG_MC2_MISC;
+ break;
+ case 0x40F:
+ regNum = MISCREG_MC3_MISC;
+ break;
+ case 0x413:
+ regNum = MISCREG_MC4_MISC;
+ break;
+ case 0x417:
+ regNum = MISCREG_MC5_MISC;
+ break;
+ case 0x41B:
+ regNum = MISCREG_MC6_MISC;
+ break;
+ case 0x41F:
+ regNum = MISCREG_MC7_MISC;
+ break;
+ case 0xC0000080:
+ regNum = MISCREG_EFER;
+ break;
+ case 0xC0000081:
+ regNum = MISCREG_STAR;
+ break;
+ case 0xC0000082:
+ regNum = MISCREG_LSTAR;
+ break;
+ case 0xC0000083:
+ regNum = MISCREG_CSTAR;
+ break;
+ case 0xC0000084:
+ regNum = MISCREG_SF_MASK;
+ break;
+ case 0xC0000100:
+ regNum = MISCREG_FS_BASE;
+ break;
+ case 0xC0000101:
+ regNum = MISCREG_GS_BASE;
+ break;
+ case 0xC0000102:
+ regNum = MISCREG_KERNEL_GS_BASE;
+ break;
+ case 0xC0000103:
+ regNum = MISCREG_TSC_AUX;
+ break;
+ case 0xC0010000:
+ regNum = MISCREG_PERF_EVT_SEL0;
+ break;
+ case 0xC0010001:
+ regNum = MISCREG_PERF_EVT_SEL1;
+ break;
+ case 0xC0010002:
+ regNum = MISCREG_PERF_EVT_SEL2;
+ break;
+ case 0xC0010003:
+ regNum = MISCREG_PERF_EVT_SEL3;
+ break;
+ case 0xC0010004:
+ regNum = MISCREG_PERF_EVT_CTR0;
+ break;
+ case 0xC0010005:
+ regNum = MISCREG_PERF_EVT_CTR1;
+ break;
+ case 0xC0010006:
+ regNum = MISCREG_PERF_EVT_CTR2;
+ break;
+ case 0xC0010007:
+ regNum = MISCREG_PERF_EVT_CTR3;
+ break;
+ case 0xC0010010:
+ regNum = MISCREG_SYSCFG;
+ break;
+ case 0xC0010016:
+ regNum = MISCREG_IORR_BASE0;
+ break;
+ case 0xC0010017:
+ regNum = MISCREG_IORR_BASE1;
+ break;
+ case 0xC0010018:
+ regNum = MISCREG_IORR_MASK0;
+ break;
+ case 0xC0010019:
+ regNum = MISCREG_IORR_MASK1;
+ break;
+ case 0xC001001A:
+ regNum = MISCREG_TOP_MEM;
+ break;
+ case 0xC001001D:
+ regNum = MISCREG_TOP_MEM2;
+ break;
+ case 0xC0010114:
+ regNum = MISCREG_VM_CR;
+ break;
+ case 0xC0010115:
+ regNum = MISCREG_IGNNE;
+ break;
+ case 0xC0010116:
+ regNum = MISCREG_SMM_CTL;
+ break;
+ case 0xC0010117:
+ regNum = MISCREG_VM_HSAVE_PA;
+ break;
+ default:
+ return new GeneralProtection(0);
+ }
+ //The index is multiplied by the size of a MiscReg so that
+ //any memory dependence calculations will not see these as
+ //overlapping.
+ req->setPaddr(regNum * sizeof(MiscReg));
+ return NoFault;
+ } else if (prefix == IntAddrPrefixIO) {
+ // TODO If CPL > IOPL or in virtual mode, check the I/O permission
+ // bitmap in the TSS.
+
+ Addr IOPort = vaddr & ~IntAddrPrefixMask;
+ // Make sure the address fits in the expected 16 bit IO address
+ // space.
+ assert(!(IOPort & ~0xFFFF));
+ 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 |
+ mbits(configAddress, 30, 2) |
+ (IOPort & mask(2)));
+ }
+ } else {
+ req->setPaddr(PhysAddrPrefixIO | IOPort);
+ }
+ return NoFault;
+ } else {
+ panic("Access to unrecognized internal address space %#x.\n",
+ prefix);
+ }
+}
+
+Fault
TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
Mode mode, bool &delayedResponse, bool timing)
{
- delayedResponse = false;
- Addr vaddr = req->getVaddr();
- DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr);
uint32_t flags = req->getFlags();
- bool storeCheck = flags & (StoreCheck << FlagShift);
-
int seg = flags & SegmentFlagMask;
+ bool storeCheck = flags & (StoreCheck << FlagShift);
- // If this is true, we're dealing with a request to read an internal
- // value.
+ // If this is true, we're dealing with a request to a non-memory address
+ // space.
if (seg == SEGMENT_REG_MS) {
- DPRINTF(TLB, "Addresses references internal memory.\n");
- Addr prefix = (vaddr >> 3) & IntAddrPrefixMask;
- if (prefix == IntAddrPrefixCPUID) {
- panic("CPUID memory space not yet implemented!\n");
- } else if (prefix == IntAddrPrefixMSR) {
- vaddr = vaddr >> 3;
- req->setMmapedIpr(true);
- Addr regNum = 0;
- switch (vaddr & ~IntAddrPrefixMask) {
- case 0x10:
- regNum = MISCREG_TSC;
- break;
- case 0x1B:
- regNum = MISCREG_APIC_BASE;
- break;
- case 0xFE:
- regNum = MISCREG_MTRRCAP;
- break;
- case 0x174:
- regNum = MISCREG_SYSENTER_CS;
- break;
- case 0x175:
- regNum = MISCREG_SYSENTER_ESP;
- break;
- case 0x176:
- regNum = MISCREG_SYSENTER_EIP;
- break;
- case 0x179:
- regNum = MISCREG_MCG_CAP;
- break;
- case 0x17A:
- regNum = MISCREG_MCG_STATUS;
- break;
- case 0x17B:
- regNum = MISCREG_MCG_CTL;
- break;
- case 0x1D9:
- regNum = MISCREG_DEBUG_CTL_MSR;
- break;
- case 0x1DB:
- regNum = MISCREG_LAST_BRANCH_FROM_IP;
- break;
- case 0x1DC:
- regNum = MISCREG_LAST_BRANCH_TO_IP;
- break;
- case 0x1DD:
- regNum = MISCREG_LAST_EXCEPTION_FROM_IP;
- break;
- case 0x1DE:
- regNum = MISCREG_LAST_EXCEPTION_TO_IP;
- break;
- case 0x200:
- regNum = MISCREG_MTRR_PHYS_BASE_0;
- break;
- case 0x201:
- regNum = MISCREG_MTRR_PHYS_MASK_0;
- break;
- case 0x202:
- regNum = MISCREG_MTRR_PHYS_BASE_1;
- break;
- case 0x203:
- regNum = MISCREG_MTRR_PHYS_MASK_1;
- break;
- case 0x204:
- regNum = MISCREG_MTRR_PHYS_BASE_2;
- break;
- case 0x205:
- regNum = MISCREG_MTRR_PHYS_MASK_2;
- break;
- case 0x206:
- regNum = MISCREG_MTRR_PHYS_BASE_3;
- break;
- case 0x207:
- regNum = MISCREG_MTRR_PHYS_MASK_3;
- break;
- case 0x208:
- regNum = MISCREG_MTRR_PHYS_BASE_4;
- break;
- case 0x209:
- regNum = MISCREG_MTRR_PHYS_MASK_4;
- break;
- case 0x20A:
- regNum = MISCREG_MTRR_PHYS_BASE_5;
- break;
- case 0x20B:
- regNum = MISCREG_MTRR_PHYS_MASK_5;
- break;
- case 0x20C:
- regNum = MISCREG_MTRR_PHYS_BASE_6;
- break;
- case 0x20D:
- regNum = MISCREG_MTRR_PHYS_MASK_6;
- break;
- case 0x20E:
- regNum = MISCREG_MTRR_PHYS_BASE_7;
- break;
- case 0x20F:
- regNum = MISCREG_MTRR_PHYS_MASK_7;
- break;
- case 0x250:
- regNum = MISCREG_MTRR_FIX_64K_00000;
- break;
- case 0x258:
- regNum = MISCREG_MTRR_FIX_16K_80000;
- break;
- case 0x259:
- regNum = MISCREG_MTRR_FIX_16K_A0000;
- break;
- case 0x268:
- regNum = MISCREG_MTRR_FIX_4K_C0000;
- break;
- case 0x269:
- regNum = MISCREG_MTRR_FIX_4K_C8000;
- break;
- case 0x26A:
- regNum = MISCREG_MTRR_FIX_4K_D0000;
- break;
- case 0x26B:
- regNum = MISCREG_MTRR_FIX_4K_D8000;
- break;
- case 0x26C:
- regNum = MISCREG_MTRR_FIX_4K_E0000;
- break;
- case 0x26D:
- regNum = MISCREG_MTRR_FIX_4K_E8000;
- break;
- case 0x26E:
- regNum = MISCREG_MTRR_FIX_4K_F0000;
- break;
- case 0x26F:
- regNum = MISCREG_MTRR_FIX_4K_F8000;
- break;
- case 0x277:
- regNum = MISCREG_PAT;
- break;
- case 0x2FF:
- regNum = MISCREG_DEF_TYPE;
- break;
- case 0x400:
- regNum = MISCREG_MC0_CTL;
- break;
- case 0x404:
- regNum = MISCREG_MC1_CTL;
- break;
- case 0x408:
- regNum = MISCREG_MC2_CTL;
- break;
- case 0x40C:
- regNum = MISCREG_MC3_CTL;
- break;
- case 0x410:
- regNum = MISCREG_MC4_CTL;
- break;
- case 0x414:
- regNum = MISCREG_MC5_CTL;
- break;
- case 0x418:
- regNum = MISCREG_MC6_CTL;
- break;
- case 0x41C:
- regNum = MISCREG_MC7_CTL;
- break;
- case 0x401:
- regNum = MISCREG_MC0_STATUS;
- break;
- case 0x405:
- regNum = MISCREG_MC1_STATUS;
- break;
- case 0x409:
- regNum = MISCREG_MC2_STATUS;
- break;
- case 0x40D:
- regNum = MISCREG_MC3_STATUS;
- break;
- case 0x411:
- regNum = MISCREG_MC4_STATUS;
- break;
- case 0x415:
- regNum = MISCREG_MC5_STATUS;
- break;
- case 0x419:
- regNum = MISCREG_MC6_STATUS;
- break;
- case 0x41D:
- regNum = MISCREG_MC7_STATUS;
- break;
- case 0x402:
- regNum = MISCREG_MC0_ADDR;
- break;
- case 0x406:
- regNum = MISCREG_MC1_ADDR;
- break;
- case 0x40A:
- regNum = MISCREG_MC2_ADDR;
- break;
- case 0x40E:
- regNum = MISCREG_MC3_ADDR;
- break;
- case 0x412:
- regNum = MISCREG_MC4_ADDR;
- break;
- case 0x416:
- regNum = MISCREG_MC5_ADDR;
- break;
- case 0x41A:
- regNum = MISCREG_MC6_ADDR;
- break;
- case 0x41E:
- regNum = MISCREG_MC7_ADDR;
- break;
- case 0x403:
- regNum = MISCREG_MC0_MISC;
- break;
- case 0x407:
- regNum = MISCREG_MC1_MISC;
- break;
- case 0x40B:
- regNum = MISCREG_MC2_MISC;
- break;
- case 0x40F:
- regNum = MISCREG_MC3_MISC;
- break;
- case 0x413:
- regNum = MISCREG_MC4_MISC;
- break;
- case 0x417:
- regNum = MISCREG_MC5_MISC;
- break;
- case 0x41B:
- regNum = MISCREG_MC6_MISC;
- break;
- case 0x41F:
- regNum = MISCREG_MC7_MISC;
- break;
- case 0xC0000080:
- regNum = MISCREG_EFER;
- break;
- case 0xC0000081:
- regNum = MISCREG_STAR;
- break;
- case 0xC0000082:
- regNum = MISCREG_LSTAR;
- break;
- case 0xC0000083:
- regNum = MISCREG_CSTAR;
- break;
- case 0xC0000084:
- regNum = MISCREG_SF_MASK;
- break;
- case 0xC0000100:
- regNum = MISCREG_FS_BASE;
- break;
- case 0xC0000101:
- regNum = MISCREG_GS_BASE;
- break;
- case 0xC0000102:
- regNum = MISCREG_KERNEL_GS_BASE;
- break;
- case 0xC0000103:
- regNum = MISCREG_TSC_AUX;
- break;
- case 0xC0010000:
- regNum = MISCREG_PERF_EVT_SEL0;
- break;
- case 0xC0010001:
- regNum = MISCREG_PERF_EVT_SEL1;
- break;
- case 0xC0010002:
- regNum = MISCREG_PERF_EVT_SEL2;
- break;
- case 0xC0010003:
- regNum = MISCREG_PERF_EVT_SEL3;
- break;
- case 0xC0010004:
- regNum = MISCREG_PERF_EVT_CTR0;
- break;
- case 0xC0010005:
- regNum = MISCREG_PERF_EVT_CTR1;
- break;
- case 0xC0010006:
- regNum = MISCREG_PERF_EVT_CTR2;
- break;
- case 0xC0010007:
- regNum = MISCREG_PERF_EVT_CTR3;
- break;
- case 0xC0010010:
- regNum = MISCREG_SYSCFG;
- break;
- case 0xC0010016:
- regNum = MISCREG_IORR_BASE0;
- break;
- case 0xC0010017:
- regNum = MISCREG_IORR_BASE1;
- break;
- case 0xC0010018:
- regNum = MISCREG_IORR_MASK0;
- break;
- case 0xC0010019:
- regNum = MISCREG_IORR_MASK1;
- break;
- case 0xC001001A:
- regNum = MISCREG_TOP_MEM;
- break;
- case 0xC001001D:
- regNum = MISCREG_TOP_MEM2;
- break;
- case 0xC0010114:
- regNum = MISCREG_VM_CR;
- break;
- case 0xC0010115:
- regNum = MISCREG_IGNNE;
- break;
- case 0xC0010116:
- regNum = MISCREG_SMM_CTL;
- break;
- case 0xC0010117:
- regNum = MISCREG_VM_HSAVE_PA;
- break;
- default:
- return new GeneralProtection(0);
- }
- //The index is multiplied by the size of a MiscReg so that
- //any memory dependence calculations will not see these as
- //overlapping.
- req->setPaddr(regNum * sizeof(MiscReg));
- return NoFault;
- } else if (prefix == IntAddrPrefixIO) {
- // TODO If CPL > IOPL or in virtual mode, check the I/O permission
- // bitmap in the TSS.
-
- Addr IOPort = vaddr & ~IntAddrPrefixMask;
- // Make sure the address fits in the expected 16 bit IO address
- // space.
- assert(!(IOPort & ~0xFFFF));
- 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 |
- mbits(configAddress, 30, 2) |
- (IOPort & mask(2)));
- }
- } else {
- req->setPaddr(PhysAddrPrefixIO | IOPort);
- }
- return NoFault;
- } else {
- panic("Access to unrecognized internal address space %#x.\n",
- prefix);
- }
+ return translateInt(req, tc);
}
- // Get cr0. This will tell us how to do translation. We'll assume it was
- // verified to be correct and consistent when set.
- CR0 cr0 = tc->readMiscRegNoEffect(MISCREG_CR0);
+ delayedResponse = false;
+ Addr vaddr = req->getVaddr();
+ DPRINTF(TLB, "Translating vaddr %#x.\n", vaddr);
+
+ HandyM5Reg m5Reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);
// If protected mode has been enabled...
- if (cr0.pe) {
+ if (m5Reg.prot) {
DPRINTF(TLB, "In protected mode.\n");
- Efer efer = tc->readMiscRegNoEffect(MISCREG_EFER);
- SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
// If we're not in 64-bit mode, do protection/limit checks
- if (!efer.lma || !csAttr.longMode) {
+ if (m5Reg.mode != LongMode) {
DPRINTF(TLB, "Not in long mode. Checking segment protection.\n");
// Check for a NULL segment selector.
if (!(seg == SEGMENT_REG_TSG || seg == SYS_SEGMENT_REG_IDTR ||
- seg == SEGMENT_REG_HS || seg == SEGMENT_REG_LS ||
- seg == SEGMENT_REG_MS)
+ seg == SEGMENT_REG_HS || seg == SEGMENT_REG_LS)
&& !tc->readMiscRegNoEffect(MISCREG_SEG_SEL(seg)))
return new GeneralProtection(0);
bool expandDown = false;
@@ -589,6 +591,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
// address size is 64 bits, overridable to 32.
int size = 32;
bool sizeOverride = (flags & (AddrSizeFlagBit << FlagShift));
+ SegAttr csAttr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
if ((csAttr.defaultSize && sizeOverride) ||
(!csAttr.defaultSize && !sizeOverride))
size = 16;
@@ -605,7 +608,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
}
}
// If paging is enabled, do the translation.
- if (cr0.pg) {
+ if (m5Reg.paging) {
DPRINTF(TLB, "Paging enabled.\n");
// The vaddr already has the segment base applied.
TlbEntry *entry = lookup(vaddr);
@@ -643,7 +646,7 @@ TLB::translate(RequestPtr req, ThreadContext *tc, Translation *translation,
#endif
}
// Do paging protection checks.
- bool inUser = (csAttr.dpl == 3 &&
+ bool inUser = (m5Reg.cpl == 3 &&
!(flags & (CPL0FlagBit << FlagShift)));
if ((inUser && !entry->user) ||
(mode == Write && !entry->writable)) {
diff --git a/src/arch/x86/tlb.hh b/src/arch/x86/tlb.hh
index f55c26435..dca95eaaf 100644
--- a/src/arch/x86/tlb.hh
+++ b/src/arch/x86/tlb.hh
@@ -124,6 +124,8 @@ namespace X86ISA
EntryList freeList;
EntryList entryList;
+ Fault translateInt(RequestPtr req, ThreadContext *tc);
+
Fault translate(RequestPtr req, ThreadContext *tc,
Translation *translation, Mode mode,
bool &delayedResponse, bool timing);
diff --git a/src/sim/SConscript b/src/sim/SConscript
index 750007947..c13ea9909 100644
--- a/src/sim/SConscript
+++ b/src/sim/SConscript
@@ -41,7 +41,7 @@ Source('debug.cc')
Source('eventq.cc')
Source('faults.cc')
Source('init.cc')
-BinSource('main.cc')
+Source('main.cc', bin_only=True)
Source('pseudo_inst.cc')
Source('root.cc')
Source('serialize.cc')