Merge zizzer:/bk/newmem

into  zeep.pool:/z/saidi/work/m5.newmem.head

--HG--
extra : convert_revision : a64362d3cf8de00c97bea25118fee33cffe22707
This commit is contained in:
Ali Saidi 2006-07-05 20:30:45 -04:00
commit b36796914a
667 changed files with 60254 additions and 13722 deletions

42
AUTHORS Normal file
View file

@ -0,0 +1,42 @@
Steven K. Reinhardt
-----------------------
Nathan L. Binkert
-----------------------
Erik G. Hallnor
-----------------------
Steve E. Raasch
-----------------------
Lisa R. Hsu
-----------------------
Ali G. Saidi
-----------------------
Andrew L. Schultz
-----------------------
Kevin T. Lim
-----------------------
Ronald G. Dreslinski Jr
-----------------------
Gabriel Black
-----------------------
Korey L. Sewell
-----------------------
David Green
-----------------------
Benjamin S. Nash
-----------------------
Miguel J. Serrano
-----------------------

View file

@ -1,4 +1,4 @@
Copyright (c) 2000-2005 The Regents of The University of Michigan
Copyright (c) 2000-2006 The Regents of The University of Michigan
All rights reserved.
Redistribution and use in source and binary forms, with or without

88
README
View file

@ -1,21 +1,27 @@
This is release m5_1.1 of the M5 simulator.
This is release 2.0 of the M5 simulator.
This file contains brief "getting started" instructions. For more
information, see http://m5.eecs.umich.edu. If you have questions,
please send mail to m5sim-users@lists.sourceforge.net.
For information about building the simulator and getting started please refer
to: http://m5.eecs.umich.edu/
Specific Pages of Interest are:
http://m5.eecs.umich.edu/wiki/index.php/Compiling_M5
http://m5.eecs.umich.edu/wiki/index.php/Running_M5
If you have questions, please send mail to m5sim-users@lists.sourceforge.net.
WHAT'S INCLUDED (AND NOT)
-------------------------
The basic source release includes these subdirectories:
- m5: the simulator itself
- m5-test: regression tests
- ext: less-common external packages needed to build m5
- alpha-system: source for Alpha console and PALcode
- m5:
- src: source code of the m5 simulator
- test: regression tests
- ext: less-common external packages needed to build m5
- system/alpha: source for Alpha console and PALcode
To run full-system simulations, you will need compiled console,
PALcode, and kernel binaries and one or more disk images. These files
are collected in a separate archive, m5_system_1.1.tar.bz2. This file
are collected in a separate archive, m5_system_2.0.tar.bz2. This file
is included on the CD release, or you can download it separately from
Sourceforge.
@ -31,66 +37,8 @@ set of Linux source patches (linux_m5-2.6.8.1.diff), and the scons
program needed to build M5. If you do not have the CD, the same HTML
documentation is available online at http://m5.eecs.umich.edu/docs,
the Linux source patches are available at
http://m5.eecs.umich.edu/dist/linux_m5-2.6.8.1.diff, and the scons
program is available from http://www.scons.org.
http://m5.eecs.umich.edu/dist/linux_m5-2.6.8.1.diff, the scons
program is available from http://www.scons.org, and swig is available from
http://www.swig.org.
WHAT'S NEEDED
-------------
- GCC version 3.3 or newer
- Python 2.3 or newer
- SCons 0.96.1 or newer (see http://www.scons.org)
WHAT'S RECOMMENDED
------------------
- MySQL (for statistics complex statistics storage/retrieval)
- Python-MysqlDB (for statistics analysis)
GETTING STARTED
---------------
There are two different build targets and three optimizations levels:
Target:
-------
ALPHA_SE - Syscall emulation simulation
ALPHA_FS - Full system simulation
Optimization:
-------------
m5.debug - debug version of the code with tracing and without optimization
m5.opt - optimized version of code with tracing
m5.fast - optimized version of the code without tracing and asserts
Different targets are built in different subdirectories of m5/build.
Binaries with the same target but different optimization levels share
the same directory. Note that you can build m5 in any directory you
choose;p just configure the target directory using the 'mkbuilddir'
script in m5/build.
The following steps will build and test the simulator. The variable
"$top" refers to the top directory where you've unpacked the files,
i.e., the one containing the m5, m5-test, and ext directories. If you
have a multiprocessor system, you should give scons a "-j N" argument (like
make) to run N jobs in parallel.
To build and test the syscall-emulation simulator:
cd $top/m5/build
scons ALPHA_SE/test/opt/quick
This process takes under 10 minutes on a dual 3GHz Xeon system (using
the '-j 4' option).
To build and test the full-system simulator:
1. Unpack the full-system binaries from m5_system_1.1.tar.bz2. (See
above for directions on obtaining this file if you don't have it.)
This package includes disk images and kernel, palcode, and console
binaries for Linux and FreeBSD.
2. Edit the SYSTEMDIR search path in $top/m5-test/SysPaths.py to
include the path to your local copy of the binaries.
3. In $top/m5/build, run "scons ALPHA_FS/test/opt/quick".
This process also takes under 10 minutes on a dual 3GHz Xeon system
(again using the '-j 4' option).

View file

@ -1,3 +1,11 @@
XXX. X, 2006: m5_2.0
--------------------
Major update to M5 including:
- New CPU model
- Sew memory system
- More extensive python integration
- Preliminary syscall emulation support for MIPS and SPARC
Oct. 8, 2005: m5_1.1
--------------------
Update release for IOSCA workshop mini-tutorial. New features include:

View file

@ -25,6 +25,8 @@
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Steve Reinhardt
###################################################
#
@ -37,17 +39,20 @@
#
# You can build M5 in a different directory as long as there is a
# 'build/<CONFIG>' somewhere along the target path. The build system
# expdects that all configs under the same build directory are being
# expects that all configs under the same build directory are being
# built for the same host system.
#
# Examples:
# These two commands are equivalent. The '-u' option tells scons to
# search up the directory tree for this SConstruct file.
#
# The following two commands are equivalent. The '-u' option tells
# scons to search up the directory tree for this SConstruct file.
# % cd <path-to-src>/m5 ; scons build/ALPHA_FS/m5.debug
# % cd <path-to-src>/m5/build/ALPHA_FS; scons -u m5.debug
# These two commands are equivalent and demonstrate building in a
# directory outside of the source tree. The '-C' option tells scons
# to chdir to the specified directory to find this SConstruct file.
#
# The following two commands are equivalent and demonstrate building
# in a directory outside of the source tree. The '-C' option tells
# scons to chdir to the specified directory to find this SConstruct
# file.
# % cd <path-to-src>/m5 ; scons /local/foo/build/ALPHA_FS/m5.debug
# % cd /local/foo/build/ALPHA_FS; scons -C <path-to-src>/m5 m5.debug
#
@ -62,9 +67,24 @@
import sys
import os
# Check for recent-enough Python and SCons versions
EnsurePythonVersion(2,3)
EnsureSConsVersion(0,96,91)
# Check for recent-enough Python and SCons versions. If your system's
# default installation of Python is not recent enough, you can use a
# non-default installation of the Python interpreter by either (1)
# rearranging your PATH so that scons finds the non-default 'python'
# first or (2) explicitly invoking an alternative interpreter on the
# scons script, e.g., "/usr/local/bin/python2.4 `which scons` [args]".
EnsurePythonVersion(2,4)
# Ironically, SCons 0.96 dies if you give EnsureSconsVersion a
# 3-element version number.
min_scons_version = (0,96,91)
try:
EnsureSConsVersion(*min_scons_version)
except:
print "Error checking current SCons version."
print "SCons", ".".join(map(str,min_scons_version)), "or greater required."
Exit(2)
# The absolute path to the current directory (where this file lives).
ROOT = Dir('.').abspath
@ -139,7 +159,13 @@ env = Environment(ENV = os.environ, # inherit user's environment vars
ROOT = ROOT,
SRCDIR = SRCDIR)
env.SConsignFile("sconsign")
env.SConsignFile(os.path.join(build_root,"sconsign"))
# Default duplicate option is to use hard links, but this messes up
# when you use emacs to edit a file in the target dir, as emacs moves
# file to file~ then copies to file, breaking the link. Symbolic
# (soft) links work better.
env.SetOption('duplicate', 'soft-copy')
# I waffle on this setting... it does avoid a few painful but
# unnecessary builds, but it also seems to make trivial builds take
@ -159,7 +185,37 @@ if sys.platform == 'cygwin':
env.Append(CCFLAGS=Split("-Wno-uninitialized"))
env.Append(CPPPATH=[Dir('ext/dnet')])
# Default libraries
# Find Python include and library directories for embedding the
# interpreter. For consistency, we will use the same Python
# installation used to run scons (and thus this script). If you want
# to link in an alternate version, see above for instructions on how
# to invoke scons with a different copy of the Python interpreter.
# Get brief Python version name (e.g., "python2.4") for locating
# include & library files
py_version_name = 'python' + sys.version[:3]
# include path, e.g. /usr/local/include/python2.4
env.Append(CPPPATH = os.path.join(sys.exec_prefix, 'include', py_version_name))
env.Append(LIBS = py_version_name)
# add library path too if it's not in the default place
if sys.exec_prefix != '/usr':
env.Append(LIBPATH = os.path.join(sys.exec_prefix, 'lib'))
# Set up SWIG flags & scanner
env.Append(SWIGFLAGS=Split('-c++ -python -modern $_CPPINCFLAGS'))
import SCons.Scanner
swig_inc_re = '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
swig_scanner = SCons.Scanner.ClassicCPP("SwigScan", ".i", "CPPPATH",
swig_inc_re)
env.Append(SCANNERS = swig_scanner)
# Other default libraries
env.Append(LIBS=['z'])
# Platform-specific configuration. Note again that we assume that all
@ -207,7 +263,8 @@ env['ALL_ISA_LIST'] = ['alpha', 'sparc', 'mips']
# Define the universe of supported CPU models
env['ALL_CPU_LIST'] = ['AtomicSimpleCPU', 'TimingSimpleCPU',
'FullCPU', 'AlphaFullCPU']
'FullCPU', 'O3CPU',
'OzoneCPU']
# Sticky options get saved in the options file so they persist from
# one invocation to the next (unless overridden, in which case the new
@ -233,9 +290,9 @@ sticky_opts.AddOptions(
BoolOption('USE_SSE2',
'Compile for SSE2 (-msse2) to get IEEE FP on x86 hosts',
False),
BoolOption('STATS_BINNING', 'Bin statistics by CPU mode', have_mysql),
BoolOption('USE_MYSQL', 'Use MySQL for stats output', have_mysql),
BoolOption('USE_FENV', 'Use <fenv.h> IEEE mode control', have_fenv),
BoolOption('USE_CHECKER', 'Use checker for detailed CPU models', False),
('CC', 'C compiler', os.environ.get('CC', env['CC'])),
('CXX', 'C++ compiler', os.environ.get('CXX', env['CXX'])),
BoolOption('BATCH', 'Use batch pool for build and tests', False),
@ -248,10 +305,10 @@ nonsticky_opts.AddOptions(
BoolOption('update_ref', 'Update test reference outputs', False)
)
# These options get exported to #defines in config/*.hh (see m5/SConscript).
# These options get exported to #defines in config/*.hh (see src/SConscript).
env.ExportOptions = ['FULL_SYSTEM', 'ALPHA_TLASER', 'USE_FENV', \
'USE_MYSQL', 'NO_FAST_ALLOC', 'SS_COMPATIBLE_FP', \
'STATS_BINNING']
'USE_CHECKER']
# Define a handy 'no-op' action
def no_action(target, source, env):
@ -300,6 +357,32 @@ config_builder = Builder(emitter = config_emitter, action = config_action)
env.Append(BUILDERS = { 'ConfigFile' : config_builder })
###################################################
#
# Define a SCons builder for copying files. This is used by the
# Python zipfile code in src/python/SConscript, but is placed up here
# since it's potentially more generally applicable.
#
###################################################
copy_builder = Builder(action = Copy("$TARGET", "$SOURCE"))
env.Append(BUILDERS = { 'CopyFile' : copy_builder })
###################################################
#
# Define a simple SCons builder to concatenate files.
#
# Used to append the Python zip archive to the executable.
#
###################################################
concat_builder = Builder(action = Action(['cat $SOURCES > $TARGET',
'chmod +x $TARGET']))
env.Append(BUILDERS = { 'Concat' : concat_builder })
# base help text
help_text = '''
Usage: scons [scons options] [build options] [target(s)]
@ -404,11 +487,11 @@ for build_path in build_paths:
if env['USE_SSE2']:
env.Append(CCFLAGS='-msse2')
# The m5/SConscript file sets up the build rules in 'env' according
# The src/SConscript file sets up the build rules in 'env' according
# to the configured options. It returns a list of environments,
# one for each variant build (debug, opt, etc.)
envList = SConscript('src/SConscript', build_dir = build_path,
exports = 'env', duplicate = False)
exports = 'env')
# Set up the regression tests for each build.
# for e in envList:

2
build_opts/SPARC_FS Normal file
View file

@ -0,0 +1,2 @@
TARGET_ISA = 'sparc'
FULL_SYSTEM = 1

View file

@ -1,32 +1,42 @@
from m5 import *
import os, sys
from os.path import isdir, join as joinpath
from os import environ as env
import os.path
import sys
systemdir = None
bindir = None
diskdir = None
scriptdir = None
# Edit the following list to include the possible paths to the binary
# and disk image directories. The first directory on the list that
# exists will be selected.
SYSTEMDIR_PATH = ['/n/poolfs/z/dist/m5/system']
def load_defaults():
global systemdir, bindir, diskdir, scriptdir
if not systemdir:
try:
path = env['M5_PATH'].split(':')
except KeyError:
path = [ '/dist/m5/system', '/n/poolfs/z/dist/m5/system' ]
SYSTEMDIR = None
for d in SYSTEMDIR_PATH:
if os.path.exists(d):
SYSTEMDIR = d
break
for systemdir in path:
if os.path.isdir(systemdir):
break
else:
raise ImportError, "Can't find a path to system files."
if not SYSTEMDIR:
print >>sys.stderr, "Can't find a path to system files."
sys.exit(1)
BINDIR = SYSTEMDIR + '/binaries'
DISKDIR = SYSTEMDIR + '/disks'
if not bindir:
bindir = joinpath(systemdir, 'binaries')
if not diskdir:
diskdir = joinpath(systemdir, 'disks')
if not scriptdir:
scriptdir = joinpath(systemdir, 'boot')
def disk(file):
return os.path.join(DISKDIR, file)
load_defaults()
return joinpath(diskdir, file)
def binary(file):
return os.path.join(BINDIR, file)
load_defaults()
return joinpath(bindir, file)
def script(file):
return os.path.join(SYSTEMDIR, 'boot', file)
load_defaults()
return joinpath(scriptdir, file)

View file

@ -1,7 +1,19 @@
from m5 import *
import m5
from m5.objects import *
import os
from SysPaths import *
parser = optparse.OptionParser(option_list=m5.standardOptions)
parser.add_option("-t", "--timing", action="store_true")
(options, args) = parser.parse_args()
m5.setStandardOptions(options)
if args:
print "Error: script doesn't take any positional arguments"
sys.exit(1)
# Base for tests is directory containing this file.
test_base = os.path.dirname(__file__)
@ -118,17 +130,7 @@ class BaseTsunami(Tsunami):
ethernet = NSGigE(configdata=NSGigEPciData(),
pci_bus=0, pci_dev=1, pci_func=0)
etherint = NSGigEInt(device=Parent.ethernet)
# ethernet = Sinic(configdata=SinicPciData(),
# pci_bus=0, pci_dev=1, pci_func=0)
# etherint = SinicInt(device=Parent.ethernet)
console = AlphaConsole(pio_addr=0x80200000000, disk=Parent.simple_disk)
# bridge = PciFake(configdata=BridgePciData(), pci_bus=0, pci_dev=2, pci_func=0)
#class FreeBSDTsunami(BaseTsunami):
# disk0 = FreeBSDRootDisk(delay='0us', driveID='master')
# ide = IdeController(disks=[Parent.disk0],
# configdata=IdeControllerPciData(),
# pci_func=0, pci_dev=0, pci_bus=0)
class LinuxTsunami(BaseTsunami):
disk0 = LinuxRootDisk(driveID='master')
@ -138,50 +140,56 @@ class LinuxTsunami(BaseTsunami):
configdata=IdeControllerPciData(),
pci_func=0, pci_dev=0, pci_bus=0)
class LinuxAlphaSystem(LinuxAlphaSystem):
class MyLinuxAlphaSystem(LinuxAlphaSystem):
magicbus = Bus(bus_id=0)
magicbus2 = Bus(bus_id=1)
bridge = Bridge()
physmem = PhysicalMemory(range = AddrRange('128MB'))
c0a = Connector(side_a=Parent.magicbus, side_b=Parent.bridge, side_b_name="side_a")
c0b = Connector(side_a=Parent.magicbus2, side_b=Parent.bridge, side_b_name="side_b")
c1 = Connector(side_a=Parent.physmem, side_b=Parent.magicbus2)
bridge.side_a = magicbus.port
bridge.side_b = magicbus2.port
physmem.port = magicbus2.port
tsunami = LinuxTsunami()
c2 = Connector(side_a=Parent.tsunami.cchip, side_a_name='pio', side_b=Parent.magicbus)
c3 = Connector(side_a=Parent.tsunami.pchip, side_a_name='pio', side_b=Parent.magicbus)
c4 = Connector(side_a=Parent.tsunami.pciconfig, side_a_name='pio', side_b=Parent.magicbus)
c5 = Connector(side_a=Parent.tsunami.fake_sm_chip, side_a_name='pio', side_b=Parent.magicbus)
c6 = Connector(side_a=Parent.tsunami.ethernet, side_a_name='pio', side_b=Parent.magicbus)
c6a = Connector(side_a=Parent.tsunami.ethernet, side_a_name='dma', side_b=Parent.magicbus)
c7 = Connector(side_a=Parent.tsunami.fake_uart1, side_a_name='pio', side_b=Parent.magicbus)
c8 = Connector(side_a=Parent.tsunami.fake_uart2, side_a_name='pio', side_b=Parent.magicbus)
c9 = Connector(side_a=Parent.tsunami.fake_uart3, side_a_name='pio', side_b=Parent.magicbus)
c10 = Connector(side_a=Parent.tsunami.fake_uart4, side_a_name='pio', side_b=Parent.magicbus)
c11 = Connector(side_a=Parent.tsunami.ide, side_a_name='pio', side_b=Parent.magicbus)
c13 = Connector(side_a=Parent.tsunami.ide, side_a_name='dma', side_b=Parent.magicbus)
c12 = Connector(side_a=Parent.tsunami.fake_ppc, side_a_name='pio', side_b=Parent.magicbus)
c14 = Connector(side_a=Parent.tsunami.fake_OROM, side_a_name='pio', side_b=Parent.magicbus)
c16 = Connector(side_a=Parent.tsunami.fake_pnp_addr, side_a_name='pio', side_b=Parent.magicbus)
c17 = Connector(side_a=Parent.tsunami.fake_pnp_write, side_a_name='pio', side_b=Parent.magicbus)
c18 = Connector(side_a=Parent.tsunami.fake_pnp_read0, side_a_name='pio', side_b=Parent.magicbus)
c19 = Connector(side_a=Parent.tsunami.fake_pnp_read1, side_a_name='pio', side_b=Parent.magicbus)
c20 = Connector(side_a=Parent.tsunami.fake_pnp_read2, side_a_name='pio', side_b=Parent.magicbus)
c21 = Connector(side_a=Parent.tsunami.fake_pnp_read3, side_a_name='pio', side_b=Parent.magicbus)
c22 = Connector(side_a=Parent.tsunami.fake_pnp_read4, side_a_name='pio', side_b=Parent.magicbus)
c23 = Connector(side_a=Parent.tsunami.fake_pnp_read5, side_a_name='pio', side_b=Parent.magicbus)
c24 = Connector(side_a=Parent.tsunami.fake_pnp_read6, side_a_name='pio', side_b=Parent.magicbus)
c25 = Connector(side_a=Parent.tsunami.fake_pnp_read7, side_a_name='pio', side_b=Parent.magicbus)
c27 = Connector(side_a=Parent.tsunami.fake_ata0, side_a_name='pio', side_b=Parent.magicbus)
c28 = Connector(side_a=Parent.tsunami.fake_ata1, side_a_name='pio', side_b=Parent.magicbus)
c30 = Connector(side_a=Parent.tsunami.fb, side_a_name='pio', side_b=Parent.magicbus)
c31 = Connector(side_a=Parent.tsunami.io, side_a_name='pio', side_b=Parent.magicbus)
c32 = Connector(side_a=Parent.tsunami.uart, side_a_name='pio', side_b=Parent.magicbus)
c33 = Connector(side_a=Parent.tsunami.console, side_a_name='pio', side_b=Parent.magicbus)
tsunami.cchip.pio = magicbus.port
tsunami.pchip.pio = magicbus.port
tsunami.pciconfig.pio = magicbus.port
tsunami.fake_sm_chip.pio = magicbus.port
tsunami.ethernet.pio = magicbus.port
tsunami.ethernet.dma = magicbus.port
tsunami.fake_uart1.pio = magicbus.port
tsunami.fake_uart2.pio = magicbus.port
tsunami.fake_uart3.pio = magicbus.port
tsunami.fake_uart4.pio = magicbus.port
tsunami.ide.pio = magicbus.port
tsunami.ide.dma = magicbus.port
tsunami.fake_ppc.pio = magicbus.port
tsunami.fake_OROM.pio = magicbus.port
tsunami.fake_pnp_addr.pio = magicbus.port
tsunami.fake_pnp_write.pio = magicbus.port
tsunami.fake_pnp_read0.pio = magicbus.port
tsunami.fake_pnp_read1.pio = magicbus.port
tsunami.fake_pnp_read2.pio = magicbus.port
tsunami.fake_pnp_read3.pio = magicbus.port
tsunami.fake_pnp_read4.pio = magicbus.port
tsunami.fake_pnp_read5.pio = magicbus.port
tsunami.fake_pnp_read6.pio = magicbus.port
tsunami.fake_pnp_read7.pio = magicbus.port
tsunami.fake_ata0.pio = magicbus.port
tsunami.fake_ata1.pio = magicbus.port
tsunami.fb.pio = magicbus.port
tsunami.io.pio = magicbus.port
tsunami.uart.pio = magicbus.port
tsunami.console.pio = magicbus.port
raw_image = RawDiskImage(image_file=disk('linux-latest.img'),
read_only=True)
simple_disk = SimpleDisk(disk=Parent.raw_image)
intrctrl = IntrControl()
cpu = AtomicSimpleCPU(mem=Parent.magicbus2)
if options.timing:
cpu = TimingSimpleCPU()
else:
cpu = AtomicSimpleCPU()
cpu.mem = magicbus2
cpu.itb = AlphaITB()
cpu.dtb = AlphaDTB()
sim_console = SimConsole(listener=ConsoleListener(port=3456))
kernel = binary('vmlinux')
pal = binary('ts_osfpal')
@ -190,18 +198,15 @@ class LinuxAlphaSystem(LinuxAlphaSystem):
# readfile = os.path.join(test_base, 'halt.sh')
BaseCPU.itb = AlphaITB()
BaseCPU.dtb = AlphaDTB()
BaseCPU.system = Parent.any
class TsunamiRoot(System):
pass
def DualRoot(ClientSystem, ServerSystem):
def DualRoot(clientSystem, serverSystem):
self = Root()
self.client = ClientSystem()
self.server = ServerSystem()
self.client = clientSystem
self.server = serverSystem
self.etherdump = EtherDump(file='ethertrace')
self.etherlink = EtherLink(int1 = Parent.client.tsunami.etherint[0],
@ -210,6 +215,12 @@ def DualRoot(ClientSystem, ServerSystem):
self.clock = '5GHz'
return self
root = DualRoot(ClientSystem = LinuxAlphaSystem(readfile=script('netperf-stream-nt-client.rcS')),
ServerSystem = LinuxAlphaSystem(readfile=script('netperf-server.rcS')))
root = DualRoot(
MyLinuxAlphaSystem(readfile=script('netperf-stream-nt-client.rcS')),
MyLinuxAlphaSystem(readfile=script('netperf-server.rcS')))
m5.instantiate(root)
exit_event = m5.simulate()
print 'Exiting @ cycle', m5.curTick(), 'because', exit_event.getCause()

View file

@ -1,12 +1,93 @@
from m5 import *
# Simple test script
#
# Alpha: "m5 test.py"
# MIPS: "m5 test.py -a Mips -c hello_mips"
class HelloWorld(AlphaLiveProcess):
executable = '../configs/test/hello'
cmd = 'hello'
import os, optparse, sys
import m5
from m5.objects import *
from FullO3Config import *
# parse command-line arguments
parser = optparse.OptionParser(option_list=m5.standardOptions)
parser.add_option("-c", "--cmd", default="hello",
help="The binary to run in syscall emulation mode.")
parser.add_option("-o", "--options", default="",
help="The options to pass to the binary, use \" \" around the entire\
string.")
parser.add_option("-i", "--input", default="",
help="A file of input to give to the binary.")
parser.add_option("-t", "--timing", action="store_true",
help="Use simple timing CPU.")
parser.add_option("-d", "--detailed", action="store_true",
help="Use detailed CPU.")
parser.add_option("-m", "--maxtick", type="int",
help="Set the maximum number of ticks to run for")
(options, args) = parser.parse_args()
m5.setStandardOptions(options)
if args:
print "Error: script doesn't take any positional arguments"
sys.exit(1)
# build configuration
this_dir = os.path.dirname(__file__)
process = LiveProcess()
process.executable = os.path.join(this_dir, options.cmd)
process.cmd = options.cmd + " " + options.options
if options.input != "":
process.input = options.input
magicbus = Bus()
mem = PhysicalMemory()
cpu = AtomicSimpleCPU(workload=HelloWorld(), mem=magicbus)
system = System(physmem=mem, cpu=cpu)
system.c1 = Connector(side_a=mem, side_b=magicbus)
root = Root(system=system)
if options.timing and options.detailed:
print "Error: you may only specify one cpu model";
sys.exit(1)
if options.timing:
cpu = TimingSimpleCPU()
elif options.detailed:
#check for SMT workload
workloads = options.cmd.split(';')
if len(workloads) > 1:
process = []
smt_idx = 0
inputs = []
if options.input != "":
inputs = options.input.split(';')
for wrkld in workloads:
smt_process = LiveProcess()
smt_process.executable = os.path.join(this_dir, wrkld)
smt_process.cmd = wrkld + " " + options.options
if inputs and inputs[smt_idx]:
smt_process.input = inputs[smt_idx]
process += [smt_process, ]
smt_idx += 1
cpu = DetailedO3CPU()
else:
cpu = AtomicSimpleCPU()
cpu.workload = process
cpu.mem = magicbus
system = System(physmem = mem, cpu = cpu)
mem.port = magicbus.port
root = Root(system = system)
# instantiate configuration
m5.instantiate(root)
# simulate until program terminates
if options.maxtick:
exit_event = m5.simulate(options.maxtick)
else:
exit_event = m5.simulate()
print 'Exiting @ tick', m5.curTick(), 'because', exit_event.getCause()

View file

@ -24,6 +24,9 @@
* 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: Erik Hallnor
* Nathan Binkert
*/
/**

View file

@ -25,6 +25,8 @@
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Steve Reinhardt
import os
import sys
@ -46,9 +48,7 @@ Import('env')
base_sources = Split('''
base/circlebuf.cc
base/copyright.cc
base/cprintf.cc
base/embedfile.cc
base/fast_alloc.cc
base/fifo_buffer.cc
base/hostinfo.cc
@ -62,7 +62,6 @@ base_sources = Split('''
base/range.cc
base/random.cc
base/sat_counter.cc
base/serializer.cc
base/socket.cc
base/statistics.cc
base/str.cc
@ -81,38 +80,62 @@ base_sources = Split('''
base/stats/visit.cc
base/stats/text.cc
cpu/activity.cc
cpu/base.cc
cpu/cpu_exec_context.cc
cpu/cpuevent.cc
cpu/exetrace.cc
cpu/func_unit.cc
cpu/op_class.cc
cpu/pc_event.cc
cpu/quiesce_event.cc
cpu/static_inst.cc
cpu/sampler/sampler.cc
cpu/simple_thread.cc
cpu/thread_state.cc
mem/bridge.cc
mem/bus.cc
mem/connector.cc
mem/mem_object.cc
mem/packet.cc
mem/physical.cc
mem/port.cc
mem/request.cc
python/pyconfig.cc
python/embedded_py.cc
mem/cache/base_cache.cc
mem/cache/cache.cc
mem/cache/coherence/coherence_protocol.cc
mem/cache/coherence/uni_coherence.cc
mem/cache/miss/blocking_buffer.cc
mem/cache/miss/miss_queue.cc
mem/cache/miss/mshr.cc
mem/cache/miss/mshr_queue.cc
mem/cache/prefetch/base_prefetcher.cc
mem/cache/prefetch/ghb_prefetcher.cc
mem/cache/prefetch/prefetcher.cc
mem/cache/prefetch/stride_prefetcher.cc
mem/cache/prefetch/tagged_prefetcher.cc
mem/cache/tags/base_tags.cc
mem/cache/tags/cache_tags.cc
mem/cache/tags/fa_lru.cc
mem/cache/tags/iic.cc
mem/cache/tags/lru.cc
mem/cache/tags/repl/gen.cc
mem/cache/tags/repl/repl.cc
mem/cache/tags/split.cc
mem/cache/tags/split_lifo.cc
mem/cache/tags/split_lru.cc
mem/cache/cache_builder.cc
sim/builder.cc
sim/configfile.cc
sim/debug.cc
sim/eventq.cc
sim/faults.cc
sim/main.cc
python/swig/cc_main_wrap.cc
sim/param.cc
sim/profile.cc
sim/root.cc
sim/serialize.cc
sim/sim_events.cc
sim/sim_exit.cc
sim/sim_object.cc
sim/startup.cc
sim/stat_context.cc
@ -217,7 +240,6 @@ full_system_sources = Split('''
dev/uart.cc
dev/uart8250.cc
kern/kernel_binning.cc
kern/kernel_stats.cc
kern/system_events.cc
kern/linux/events.cc
@ -284,14 +306,18 @@ memtest_sources = Split('''
cpu/memtest/memtest.cc
''')
# Include file paths are rooted in this directory. SCons will
# automatically expand '.' to refer to both the source directory and
# the corresponding build directory to pick up generated include
# files.
env.Append(CPPPATH=Dir('.'))
# Add a flag defining what THE_ISA should be for all compilation
env.Append(CPPDEFINES=[('THE_ISA','%s_ISA' % env['TARGET_ISA'].upper())])
arch_sources = SConscript('arch/SConscript',
exports = 'env', duplicate = False)
arch_sources = SConscript('arch/SConscript', exports = 'env')
cpu_sources = SConscript('cpu/SConscript',
exports = 'env', duplicate = False)
cpu_sources = SConscript('cpu/SConscript', exports = 'env')
# This is outside of cpu/SConscript since the source directory isn't
# underneath 'cpu'.
@ -326,7 +352,7 @@ env.Command(Split('base/traceflags.hh base/traceflags.cc'),
'base/traceflags.py',
'python $SOURCE $TARGET.base')
SConscript('python/SConscript', exports = ['env'], duplicate=0)
SConscript('python/SConscript', exports = ['env'])
# This function adds the specified sources to the given build
# environment, and returns a list of all the corresponding SCons
@ -349,49 +375,45 @@ def make_objs(sources, env):
#
###################################################
# Include file paths are rooted in this directory. SCons will
# automatically expand '.' to refer to both the source directory and
# the corresponding build directory to pick up generated include
# files.
env.Append(CPPPATH='.')
# List of constructed environments to pass back to SConstruct
envList = []
# Function to create a new build environment as clone of current
# environment 'env' with modified object suffix and optional stripped
# binary. Additional keyword arguments are appended to corresponding
# build environment vars.
def makeEnv(label, objsfx, strip = False, **kwargs):
newEnv = env.Copy(OBJSUFFIX=objsfx)
newEnv.Label = label
newEnv.Append(**kwargs)
exe = 'm5.' + label # final executable
bin = exe + '.bin' # executable w/o appended Python zip archive
newEnv.Program(bin, make_objs(sources, newEnv))
if strip:
stripped_bin = bin + '.stripped'
newEnv.Command(stripped_bin, bin, 'strip $SOURCE -o $TARGET')
bin = stripped_bin
targets = newEnv.Concat(exe, [bin, 'python/m5py.zip'])
newEnv.M5Binary = targets[0]
envList.append(newEnv)
# Debug binary
debugEnv = env.Copy(OBJSUFFIX='.do')
debugEnv.Label = 'debug'
debugEnv.Append(CCFLAGS=Split('-g3 -gdwarf-2 -O0'))
debugEnv.Append(CPPDEFINES='DEBUG')
tlist = debugEnv.Program(target = 'm5.debug',
source = make_objs(sources, debugEnv))
debugEnv.M5Binary = tlist[0]
makeEnv('debug', '.do',
CCFLAGS = Split('-g3 -gdwarf-2 -O0'),
CPPDEFINES = 'DEBUG')
# Optimized binary
optEnv = env.Copy()
optEnv.Label = 'opt'
optEnv.Append(CCFLAGS=Split('-g -O3'))
tlist = optEnv.Program(target = 'm5.opt',
source = make_objs(sources, optEnv))
optEnv.M5Binary = tlist[0]
makeEnv('opt', '.o',
CCFLAGS = Split('-g -O3'))
# "Fast" binary
fastEnv = env.Copy(OBJSUFFIX='.fo')
fastEnv.Label = 'fast'
fastEnv.Append(CCFLAGS=Split('-O3'))
fastEnv.Append(CPPDEFINES='NDEBUG')
fastEnv.Program(target = 'm5.fast.unstripped',
source = make_objs(sources, fastEnv))
tlist = fastEnv.Command(target = 'm5.fast',
source = 'm5.fast.unstripped',
action = 'strip $SOURCE -o $TARGET')
fastEnv.M5Binary = tlist[0]
makeEnv('fast', '.fo', strip = True,
CCFLAGS = Split('-O3'),
CPPDEFINES = 'NDEBUG')
# Profiled binary
profEnv = env.Copy(OBJSUFFIX='.po')
profEnv.Label = 'prof'
profEnv.Append(CCFLAGS=Split('-O3 -g -pg'), LINKFLAGS='-pg')
tlist = profEnv.Program(target = 'm5.prof',
source = make_objs(sources, profEnv))
profEnv.M5Binary = tlist[0]
envList = [debugEnv, optEnv, fastEnv, profEnv]
makeEnv('prof', '.po',
CCFLAGS = Split('-O3 -g -pg'),
LINKFLAGS = '-pg')
Return('envList')

View file

@ -25,8 +25,10 @@
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Steve Reinhardt
import os.path
import os.path, sys
# Import build environment variable from SConstruct.
Import('env')
@ -126,13 +128,19 @@ isa_desc_gen_files = Split('decoder.cc decoder.hh')
isa_desc_gen_files += [CpuModel.dict[cpu].filename
for cpu in env['CPU_MODELS']]
# Also include the CheckerCPU as one of the models if it is being
# enabled via command line.
if env['USE_CHECKER']:
isa_desc_gen_files += [CpuModel.dict['CheckerCPU'].filename]
# The emitter patches up the sources & targets to include the
# autogenerated files as targets and isa parser itself as a source.
def isa_desc_emitter(target, source, env):
return (isa_desc_gen_files, [isa_parser, cpu_models_file] + source)
# Pieces are in place, so create the builder.
isa_desc_builder = Builder(action='python2.4 $SOURCES $TARGET.dir $CPU_MODELS',
python = sys.executable # use same Python binary used to run scons
isa_desc_builder = Builder(action=python + ' $SOURCES $TARGET.dir $CPU_MODELS',
emitter = isa_desc_emitter)
env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })
@ -144,7 +152,6 @@ env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })
isa = env['TARGET_ISA'] # someday this may be a list of ISAs
# Let the target architecture define what additional sources it needs
sources += SConscript(os.path.join(isa, 'SConscript'),
exports = 'env', duplicate = False)
sources += SConscript(os.path.join(isa, 'SConscript'), exports = 'env')
Return('sources')

View file

@ -25,6 +25,9 @@
# 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
# Steve Reinhardt
import os
import sys

View file

@ -24,6 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
* Nathan Binkert
*/
#ifndef __AOUT_MACHDEP_H__

View file

@ -24,11 +24,13 @@
* 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: Nathan Binkert
*/
#include "arch/alpha/arguments.hh"
#include "arch/alpha/vtophys.hh"
#include "cpu/exec_context.hh"
#include "cpu/thread_context.hh"
#include "mem/vport.hh"
using namespace AlphaISA;
@ -54,14 +56,14 @@ AlphaArguments::getArg(bool fp)
{
if (number < 6) {
if (fp)
return xc->readFloatRegBits(16 + number);
return tc->readFloatRegBits(16 + number);
else
return xc->readIntReg(16 + number);
return tc->readIntReg(16 + number);
} else {
Addr sp = xc->readIntReg(30);
VirtualPort *vp = xc->getVirtPort(xc);
Addr sp = tc->readIntReg(30);
VirtualPort *vp = tc->getVirtPort(tc);
uint64_t arg = vp->read<uint64_t>(sp + (number-6) * sizeof(uint64_t));
xc->delVirtPort(vp);
tc->delVirtPort(vp);
return arg;
}
}

View file

@ -24,6 +24,8 @@
* 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: Nathan Binkert
*/
#ifndef __ARCH_ALPHA_ARGUMENTS_HH__
@ -35,14 +37,14 @@
#include "base/refcnt.hh"
#include "sim/host.hh"
class ExecContext;
class ThreadContext;
namespace AlphaISA {
class AlphaArguments
{
protected:
ExecContext *xc;
ThreadContext *tc;
int number;
uint64_t getArg(bool fp = false);
@ -63,17 +65,17 @@ class AlphaArguments
RefCountingPtr<Data> data;
public:
AlphaArguments(ExecContext *ctx, int n = 0)
: xc(ctx), number(n), data(NULL)
AlphaArguments(ThreadContext *ctx, int n = 0)
: tc(ctx), number(n), data(NULL)
{ assert(number >= 0); data = new Data;}
AlphaArguments(const AlphaArguments &args)
: xc(args.xc), number(args.number), data(args.data) {}
: tc(args.tc), number(args.number), data(args.data) {}
~AlphaArguments() {}
ExecContext *getExecContext() const { return xc; }
ThreadContext *getThreadContext() const { return tc; }
const AlphaArguments &operator=(const AlphaArguments &args) {
xc = args.xc;
tc = args.tc;
number = args.number;
data = args.data;
return *this;
@ -118,7 +120,7 @@ class AlphaArguments
}
AlphaArguments operator[](int index) {
return AlphaArguments(xc, index);
return AlphaArguments(tc, index);
}
template <class T>
@ -131,13 +133,13 @@ class AlphaArguments
template <class T>
operator T *() {
T *buf = (T *)data->alloc(sizeof(T));
CopyData(xc, buf, getArg(), sizeof(T));
CopyData(tc, buf, getArg(), sizeof(T));
return buf;
}
operator char *() {
char *buf = data->alloc(2048);
CopyStringOut(xc, buf, getArg(), 2048);
CopyStringOut(tc, buf, getArg(), 2048);
return buf;
}
};

View file

@ -24,6 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
* Nathan Binkert
*/
#include "arch/alpha/tlb.hh"
@ -34,11 +37,11 @@
#include "base/stats/events.hh"
#include "config/full_system.hh"
#include "cpu/base.hh"
#include "cpu/cpu_exec_context.hh"
#include "cpu/exec_context.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "kern/kernel_stats.hh"
#include "sim/debug.hh"
#include "sim/sim_events.hh"
#include "sim/sim_exit.hh"
#if FULL_SYSTEM
@ -49,15 +52,19 @@ using namespace EV5;
// Machine dependent functions
//
void
AlphaISA::initCPU(ExecContext *xc, int cpuId)
AlphaISA::initCPU(ThreadContext *tc, int cpuId)
{
initIPRs(xc, cpuId);
initIPRs(tc, cpuId);
xc->setIntReg(16, cpuId);
xc->setIntReg(0, cpuId);
tc->setIntReg(16, cpuId);
tc->setIntReg(0, cpuId);
xc->setPC(xc->readMiscReg(IPR_PAL_BASE) + (new ResetFault)->vect());
xc->setNextPC(xc->readPC() + sizeof(MachInst));
AlphaFault *reset = new ResetFault;
tc->setPC(tc->readMiscReg(IPR_PAL_BASE) + reset->vect());
tc->setNextPC(tc->readPC() + sizeof(MachInst));
delete reset;
}
////////////////////////////////////////////////////////////////////////
@ -65,15 +72,15 @@ AlphaISA::initCPU(ExecContext *xc, int cpuId)
//
//
void
AlphaISA::initIPRs(ExecContext *xc, int cpuId)
AlphaISA::initIPRs(ThreadContext *tc, int cpuId)
{
for (int i = 0; i < NumInternalProcRegs; ++i) {
xc->setMiscReg(i, 0);
tc->setMiscReg(i, 0);
}
xc->setMiscReg(IPR_PAL_BASE, PalBase);
xc->setMiscReg(IPR_MCSR, 0x6);
xc->setMiscReg(IPR_PALtemp16, cpuId);
tc->setMiscReg(IPR_PAL_BASE, PalBase);
tc->setMiscReg(IPR_MCSR, 0x6);
tc->setMiscReg(IPR_PALtemp16, cpuId);
}
@ -132,12 +139,12 @@ AlphaISA::zeroRegisters(CPU *cpu)
// Insure ISA semantics
// (no longer very clean due to the change in setIntReg() in the
// cpu model. Consider changing later.)
cpu->cpuXC->setIntReg(ZeroReg, 0);
cpu->cpuXC->setFloatReg(ZeroReg, 0.0);
cpu->thread->setIntReg(ZeroReg, 0);
cpu->thread->setFloatReg(ZeroReg, 0.0);
}
Fault
CPUExecContext::hwrei()
SimpleThread::hwrei()
{
if (!inPalMode())
return new UnimplementedOpcodeFault;
@ -145,7 +152,8 @@ CPUExecContext::hwrei()
setNextPC(readMiscReg(AlphaISA::IPR_EXC_ADDR));
if (!misspeculating()) {
cpu->kernelStats->hwrei();
if (kernelStats)
kernelStats->hwrei();
cpu->checkInterrupts = true;
}
@ -167,7 +175,7 @@ AlphaISA::MiscRegFile::getDataAsid()
}
AlphaISA::MiscReg
AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc)
AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ThreadContext *tc)
{
uint64_t retval = 0; // return value, default 0
@ -221,7 +229,7 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc)
case AlphaISA::IPR_CC:
retval |= ipr[idx] & ULL(0xffffffff00000000);
retval |= xc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff);
retval |= tc->getCpuPtr()->curCycle() & ULL(0x00000000ffffffff);
break;
case AlphaISA::IPR_VA:
@ -238,7 +246,7 @@ AlphaISA::MiscRegFile::readIpr(int idx, Fault &fault, ExecContext *xc)
case AlphaISA::IPR_DTB_PTE:
{
AlphaISA::PTE &pte = xc->getDTBPtr()->index(!xc->misspeculating());
AlphaISA::PTE &pte = tc->getDTBPtr()->index(!tc->misspeculating());
retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32;
retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8;
@ -278,11 +286,11 @@ int break_ipl = -1;
#endif
Fault
AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ThreadContext *tc)
{
uint64_t old;
if (xc->misspeculating())
if (tc->misspeculating())
return NoFault;
switch (idx) {
@ -335,7 +343,8 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// write entire quad w/ no side-effect
old = ipr[idx];
ipr[idx] = val;
xc->getCpuPtr()->kernelStats->context(old, val, xc);
if (tc->getKernelStats())
tc->getKernelStats()->context(old, val, tc);
break;
case AlphaISA::IPR_DTB_PTE:
@ -362,14 +371,18 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// only write least significant five bits - interrupt level
ipr[idx] = val & 0x1f;
xc->getCpuPtr()->kernelStats->swpipl(ipr[idx]);
if (tc->getKernelStats())
tc->getKernelStats()->swpipl(ipr[idx]);
break;
case AlphaISA::IPR_DTB_CM:
if (val & 0x18)
xc->getCpuPtr()->kernelStats->mode(Kernel::user, xc);
else
xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc);
if (val & 0x18) {
if (tc->getKernelStats())
tc->getKernelStats()->mode(Kernel::user, tc);
} else {
if (tc->getKernelStats())
tc->getKernelStats()->mode(Kernel::kernel, tc);
}
case AlphaISA::IPR_ICM:
// only write two mode bits - processor mode
@ -443,21 +456,21 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// really a control write
ipr[idx] = 0;
xc->getDTBPtr()->flushAll();
tc->getDTBPtr()->flushAll();
break;
case AlphaISA::IPR_DTB_IAP:
// really a control write
ipr[idx] = 0;
xc->getDTBPtr()->flushProcesses();
tc->getDTBPtr()->flushProcesses();
break;
case AlphaISA::IPR_DTB_IS:
// really a control write
ipr[idx] = val;
xc->getDTBPtr()->flushAddr(val,
tc->getDTBPtr()->flushAddr(val,
DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]));
break;
@ -481,7 +494,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
pte.asn = DTB_ASN_ASN(ipr[AlphaISA::IPR_DTB_ASN]);
// insert new TAG/PTE value into data TLB
xc->getDTBPtr()->insert(val, pte);
tc->getDTBPtr()->insert(val, pte);
}
break;
@ -505,7 +518,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
pte.asn = ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]);
// insert new TAG/PTE value into data TLB
xc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], pte);
tc->getITBPtr()->insert(ipr[AlphaISA::IPR_ITB_TAG], pte);
}
break;
@ -513,21 +526,21 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
// really a control write
ipr[idx] = 0;
xc->getITBPtr()->flushAll();
tc->getITBPtr()->flushAll();
break;
case AlphaISA::IPR_ITB_IAP:
// really a control write
ipr[idx] = 0;
xc->getITBPtr()->flushProcesses();
tc->getITBPtr()->flushProcesses();
break;
case AlphaISA::IPR_ITB_IS:
// really a control write
ipr[idx] = val;
xc->getITBPtr()->flushAddr(val,
tc->getITBPtr()->flushAddr(val,
ITB_ASN_ASN(ipr[AlphaISA::IPR_ITB_ASN]));
break;
@ -541,7 +554,7 @@ AlphaISA::MiscRegFile::setIpr(int idx, uint64_t val, ExecContext *xc)
}
void
AlphaISA::copyIprs(ExecContext *src, ExecContext *dest)
AlphaISA::copyIprs(ThreadContext *src, ThreadContext *dest)
{
for (int i = IPR_Base_DepTag; i < NumInternalProcRegs; ++i) {
dest->setMiscReg(i, src->readMiscReg(i));
@ -553,15 +566,16 @@ AlphaISA::copyIprs(ExecContext *src, ExecContext *dest)
* If return value is false, actual PAL call will be suppressed.
*/
bool
CPUExecContext::simPalCheck(int palFunc)
SimpleThread::simPalCheck(int palFunc)
{
cpu->kernelStats->callpal(palFunc, proxy);
if (kernelStats)
kernelStats->callpal(palFunc, tc);
switch (palFunc) {
case PAL::halt:
halt();
if (--System::numSystemsRunning == 0)
new SimExitEvent("all cpus halted");
exitSimLoop("all cpus halted");
break;
case PAL::bpt:

View file

@ -24,6 +24,10 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
* Nathan Binkert
* Ali Saidi
*/
#ifndef __ARCH_ALPHA_EV5_HH__

View file

@ -24,14 +24,20 @@
* 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
* Kevin Lim
*/
#include "arch/alpha/faults.hh"
#include "cpu/exec_context.hh"
#include "cpu/thread_context.hh"
#include "cpu/base.hh"
#include "base/trace.hh"
#if FULL_SYSTEM
#include "arch/alpha/ev5.hh"
#else
#include "sim/process.hh"
#include "mem/page_table.hh"
#endif
namespace AlphaISA
@ -53,6 +59,12 @@ FaultName ArithmeticFault::_name = "arith";
FaultVect ArithmeticFault::_vect = 0x0501;
FaultStat ArithmeticFault::_count;
#if !FULL_SYSTEM
FaultName PageTableFault::_name = "page_table_fault";
FaultVect PageTableFault::_vect = 0x0000;
FaultStat PageTableFault::_count;
#endif
FaultName InterruptFault::_name = "interrupt";
FaultVect InterruptFault::_vect = 0x0101;
FaultStat InterruptFault::_count;
@ -107,67 +119,91 @@ FaultStat IntegerOverflowFault::_count;
#if FULL_SYSTEM
void AlphaFault::invoke(ExecContext * xc)
void AlphaFault::invoke(ThreadContext * tc)
{
FaultBase::invoke(xc);
FaultBase::invoke(tc);
countStat()++;
// exception restart address
if (setRestartAddress() || !xc->inPalMode())
xc->setMiscReg(AlphaISA::IPR_EXC_ADDR, xc->readPC());
if (setRestartAddress() || !tc->inPalMode())
tc->setMiscReg(AlphaISA::IPR_EXC_ADDR, tc->readPC());
if (skipFaultingInstruction()) {
// traps... skip faulting instruction.
xc->setMiscReg(AlphaISA::IPR_EXC_ADDR,
xc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4);
tc->setMiscReg(AlphaISA::IPR_EXC_ADDR,
tc->readMiscReg(AlphaISA::IPR_EXC_ADDR) + 4);
}
xc->setPC(xc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect());
xc->setNextPC(xc->readPC() + sizeof(MachInst));
tc->setPC(tc->readMiscReg(AlphaISA::IPR_PAL_BASE) + vect());
tc->setNextPC(tc->readPC() + sizeof(MachInst));
}
void ArithmeticFault::invoke(ExecContext * xc)
void ArithmeticFault::invoke(ThreadContext * tc)
{
FaultBase::invoke(xc);
FaultBase::invoke(tc);
panic("Arithmetic traps are unimplemented!");
}
void DtbFault::invoke(ExecContext * xc)
void DtbFault::invoke(ThreadContext * tc)
{
// Set fault address and flags. Even though we're modeling an
// EV5, we use the EV6 technique of not latching fault registers
// on VPTE loads (instead of locking the registers until IPR_VA is
// read, like the EV5). The EV6 approach is cleaner and seems to
// work with EV5 PAL code, but not the other way around.
if (!xc->misspeculating()
if (!tc->misspeculating()
&& !(reqFlags & VPTE) && !(reqFlags & NO_FAULT)) {
// set VA register with faulting address
xc->setMiscReg(AlphaISA::IPR_VA, vaddr);
tc->setMiscReg(AlphaISA::IPR_VA, vaddr);
// set MM_STAT register flags
xc->setMiscReg(AlphaISA::IPR_MM_STAT,
(((EV5::Opcode(xc->getInst()) & 0x3f) << 11)
| ((EV5::Ra(xc->getInst()) & 0x1f) << 6)
tc->setMiscReg(AlphaISA::IPR_MM_STAT,
(((EV5::Opcode(tc->getInst()) & 0x3f) << 11)
| ((EV5::Ra(tc->getInst()) & 0x1f) << 6)
| (flags & 0x3f)));
// set VA_FORM register with faulting formatted address
xc->setMiscReg(AlphaISA::IPR_VA_FORM,
xc->readMiscReg(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3));
tc->setMiscReg(AlphaISA::IPR_VA_FORM,
tc->readMiscReg(AlphaISA::IPR_MVPTBR) | (vaddr.vpn() << 3));
}
AlphaFault::invoke(xc);
AlphaFault::invoke(tc);
}
void ItbFault::invoke(ExecContext * xc)
void ItbFault::invoke(ThreadContext * tc)
{
if (!xc->misspeculating()) {
xc->setMiscReg(AlphaISA::IPR_ITB_TAG, pc);
xc->setMiscReg(AlphaISA::IPR_IFAULT_VA_FORM,
xc->readMiscReg(AlphaISA::IPR_IVPTBR) |
if (!tc->misspeculating()) {
tc->setMiscReg(AlphaISA::IPR_ITB_TAG, pc);
tc->setMiscReg(AlphaISA::IPR_IFAULT_VA_FORM,
tc->readMiscReg(AlphaISA::IPR_IVPTBR) |
(AlphaISA::VAddr(pc).vpn() << 3));
}
AlphaFault::invoke(xc);
AlphaFault::invoke(tc);
}
#else //!FULL_SYSTEM
void PageTableFault::invoke(ThreadContext *tc)
{
Process *p = tc->getProcessPtr();
// address is higher than the stack region or in the current stack region
if (vaddr > p->stack_base || vaddr > p->stack_min)
FaultBase::invoke(tc);
// We've accessed the next page
if (vaddr > p->stack_min - PageBytes) {
warn("Increasing stack %#x:%#x to %#x:%#x because of access to %#x",
p->stack_min, p->stack_base, p->stack_min - PageBytes,
p->stack_base, vaddr);
p->stack_min -= PageBytes;
if (p->stack_base - p->stack_min > 8*1024*1024)
fatal("Over max stack size for one thread\n");
p->pTable->allocate(p->stack_min, PageBytes);
} else {
FaultBase::invoke(tc);
}
}
#endif

View file

@ -24,6 +24,9 @@
* 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
* Kevin Lim
*/
#ifndef __ALPHA_FAULTS_HH__
@ -46,7 +49,7 @@ class AlphaFault : public FaultBase
virtual bool setRestartAddress() {return true;}
public:
#if FULL_SYSTEM
void invoke(ExecContext * xc);
void invoke(ThreadContext * tc);
#endif
virtual FaultVect vect() = 0;
virtual FaultStat & countStat() = 0;
@ -78,6 +81,29 @@ class AlignmentFault : public AlphaFault
bool isAlignmentFault() {return true;}
};
#if !FULL_SYSTEM
class PageTableFault : public AlphaFault
{
private:
Addr vaddr;
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
PageTableFault(Addr va)
: vaddr(va) {}
FaultName name() {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc);
};
static inline Fault genPageTableFault(Addr va)
{
return new PageTableFault(va);
}
#endif
static inline Fault genMachineCheckFault()
{
return new MachineCheckFault;
@ -113,7 +139,7 @@ class ArithmeticFault : public AlphaFault
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
#if FULL_SYSTEM
void invoke(ExecContext * xc);
void invoke(ThreadContext * tc);
#endif
};
@ -147,7 +173,7 @@ class DtbFault : public AlphaFault
FaultVect vect() = 0;
FaultStat & countStat() = 0;
#if FULL_SYSTEM
void invoke(ExecContext * xc);
void invoke(ThreadContext * tc);
#endif
};
@ -248,7 +274,7 @@ class ItbFault : public AlphaFault
FaultVect vect() = 0;
FaultStat & countStat() = 0;
#if FULL_SYSTEM
void invoke(ExecContext * xc);
void invoke(ThreadContext * tc);
#endif
};

View file

@ -24,6 +24,8 @@
* 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: Ben Nash
*/
/**
@ -36,7 +38,7 @@
#include "arch/alpha/system.hh"
#include "arch/alpha/freebsd/system.hh"
#include "base/loader/symtab.hh"
#include "cpu/exec_context.hh"
#include "cpu/thread_context.hh"
#include "mem/physical.hh"
#include "mem/port.hh"
#include "arch/isa_traits.hh"
@ -70,13 +72,13 @@ FreebsdAlphaSystem::~FreebsdAlphaSystem()
void
FreebsdAlphaSystem::doCalibrateClocks(ExecContext *xc)
FreebsdAlphaSystem::doCalibrateClocks(ThreadContext *tc)
{
Addr ppc_vaddr = 0;
Addr timer_vaddr = 0;
ppc_vaddr = (Addr)xc->readIntReg(ArgumentReg1);
timer_vaddr = (Addr)xc->readIntReg(ArgumentReg2);
ppc_vaddr = (Addr)tc->readIntReg(ArgumentReg1);
timer_vaddr = (Addr)tc->readIntReg(ArgumentReg2);
virtPort.write(ppc_vaddr, (uint32_t)Clock::Frequency);
virtPort.write(timer_vaddr, (uint32_t)TIMER_FREQUENCY);
@ -84,10 +86,10 @@ FreebsdAlphaSystem::doCalibrateClocks(ExecContext *xc)
void
FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ExecContext *xc)
FreebsdAlphaSystem::SkipCalibrateClocksEvent::process(ThreadContext *tc)
{
SkipFuncEvent::process(xc);
((FreebsdAlphaSystem *)xc->getSystemPtr())->doCalibrateClocks(xc);
SkipFuncEvent::process(tc);
((FreebsdAlphaSystem *)tc->getSystemPtr())->doCalibrateClocks(tc);
}
@ -107,10 +109,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
Param<uint64_t> system_type;
Param<uint64_t> system_rev;
Param<bool> bin;
VectorParam<string> binned_fns;
Param<bool> bin_int;
END_DECLARE_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
@ -125,10 +123,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
INIT_PARAM_DFLT(bin, "is this system to be binned", false),
INIT_PARAM(binned_fns, "functions to be broken down and binned"),
INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
END_INIT_SIM_OBJECT_PARAMS(FreebsdAlphaSystem)
@ -146,9 +141,6 @@ CREATE_SIM_OBJECT(FreebsdAlphaSystem)
p->readfile = readfile;
p->system_type = system_type;
p->system_rev = system_rev;
p->bin = bin;
p->binned_fns = binned_fns;
p->bin_int = bin_int;
return new FreebsdAlphaSystem(p);
}

View file

@ -24,6 +24,8 @@
* 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: Ben Nash
*/
#ifndef __KERN_FREEBSD_FREEBSD_SYSTEM_HH__
@ -40,7 +42,7 @@ class FreebsdAlphaSystem : public AlphaSystem
SkipCalibrateClocksEvent(PCEventQueue *q, const std::string &desc,
Addr addr)
: SkipFuncEvent(q, desc, addr) {}
virtual void process(ExecContext *xc);
virtual void process(ThreadContext *tc);
};
SkipFuncEvent *skipDelayEvent;
@ -49,7 +51,7 @@ class FreebsdAlphaSystem : public AlphaSystem
public:
FreebsdAlphaSystem(Params *p);
~FreebsdAlphaSystem();
void doCalibrateClocks(ExecContext *xc);
void doCalibrateClocks(ThreadContext *tc);
};

View file

@ -25,6 +25,13 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Control transfer instructions
//
output header {{
@ -99,7 +106,7 @@ output header {{
{
}
Addr branchTarget(ExecContext *xc) const;
Addr branchTarget(ThreadContext *tc) const;
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
@ -114,10 +121,10 @@ output decoder {{
}
Addr
Jump::branchTarget(ExecContext *xc) const
Jump::branchTarget(ThreadContext *tc) const
{
Addr NPC = xc->readPC() + 4;
uint64_t Rb = xc->readIntReg(_srcRegIdx[0]);
Addr NPC = tc->readPC() + 4;
uint64_t Rb = tc->readIntReg(_srcRegIdx[0]);
return (Rb & ~3) | (NPC & 1);
}

View file

@ -25,6 +25,13 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// The actual decoder specification
//
decode OPCODE default Unknown::unknown() {
@ -40,9 +47,11 @@ decode OPCODE default Unknown::unknown() {
0x23: ldt({{ Fa = Mem.df; }});
0x2a: ldl_l({{ Ra.sl = Mem.sl; }}, mem_flags = LOCKED);
0x2b: ldq_l({{ Ra.uq = Mem.uq; }}, mem_flags = LOCKED);
#ifdef USE_COPY
0x20: MiscPrefetch::copy_load({{ EA = Ra; }},
{{ fault = xc->copySrcTranslate(EA); }},
inst_flags = [IsMemRef, IsLoad, IsCopy]);
#endif
}
format LoadOrPrefetch {
@ -62,9 +71,11 @@ decode OPCODE default Unknown::unknown() {
0x0f: stq_u({{ Mem.uq = Ra.uq; }}, {{ EA = (Rb + disp) & ~7; }});
0x26: sts({{ Mem.ul = t_to_s(Fa.uq); }});
0x27: stt({{ Mem.df = Fa; }});
#ifdef USE_COPY
0x24: MiscPrefetch::copy_store({{ EA = Rb; }},
{{ fault = xc->copy(EA); }},
inst_flags = [IsMemRef, IsStore, IsCopy]);
#endif
}
format StoreCond {
@ -73,7 +84,7 @@ decode OPCODE default Unknown::unknown() {
uint64_t tmp = write_result;
// see stq_c
Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
}}, mem_flags = LOCKED);
}}, mem_flags = LOCKED, inst_flags = IsStoreConditional);
0x2f: stq_c({{ Mem.uq = Ra; }},
{{
uint64_t tmp = write_result;
@ -85,7 +96,7 @@ decode OPCODE default Unknown::unknown() {
// mailbox access, and we don't update the
// result register at all.
Ra = (tmp == 0 || tmp == 1) ? tmp : Ra;
}}, mem_flags = LOCKED);
}}, mem_flags = LOCKED, inst_flags = IsStoreConditional);
}
format IntegerOperate {
@ -591,8 +602,8 @@ decode OPCODE default Unknown::unknown() {
0x02e: fcmovle({{ Fc = (Fa <= 0) ? Fb : Fc; }});
0x02f: fcmovgt({{ Fc = (Fa > 0) ? Fb : Fc; }});
0x024: mt_fpcr({{ FPCR = Fa.uq; }});
0x025: mf_fpcr({{ Fa.uq = FPCR; }});
0x024: mt_fpcr({{ FPCR = Fa.uq; }}, IsIprAccess);
0x025: mf_fpcr({{ Fa.uq = FPCR; }}, IsIprAccess);
}
}
@ -623,7 +634,7 @@ decode OPCODE default Unknown::unknown() {
#else
Ra = curTick;
#endif
}});
}}, IsUnverifiable);
// All of the barrier instructions below do nothing in
// their execute() methods (hence the empty code blocks).
@ -641,8 +652,8 @@ decode OPCODE default Unknown::unknown() {
// a barrier on integer and FP traps. "EXCB is thus a
// superset of TRAPB." (Alpha ARM, Sec 4.11.4) We treat
// them the same though.
0x0000: trapb({{ }}, IsSerializing, No_OpClass);
0x0400: excb({{ }}, IsSerializing, No_OpClass);
0x0000: trapb({{ }}, IsSerializing, IsSerializeBefore, No_OpClass);
0x0400: excb({{ }}, IsSerializing, IsSerializeBefore, No_OpClass);
0x4000: mb({{ }}, IsMemBarrier, MemReadOp);
0x4400: wmb({{ }}, IsWriteBarrier, MemWriteOp);
}
@ -652,11 +663,11 @@ decode OPCODE default Unknown::unknown() {
0xe000: rc({{
Ra = xc->readIntrFlag();
xc->setIntrFlag(0);
}}, IsNonSpeculative);
}}, IsNonSpeculative, IsUnverifiable);
0xf000: rs({{
Ra = xc->readIntrFlag();
xc->setIntrFlag(1);
}}, IsNonSpeculative);
}}, IsNonSpeculative, IsUnverifiable);
}
#else
format FailUnimpl {
@ -690,15 +701,15 @@ decode OPCODE default Unknown::unknown() {
0x00: decode PALFUNC {
format EmulatedCallPal {
0x00: halt ({{
SimExit(curTick, "halt instruction encountered");
exitSimLoop(curTick, "halt instruction encountered");
}}, IsNonSpeculative);
0x83: callsys({{
xc->syscall(R0);
}}, IsNonSpeculative);
}}, IsSerializeAfter, IsNonSpeculative);
// Read uniq reg into ABI return value register (r0)
0x9e: rduniq({{ R0 = Runiq; }});
0x9e: rduniq({{ R0 = Runiq; }}, IsIprAccess);
// Write uniq reg with value from ABI arg register (r16)
0x9f: wruniq({{ Runiq = R16; }});
0x9f: wruniq({{ Runiq = R16; }}, IsIprAccess);
}
}
#endif
@ -735,7 +746,7 @@ decode OPCODE default Unknown::unknown() {
format HwMoveIPR {
1: hw_mfpr({{
Ra = xc->readMiscRegWithEffect(ipr_index, fault);
}});
}}, IsIprAccess);
}
}
@ -745,69 +756,69 @@ decode OPCODE default Unknown::unknown() {
1: hw_mtpr({{
xc->setMiscRegWithEffect(ipr_index, Ra);
if (traceData) { traceData->setData(Ra); }
}});
}}, IsIprAccess);
}
}
format BasicOperate {
0x1e: decode PALMODE {
0: OpcdecFault::hw_rei();
1:hw_rei({{ xc->hwrei(); }}, IsSerializing);
1:hw_rei({{ xc->hwrei(); }}, IsSerializing, IsSerializeBefore);
}
// M5 special opcodes use the reserved 0x01 opcode space
0x01: decode M5FUNC {
0x00: arm({{
AlphaPseudo::arm(xc->xcBase());
AlphaPseudo::arm(xc->tcBase());
}}, IsNonSpeculative);
0x01: quiesce({{
AlphaPseudo::quiesce(xc->xcBase());
}}, IsNonSpeculative);
AlphaPseudo::quiesce(xc->tcBase());
}}, IsNonSpeculative, IsQuiesce);
0x02: quiesceNs({{
AlphaPseudo::quiesceNs(xc->xcBase(), R16);
}}, IsNonSpeculative);
AlphaPseudo::quiesceNs(xc->tcBase(), R16);
}}, IsNonSpeculative, IsQuiesce);
0x03: quiesceCycles({{
AlphaPseudo::quiesceCycles(xc->xcBase(), R16);
}}, IsNonSpeculative);
AlphaPseudo::quiesceCycles(xc->tcBase(), R16);
}}, IsNonSpeculative, IsQuiesce);
0x04: quiesceTime({{
R0 = AlphaPseudo::quiesceTime(xc->xcBase());
R0 = AlphaPseudo::quiesceTime(xc->tcBase());
}}, IsNonSpeculative);
0x10: ivlb({{
AlphaPseudo::ivlb(xc->xcBase());
AlphaPseudo::ivlb(xc->tcBase());
}}, No_OpClass, IsNonSpeculative);
0x11: ivle({{
AlphaPseudo::ivle(xc->xcBase());
AlphaPseudo::ivle(xc->tcBase());
}}, No_OpClass, IsNonSpeculative);
0x20: m5exit_old({{
AlphaPseudo::m5exit_old(xc->xcBase());
AlphaPseudo::m5exit_old(xc->tcBase());
}}, No_OpClass, IsNonSpeculative);
0x21: m5exit({{
AlphaPseudo::m5exit(xc->xcBase(), R16);
AlphaPseudo::m5exit(xc->tcBase(), R16);
}}, No_OpClass, IsNonSpeculative);
0x30: initparam({{ Ra = xc->xcBase()->getCpuPtr()->system->init_param; }});
0x30: initparam({{ Ra = xc->tcBase()->getCpuPtr()->system->init_param; }});
0x40: resetstats({{
AlphaPseudo::resetstats(xc->xcBase(), R16, R17);
AlphaPseudo::resetstats(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
0x41: dumpstats({{
AlphaPseudo::dumpstats(xc->xcBase(), R16, R17);
AlphaPseudo::dumpstats(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
0x42: dumpresetstats({{
AlphaPseudo::dumpresetstats(xc->xcBase(), R16, R17);
AlphaPseudo::dumpresetstats(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
0x43: m5checkpoint({{
AlphaPseudo::m5checkpoint(xc->xcBase(), R16, R17);
AlphaPseudo::m5checkpoint(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
0x50: m5readfile({{
R0 = AlphaPseudo::readfile(xc->xcBase(), R16, R17, R18);
R0 = AlphaPseudo::readfile(xc->tcBase(), R16, R17, R18);
}}, IsNonSpeculative);
0x51: m5break({{
AlphaPseudo::debugbreak(xc->xcBase());
AlphaPseudo::debugbreak(xc->tcBase());
}}, IsNonSpeculative);
0x52: m5switchcpu({{
AlphaPseudo::switchcpu(xc->xcBase());
AlphaPseudo::switchcpu(xc->tcBase());
}}, IsNonSpeculative);
0x53: m5addsymbol({{
AlphaPseudo::addsymbol(xc->xcBase(), R16, R17);
AlphaPseudo::addsymbol(xc->tcBase(), R16, R17);
}}, IsNonSpeculative);
0x54: m5panic({{
panic("M5 panic instruction called at pc=%#x.", xc->readPC());

View file

@ -25,6 +25,17 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Floating-point instructions
//
// Note that many FP-type instructions which do not support all the
// various rounding & trapping modes use the simpler format
// BasicOperateWithNopCheck.
//
output exec {{
/// Check "FP enabled" machine status bit. Called when executing any FP

View file

@ -25,6 +25,13 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Integer operate instructions
//
output header {{
/**

View file

@ -25,6 +25,20 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Alpha ISA description file.
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
//
// Output include file directives.
//
output header {{
#include <sstream>
@ -42,7 +56,7 @@ output decoder {{
#include "base/fenv.hh"
#include "base/loader/symtab.hh"
#include "config/ss_compatible_fp.hh"
#include "cpu/exec_context.hh" // for Jump::branchTarget()
#include "cpu/thread_context.hh" // for Jump::branchTarget()
#include <math.h>

View file

@ -25,6 +25,14 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Steve Reinhardt
// Kevin Lim
////////////////////////////////////////////////////////////////////
//
// Memory-format instructions: LoadAddress, Load, Store
//
output header {{
/**

View file

@ -25,6 +25,13 @@
// 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: Kevin Lim
////////////////////////////////////////////////////////////////////
//
// OPCDEC fault instructions
//
output header {{
/**

View file

@ -25,6 +25,13 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// PAL calls & PAL-specific instructions
//
output header {{
/**
@ -259,9 +266,11 @@ output decoder {{
}
}};
def format HwMoveIPR(code) {{
def format HwMoveIPR(code, *flags) {{
all_flags = ['IprAccessOp']
all_flags += flags
iop = InstObjParams(name, Name, 'HwMoveIPR', CodeBlock(code),
['IprAccessOp'])
all_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)

View file

@ -25,6 +25,13 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Unimplemented instructions
//
output header {{
/**

View file

@ -25,6 +25,13 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Unknown instructions
//
output decoder {{
std::string

View file

@ -25,6 +25,13 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Steve Reinhardt
////////////////////////////////////////////////////////////////////
//
// Utility functions for execute methods
//
output exec {{

View file

@ -24,6 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
* Gabe Black
*/
#ifndef __ARCH_ALPHA_ISA_TRAITS_HH__

View file

@ -24,6 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ali Saidi
* Nathan Binkert
*/
#ifndef __ARCH_ALPHA_LINUX_ALIGNED_HH__

View file

@ -24,6 +24,8 @@
* 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: Korey Sewell
*/
#include "arch/alpha/linux/linux.hh"

View file

@ -24,6 +24,8 @@
* 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: Korey Sewell
*/
#ifndef __ALPHA_ALPHA_LINUX_HH

View file

@ -24,6 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
* Ali Saidi
*/
#include "arch/alpha/linux/linux.hh"
@ -31,7 +34,7 @@
#include "arch/alpha/isa_traits.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "cpu/thread_context.hh"
#include "kern/linux/linux.hh"
#include "sim/process.hh"
@ -45,9 +48,9 @@ using namespace AlphaISA;
/// Target uname() handler.
static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
ThreadContext *tc)
{
TypedBufferArg<Linux::utsname> name(xc->getSyscallArg(0));
TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@ -55,7 +58,7 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "alpha");
name.copyOut(xc->getMemPort());
name.copyOut(tc->getMemPort());
return 0;
}
@ -64,18 +67,18 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
/// different in practice from those used by Tru64 processes.
static SyscallReturn
osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
ThreadContext *tc)
{
unsigned op = xc->getSyscallArg(0);
// unsigned nbytes = xc->getSyscallArg(2);
unsigned op = tc->getSyscallArg(0);
// unsigned nbytes = tc->getSyscallArg(2);
switch (op) {
case 45: { // GSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
fpcr.copyOut(xc->getMemPort());
fpcr.copyOut(tc->getMemPort());
return 0;
}
@ -91,17 +94,17 @@ osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
/// Target osf_setsysinfo() handler.
static SyscallReturn
osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
ThreadContext *tc)
{
unsigned op = xc->getSyscallArg(0);
// unsigned nbytes = xc->getSyscallArg(2);
unsigned op = tc->getSyscallArg(0);
// unsigned nbytes = tc->getSyscallArg(2);
switch (op) {
case 14: { // SSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
// I don't think this exactly matches the HW FPCR
fpcr.copyIn(xc->getMemPort());
fpcr.copyIn(tc->getMemPort());
DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
return 0;

View file

@ -24,6 +24,8 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
*/
#ifndef __ALPHA_LINUX_PROCESS_HH__

View file

@ -24,6 +24,11 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ali Saidi
* Lisa Hsu
* Nathan Binkert
* Steve Reinhardt
*/
/**
@ -41,7 +46,7 @@
#include "arch/alpha/linux/threadinfo.hh"
#include "arch/alpha/system.hh"
#include "base/loader/symtab.hh"
#include "cpu/exec_context.hh"
#include "cpu/thread_context.hh"
#include "cpu/base.hh"
#include "dev/platform.hh"
#include "kern/linux/printk.hh"
@ -132,24 +137,6 @@ LinuxAlphaSystem::LinuxAlphaSystem(Params *p)
} else {
printThreadEvent = NULL;
}
if (params()->bin_int) {
intStartEvent = addPalFuncEvent<InterruptStartEvent>("sys_int_21");
if (!intStartEvent)
panic("could not find symbol: sys_int_21\n");
intEndEvent = addPalFuncEvent<InterruptEndEvent>("rti_to_kern");
if (!intEndEvent)
panic("could not find symbol: rti_to_kern\n");
intEndEvent2 = addPalFuncEvent<InterruptEndEvent>("rti_to_user");
if (!intEndEvent2)
panic("could not find symbol: rti_to_user\n");
intEndEvent3 = addKernelFuncEvent<InterruptEndEvent>("do_softirq");
if (!intEndEvent3)
panic("could not find symbol: do_softirq\n");
}
}
LinuxAlphaSystem::~LinuxAlphaSystem()
@ -163,37 +150,37 @@ LinuxAlphaSystem::~LinuxAlphaSystem()
delete debugPrintkEvent;
delete idleStartEvent;
delete printThreadEvent;
delete intStartEvent;
delete intEndEvent;
delete intEndEvent2;
}
void
LinuxAlphaSystem::setDelayLoop(ExecContext *xc)
LinuxAlphaSystem::setDelayLoop(ThreadContext *tc)
{
Addr addr = 0;
if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
Tick cpuFreq = xc->getCpuPtr()->frequency();
Tick cpuFreq = tc->getCpuPtr()->frequency();
Tick intrFreq = platform->intrFrequency();
xc->getVirtPort(xc)->write(addr,
(uint32_t)((cpuFreq / intrFreq) * 0.9988));
VirtualPort *vp;
vp = tc->getVirtPort();
vp->writeHtoG(addr, (uint32_t)((cpuFreq / intrFreq) * 0.9988));
tc->delVirtPort(vp);
}
}
void
LinuxAlphaSystem::SkipDelayLoopEvent::process(ExecContext *xc)
LinuxAlphaSystem::SkipDelayLoopEvent::process(ThreadContext *tc)
{
SkipFuncEvent::process(xc);
SkipFuncEvent::process(tc);
// calculate and set loops_per_jiffy
((LinuxAlphaSystem *)xc->getSystemPtr())->setDelayLoop(xc);
((LinuxAlphaSystem *)tc->getSystemPtr())->setDelayLoop(tc);
}
void
LinuxAlphaSystem::PrintThreadInfo::process(ExecContext *xc)
LinuxAlphaSystem::PrintThreadInfo::process(ThreadContext *tc)
{
Linux::ThreadInfo ti(xc);
Linux::ThreadInfo ti(tc);
DPRINTF(Thread, "Currently Executing Thread %s, pid %d, started at: %d\n",
ti.curTaskName(), ti.curTaskPID(), ti.curTaskStart());
@ -216,10 +203,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
Param<uint64_t> system_type;
Param<uint64_t> system_rev;
Param<bool> bin;
VectorParam<string> binned_fns;
Param<bool> bin_int;
END_DECLARE_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
@ -234,10 +217,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
INIT_PARAM_DFLT(bin, "is this system to be binned", false),
INIT_PARAM(binned_fns, "functions to be broken down and binned"),
INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
END_INIT_SIM_OBJECT_PARAMS(LinuxAlphaSystem)
@ -255,9 +235,6 @@ CREATE_SIM_OBJECT(LinuxAlphaSystem)
p->readfile = readfile;
p->system_type = system_type;
p->system_rev = system_rev;
p->bin = bin;
p->binned_fns = binned_fns;
p->bin_int = bin_int;
return new LinuxAlphaSystem(p);
}

View file

@ -24,12 +24,16 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ali Saidi
* Lisa Hsu
* Nathan Binkert
*/
#ifndef __ARCH_ALPHA_LINUX_SYSTEM_HH__
#define __ARCH_ALPHA_LINUX_SYSTEM_HH__
class ExecContext;
class ThreadContext;
class BreakPCEvent;
class IdleStartEvent;
@ -41,7 +45,7 @@ using namespace AlphaISA;
using namespace Linux;
/**
* This class contains linux specific system code (Loading, Events, Binning).
* This class contains linux specific system code (Loading, Events).
* It points to objects that are the system binaries to load and patches them
* appropriately to work in simulator.
*/
@ -53,7 +57,7 @@ class LinuxAlphaSystem : public AlphaSystem
public:
SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr)
: SkipFuncEvent(q, desc, addr) {}
virtual void process(ExecContext *xc);
virtual void process(ThreadContext *tc);
};
class PrintThreadInfo : public PCEvent
@ -61,7 +65,7 @@ class LinuxAlphaSystem : public AlphaSystem
public:
PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr)
: PCEvent(q, desc, addr) {}
virtual void process(ExecContext *xc);
virtual void process(ThreadContext *tc);
};
@ -120,18 +124,6 @@ class LinuxAlphaSystem : public AlphaSystem
*/
PrintThreadInfo *printThreadEvent;
/**
* Event to bin Interrupts seperately from kernel code
*/
InterruptStartEvent *intStartEvent;
/**
* Event to bin Interrupts seperately from kernel code
*/
InterruptEndEvent *intEndEvent;
InterruptEndEvent *intEndEvent2;
InterruptEndEvent *intEndEvent3;
/** Grab the PCBB of the idle process when it starts */
IdleStartEvent *idleStartEvent;
@ -139,7 +131,7 @@ class LinuxAlphaSystem : public AlphaSystem
LinuxAlphaSystem(Params *p);
~LinuxAlphaSystem();
void setDelayLoop(ExecContext *xc);
void setDelayLoop(ThreadContext *tc);
};
#endif // __ARCH_ALPHA_LINUX_SYSTEM_HH__

View file

@ -24,6 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ali Saidi
* Nathan Binkert
*/
#ifndef __ARCH_ALPHA_LINUX_THREAD_INFO_H__

View file

@ -24,13 +24,16 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ali Saidi
* Nathan Binkert
*/
#ifndef __ARCH_ALPHA_LINUX_LINUX_TREADNIFO_HH__
#define __ARCH_ALPHA_LINUX_LINUX_TREADNIFO_HH__
#include "arch/alpha/linux/thread_info.hh"
#include "cpu/exec_context.hh"
#include "cpu/thread_context.hh"
#include "kern/linux/sched.hh"
#include "sim/vptr.hh"
@ -39,10 +42,10 @@ namespace Linux {
class ThreadInfo
{
private:
ExecContext *xc;
ThreadContext *tc;
public:
ThreadInfo(ExecContext *exec) : xc(exec) {}
ThreadInfo(ThreadContext *_tc) : tc(_tc) {}
~ThreadInfo() {}
inline VPtr<thread_info>
@ -54,15 +57,15 @@ class ThreadInfo
* thread_info struct. So we can get the address by masking off
* the lower 14 bits.
*/
current = xc->readIntReg(TheISA::StackPointerReg) & ~0x3fff;
return VPtr<thread_info>(xc, current);
current = tc->readIntReg(TheISA::StackPointerReg) & ~0x3fff;
return VPtr<thread_info>(tc, current);
}
inline VPtr<task_struct>
curTaskInfo()
{
Addr task = curThreadInfo()->task;
return VPtr<task_struct>(xc, task);
return VPtr<task_struct>(tc, task);
}
std::string

View file

@ -24,6 +24,8 @@
* 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: Nathan Binkert
*/
#include "arch/alpha/osfpal.hh"

View file

@ -24,6 +24,8 @@
* 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: Nathan Binkert
*/
#ifndef __OSFPAL_HH__

View file

@ -24,59 +24,22 @@
* 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
* Ali Saidi
*/
#include "arch/alpha/constants.hh"
#include "arch/alpha/process.hh"
#include "arch/alpha/linux/process.hh"
#include "arch/alpha/tru64/process.hh"
#include "base/loader/object_file.hh"
#include "base/misc.hh"
#include "cpu/exec_context.hh"
#include "sim/builder.hh"
#include "cpu/thread_context.hh"
#include "sim/system.hh"
using namespace AlphaISA;
using namespace std;
AlphaLiveProcess *
AlphaLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
int stdout_fd, int stderr_fd, std::string executable,
std::vector<std::string> &argv, std::vector<std::string> &envp)
{
AlphaLiveProcess *process = NULL;
ObjectFile *objFile = createObjectFile(executable);
if (objFile == NULL) {
fatal("Can't load object file %s", executable);
}
if (objFile->getArch() != ObjectFile::Alpha)
fatal("Object file does not match architecture.");
switch (objFile->getOpSys()) {
case ObjectFile::Tru64:
process = new AlphaTru64Process(nm, objFile, system,
stdin_fd, stdout_fd, stderr_fd,
argv, envp);
break;
case ObjectFile::Linux:
process = new AlphaLinuxProcess(nm, objFile, system,
stdin_fd, stdout_fd, stderr_fd,
argv, envp);
break;
default:
fatal("Unknown/unsupported operating system.");
}
if (process == NULL)
fatal("Unknown error creating process object.");
return process;
}
AlphaLiveProcess::AlphaLiveProcess(const std::string &nm, ObjectFile *objFile,
System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
std::vector<std::string> &argv, std::vector<std::string> &envp)
@ -104,64 +67,7 @@ AlphaLiveProcess::startup()
{
argsInit(MachineBytes, VMPageSize);
execContexts[0]->setIntReg(GlobalPointerReg, objFile->globalPointer());
threadContexts[0]->setIntReg(GlobalPointerReg, objFile->globalPointer());
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaLiveProcess)
VectorParam<string> cmd;
Param<string> executable;
Param<string> input;
Param<string> output;
VectorParam<string> env;
SimObjectParam<System *> system;
END_DECLARE_SIM_OBJECT_PARAMS(AlphaLiveProcess)
BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaLiveProcess)
INIT_PARAM(cmd, "command line (executable plus arguments)"),
INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
INIT_PARAM(env, "environment settings"),
INIT_PARAM(system, "system")
END_INIT_SIM_OBJECT_PARAMS(AlphaLiveProcess)
CREATE_SIM_OBJECT(AlphaLiveProcess)
{
string in = input;
string out = output;
// initialize file descriptors to default: same as simulator
int stdin_fd, stdout_fd, stderr_fd;
if (in == "stdin" || in == "cin")
stdin_fd = STDIN_FILENO;
else
stdin_fd = Process::openInputFile(input);
if (out == "stdout" || out == "cout")
stdout_fd = STDOUT_FILENO;
else if (out == "stderr" || out == "cerr")
stdout_fd = STDERR_FILENO;
else
stdout_fd = Process::openOutputFile(out);
stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
return AlphaLiveProcess::create(getInstanceName(), system,
stdin_fd, stdout_fd, stderr_fd,
(string)executable == "" ? cmd[0] : executable,
cmd, env);
}
REGISTER_SIM_OBJECT("AlphaLiveProcess", AlphaLiveProcess)

View file

@ -24,6 +24,9 @@
* 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
* Ali Saidi
*/
#ifndef __ALPHA_PROCESS_HH__
@ -46,18 +49,6 @@ class AlphaLiveProcess : public LiveProcess
std::vector<std::string> &envp);
void startup();
public:
// this function is used to create the LiveProcess object, since
// we can't tell which subclass of LiveProcess to use until we
// open and look at the object file.
static AlphaLiveProcess *create(const std::string &nm,
System *_system,
int stdin_fd, int stdout_fd, int stderr_fd,
std::string executable,
std::vector<std::string> &argv,
std::vector<std::string> &envp);
};

View file

@ -24,6 +24,8 @@
* 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
*/
#ifndef __ARCH_ALPHA_REGFILE_HH__
@ -34,7 +36,7 @@
#include "sim/faults.hh"
class Checkpoint;
class ExecContext;
class ThreadContext;
namespace AlphaISA
{
@ -60,6 +62,8 @@ namespace AlphaISA
void unserialize(Checkpoint *cp, const std::string &section);
void clear()
{ bzero(regs, sizeof(regs)); }
};
class FloatRegFile
@ -75,6 +79,8 @@ namespace AlphaISA
void unserialize(Checkpoint *cp, const std::string &section);
void clear()
{ bzero(d, sizeof(d)); }
};
class MiscRegFile {
@ -88,7 +94,7 @@ namespace AlphaISA
MiscReg readReg(int misc_reg);
MiscReg readRegWithEffect(int misc_reg, Fault &fault,
ExecContext *xc);
ThreadContext *tc);
//These functions should be removed once the simplescalar cpu model
//has been replaced.
@ -98,8 +104,14 @@ namespace AlphaISA
Fault setReg(int misc_reg, const MiscReg &val);
Fault setRegWithEffect(int misc_reg, const MiscReg &val,
ExecContext *xc);
ThreadContext *tc);
void clear()
{
fpcr = uniq = 0;
lock_flag = 0;
lock_addr = 0;
}
#if FULL_SYSTEM
protected:
typedef uint64_t InternalProcReg;
@ -107,9 +119,9 @@ namespace AlphaISA
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
private:
InternalProcReg readIpr(int idx, Fault &fault, ExecContext *xc);
InternalProcReg readIpr(int idx, Fault &fault, ThreadContext *tc);
Fault setIpr(int idx, InternalProcReg val, ExecContext *xc);
Fault setIpr(int idx, InternalProcReg val, ThreadContext *tc);
#endif
friend class RegFile;
};
@ -169,9 +181,9 @@ namespace AlphaISA
void clear()
{
bzero(&intRegFile, sizeof(intRegFile));
bzero(&floatRegFile, sizeof(floatRegFile));
bzero(&miscRegFile, sizeof(miscRegFile));
intRegFile.clear();
floatRegFile.clear();
miscRegFile.clear();
}
MiscReg readMiscReg(int miscReg)
@ -180,10 +192,10 @@ namespace AlphaISA
}
MiscReg readMiscRegWithEffect(int miscReg,
Fault &fault, ExecContext *xc)
Fault &fault, ThreadContext *tc)
{
fault = NoFault;
return miscRegFile.readRegWithEffect(miscReg, fault, xc);
return miscRegFile.readRegWithEffect(miscReg, fault, tc);
}
Fault setMiscReg(int miscReg, const MiscReg &val)
@ -192,9 +204,9 @@ namespace AlphaISA
}
Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
ExecContext * xc)
ThreadContext * tc)
{
return miscRegFile.setRegWithEffect(miscReg, val, xc);
return miscRegFile.setRegWithEffect(miscReg, val, tc);
}
FloatReg readFloatReg(int floatReg)
@ -266,12 +278,12 @@ namespace AlphaISA
}
};
void copyRegs(ExecContext *src, ExecContext *dest);
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ExecContext *src, ExecContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
#if FULL_SYSTEM
void copyIprs(ExecContext *src, ExecContext *dest);
void copyIprs(ThreadContext *src, ThreadContext *dest);
#endif
} // namespace AlphaISA

View file

@ -24,6 +24,8 @@
* 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: Nathan Binkert
*/
#include <string>
@ -34,36 +36,42 @@
#include "base/bitfield.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/exec_context.hh"
#include "cpu/thread_context.hh"
#include "sim/system.hh"
using namespace std;
using namespace AlphaISA;
ProcessInfo::ProcessInfo(ExecContext *_xc)
: xc(_xc)
ProcessInfo::ProcessInfo(ThreadContext *_tc)
: tc(_tc)
{
Addr addr = 0;
if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
panic("thread info not compiled into kernel\n");
thread_info_size = gtoh(xc->getVirtPort()->read<int32_t>(addr));
VirtualPort *vp;
if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
panic("thread info not compiled into kernel\n");
task_struct_size = gtoh(xc->getVirtPort()->read<int32_t>(addr));
vp = tc->getVirtPort();
if (!xc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_size", addr))
panic("thread info not compiled into kernel\n");
task_off = gtoh(xc->getVirtPort()->read<int32_t>(addr));
thread_info_size = vp->readGtoH<int32_t>(addr);
if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_size", addr))
panic("thread info not compiled into kernel\n");
pid_off = gtoh(xc->getVirtPort()->read<int32_t>(addr));
task_struct_size = vp->readGtoH<int32_t>(addr);
if (!xc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
if (!tc->getSystemPtr()->kernelSymtab->findAddress("thread_info_task", addr))
panic("thread info not compiled into kernel\n");
name_off = gtoh(xc->getVirtPort()->read<int32_t>(addr));
task_off = vp->readGtoH<int32_t>(addr);
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_pid", addr))
panic("thread info not compiled into kernel\n");
pid_off = vp->readGtoH<int32_t>(addr);
if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr))
panic("thread info not compiled into kernel\n");
name_off = vp->readGtoH<int32_t>(addr);
tc->delVirtPort(vp);
}
Addr
@ -73,7 +81,15 @@ ProcessInfo::task(Addr ksp) const
if (base == ULL(0xfffffc0000000000))
return 0;
return gtoh(xc->getVirtPort()->read<Addr>(base + task_off));
Addr tsk;
VirtualPort *vp;
vp = tc->getVirtPort();
tsk = vp->readGtoH<Addr>(base + task_off);
tc->delVirtPort(vp);
return tsk;
}
int
@ -83,7 +99,15 @@ ProcessInfo::pid(Addr ksp) const
if (!task)
return -1;
return gtoh(xc->getVirtPort()->read<uint16_t>(task + pid_off));
uint16_t pd;
VirtualPort *vp;
vp = tc->getVirtPort();
pd = vp->readGtoH<uint16_t>(task + pid_off);
tc->delVirtPort(vp);
return pd;
}
string
@ -94,7 +118,7 @@ ProcessInfo::name(Addr ksp) const
return "console";
char comm[256];
CopyStringOut(xc, comm, task + name_off, sizeof(comm));
CopyStringOut(tc, comm, task + name_off, sizeof(comm));
if (!comm[0])
return "startup";
@ -102,14 +126,14 @@ ProcessInfo::name(Addr ksp) const
}
StackTrace::StackTrace()
: xc(0), stack(64)
: tc(0), stack(64)
{
}
StackTrace::StackTrace(ExecContext *_xc, StaticInstPtr inst)
: xc(0), stack(64)
StackTrace::StackTrace(ThreadContext *_tc, StaticInstPtr inst)
: tc(0), stack(64)
{
trace(_xc, inst);
trace(_tc, inst);
}
StackTrace::~StackTrace()
@ -117,15 +141,15 @@ StackTrace::~StackTrace()
}
void
StackTrace::trace(ExecContext *_xc, bool is_call)
StackTrace::trace(ThreadContext *_tc, bool is_call)
{
xc = _xc;
tc = _tc;
bool usermode = (xc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
bool usermode = (tc->readMiscReg(AlphaISA::IPR_DTB_CM) & 0x18) != 0;
Addr pc = xc->readNextPC();
bool kernel = xc->getSystemPtr()->kernelStart <= pc &&
pc <= xc->getSystemPtr()->kernelEnd;
Addr pc = tc->readNextPC();
bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
pc <= tc->getSystemPtr()->kernelEnd;
if (usermode) {
stack.push_back(user);
@ -137,8 +161,8 @@ StackTrace::trace(ExecContext *_xc, bool is_call)
return;
}
SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab;
Addr ksp = xc->readIntReg(TheISA::StackPointerReg);
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
Addr ksp = tc->readIntReg(TheISA::StackPointerReg);
Addr bottom = ksp & ~0x3fff;
Addr addr;
@ -147,7 +171,7 @@ StackTrace::trace(ExecContext *_xc, bool is_call)
panic("could not find address %#x", pc);
stack.push_back(addr);
pc = xc->readPC();
pc = tc->readPC();
}
Addr ra;
@ -179,8 +203,8 @@ StackTrace::trace(ExecContext *_xc, bool is_call)
return;
}
bool kernel = xc->getSystemPtr()->kernelStart <= pc &&
pc <= xc->getSystemPtr()->kernelEnd;
bool kernel = tc->getSystemPtr()->kernelStart <= pc &&
pc <= tc->getSystemPtr()->kernelEnd;
if (!kernel)
return;
@ -194,22 +218,22 @@ StackTrace::trace(ExecContext *_xc, bool is_call)
bool
StackTrace::isEntry(Addr addr)
{
if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp12))
if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp12))
return true;
if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp7))
if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp7))
return true;
if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp11))
if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp11))
return true;
if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp21))
if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp21))
return true;
if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp9))
if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp9))
return true;
if (addr == xc->readMiscReg(AlphaISA::IPR_PALtemp2))
if (addr == tc->readMiscReg(AlphaISA::IPR_PALtemp2))
return true;
return false;
@ -294,7 +318,7 @@ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
MachInst inst;
CopyOut(xc, (uint8_t *)&inst, pc, sizeof(MachInst));
CopyOut(tc, (uint8_t *)&inst, pc, sizeof(MachInst));
int reg, disp;
if (decodeStack(inst, disp)) {
@ -305,7 +329,7 @@ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
size += disp;
} else if (decodeSave(inst, reg, disp)) {
if (!ra && reg == ReturnAddressReg) {
CopyOut(xc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
CopyOut(tc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
if (!ra) {
// panic("no return address value pc=%#x\n", pc);
return false;
@ -321,8 +345,8 @@ StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
void
StackTrace::dump()
{
StringWrap name(xc->getCpuPtr()->name());
SymbolTable *symtab = xc->getSystemPtr()->kernelSymtab;
StringWrap name(tc->getCpuPtr()->name());
SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab;
DPRINTFN("------ Stack ------\n");

View file

@ -24,6 +24,8 @@
* 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: Nathan Binkert
*/
#ifndef __ARCH_ALPHA_STACKTRACE_HH__
@ -32,13 +34,13 @@
#include "base/trace.hh"
#include "cpu/static_inst.hh"
class ExecContext;
class ThreadContext;
class StackTrace;
class ProcessInfo
{
private:
ExecContext *xc;
ThreadContext *tc;
int thread_info_size;
int task_struct_size;
@ -47,7 +49,7 @@ class ProcessInfo
int name_off;
public:
ProcessInfo(ExecContext *_xc);
ProcessInfo(ThreadContext *_tc);
Addr task(Addr ksp) const;
int pid(Addr ksp) const;
@ -59,7 +61,7 @@ class StackTrace
protected:
typedef TheISA::MachInst MachInst;
private:
ExecContext *xc;
ThreadContext *tc;
std::vector<Addr> stack;
private:
@ -68,21 +70,21 @@ class StackTrace
bool decodeSave(MachInst inst, int &reg, int &disp);
bool decodeStack(MachInst inst, int &disp);
void trace(ExecContext *xc, bool is_call);
void trace(ThreadContext *tc, bool is_call);
public:
StackTrace();
StackTrace(ExecContext *xc, StaticInstPtr inst);
StackTrace(ThreadContext *tc, StaticInstPtr inst);
~StackTrace();
void clear()
{
xc = 0;
tc = 0;
stack.clear();
}
bool valid() const { return xc != NULL; }
bool trace(ExecContext *xc, StaticInstPtr inst);
bool valid() const { return tc != NULL; }
bool trace(ThreadContext *tc, StaticInstPtr inst);
public:
const std::vector<Addr> &getstack() const { return stack; }
@ -104,7 +106,7 @@ class StackTrace
};
inline bool
StackTrace::trace(ExecContext *xc, StaticInstPtr inst)
StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
{
if (!inst->isCall() && !inst->isReturn())
return false;
@ -112,7 +114,7 @@ StackTrace::trace(ExecContext *xc, StaticInstPtr inst)
if (valid())
clear();
trace(xc, !inst->isReturn());
trace(tc, !inst->isReturn());
return true;
}

View file

@ -24,6 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ali Saidi
* Nathan Binkert
*/
#include "arch/alpha/ev5.hh"
@ -230,10 +233,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem)
Param<uint64_t> system_type;
Param<uint64_t> system_rev;
Param<bool> bin;
VectorParam<std::string> binned_fns;
Param<bool> bin_int;
END_DECLARE_SIM_OBJECT_PARAMS(AlphaSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem)
@ -248,10 +247,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(AlphaSystem)
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
INIT_PARAM_DFLT(bin, "is this system to be binned", false),
INIT_PARAM(binned_fns, "functions to be broken down and binned"),
INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10)
END_INIT_SIM_OBJECT_PARAMS(AlphaSystem)
@ -269,9 +265,6 @@ CREATE_SIM_OBJECT(AlphaSystem)
p->readfile = readfile;
p->system_type = system_type;
p->system_rev = system_rev;
p->bin = bin;
p->binned_fns = binned_fns;
p->bin_int = bin_int;
return new AlphaSystem(p);
}

View file

@ -24,6 +24,9 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ali Saidi
* Nathan Binkert
*/
#ifndef __ARCH_ALPHA_SYSTEM_HH__

View file

@ -24,6 +24,10 @@
* 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: Nathan Binkert
* Steve Reinhardt
* Andrew Schultz
*/
#include <string>
@ -34,7 +38,7 @@
#include "base/str.hh"
#include "base/trace.hh"
#include "config/alpha_tlaser.hh"
#include "cpu/exec_context.hh"
#include "cpu/thread_context.hh"
#include "sim/builder.hh"
using namespace std;
@ -282,7 +286,7 @@ AlphaITB::regStats()
Fault
AlphaITB::translate(RequestPtr &req, ExecContext *xc) const
AlphaITB::translate(RequestPtr &req, ThreadContext *tc) const
{
if (AlphaISA::PcPAL(req->getVaddr())) {
// strip off PAL PC marker (lsb is 1)
@ -304,13 +308,13 @@ AlphaITB::translate(RequestPtr &req, ExecContext *xc) const
// VA<42:41> == 2, VA<39:13> maps directly to PA<39:13> for EV5
// VA<47:41> == 0x7e, VA<40:13> maps directly to PA<40:13> for EV6
#if ALPHA_TLASER
if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) &&
if ((MCSR_SP(tc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) &&
VAddrSpaceEV5(req->getVaddr()) == 2) {
#else
if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
#endif
// only valid in kernel mode
if (ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM)) !=
if (ICM_CM(tc->readMiscReg(AlphaISA::IPR_ICM)) !=
AlphaISA::mode_kernel) {
acv++;
return new ItbAcvFault(req->getVaddr());
@ -328,7 +332,7 @@ AlphaITB::translate(RequestPtr &req, ExecContext *xc) const
} else {
// not a physical address: need to look up pte
int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN));
int asn = DTB_ASN_ASN(tc->readMiscReg(AlphaISA::IPR_DTB_ASN));
AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(),
asn);
@ -343,7 +347,7 @@ AlphaITB::translate(RequestPtr &req, ExecContext *xc) const
// check permissions for this access
if (!(pte->xre &
(1 << ICM_CM(xc->readMiscReg(AlphaISA::IPR_ICM))))) {
(1 << ICM_CM(tc->readMiscReg(AlphaISA::IPR_ICM))))) {
// instruction access fault
acv++;
return new ItbAcvFault(req->getVaddr());
@ -439,12 +443,12 @@ AlphaDTB::regStats()
}
Fault
AlphaDTB::translate(RequestPtr &req, ExecContext *xc, bool write) const
AlphaDTB::translate(RequestPtr &req, ThreadContext *tc, bool write) const
{
Addr pc = xc->readPC();
Addr pc = tc->readPC();
AlphaISA::mode_type mode =
(AlphaISA::mode_type)DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM));
(AlphaISA::mode_type)DTB_CM_CM(tc->readMiscReg(AlphaISA::IPR_DTB_CM));
/**
@ -460,7 +464,7 @@ AlphaDTB::translate(RequestPtr &req, ExecContext *xc, bool write) const
if (pc & 0x1) {
mode = (req->getFlags() & ALTMODE) ?
(AlphaISA::mode_type)ALT_MODE_AM(
xc->readMiscReg(AlphaISA::IPR_ALT_MODE))
tc->readMiscReg(AlphaISA::IPR_ALT_MODE))
: AlphaISA::mode_kernel;
}
@ -478,14 +482,14 @@ AlphaDTB::translate(RequestPtr &req, ExecContext *xc, bool write) const
// Check for "superpage" mapping
#if ALPHA_TLASER
if ((MCSR_SP(xc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) &&
if ((MCSR_SP(tc->readMiscReg(AlphaISA::IPR_MCSR)) & 2) &&
VAddrSpaceEV5(req->getVaddr()) == 2) {
#else
if (VAddrSpaceEV6(req->getVaddr()) == 0x7e) {
#endif
// only valid in kernel mode
if (DTB_CM_CM(xc->readMiscReg(AlphaISA::IPR_DTB_CM)) !=
if (DTB_CM_CM(tc->readMiscReg(AlphaISA::IPR_DTB_CM)) !=
AlphaISA::mode_kernel) {
if (write) { write_acv++; } else { read_acv++; }
uint64_t flags = ((write ? MM_STAT_WR_MASK : 0) |
@ -509,7 +513,7 @@ AlphaDTB::translate(RequestPtr &req, ExecContext *xc, bool write) const
else
read_accesses++;
int asn = DTB_ASN_ASN(xc->readMiscReg(AlphaISA::IPR_DTB_ASN));
int asn = DTB_ASN_ASN(tc->readMiscReg(AlphaISA::IPR_DTB_ASN));
// not a physical address: need to look up pte
AlphaISA::PTE *pte = lookup(AlphaISA::VAddr(req->getVaddr()).vpn(),

View file

@ -24,6 +24,9 @@
* 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: Nathan Binkert
* Steve Reinhardt
*/
#ifndef __ALPHA_MEMORY_HH__
@ -38,7 +41,7 @@
#include "mem/request.hh"
#include "sim/sim_object.hh"
class ExecContext;
class ThreadContext;
class AlphaTLB : public SimObject
{
@ -92,7 +95,7 @@ class AlphaITB : public AlphaTLB
AlphaITB(const std::string &name, int size);
virtual void regStats();
Fault translate(RequestPtr &req, ExecContext *xc) const;
Fault translate(RequestPtr &req, ThreadContext *tc) const;
};
class AlphaDTB : public AlphaTLB
@ -115,7 +118,7 @@ class AlphaDTB : public AlphaTLB
AlphaDTB(const std::string &name, int size);
virtual void regStats();
Fault translate(RequestPtr &req, ExecContext *xc, bool write) const;
Fault translate(RequestPtr &req, ThreadContext *tc, bool write) const;
};
#endif // __ALPHA_MEMORY_HH__

View file

@ -24,13 +24,16 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
* Ali Saidi
*/
#include "arch/alpha/tru64/tru64.hh"
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/tru64/process.hh"
#include "cpu/exec_context.hh"
#include "cpu/thread_context.hh"
#include "kern/tru64/tru64.hh"
#include "sim/process.hh"
@ -42,9 +45,9 @@ using namespace AlphaISA;
/// Target uname() handler.
static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
ThreadContext *tc)
{
TypedBufferArg<AlphaTru64::utsname> name(xc->getSyscallArg(0));
TypedBufferArg<AlphaTru64::utsname> name(tc->getSyscallArg(0));
strcpy(name->sysname, "OSF1");
strcpy(name->nodename, "m5.eecs.umich.edu");
@ -52,43 +55,43 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
strcpy(name->version, "732");
strcpy(name->machine, "alpha");
name.copyOut(xc->getMemPort());
name.copyOut(tc->getMemPort());
return 0;
}
/// Target getsysyinfo() handler.
static SyscallReturn
getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
ThreadContext *tc)
{
unsigned op = xc->getSyscallArg(0);
unsigned nbytes = xc->getSyscallArg(2);
unsigned op = tc->getSyscallArg(0);
unsigned nbytes = tc->getSyscallArg(2);
switch (op) {
case AlphaTru64::GSI_MAX_CPU: {
TypedBufferArg<uint32_t> max_cpu(xc->getSyscallArg(1));
TypedBufferArg<uint32_t> max_cpu(tc->getSyscallArg(1));
*max_cpu = htog((uint32_t)process->numCpus());
max_cpu.copyOut(xc->getMemPort());
max_cpu.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_CPUS_IN_BOX: {
TypedBufferArg<uint32_t> cpus_in_box(xc->getSyscallArg(1));
TypedBufferArg<uint32_t> cpus_in_box(tc->getSyscallArg(1));
*cpus_in_box = htog((uint32_t)process->numCpus());
cpus_in_box.copyOut(xc->getMemPort());
cpus_in_box.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_PHYSMEM: {
TypedBufferArg<uint64_t> physmem(xc->getSyscallArg(1));
TypedBufferArg<uint64_t> physmem(tc->getSyscallArg(1));
*physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
physmem.copyOut(xc->getMemPort());
physmem.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_CPU_INFO: {
TypedBufferArg<AlphaTru64::cpu_info> infop(xc->getSyscallArg(1));
TypedBufferArg<AlphaTru64::cpu_info> infop(tc->getSyscallArg(1));
infop->current_cpu = htog(0);
infop->cpus_in_box = htog(process->numCpus());
@ -100,30 +103,30 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
infop->cpu_ex_binding = htog(0);
infop->mhz = htog(667);
infop.copyOut(xc->getMemPort());
infop.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_PROC_TYPE: {
TypedBufferArg<uint64_t> proc_type(xc->getSyscallArg(1));
TypedBufferArg<uint64_t> proc_type(tc->getSyscallArg(1));
*proc_type = htog((uint64_t)11);
proc_type.copyOut(xc->getMemPort());
proc_type.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_PLATFORM_NAME: {
BufferArg bufArg(xc->getSyscallArg(1), nbytes);
BufferArg bufArg(tc->getSyscallArg(1), nbytes);
strncpy((char *)bufArg.bufferPtr(),
"COMPAQ Professional Workstation XP1000",
nbytes);
bufArg.copyOut(xc->getMemPort());
bufArg.copyOut(tc->getMemPort());
return 1;
}
case AlphaTru64::GSI_CLK_TCK: {
TypedBufferArg<uint64_t> clk_hz(xc->getSyscallArg(1));
TypedBufferArg<uint64_t> clk_hz(tc->getSyscallArg(1));
*clk_hz = htog((uint64_t)1024);
clk_hz.copyOut(xc->getMemPort());
clk_hz.copyOut(tc->getMemPort());
return 1;
}
@ -138,14 +141,14 @@ getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
/// Target setsysyinfo() handler.
static SyscallReturn
setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
ThreadContext *tc)
{
unsigned op = xc->getSyscallArg(0);
unsigned op = tc->getSyscallArg(0);
switch (op) {
case AlphaTru64::SSI_IEEE_FP_CONTROL:
warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n",
xc->getSyscallArg(1));
tc->getSyscallArg(1));
break;
default:
@ -160,22 +163,22 @@ setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
/// Target table() handler.
static
SyscallReturn tableFunc(SyscallDesc *desc, int callnum,Process *process,
ExecContext *xc)
ThreadContext *tc)
{
using namespace std;
using namespace TheISA;
int id = xc->getSyscallArg(0); // table ID
int index = xc->getSyscallArg(1); // index into table
int id = tc->getSyscallArg(0); // table ID
int index = tc->getSyscallArg(1); // index into table
// arg 2 is buffer pointer; type depends on table ID
int nel = xc->getSyscallArg(3); // number of elements
int lel = xc->getSyscallArg(4); // expected element size
int nel = tc->getSyscallArg(3); // number of elements
int lel = tc->getSyscallArg(4); // expected element size
switch (id) {
case AlphaTru64::TBL_SYSINFO: {
if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
return -EINVAL;
TypedBufferArg<Tru64::tbl_sysinfo> elp(xc->getSyscallArg(2));
TypedBufferArg<Tru64::tbl_sysinfo> elp(tc->getSyscallArg(2));
const int clk_hz = one_million;
elp->si_user = htog(curTick / (Clock::Frequency / clk_hz));
@ -187,7 +190,7 @@ SyscallReturn tableFunc(SyscallDesc *desc, int callnum,Process *process,
elp->si_phz = htog(clk_hz);
elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
elp->si_max_procs = htog(process->numCpus());
elp.copyOut(xc->getMemPort());
elp.copyOut(tc->getMemPort());
return 0;
}

View file

@ -24,6 +24,8 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Steve Reinhardt
*/
#ifndef __ALPHA_TRU64_PROCESS_HH__

View file

@ -24,6 +24,9 @@
* 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: Nathan Binkert
* Lisa Hsu
*/
#include "arch/alpha/tru64/system.hh"
@ -32,7 +35,7 @@
#include "base/loader/symtab.hh"
#include "base/trace.hh"
#include "cpu/base.hh"
#include "cpu/exec_context.hh"
#include "cpu/thread_context.hh"
#include "kern/tru64/tru64_events.hh"
#include "kern/system_events.hh"
#include "mem/physical.hh"
@ -104,9 +107,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
Param<uint64_t> system_type;
Param<uint64_t> system_rev;
Param<bool> bin;
VectorParam<string> binned_fns;
END_DECLARE_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
@ -121,9 +121,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 12),
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1),
INIT_PARAM_DFLT(bin, "is this system to be binned", false),
INIT_PARAM(binned_fns, "functions to be broken down and binned")
INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1)
END_INIT_SIM_OBJECT_PARAMS(Tru64AlphaSystem)
@ -141,9 +139,6 @@ CREATE_SIM_OBJECT(Tru64AlphaSystem)
p->readfile = readfile;
p->system_type = system_type;
p->system_rev = system_rev;
p->bin = bin;
p->binned_fns = binned_fns;
p->bin_int = false;
return new Tru64AlphaSystem(p);
}

View file

@ -24,6 +24,9 @@
* 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: Nathan Binkert
* Lisa Hsu
*/
#ifndef __ARCH_ALPHA_TRU64_SYSTEM_HH__
@ -33,7 +36,7 @@
#include "arch/isa_traits.hh"
#include "sim/system.hh"
class ExecContext;
class ThreadContext;
class BreakPCEvent;
class BadAddrEvent;

View file

@ -24,6 +24,8 @@
* 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: Korey Sewell
*/
#include "arch/alpha/tru64/tru64.hh"

View file

@ -24,6 +24,8 @@
* 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: Korey Sewell
*/
#ifndef __ALPHA_ALPHA_TRU64_HH

View file

@ -24,6 +24,9 @@
* 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: Nathan Binkert
* Steve Reinhardt
*/
#ifndef __ARCH_ALPHA_TYPES_HH__

View file

@ -24,6 +24,9 @@
* 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: Nathan Binkert
* Steve Reinhardt
*/
#ifndef __ARCH_ALPHA_UTILITY_HH__
@ -106,10 +109,10 @@ namespace AlphaISA
/**
* Function to insure ISA semantics about 0 registers.
* @param xc The execution context.
* @param tc The thread context.
*/
template <class XC>
void zeroRegisters(XC *xc);
template <class TC>
void zeroRegisters(TC *tc);
#if FULL_SYSTEM
// Alpha IPR register accessors
@ -140,15 +143,15 @@ namespace AlphaISA
RoundPage(Addr addr)
{ return (addr + PageBytes - 1) & ~(PageBytes - 1); }
void initCPU(ExecContext *xc, int cpuId);
void initIPRs(ExecContext *xc, int cpuId);
void initCPU(ThreadContext *tc, int cpuId);
void initIPRs(ThreadContext *tc, int cpuId);
/**
* Function to check for and process any interrupts.
* @param xc The execution context.
* @param tc The thread context.
*/
template <class XC>
void processInterrupts(XC *xc);
template <class TC>
void processInterrupts(TC *tc);
#endif
} // namespace AlphaISA

View file

@ -24,6 +24,10 @@
* 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: Nathan Binkert
* Steve Reinhardt
* Ali Saidi
*/
#include <string>
@ -32,7 +36,7 @@
#include "arch/alpha/vtophys.hh"
#include "base/chunk_generator.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "cpu/thread_context.hh"
#include "mem/vport.hh"
using namespace std;
@ -81,10 +85,10 @@ AlphaISA::vtophys(Addr vaddr)
}
Addr
AlphaISA::vtophys(ExecContext *xc, Addr addr)
AlphaISA::vtophys(ThreadContext *tc, Addr addr)
{
AlphaISA::VAddr vaddr = addr;
Addr ptbr = xc->readMiscReg(AlphaISA::IPR_PALtemp20);
Addr ptbr = tc->readMiscReg(AlphaISA::IPR_PALtemp20);
Addr paddr = 0;
//@todo Andrew couldn't remember why he commented some of this code
//so I put it back in. Perhaps something to do with gdb debugging?
@ -97,7 +101,7 @@ AlphaISA::vtophys(ExecContext *xc, Addr addr)
paddr = vaddr;
} else {
AlphaISA::PageTableEntry pte =
kernel_pte_lookup(xc->getPhysPort(), ptbr, vaddr);
kernel_pte_lookup(tc->getPhysPort(), ptbr, vaddr);
if (pte.valid())
paddr = pte.paddr() | vaddr.offset();
}
@ -111,52 +115,52 @@ AlphaISA::vtophys(ExecContext *xc, Addr addr)
void
AlphaISA::CopyOut(ExecContext *xc, void *dest, Addr src, size_t cplen)
AlphaISA::CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
{
uint8_t *dst = (uint8_t *)dest;
VirtualPort *vp = xc->getVirtPort(xc);
VirtualPort *vp = tc->getVirtPort(tc);
vp->readBlob(src, dst, cplen);
xc->delVirtPort(vp);
tc->delVirtPort(vp);
}
void
AlphaISA::CopyIn(ExecContext *xc, Addr dest, void *source, size_t cplen)
AlphaISA::CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
{
uint8_t *src = (uint8_t *)source;
VirtualPort *vp = xc->getVirtPort(xc);
VirtualPort *vp = tc->getVirtPort(tc);
vp->writeBlob(dest, src, cplen);
xc->delVirtPort(vp);
tc->delVirtPort(vp);
}
void
AlphaISA::CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen)
AlphaISA::CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
{
int len = 0;
VirtualPort *vp = xc->getVirtPort(xc);
VirtualPort *vp = tc->getVirtPort(tc);
do {
vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
len++;
} while (len < maxlen && dst[len] != 0 );
xc->delVirtPort(vp);
tc->delVirtPort(vp);
dst[len] = 0;
}
void
AlphaISA::CopyStringIn(ExecContext *xc, char *src, Addr vaddr)
AlphaISA::CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
{
VirtualPort *vp = xc->getVirtPort(xc);
VirtualPort *vp = tc->getVirtPort(tc);
for (ChunkGenerator gen(vaddr, strlen(src), AlphaISA::PageBytes); !gen.done();
gen.next())
{
vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
src += gen.size();
}
xc->delVirtPort(vp);
tc->delVirtPort(vp);
}

View file

@ -24,6 +24,9 @@
* 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: Nathan Binkert
* Steve Reinhardt
*/
#ifndef __ARCH_ALPHA_VTOPHYS_H__
@ -31,7 +34,7 @@
#include "arch/alpha/isa_traits.hh"
class ExecContext;
class ThreadContext;
class FunctionalPort;
namespace AlphaISA {
@ -40,12 +43,12 @@ PageTableEntry
kernel_pte_lookup(FunctionalPort *mem, Addr ptbr, AlphaISA::VAddr vaddr);
Addr vtophys(Addr vaddr);
Addr vtophys(ExecContext *xc, Addr vaddr);
Addr vtophys(ThreadContext *tc, Addr vaddr);
void CopyOut(ExecContext *xc, void *dst, Addr src, size_t len);
void CopyIn(ExecContext *xc, Addr dst, void *src, size_t len);
void CopyStringOut(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen);
void CopyStringIn(ExecContext *xc, char *src, Addr vaddr);
void CopyOut(ThreadContext *tc, void *dst, Addr src, size_t len);
void CopyIn(ThreadContext *tc, Addr dst, void *src, size_t len);
void CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen);
void CopyStringIn(ThreadContext *tc, char *src, Addr vaddr);
};
#endif // __ARCH_ALPHA_VTOPHYS_H__

View file

@ -23,6 +23,9 @@
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Steve Reinhardt
# Korey Sewell
import os
import sys
@ -1179,6 +1182,11 @@ class IntRegOperand(Operand):
if (self.size == self.dflt_size):
return '%s = xc->readIntReg(this, %d);\n' % \
(self.base_name, self.src_reg_idx)
elif (self.size > self.dflt_size):
int_reg_val = 'xc->readIntReg(this, %d)' % (self.src_reg_idx)
if (self.is_signed):
int_reg_val = 'sext<%d>(%s)' % (self.dflt_size, int_reg_val)
return '%s = %s;\n' % (self.base_name, int_reg_val)
else:
return '%s = bits(xc->readIntReg(this, %d), %d, 0);\n' % \
(self.base_name, self.src_reg_idx, self.size-1)

View file

@ -24,6 +24,8 @@
* 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
*/
#ifndef __ARCH_ISA_SPECIFIC_HH__

View file

@ -25,6 +25,10 @@
# 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
# Steve Reinhardt
# Korey Sewell
import os
import sys
@ -43,16 +47,12 @@ Import('env')
base_sources = Split('''
faults.cc
isa_traits.cc
utility.cc
''')
# Full-system sources
full_system_sources = Split('''
memory.cc
arguments.cc
mips34k.cc
osfpal.cc
stacktrace.cc
vtophys.cc
#Insert Full-System Files Here
''')
# Syscall emulation (non-full-system) sources

View file

@ -24,12 +24,18 @@
* 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: Korey Sewell
*/
#include "arch/mips/faults.hh"
#include "cpu/exec_context.hh"
#include "cpu/thread_context.hh"
#include "cpu/base.hh"
#include "base/trace.hh"
#if !FULL_SYSTEM
#include "sim/process.hh"
#include "mem/page_table.hh"
#endif
namespace MipsISA
{
@ -50,6 +56,12 @@ FaultName ArithmeticFault::_name = "arith";
FaultVect ArithmeticFault::_vect = 0x0501;
FaultStat ArithmeticFault::_count;
#if !FULL_SYSTEM
FaultName PageTableFault::_name = "page_table_fault";
FaultVect PageTableFault::_vect = 0x0000;
FaultStat PageTableFault::_count;
#endif
FaultName InterruptFault::_name = "interrupt";
FaultVect InterruptFault::_vect = 0x0101;
FaultStat InterruptFault::_count;
@ -100,32 +112,53 @@ FaultStat IntegerOverflowFault::_count;
#if FULL_SYSTEM
void MipsFault::invoke(ExecContext * xc)
void MipsFault::invoke(ThreadContext * tc)
{
FaultBase::invoke(xc);
FaultBase::invoke(tc);
countStat()++;
// exception restart address
if (setRestartAddress() || !xc->inPalMode())
xc->setMiscReg(MipsISA::IPR_EXC_ADDR, xc->readPC());
if (setRestartAddress() || !tc->inPalMode())
tc->setMiscReg(MipsISA::IPR_EXC_ADDR, tc->readPC());
if (skipFaultingInstruction()) {
// traps... skip faulting instruction.
xc->setMiscReg(MipsISA::IPR_EXC_ADDR,
xc->readMiscReg(MipsISA::IPR_EXC_ADDR) + 4);
tc->setMiscReg(MipsISA::IPR_EXC_ADDR,
tc->readMiscReg(MipsISA::IPR_EXC_ADDR) + 4);
}
xc->setPC(xc->readMiscReg(MipsISA::IPR_PAL_BASE) + vect());
xc->setNextPC(xc->readPC() + sizeof(MachInst));
tc->setPC(tc->readMiscReg(MipsISA::IPR_PAL_BASE) + vect());
tc->setNextPC(tc->readPC() + sizeof(MachInst));
}
void ArithmeticFault::invoke(ExecContext * xc)
void ArithmeticFault::invoke(ThreadContext * tc)
{
FaultBase::invoke(xc);
FaultBase::invoke(tc);
panic("Arithmetic traps are unimplemented!");
}
#endif
#else //!FULL_SYSTEM
void PageTableFault::invoke(ThreadContext *tc)
{
Process *p = tc->getProcessPtr();
// address is higher than the stack region or in the current stack region
if (vaddr > p->stack_base || vaddr > p->stack_min)
FaultBase::invoke(tc);
// We've accessed the next page
if (vaddr > p->stack_min - PageBytes) {
p->stack_min -= PageBytes;
if (p->stack_base - p->stack_min > 8*1024*1024)
fatal("Over max stack size for one thread\n");
p->pTable->allocate(p->stack_min, PageBytes);
warn("Increasing stack size by one page.");
} else {
FaultBase::invoke(tc);
}
}
#endif
} // namespace MipsISA

View file

@ -24,6 +24,8 @@
* 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: Korey Sewell
*/
#ifndef __MIPS_FAULTS_HH__
@ -45,7 +47,7 @@ class MipsFault : public FaultBase
virtual bool setRestartAddress() {return true;}
public:
#if FULL_SYSTEM
void invoke(ExecContext * xc);
void invoke(ThreadContext * tc);
#endif
virtual FaultVect vect() = 0;
virtual FaultStat & countStat() = 0;
@ -77,6 +79,30 @@ class AlignmentFault : public MipsFault
bool isAlignmentFault() {return true;}
};
#if !FULL_SYSTEM
class PageTableFault : public MipsFault
{
private:
Addr vaddr;
static FaultName _name;
static FaultVect _vect;
static FaultStat _count;
public:
PageTableFault(Addr va)
: vaddr(va) {}
FaultName name() {return _name;}
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
void invoke(ThreadContext * tc);
};
static inline Fault genPageTableFault(Addr va)
{
return new PageTableFault(va);
}
#endif
static inline Fault genMachineCheckFault()
{
return new MachineCheckFault;
@ -112,7 +138,7 @@ class ArithmeticFault : public MipsFault
FaultVect vect() {return _vect;}
FaultStat & countStat() {return _count;}
#if FULL_SYSTEM
void invoke(ExecContext * xc);
void invoke(ThreadContext * tc);
#endif
};

View file

@ -1,5 +1,33 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// Base class for MIPS instructions, and some support functions
@ -10,7 +38,6 @@ output header {{
using namespace MipsISA;
/**
* Base class for all MIPS static instructions.
*/
@ -18,16 +45,6 @@ output header {{
{
protected:
/// Make MipsISA register dependence tags directly visible in
/// this class and derived classes. Maybe these should really
/// live here and not in the MipsISA namespace.
/*enum DependenceTags {
FP_Base_DepTag = MipsISA::FP_Base_DepTag,
Fpcr_DepTag = MipsISA::Fpcr_DepTag,
Uniq_DepTag = MipsISA::Uniq_DepTag,
IPR_Base_DepTag = MipsISA::IPR_Base_DepTag
};*/
// Constructor
MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
: StaticInst(mnem, _machInst, __opClass)
@ -67,12 +84,12 @@ output decoder {{
}
if(_numSrcRegs > 0) {
ss << ",";
ss << ", ";
printReg(ss, _srcRegIdx[0]);
}
if(_numSrcRegs > 1) {
ss << ",";
ss << ", ";
printReg(ss, _srcRegIdx[1]);
}

View file

@ -1,5 +1,33 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// Bitfield definitions.
@ -17,20 +45,19 @@ def bitfield FUNCTION < 5: 0>;
def bitfield FUNCTION_HI < 5: 3>;
def bitfield FUNCTION_LO < 2: 0>;
// Integer operate format
def bitfield RT <20:16>;
def bitfield RT_HI <20:19>;
def bitfield RT_LO <18:16>;
def bitfield RS <25:21>;
def bitfield RS_MSB <25:25>;
def bitfield RS_HI <25:24>;
def bitfield RS_LO <23:21>;
def bitfield RS_SRL <25:22>;
def bitfield RS_SRL <25:22>;
def bitfield RS_RT <25:16>;
def bitfield RT <20:16>;
def bitfield RT_HI <20:19>;
def bitfield RT_LO <18:16>;
def bitfield RT_RD <20:11>;
def bitfield RD <15:11>;
def bitfield INTIMM <15: 0>; // integer immediate (literal)
def bitfield INTIMM <15: 0>;
// Floating-point operate format
def bitfield FMT <25:21>;
@ -67,5 +94,9 @@ def bitfield HINT <10: 6>;
def bitfield SYSCALLCODE <25: 6>;
def bitfield TRAPCODE <15:13>;
// EXT/INS instructions
def bitfield MSB <15:11>;
def bitfield LSB <10: 6>;
// M5 instructions
def bitfield M5FUNC <7:0>;

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,33 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
// Declarations for execute() methods.
def template BasicExecDeclare {{
Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
@ -12,11 +40,11 @@ def template BasicDeclare {{
*/
class %(class_name)s : public %(base_class)s
{
public:
public:
/// Constructor.
%(class_name)s(MachInst machInst);
%(BasicExecDeclare)s
};
};
}};
// Basic instruction class constructor template.
@ -27,6 +55,7 @@ def template BasicConstructor {{
}
}};
// Basic instruction class execute method template.
def template BasicExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const

View file

@ -1,5 +1,33 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// Control transfer instructions
@ -67,29 +95,6 @@ output header {{
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for branch likely branches (PC-relative control transfers),
*/
class BranchLikely : public PCDependentDisassembly
{
protected:
/// target address (signed) Displacement .
int32_t disp;
/// Constructor.
BranchLikely(const char *mnem, MachInst _machInst, OpClass __opClass)
: PCDependentDisassembly(mnem, _machInst, __opClass),
disp(OFFSET << 2)
{
}
Addr branchTarget(Addr branchPC) const;
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
/**
* Base class for jumps (register-indirect control transfers). In
* the Mips ISA, these are always unconditional.
@ -111,7 +116,7 @@ output header {{
{
}
Addr branchTarget(ExecContext *xc) const;
Addr branchTarget(ThreadContext *tc) const;
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
@ -126,16 +131,10 @@ output decoder {{
}
Addr
BranchLikely::branchTarget(Addr branchPC) const
Jump::branchTarget(ThreadContext *tc) const
{
return branchPC + 4 + disp;
}
Addr
Jump::branchTarget(ExecContext *xc) const
{
Addr NPC = xc->readPC() + 4;
uint64_t Rb = xc->readIntReg(_srcRegIdx[0]);
Addr NPC = tc->readPC() + 4;
uint64_t Rb = tc->readIntReg(_srcRegIdx[0]);
return (Rb & ~3) | (NPC & 1);
}
@ -171,49 +170,12 @@ output decoder {{
// unconditional branches)
if (_numSrcRegs == 1) {
printReg(ss, _srcRegIdx[0]);
ss << ",";
ss << ", ";
} else if(_numSrcRegs == 2) {
printReg(ss, _srcRegIdx[0]);
ss << ",";
ss << ", ";
printReg(ss, _srcRegIdx[1]);
ss << ",";
}
Addr target = pc + 4 + disp;
std::string str;
if (symtab && symtab->findSymbol(target, str))
ss << str;
else
ccprintf(ss, "0x%x", target);
string inst_name = mnemonic;
if (inst_name.substr(inst_name.length()-2,inst_name.length()) == "al"){
ccprintf(ss, " (r31=0x%x)",pc+8);
}
return ss.str();
}
std::string
BranchLikely::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
// There's only one register arg (RA), but it could be
// either a source (the condition for conditional
// branches) or a destination (the link reg for
// unconditional branches)
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
ss << ",";
}
else if (_numDestRegs > 0) {
printReg(ss, _destRegIdx[0]);
ss << ",";
ss << ", ";
}
Addr target = pc + 4 + disp;
@ -247,72 +209,64 @@ output decoder {{
printReg(ss, _srcRegIdx[0]);
} else if(_numSrcRegs == 2) {
printReg(ss, _srcRegIdx[0]);
ss << ",";
ss << ", ";
printReg(ss, _srcRegIdx[1]);
} else {
panic(">= 3 Source Registers!!!");
}
return ss.str();
}
}};
def format Branch(code,*flags) {{
#Add Link Code if Link instruction
strlen = len(name)
if name[strlen-2:] == 'al':
code += 'R31 = NNPC;\n'
def format Branch(code,*opt_flags) {{
not_taken_code = ' NNPC = NNPC;\n'
not_taken_code += '} \n'
#Build Instruction Flags
#Use Link & Likely Flags to Add Link/Condition Code
inst_flags = ('IsDirectControl', )
for x in opt_flags:
if x == 'Link':
code += 'R31 = NNPC;\n'
elif x == 'Likely':
not_taken_code = ' NPC = NNPC;\n'
not_taken_code += ' NNPC = NNPC + 4;\n'
not_taken_code += '} \n'
inst_flags = ('IsCondDelaySlot', )
else:
inst_flags += (x, )
if 'cond == 1' in code:
inst_flags += ('IsCondControl', )
else:
inst_flags += ('IsUncondControl', )
#Condition code
code = 'bool cond;\n' + code
code += 'if (cond) {\n'
code += ' NNPC = NPC + disp;\n'
code += '} else {\n'
code += ' NNPC = NNPC;\n'
code += '} \n'
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
('IsDirectControl', 'IsCondControl'))
code += not_taken_code
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code), inst_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format BranchLikely(code,*flags) {{
#Add Link Code if Link instruction
strlen = len(name)
if name[strlen-3:] == 'all':
code += 'R31 = NNPC;\n'
#Condition code
code = 'bool cond;\n' + code
code += 'if (cond) {'
code += 'NNPC = NPC + disp;\n'
code += '} \n'
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
('IsDirectControl', 'IsCondControl','IsCondDelaySlot'))
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format Jump(code,*flags) {{
#Add Link Code if Link instruction
strlen = len(name)
if strlen > 1 and name[1:] == 'al':
def format Jump(code, *opt_flags) {{
#Build Instruction Flags
#Use Link Flag to Add Link Code
inst_flags = ('IsIndirectControl', 'IsUncondControl')
for x in opt_flags:
if x == 'Link':
code = 'R31 = NNPC;\n' + code
elif x == 'ClearHazards':
code += '/* Code Needed to Clear Execute & Inst Hazards */\n'
else:
inst_flags += (x, )
iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\
('IsIndirectControl', 'IsUncondControl'))
iop = InstObjParams(name, Name, 'Jump', CodeBlock(code), inst_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)

View file

@ -0,0 +1,156 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// Integer operate instructions
//
//Outputs to decoder.hh
output header {{
class Control : public MipsStaticInst
{
protected:
/// Constructor
Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class CP0Control : public Control
{
protected:
/// Constructor
CP0Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
Control(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class CP1Control : public Control
{
protected:
/// Constructor
CP1Control(const char *mnem, MachInst _machInst, OpClass __opClass) :
Control(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
//Outputs to decoder.cc
output decoder {{
std::string Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
if (mnemonic == "mfc0" || mnemonic == "mtc0") {
ccprintf(ss, "%-10s %d,%d,%d", mnemonic,RT,RD,SEL);
} else {
// just print the first dest... if there's a second one,
// it's generally implicit
if (_numDestRegs > 0) {
printReg(ss, _destRegIdx[0]);
}
ss << ", ";
// just print the first two source regs... if there's
// a third one, it's a read-modify-write dest (Rc),
// e.g. for CMOVxx
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
}
if (_numSrcRegs > 1) {
ss << ", ";
printReg(ss, _srcRegIdx[1]);
}
}
return ss.str();
}
std::string CP0Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s r%d, r%d, %d", mnemonic, RT, RD, SEL);
return ss.str();
}
std::string CP1Control::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s r%d, f%d", mnemonic, RT, FS);
return ss.str();
}
}};
def format System(code, *flags) {{
iop = InstObjParams(name, Name, 'Control', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format CP0Control(code, *flags) {{
iop = InstObjParams(name, Name, 'CP0Control', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format CP1Control(code, *flags) {{
iop = InstObjParams(name, Name, 'CP1Control', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};

View file

@ -1,5 +1,33 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
//Templates from this format are used later
//Include the basic format
##include "basic.isa"
@ -10,8 +38,8 @@
//Include utility functions
##include "util.isa"
//Include the cop0 formats
##include "cop0.isa"
//Include the control/cp0/cp1 formats
##include "control.isa"
//Include the integer formats
##include "int.isa"
@ -22,6 +50,9 @@
//Include the mem format
##include "mem.isa"
//Include the mem format
##include "mt.isa"
//Include the trap format
##include "trap.isa"

View file

@ -1,5 +1,33 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// Floating Point operate instructions
@ -18,49 +46,264 @@ output header {{
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
//std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
//needs function to check for fpEnable or not
};
class FPCompareOp : public FPOp
{
protected:
FPCompareOp(const char *mnem, MachInst _machInst, OpClass __opClass) : FPOp(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string FPOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
std::string FPCompareOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return "Disassembly of integer instruction\n";
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
ccprintf(ss,"%d",CC);
if(_numSrcRegs > 0) {
ss << ", ";
printReg(ss, _srcRegIdx[0]);
}
if(_numSrcRegs > 1) {
ss << ", ";
printReg(ss, _srcRegIdx[1]);
}
return ss.str();
}
}};
output exec {{
// Primary format for float operate instructions:
//If any operand is Nan return the appropriate QNaN
template <class T>
bool
fpNanOperands(FPOp *inst, %(CPU_exec_context)s *xc, const T &src_type,
Trace::InstRecord *traceData)
{
uint64_t mips_nan = 0;
T src_op = 0;
int size = sizeof(src_op) * 8;
for (int i = 0; i < inst->numSrcRegs(); i++) {
uint64_t src_bits = xc->readFloatRegBits(inst, 0, size);
if (isNan(&src_bits, size) ) {
if (isSnan(&src_bits, size)) {
switch (size)
{
case 32: mips_nan = MIPS32_QNAN; break;
case 64: mips_nan = MIPS64_QNAN; break;
default: panic("Unsupported Floating Point Size (%d)", size);
}
} else {
mips_nan = src_bits;
}
xc->setFloatRegBits(inst, 0, mips_nan, size);
if (traceData) { traceData->setData(mips_nan); }
return true;
}
}
return false;
}
template <class T>
bool
fpInvalidOp(FPOp *inst, %(CPU_exec_context)s *cpu, const T dest_val,
Trace::InstRecord *traceData)
{
uint64_t mips_nan = 0;
T src_op = dest_val;
int size = sizeof(src_op) * 8;
if (isNan(&src_op, size)) {
switch (size)
{
case 32: mips_nan = MIPS32_QNAN; break;
case 64: mips_nan = MIPS64_QNAN; break;
default: panic("Unsupported Floating Point Size (%d)", size);
}
//Set value to QNAN
cpu->setFloatRegBits(inst, 0, mips_nan, size);
//Read FCSR from FloatRegFile
uint32_t fcsr_bits = cpu->tc->readFloatRegBits(FCSR);
//Write FCSR from FloatRegFile
cpu->tc->setFloatRegBits(FCSR, genInvalidVector(fcsr_bits));
if (traceData) { traceData->setData(mips_nan); }
return true;
}
return false;
}
void
fpResetCauseBits(%(CPU_exec_context)s *cpu)
{
//Read FCSR from FloatRegFile
uint32_t fcsr = cpu->tc->readFloatRegBits(FCSR);
fcsr = bits(fcsr, 31, 18) << 18 | bits(fcsr, 11, 0);
//Write FCSR from FloatRegFile
cpu->tc->setFloatRegBits(FCSR, fcsr);
}
}};
def template FloatingPointExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(fp_enable_check)s;
//When is the right time to reset cause bits?
//start of every instruction or every cycle?
fpResetCauseBits(xc);
%(op_decl)s;
%(op_rd)s;
//Check if any FP operand is a NaN value
if (!fpNanOperands((FPOp*)this, xc, Fd, traceData)) {
%(code)s;
//Change this code for Full-System/Sycall Emulation
//separation
//----
//Should Full System-Mode throw a fault here?
//----
//Check for IEEE 754 FP Exceptions
//fault = fpNanOperands((FPOp*)this, xc, Fd, traceData);
if (!fpInvalidOp((FPOp*)this, xc, Fd, traceData) &&
fault == NoFault)
{
%(op_wb)s;
}
}
return fault;
}
}};
// Primary format for float point operate instructions:
def format FloatOp(code, *flags) {{
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
exec_output = FloatingPointExecute.subst(iop)
}};
def format FloatCompareOp(code, *flags) {{
code = 'bool cond;\n' + code
code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format FloatCompareOp(cond_code, *flags) {{
import sys
def format FloatCompareWithXcptOp(code, *flags) {{
code = 'bool cond;\n' + code
code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
code = 'bool cond;\n'
if '.sf' in cond_code or 'SinglePrecision' in flags:
if 'QnanException' in flags:
code += 'if (isQnan(&Fs.sf, 32) || isQnan(&Ft.sf, 32)) {\n'
code += '\tFCSR = genInvalidVector(FCSR);\n'
code += '\treturn NoFault;'
code += '}\n else '
code += 'if (isNan(&Fs.sf, 32) || isNan(&Ft.sf, 32)) {\n'
elif '.df' in cond_code or 'DoublePrecision' in flags:
if 'QnanException' in flags:
code += 'if (isQnan(&Fs.df, 64) || isQnan(&Ft.df, 64)) {\n'
code += '\tFCSR = genInvalidVector(FCSR);\n'
code += '\treturn NoFault;'
code += '}\n else '
code += 'if (isNan(&Fs.df, 64) || isNan(&Ft.df, 64)) {\n'
else:
sys.exit('Decoder Failed: Can\'t Determine Operand Type\n')
if 'UnorderedTrue' in flags:
code += 'cond = 1;\n'
elif 'UnorderedFalse' in flags:
code += 'cond = 0;\n'
else:
sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
code += '} else {\n'
code += cond_code + '}'
code += 'FCSR = genCCVector(FCSR, CC, cond);\n'
iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code))
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format FloatConvertOp(code, *flags) {{
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
import sys
#Determine Source Type
convert = 'fpConvert('
if '.sf' in code:
code = 'float ' + code + '\n'
convert += 'SINGLE_TO_'
elif '.df' in code:
code = 'double ' + code + '\n'
convert += 'DOUBLE_TO_'
elif '.uw' in code:
code = 'uint32_t ' + code + '\n'
convert += 'WORD_TO_'
elif '.ud' in code:
code = 'uint64_t ' + code + '\n'
convert += 'LONG_TO_'
else:
sys.exit("Error Determining Source Type for Conversion")
#Determine Destination Type
if 'ToSingle' in flags:
code += 'Fd.uw = ' + convert + 'SINGLE, '
elif 'ToDouble' in flags:
code += 'Fd.ud = ' + convert + 'DOUBLE, '
elif 'ToWord' in flags:
code += 'Fd.uw = ' + convert + 'WORD, '
elif 'ToLong' in flags:
code += 'Fd.ud = ' + convert + 'LONG, '
else:
sys.exit("Error Determining Destination Type for Conversion")
#Figure out how to round value
if 'Ceil' in flags:
code += 'ceil(val)); '
elif 'Floor' in flags:
code += 'floor(val)); '
elif 'Round' in flags:
code += 'roundFP(val, 0)); '
elif 'Trunc' in flags:
code += 'truncFP(val));'
else:
code += 'val); '
iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code))
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format FloatAccOp(code, *flags) {{
iop = InstObjParams(name, Name, 'FPOp', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
@ -76,34 +319,51 @@ def format Float64Op(code, *flags) {{
exec_output = BasicExecute.subst(iop)
}};
def format Float64ConvertOp(code, *flags) {{
code = 'bool cond;\n' + code
code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
def format FloatPSCompareOp(cond_code1, cond_code2, *flags) {{
import sys
code = 'bool cond1, cond2;\n'
code += 'bool code_block1, code_block2;\n'
code += 'code_block1 = code_block2 = true;\n'
if 'QnanException' in flags:
code += 'if (isQnan(&Fs1.sf, 32) || isQnan(&Ft1.sf, 32)) {\n'
code += '\tFCSR = genInvalidVector(FCSR);\n'
code += 'code_block1 = false;'
code += '}\n'
code += 'if (isQnan(&Fs2.sf, 32) || isQnan(&Ft2.sf, 32)) {\n'
code += '\tFCSR = genInvalidVector(FCSR);\n'
code += 'code_block2 = false;'
code += '}\n'
code += 'if (code_block1) {'
code += '\tif (isNan(&Fs1.sf, 32) || isNan(&Ft1.sf, 32)) {\n'
if 'UnorderedTrue' in flags:
code += 'cond1 = 1;\n'
elif 'UnorderedFalse' in flags:
code += 'cond1 = 0;\n'
else:
sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
code += '} else {\n'
code += cond_code1
code += 'FCSR = genCCVector(FCSR, CC, cond1);}\n}\n'
code += 'if (code_block2) {'
code += '\tif (isNan(&Fs2.sf, 32) || isNan(&Ft2.sf, 32)) {\n'
if 'UnorderedTrue' in flags:
code += 'cond2 = 1;\n'
elif 'UnorderedFalse' in flags:
code += 'cond2 = 0;\n'
else:
sys.exit('Decoder Failed: Float Compare Instruction Needs A Unordered Flag\n')
code += '} else {\n'
code += cond_code2
code += 'FCSR = genCCVector(FCSR, CC, cond2);}\n}'
iop = InstObjParams(name, Name, 'FPCompareOp', CodeBlock(code))
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format FloatPSCompareOp(code, *flags) {{
code = 'bool cond1;\nbool cond2;\n' + code
code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n'
code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n'
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def format FloatPSCompareWithXcptOp(code, *flags) {{
code = 'bool cond1;\nbool cond2;\n' + code
code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n'
code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n'
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};

View file

@ -1,11 +1,37 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// Integer operate instructions
//
//Outputs to decoder.hh
output header {{
#include <iostream>
using namespace std;
@ -25,6 +51,34 @@ output header {{
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class HiLoOp: public IntOp
{
protected:
/// Constructor
HiLoOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
IntOp(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class HiLoMiscOp: public HiLoOp
{
protected:
/// Constructor
HiLoMiscOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
HiLoOp(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
class IntImmOp : public MipsStaticInst
{
protected:
@ -52,6 +106,33 @@ output header {{
}};
// HiLo<Misc> instruction class execute method template.
// Mainly to get instruction trace data to print out
// correctly
def template HiLoExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(code)s;
if(fault == NoFault)
{
%(op_wb)s;
//If there are 2 Destination Registers then
//concatenate the values for the traceData
if(traceData && _numDestRegs == 2) {
uint64_t hilo_final_val = (uint64_t)HI << 32 | LO;
traceData->setData(hilo_final_val);
}
}
return fault;
}
}};
//Outputs to decoder.cc
output decoder {{
std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
@ -64,7 +145,7 @@ output decoder {{
// it's generally implicit
if (_numDestRegs > 0) {
printReg(ss, _destRegIdx[0]);
ss << ",";
ss << ", ";
}
// just print the first two source regs... if there's
@ -75,13 +156,47 @@ output decoder {{
}
if (_numSrcRegs > 1) {
ss << ",";
ss << ", ";
printReg(ss, _srcRegIdx[1]);
}
return ss.str();
}
std::string HiLoOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
//Destination Registers are implicit for HI/LO ops
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
}
if (_numSrcRegs > 1) {
ss << ", ";
printReg(ss, _srcRegIdx[1]);
}
return ss.str();
}
std::string HiLoMiscOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
ccprintf(ss, "%-10s ", mnemonic);
if (_numDestRegs > 0 && _destRegIdx[0] < 32) {
printReg(ss, _destRegIdx[0]);
} else if (_numSrcRegs > 0 && _srcRegIdx[0] < 32) {
printReg(ss, _srcRegIdx[0]);
}
return ss.str();
}
std::string IntImmOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
@ -92,15 +207,15 @@ output decoder {{
printReg(ss, _destRegIdx[0]);
}
ss << ",";
ss << ", ";
if (_numSrcRegs > 0) {
printReg(ss, _srcRegIdx[0]);
ss << ",";
ss << ", ";
}
if( mnemonic == "lui")
ccprintf(ss, "%08p ", sextImm);
ccprintf(ss, "0x%x ", sextImm);
else
ss << (int) sextImm;
@ -109,23 +224,47 @@ output decoder {{
}};
//Used by decoder.isa
def format IntOp(code, *opt_flags) {{
orig_code = code
cblk = CodeBlock(code)
iop = InstObjParams(name, Name, 'IntOp', CodeBlock(code), opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = RegNopCheckDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
# Figure out if we are creating a IntImmOp or a IntOp
# by looking at the instruction name
iop = InstObjParams(name, Name, 'IntOp', cblk, opt_flags)
strlen = len(name)
if name[strlen-1] == 'i' or name[strlen-2:] == 'iu':
iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags)
def format IntImmOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'IntImmOp', CodeBlock(code), opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = ImmNopCheckDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = OperateNopCheckDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
def format HiLoOp(code, *opt_flags) {{
if '.sd' in code:
code = 'int64_t ' + code
elif '.ud' in code:
code = 'uint64_t ' + code
code += 'HI = val<63:32>;\n'
code += 'LO = val<31:0>;\n'
iop = InstObjParams(name, Name, 'HiLoOp', CodeBlock(code), opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = HiLoExecute.subst(iop)
}};
def format HiLoMiscOp(code, *opt_flags) {{
iop = InstObjParams(name, Name, 'HiLoMiscOp', CodeBlock(code), opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = HiLoExecute.subst(iop)
}};

View file

@ -1,6 +1,6 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@ -25,6 +25,14 @@
// 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
// Korey Sewell
////////////////////////////////////////////////////////////////////
//
// Memory-format instructions
//
output header {{
/**
@ -50,14 +58,8 @@ output header {{
StaticInstPtr _memAccPtr = nullStaticInstPtr)
: MipsStaticInst(mnem, _machInst, __opClass),
memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
disp(OFFSET)
disp(sext<16>(OFFSET))
{
//If Bit 15 is 1 then Sign Extend
int32_t temp = disp & 0x00008000;
if (temp > 0) {
disp |= 0xFFFF0000;
}
}
std::string
@ -69,6 +71,24 @@ output header {{
const StaticInstPtr &memAccInst() const { return memAccPtr; }
};
/**
* Base class for a few miscellaneous memory-format insts
* that don't interpret the disp field
*/
class MemoryNoDisp : public Memory
{
protected:
/// Constructor
MemoryNoDisp(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
StaticInstPtr _eaCompPtr = nullStaticInstPtr,
StaticInstPtr _memAccPtr = nullStaticInstPtr)
: Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
{
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
@ -76,21 +96,20 @@ output decoder {{
std::string
Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
return csprintf("%-10s %c%d, %d(r%d)", mnemonic,
flags[IsFloating] ? 'f' : 'r', RT, disp, RS);
}
std::string
MemoryNoDisp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return csprintf("%-10s %c%d, r%d(r%d)", mnemonic,
flags[IsFloating] ? 'f' : 'r',
flags[IsFloating] ? FD : RD,
RS, RT);
}
}};
def format LoadAddress(code) {{
iop = InstObjParams(name, Name, 'MemoryDisp32', CodeBlock(code))
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
def template LoadStoreDeclare {{
/**
* Static instruction class for "%(mnemonic)s".
@ -418,27 +437,76 @@ def template StoreCompleteAcc {{
}
}};
// load instructions use Rt as dest, so check for
// Rt == 31 to detect nops
def template LoadNopCheckDecode {{
{
MipsStaticInst *i = new %(class_name)s(machInst);
if (RT == 0) {
i = makeNop(i);
}
return i;
}
def template MiscMemAccExecute {{
Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
EA = xc->getEA();
if (fault == NoFault) {
%(code)s;
}
return NoFault;
}
}};
def template MiscExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
%(op_rd)s;
%(ea_code)s;
if (fault == NoFault) {
%(memacc_code)s;
}
return NoFault;
}
}};
def template MiscInitiateAcc {{
Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
panic("Misc instruction does not support split access method!");
return NoFault;
}
}};
def template MiscCompleteAcc {{
Fault %(class_name)s::completeAcc(uint8_t *data,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
panic("Misc instruction does not support split access method!");
return NoFault;
}
}};
def format LoadMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
decode_template = LoadNopCheckDecode,
decode_template = ImmNopCheckDecode,
exec_template_base = 'Load')
}};
def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
@ -446,26 +514,69 @@ def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
exec_template_base = 'Store')
}};
//FP loads are offloaded to these formats for now ...
def format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
def format LoadIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
decode_template = BasicDecode,
decode_template = ImmNopCheckDecode,
exec_template_base = 'Load')
}};
def format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }},
def format StoreIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
exec_template_base = 'Store')
}};
def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
mem_flags = [], inst_flags = []) {{
decl_code = 'uint32_t mem_word = Mem.uw;\n'
decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
decl_code += '\tbyte_offset ^= 3;\n'
decl_code += '#endif\n'
def format UnalignedStore(memacc_code, postacc_code,
ea_code = {{ EA = Rb + disp; }},
memacc_code = decl_code + memacc_code
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
decode_template = ImmNopCheckDecode,
exec_template_base = 'Load')
}};
def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
mem_flags = [], inst_flags = []) {{
decl_code = 'uint32_t mem_word = 0;\n'
decl_code += 'uint32_t unaligned_addr = Rs + disp;\n'
decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n'
decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
decl_code += '\tbyte_offset ^= 3;\n'
decl_code += '#endif\n'
decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
exec_template_base = 'Store')
}};
def format Prefetch(ea_code = {{ EA = Rs + disp; }},
mem_flags = [], pf_flags = [], inst_flags = []) {{
pf_mem_flags = mem_flags + pf_flags + ['NO_FAULT']
pf_inst_flags = inst_flags + ['IsMemRef', 'IsLoad',
'IsDataPrefetch', 'MemReadOp']
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code,
'xc->prefetch(EA, memAccessFlags);',
pf_mem_flags, pf_inst_flags, exec_template_base = 'Misc')
}};
def format StoreCond(memacc_code, postacc_code,
ea_code = {{ EA = Rs + disp; }},
mem_flags = [], inst_flags = []) {{
(header_output, decoder_output, decode_block, exec_output) = \
LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,

View file

@ -0,0 +1,82 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// MT instructions
//
output header {{
/**
* Base class for MIPS MT ASE operations.
*/
class MT : public MipsStaticInst
{
protected:
/// Constructor
MT(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass)
{
}
std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
//Edit This Template When MT is Implemented
std::string MT::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return "Disassembly of MT instruction\n";
}
}};
def template MTExecute {{
//Edit This Template When MT is Implemented
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
//Write the resulting state to the execution context
%(op_wb)s;
//Call into the trap handler with the appropriate fault
return No_Fault;
}
}};
// Primary format for integer operate instructions:
def format MipsMT() {{
code = 'panic(\"Mips MT Is Currently Unimplemented.\");\n'
iop = InstObjParams(name, Name, 'MT', CodeBlock(code))
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};

View file

@ -1,5 +1,33 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// Nop
@ -36,11 +64,7 @@ output decoder {{
std::string Nop::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
#ifdef SS_COMPATIBLE_DISASSEMBLY
return originalDisassembly;
#else
return csprintf("%-10s (%s)", "nop", originalDisassembly);
#endif
return csprintf("%-10s %s", "nop", originalDisassembly);
}
/// Helper function for decoding nops. Substitute Nop object
@ -49,7 +73,8 @@ output decoder {{
MipsStaticInst *
makeNop(MipsStaticInst *inst)
{
MipsStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst);
std::string nop_str = "(" + inst->disassemble(0) + ")";
MipsStaticInst *nop = new Nop(nop_str, inst->machInst);
delete inst;
return nop;
}
@ -63,16 +88,36 @@ output exec {{
}
}};
// integer & FP operate instructions use RT as dest, so check for
// RT == 0 to detect nops
// Int & FP operate instructions use RD as dest, so check for
// RD == 0 to detect nops
def template RegNopCheckDecode {{
{
MipsStaticInst *i = new %(class_name)s(machInst);
//if (RD == 0) {
//i = makeNop(i);
//}
return i;
}
}};
def template OperateNopCheckDecode {{
{
MipsStaticInst *i = new %(class_name)s(machInst);
//if (RD == 0) {
// i = makeNop(i);
// i = makeNop(i);
//}
return i;
}
}};
// IntImm & Memory instructions use Rt as dest, so check for
// Rt == 0 to detect nops
def template ImmNopCheckDecode {{
{
MipsStaticInst *i = new %(class_name)s(machInst);
//if (RT == 0) {
// i = makeNop(i);
// }
return i;
}
}};
@ -89,6 +134,6 @@ def format BasicOperateWithNopCheck(code, *opt_args) {{
}};
def format Nop() {{
decode_block = 'return new Nop(\"sll r0,r0,0\",machInst);\n'
decode_block = 'return new Nop(\"\",machInst);\n'
}};

View file

@ -1,3 +1,33 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// TlbOp instructions
@ -30,13 +60,10 @@ output decoder {{
def template TlbOpExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
//Call into the trap handler with the appropriate fault
return No_Fault;
}
//Write the resulting state to the execution context
%(op_wb)s;
//Call into the trap handler with the appropriate fault
return No_Fault;
}
}};

View file

@ -1,3 +1,33 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// Trap instructions
@ -23,27 +53,26 @@ output header {{
output decoder {{
std::string Trap::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
return "Disassembly of integer instruction\n";
return "Disassembly of trap instruction\n";
}
}};
def template TrapExecute {{
//Edit This Template When Traps Are Implemented
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
{
//Call into the trap handler with the appropriate fault
return No_Fault;
}
//Write the resulting state to the execution context
%(op_wb)s;
//Call into the trap handler with the appropriate fault
return No_Fault;
}
}};
// Primary format for integer operate instructions:
def format Trap(code, *flags) {{
code = 'bool cond;\n' + code;
code = 'warn(\"'
code += 'Trap Exception Handler Is Currently Not Implemented.'
code += '\");'
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)

View file

@ -1,6 +1,7 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@ -25,6 +26,13 @@
// 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: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// Unimplemented instructions
//
output header {{
/**
@ -96,11 +104,7 @@ output decoder {{
WarnUnimplemented::generateDisassembly(Addr pc,
const SymbolTable *symtab) const
{
#ifdef SS_COMPATIBLE_DISASSEMBLY
return csprintf("%-10s", mnemonic);
#else
return csprintf("%-10s (unimplemented)", mnemonic);
#endif
}
}};
@ -120,7 +124,7 @@ output exec {{
Trace::InstRecord *traceData) const
{
if (!warned) {
warn("instruction '%s' unimplemented\n", mnemonic);
warn("\tinstruction '%s' unimplemented\n", mnemonic);
warned = true;
}
@ -139,28 +143,3 @@ def format WarnUnimpl() {{
decode_block = BasicDecodeWithMnemonic.subst(iop)
}};
output header {{
/**
* Static instruction class for unknown (illegal) instructions.
* These cause simulator termination if they are executed in a
* non-speculative mode. This is a leaf class.
*/
class Unknown : public MipsStaticInst
{
public:
/// Constructor
Unknown(MachInst _machInst)
: MipsStaticInst("unknown", _machInst, No_OpClass)
{
// don't call execute() (which panics) if we're on a
// speculative path
flags[IsNonSpeculative] = true;
}
%(BasicExecDeclare)s
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};

View file

@ -1,6 +1,6 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@ -25,30 +25,40 @@
// 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: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// Unknown instructions
//
output header {{
std::string inst2string(MachInst machInst);
}};
output decoder {{
std::string inst2string(MachInst machInst)
{
string str = "";
uint32_t mask = 0x80000000;
for(int i=0; i < 32; i++) {
if ((machInst & mask) == 0) {
str += "0";
} else {
str += "1";
/**
* Static instruction class for unknown (illegal) instructions.
* These cause simulator termination if they are executed in a
* non-speculative mode. This is a leaf class.
*/
class Unknown : public MipsStaticInst
{
public:
/// Constructor
Unknown(MachInst _machInst)
: MipsStaticInst("unknown", _machInst, No_OpClass)
{
// don't call execute() (which panics) if we're on a
// speculative path
flags[IsNonSpeculative] = true;
}
mask = mask >> 1;
}
%(BasicExecDeclare)s
return str;
}
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
};
}};
output decoder {{
std::string
Unknown::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{

View file

@ -1,5 +1,34 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Steve Reinhardt
// Korey Sewell
let {{
def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
postacc_code = '', base_class = 'Memory',
@ -90,7 +119,31 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ completeAccTemplate.subst(completeacc_iop))
}};
output header {{
std::string inst2string(MachInst machInst);
}};
output decoder {{
std::string inst2string(MachInst machInst)
{
string str = "";
uint32_t mask = 0x80000000;
for(int i=0; i < 32; i++) {
if ((machInst & mask) == 0) {
str += "0";
} else {
str += "1";
}
mask = mask >> 1;
}
return str;
}
}};
output exec {{
using namespace MipsISA;
@ -124,6 +177,7 @@ output exec {{
#endif
}};

View file

@ -1,3 +1,33 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// Output include file directives.
@ -16,9 +46,10 @@ output decoder {{
#include "arch/mips/isa_traits.hh"
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "cpu/exec_context.hh" // for Jump::branchTarget()
#include "cpu/thread_context.hh"
#include "arch/mips/faults.hh"
#include "arch/mips/isa_traits.hh"
#include "arch/mips/utility.hh"
#include <math.h>
#if defined(linux)
@ -31,6 +62,8 @@ using namespace MipsISA;
output exec {{
#include "arch/mips/faults.hh"
#include "arch/mips/isa_traits.hh"
#include "arch/mips/utility.hh"
#include <math.h>
#if defined(linux)
#include <fenv.h>

View file

@ -1,6 +1,6 @@
// -*- mode:c++ -*-
// Copyright (c) 2003-2005 The Regents of The University of Michigan
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@ -25,7 +25,16 @@
// 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: Korey Sewell
////////////////////////////////////////////////////////////////////
//
// MIPS ISA description file.
//
////////////////////////////////////////////////////////////////////
//Include the C++ include directives
##include "includes.isa"
////////////////////////////////////////////////////////////////////

View file

@ -1,3 +1,33 @@
// -*- mode:c++ -*-
// Copyright (c) 2006 The Regents of The University of Michigan
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Korey Sewell
def operand_types {{
'sb' : ('signed int', 8),
'ub' : ('unsigned int', 8),
@ -23,8 +53,8 @@ def operands {{
'R2': ('IntReg', 'uw','2', 'IsInteger', 5),
#Special Integer Reg operands
'HI': ('IntReg', 'uw','32', 'IsInteger', 6),
'LO': ('IntReg', 'uw','33', 'IsInteger', 7),
'HI': ('IntReg', 'uw','MipsISA::HI', 'IsInteger', 6),
'LO': ('IntReg', 'uw','MipsISA::LO', 'IsInteger', 7),
#Immediate Value operand
'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
@ -36,11 +66,11 @@ def operands {{
'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3),
#Special Floating Point Control Reg Operands
'FIR': ('FloatReg', 'uw', '32', 'IsFloating', 1),
'FCCR': ('FloatReg', 'uw', '33', 'IsFloating', 2),
'FEXR': ('FloatReg', 'uw', '34', 'IsFloating', 3),
'FENR': ('FloatReg', 'uw', '35', 'IsFloating', 3),
'FCSR': ('FloatReg', 'uw', '36', 'IsFloating', 3),
'FIR': ('FloatReg', 'uw', 'MipsISA::FIR', 'IsFloating', 1),
'FCCR': ('FloatReg', 'uw', 'MipsISA::FCCR', 'IsFloating', 2),
'FEXR': ('FloatReg', 'uw', 'MipsISA::FEXR', 'IsFloating', 3),
'FENR': ('FloatReg', 'uw', 'MipsISA::FENR', 'IsFloating', 3),
'FCSR': ('FloatReg', 'uw', 'MipsISA::FCSR', 'IsFloating', 3),
#Operands For Paired Singles FP Operations
'Fd1': ('FloatReg', 'sf', 'FD', 'IsFloating', 4),

View file

@ -24,10 +24,13 @@
* 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
* Korey Sewell
*/
#include "arch/mips/isa_traits.hh"
#include "config/full_system.hh"
//#include "config/full_system.hh"
#include "cpu/static_inst.hh"
#include "sim/serialize.hh"
#include "base/bitfield.hh"
@ -37,111 +40,17 @@ using namespace std;
void
MipsISA::copyRegs(ExecContext *src, ExecContext *dest)
MipsISA::copyRegs(ThreadContext *src, ThreadContext *dest)
{
/*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag);
uniq = xc->readMiscReg(MipsISA::Uniq_DepTag);
lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag);
lock_addr = xc->readMiscReg(MipsISA::Lock_Addr_DepTag);
#if FULL_SYSTEM
copyIprs(xc);
#endif*/
panic("Copy Regs Not Implemented Yet\n");
}
void
MipsISA::MiscRegFile::copyMiscRegs(ExecContext *xc)
MipsISA::MiscRegFile::copyMiscRegs(ThreadContext *tc)
{
/*fpcr = xc->readMiscReg(MipsISA::Fpcr_DepTag);
uniq = xc->readMiscReg(MipsISA::Uniq_DepTag);
lock_flag = xc->readMiscReg(MipsISA::Lock_Flag_DepTag);
lock_addr = xc->readMiscReg(MipsISA::Lock_Addr_DepTag);
#endif*/
panic("Copy Misc. Regs Not Implemented Yet\n");
}
uint64_t
MipsISA::fpConvert(double fp_val, ConvertType cvt_type)
{
switch (cvt_type)
{
case SINGLE_TO_DOUBLE:
double sdouble_val = fp_val;
void *sdouble_ptr = &sdouble_val;
uint64_t sdp_bits = *(uint64_t *) sdouble_ptr;
return sdp_bits;
case SINGLE_TO_WORD:
int32_t sword_val = (int32_t) fp_val;
void *sword_ptr = &sword_val;
uint64_t sword_bits= *(uint32_t *) sword_ptr;
return sword_bits;
case WORD_TO_SINGLE:
float wfloat_val = fp_val;
void *wfloat_ptr = &wfloat_val;
uint64_t wfloat_bits = *(uint32_t *) wfloat_ptr;
return wfloat_bits;
case WORD_TO_DOUBLE:
double wdouble_val = fp_val;
void *wdouble_ptr = &wdouble_val;
uint64_t wdp_bits = *(uint64_t *) wdouble_ptr;
return wdp_bits;
default:
panic("Invalid Floating Point Conversion Type (%d). See \"types.hh\" for List of Conversions\n",cvt_type);
return 0;
}
}
double
MipsISA::roundFP(double val, int digits)
{
double digit_offset = pow(10.0,digits);
val = val * digit_offset;
val = val + 0.5;
val = floor(val);
val = val / digit_offset;
return val;
}
double
MipsISA::truncFP(double val)
{
int trunc_val = (int) val;
return (double) trunc_val;
}
bool
MipsISA::getFPConditionCode(uint32_t fcsr_reg, int cc)
{
//uint32_t cc_bits = xc->readFloatReg(35);
return false;//regFile.floatRegfile.getConditionCode(cc);
}
uint32_t
MipsISA::makeCCVector(uint32_t fcsr, int num, bool val)
{
int shift = (num == 0) ? 22 : num + 23;
fcsr = fcsr | (val << shift);
return fcsr;
}
#if FULL_SYSTEM
static inline Addr
TruncPage(Addr addr)
{ return addr & ~(MipsISA::PageBytes - 1); }
static inline Addr
RoundPage(Addr addr)
{ return (addr + MipsISA::PageBytes - 1) & ~(MipsISA::PageBytes - 1); }
#endif
void
IntRegFile::serialize(std::ostream &os)
{
@ -166,12 +75,6 @@ RegFile::serialize(std::ostream &os)
SERIALIZE_SCALAR(pc);
SERIALIZE_SCALAR(npc);
SERIALIZE_SCALAR(nnpc);
#if FULL_SYSTEM
SERIALIZE_ARRAY(palregs, NumIntRegs);
SERIALIZE_ARRAY(ipr, NumInternalProcRegs);
SERIALIZE_SCALAR(intrflag);
SERIALIZE_SCALAR(pal_shadow);
#endif
}
@ -187,43 +90,5 @@ RegFile::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(pc);
UNSERIALIZE_SCALAR(npc);
UNSERIALIZE_SCALAR(nnpc);
#if FULL_SYSTEM
UNSERIALIZE_ARRAY(palregs, NumIntRegs);
UNSERIALIZE_ARRAY(ipr, NumInternalProcRegs);
UNSERIALIZE_SCALAR(intrflag);
UNSERIALIZE_SCALAR(pal_shadow);
#endif
}
#if FULL_SYSTEM
void
PTE::serialize(std::ostream &os)
{
SERIALIZE_SCALAR(tag);
SERIALIZE_SCALAR(ppn);
SERIALIZE_SCALAR(xre);
SERIALIZE_SCALAR(xwe);
SERIALIZE_SCALAR(asn);
SERIALIZE_SCALAR(asma);
SERIALIZE_SCALAR(fonr);
SERIALIZE_SCALAR(fonw);
SERIALIZE_SCALAR(valid);
}
void
PTE::unserialize(Checkpoint *cp, const std::string &section)
{
UNSERIALIZE_SCALAR(tag);
UNSERIALIZE_SCALAR(ppn);
UNSERIALIZE_SCALAR(xre);
UNSERIALIZE_SCALAR(xwe);
UNSERIALIZE_SCALAR(asn);
UNSERIALIZE_SCALAR(asma);
UNSERIALIZE_SCALAR(fonr);
UNSERIALIZE_SCALAR(fonw);
UNSERIALIZE_SCALAR(valid);
}
#endif //FULL_SYSTEM

View file

@ -24,6 +24,9 @@
* 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
* Korey Sewell
*/
#ifndef __ARCH_MIPS_ISA_TRAITS_HH__
@ -45,7 +48,7 @@
class FastCPU;
class FullCPU;
class Checkpoint;
class ExecContext;
class ThreadContext;
namespace LittleEndianGuest {};
@ -54,12 +57,6 @@ namespace LittleEndianGuest {};
class StaticInst;
class StaticInstPtr;
namespace MIPS34K {
int DTB_ASN_ASN(uint64_t reg);
int ITB_ASN_ASN(uint64_t reg);
};
#if !FULL_SYSTEM
class SyscallReturn {
public:
template <class T>
@ -92,7 +89,6 @@ class SyscallReturn {
uint64_t retval;
bool success;
};
#endif
namespace MipsISA
{
@ -128,20 +124,14 @@ namespace MipsISA
/**
* Function to insure ISA semantics about 0 registers.
* @param xc The execution context.
* @param tc The thread context.
*/
template <class XC>
void zeroRegisters(XC *xc);
template <class TC>
void zeroRegisters(TC *tc);
const Addr MaxAddr = (Addr)-1;
void copyRegs(ExecContext *src, ExecContext *dest);
uint64_t fpConvert(double fp_val, ConvertType cvt_type);
double roundFP(double val, int digits);
double truncFP(double val);
bool getFPConditionCode(uint32_t fcsr_reg, int cc);
uint32_t makeCCVector(uint32_t fcsr, int num, bool val);
void copyRegs(ThreadContext *src, ThreadContext *dest);
// Machine operations
@ -188,12 +178,6 @@ namespace MipsISA
};
#if FULL_SYSTEM
#include "arch/mips/mips34k.hh"
#endif
using namespace MipsISA;
#endif // __ARCH_MIPS_ISA_TRAITS_HH__

View file

@ -24,6 +24,8 @@
* 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: Korey Sewell
*/
#include "arch/mips/linux/linux.hh"
@ -31,7 +33,7 @@
#include "arch/mips/isa_traits.hh"
#include "base/trace.hh"
#include "cpu/exec_context.hh"
#include "cpu/thread_context.hh"
#include "kern/linux/linux.hh"
#include "sim/process.hh"
@ -43,9 +45,9 @@ using namespace MipsISA;
/// Target uname() handler.
static SyscallReturn
unameFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
ThreadContext *tc)
{
TypedBufferArg<Linux::utsname> name(xc->getSyscallArg(0));
TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0));
strcpy(name->sysname, "Linux");
strcpy(name->nodename, "m5.eecs.umich.edu");
@ -53,7 +55,7 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
strcpy(name->machine, "mips");
name.copyOut(xc->getMemPort());
name.copyOut(tc->getMemPort());
return 0;
}
@ -62,18 +64,18 @@ unameFunc(SyscallDesc *desc, int callnum, Process *process,
/// different in practice from those used by Tru64 processes.
static SyscallReturn
sys_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
ThreadContext *tc)
{
unsigned op = xc->getSyscallArg(0);
// unsigned nbytes = xc->getSyscallArg(2);
unsigned op = tc->getSyscallArg(0);
// unsigned nbytes = tc->getSyscallArg(2);
switch (op) {
case 45: { // GSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
// I don't think this exactly matches the HW FPCR
*fpcr = 0;
fpcr.copyOut(xc->getMemPort());
fpcr.copyOut(tc->getMemPort());
return 0;
}
@ -89,17 +91,17 @@ sys_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
/// Target sys_setsysinfo() handler.
static SyscallReturn
sys_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
ExecContext *xc)
ThreadContext *tc)
{
unsigned op = xc->getSyscallArg(0);
// unsigned nbytes = xc->getSyscallArg(2);
unsigned op = tc->getSyscallArg(0);
// unsigned nbytes = tc->getSyscallArg(2);
switch (op) {
case 14: { // SSI_IEEE_FP_CONTROL
TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
TypedBufferArg<uint64_t> fpcr(tc->getSyscallArg(1));
// I don't think this exactly matches the HW FPCR
fpcr.copyIn(xc->getMemPort());
fpcr.copyIn(tc->getMemPort());
DPRINTFR(SyscallVerbose, "sys_setsysinfo(SSI_IEEE_FP_CONTROL): "
" setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
return 0;
@ -133,7 +135,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 14 */ SyscallDesc("mknod", unimplementedFunc),
/* 15 */ SyscallDesc("chmod", chmodFunc<MipsLinux>),
/* 16 */ SyscallDesc("lchown", chownFunc),
/* 17 */ SyscallDesc("break", obreakFunc), /*obreak*/
/* 17 */ SyscallDesc("break", obreakFunc),
/* 18 */ SyscallDesc("unused#18", unimplementedFunc),
/* 19 */ SyscallDesc("lseek", lseekFunc),
/* 20 */ SyscallDesc("getpid", getpidFunc),
@ -161,7 +163,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 42 */ SyscallDesc("pipe", unimplementedFunc),
/* 43 */ SyscallDesc("times", unimplementedFunc),
/* 44 */ SyscallDesc("prof", unimplementedFunc),
/* 45 */ SyscallDesc("brk", obreakFunc),/*openFunc<MipsLinux>*/
/* 45 */ SyscallDesc("brk", obreakFunc),
/* 46 */ SyscallDesc("setgid", unimplementedFunc),
/* 47 */ SyscallDesc("getgid", getgidFunc),
/* 48 */ SyscallDesc("signal", ignoreFunc),
@ -171,7 +173,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 52 */ SyscallDesc("umount2", unimplementedFunc),
/* 53 */ SyscallDesc("lock", unimplementedFunc),
/* 54 */ SyscallDesc("ioctl", ioctlFunc<MipsLinux>),
/* 55 */ SyscallDesc("fcntl", unimplementedFunc),
/* 55 */ SyscallDesc("fcntl", fcntlFunc),
/* 56 */ SyscallDesc("mpx", unimplementedFunc),
/* 57 */ SyscallDesc("setpgid", unimplementedFunc),
/* 58 */ SyscallDesc("ulimit", unimplementedFunc),
@ -208,8 +210,8 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 89 */ SyscallDesc("readdir", unimplementedFunc),
/* 90 */ SyscallDesc("mmap", mmapFunc<MipsLinux>),
/* 91 */ SyscallDesc("munmap",munmapFunc),
/* 92 */ SyscallDesc("truncate", fcntlFunc),
/* 93 */ SyscallDesc("ftruncate", unimplementedFunc),
/* 92 */ SyscallDesc("truncate", truncateFunc),
/* 93 */ SyscallDesc("ftruncate", ftruncateFunc),
/* 94 */ SyscallDesc("fchmod", unimplementedFunc),
/* 95 */ SyscallDesc("fchown", unimplementedFunc),
/* 96 */ SyscallDesc("getpriority", unimplementedFunc),
@ -260,7 +262,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 141 */ SyscallDesc("getdents", unimplementedFunc),
/* 142 */ SyscallDesc("newselect", unimplementedFunc),
/* 143 */ SyscallDesc("flock", unimplementedFunc),
/* 144 */ SyscallDesc("msync", unimplementedFunc),/*getrlimitFunc<MipsLinux>*/
/* 144 */ SyscallDesc("msync", unimplementedFunc),
/* 145 */ SyscallDesc("readv", unimplementedFunc),
/* 146 */ SyscallDesc("writev", writevFunc<MipsLinux>),
/* 147 */ SyscallDesc("cacheflush", unimplementedFunc),
@ -336,7 +338,7 @@ SyscallDesc MipsLinuxProcess::syscallDescs[] = {
/* 217 */ SyscallDesc("mincore", unimplementedFunc),
/* 218 */ SyscallDesc("madvise", unimplementedFunc),
/* 219 */ SyscallDesc("getdents64", unimplementedFunc),
/* 220 */ SyscallDesc("fcntl64", fcntlFunc),
/* 220 */ SyscallDesc("fcntl64", fcntl64Func),
/* 221 */ SyscallDesc("reserved#221", unimplementedFunc),
/* 222 */ SyscallDesc("gettid", unimplementedFunc),
/* 223 */ SyscallDesc("readahead", unimplementedFunc),
@ -412,9 +414,7 @@ MipsLinuxProcess::MipsLinuxProcess(const std::string &name,
: MipsLiveProcess(name, objFile, system, stdin_fd, stdout_fd, stderr_fd,
argv, envp),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
{
//init_regs->intRegFile[0] = 0;
}
{ }
SyscallDesc*
MipsLinuxProcess::getDesc(int callnum)

View file

@ -1,3 +1,4 @@
/*
* Copyright (c) 2003-2004 The Regents of The University of Michigan
* All rights reserved.
@ -24,74 +25,41 @@
* 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
* Ali Saidi
* Korey Sewell
*/
#include "arch/mips/isa_traits.hh"
#include "arch/mips/process.hh"
#include "arch/mips/linux/process.hh"
#include "base/loader/object_file.hh"
#include "base/misc.hh"
#include "cpu/exec_context.hh"
#include "sim/builder.hh"
#include "cpu/thread_context.hh"
#include "sim/system.hh"
using namespace std;
using namespace MipsISA;
MipsLiveProcess *
MipsLiveProcess::create(const std::string &nm, System *system, int stdin_fd,
int stdout_fd, int stderr_fd, std::string executable,
std::vector<std::string> &argv, std::vector<std::string> &envp)
{
MipsLiveProcess *process = NULL;
ObjectFile *objFile = createObjectFile(executable);
if (objFile == NULL) {
fatal("Can't load object file %s", executable);
}
if (objFile->getArch() != ObjectFile::Mips)
fatal("Object file does not match architecture.");
switch (objFile->getOpSys()) {
case ObjectFile::Linux:
process = new MipsLinuxProcess(nm, objFile, system,
stdin_fd, stdout_fd, stderr_fd,
argv, envp);
break;
default:
fatal("Unknown/unsupported operating system.");
}
if (process == NULL)
fatal("Unknown error creating process object.");
return process;
}
MipsLiveProcess::MipsLiveProcess(const std::string &nm, ObjectFile *objFile,
System *_system, int stdin_fd, int stdout_fd, int stderr_fd,
std::vector<std::string> &argv, std::vector<std::string> &envp)
: LiveProcess(nm, objFile, _system, stdin_fd, stdout_fd, stderr_fd,
argv, envp)
{
// XXX all the below need to be updated for SPARC - Ali
brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
brk_point = roundUp(brk_point, VMPageSize);
// Set up stack. On Alpha, stack goes below text section. This
// code should get moved to some architecture-specific spot.
stack_base = objFile->textBase() - (409600+4096);
// Set up region for mmaps. Tru64 seems to start just above 0 and
// grow up from there.
mmap_start = mmap_end = 0x10000;
// Set up stack. On MIPS, stack starts at the top of kuseg
// user address space. MIPS stack grows down from here
stack_base = 0x7FFFFFFF;
// Set pointer for next thread stack. Reserve 8M for main stack.
next_thread_stack_base = stack_base - (8 * 1024 * 1024);
// Set up break point (Top of Heap)
brk_point = objFile->dataBase() + objFile->dataSize() + objFile->bssSize();
brk_point = roundUp(brk_point, VMPageSize);
// Set up region for mmaps. For now, start at bottom of kuseg space.
mmap_start = mmap_end = 0x10000;
}
void
@ -99,63 +67,3 @@ MipsLiveProcess::startup()
{
argsInit(MachineBytes, VMPageSize);
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess)
VectorParam<string> cmd;
Param<string> executable;
Param<string> input;
Param<string> output;
VectorParam<string> env;
SimObjectParam<System *> system;
END_DECLARE_SIM_OBJECT_PARAMS(MipsLiveProcess)
BEGIN_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess)
INIT_PARAM(cmd, "command line (executable plus arguments)"),
INIT_PARAM(executable, "executable (overrides cmd[0] if set)"),
INIT_PARAM(input, "filename for stdin (dflt: use sim stdin)"),
INIT_PARAM(output, "filename for stdout/stderr (dflt: use sim stdout)"),
INIT_PARAM(env, "environment settings"),
INIT_PARAM(system, "system")
END_INIT_SIM_OBJECT_PARAMS(MipsLiveProcess)
CREATE_SIM_OBJECT(MipsLiveProcess)
{
string in = input;
string out = output;
// initialize file descriptors to default: same as simulator
int stdin_fd, stdout_fd, stderr_fd;
if (in == "stdin" || in == "cin")
stdin_fd = STDIN_FILENO;
else
stdin_fd = Process::openInputFile(input);
if (out == "stdout" || out == "cout")
stdout_fd = STDOUT_FILENO;
else if (out == "stderr" || out == "cerr")
stdout_fd = STDERR_FILENO;
else
stdout_fd = Process::openOutputFile(out);
stderr_fd = (stdout_fd != STDOUT_FILENO) ? stdout_fd : STDERR_FILENO;
return MipsLiveProcess::create(getInstanceName(), system,
stdin_fd, stdout_fd, stderr_fd,
(string)executable == "" ? cmd[0] : executable,
cmd, env);
}
REGISTER_SIM_OBJECT("MipsLiveProcess", MipsLiveProcess)

View file

@ -24,6 +24,10 @@
* 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
* Ali Saidi
* Korey Sewell
*/
#ifndef __MIPS_PROCESS_HH__
@ -46,18 +50,6 @@ class MipsLiveProcess : public LiveProcess
std::vector<std::string> &envp);
void startup();
public:
// this function is used to create the LiveProcess object, since
// we can't tell which subclass of LiveProcess to use until we
// open and look at the object file.
static MipsLiveProcess *create(const std::string &nm,
System *_system,
int stdin_fd, int stdout_fd, int stderr_fd,
std::string executable,
std::vector<std::string> &argv,
std::vector<std::string> &envp);
};

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,6 +32,7 @@
#include "arch/mips/types.hh"
#include "arch/mips/constants.hh"
#include "base/misc.hh"
#include "base/bitfield.hh"
#include "config/full_system.hh"
#include "sim/byteswap.hh"
#include "sim/faults.hh"
@ -60,13 +61,17 @@ namespace MipsISA
switch(width)
{
case SingleWidth:
void *float_ptr = &regs[floatReg];
return *(float *) float_ptr;
{
void *float_ptr = &regs[floatReg];
return *(float *) float_ptr;
}
case DoubleWidth:
uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
void *double_ptr = &double_val;
return *(double *) double_ptr;
{
uint64_t double_val = (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
void *double_ptr = &double_val;
return *(double *) double_ptr;
}
default:
panic("Attempted to read a %d bit floating point register!", width);
@ -95,23 +100,27 @@ namespace MipsISA
}
}
Fault setReg(int floatReg, const FloatReg &val, int width)
Fault setReg(int floatReg, const FloatRegVal &val, int width)
{
using namespace std;
switch(width)
{
case SingleWidth:
float temp = val;
void *float_ptr = &temp;
regs[floatReg] = *(FloatReg32 *) float_ptr;
break;
{
float temp = val;
void *float_ptr = &temp;
regs[floatReg] = *(FloatReg32 *) float_ptr;
break;
}
case DoubleWidth:
const void *double_ptr = &val;
FloatReg64 temp_double = *(FloatReg64 *) double_ptr;
regs[floatReg + 1] = temp_double >> 32;
regs[floatReg] = temp_double;
break;
{
const void *double_ptr = &val;
FloatReg64 temp_double = *(FloatReg64 *) double_ptr;
regs[floatReg + 1] = bits(temp_double, 63, 32);
regs[floatReg] = bits(temp_double, 31, 0);
break;
}
default:
panic("Attempted to read a %d bit floating point register!", width);
@ -131,8 +140,8 @@ namespace MipsISA
break;
case DoubleWidth:
regs[floatReg + 1] = val >> 32;
regs[floatReg] = val;
regs[floatReg + 1] = bits(val, 63, 32);
regs[floatReg] = bits(val, 31, 0);
break;
default:
@ -146,14 +155,6 @@ namespace MipsISA
void unserialize(Checkpoint *cp, const std::string &section);
};
enum MiscFloatRegNums {
FIR = NumFloatArchRegs,
FCCR,
FEXR,
FENR,
FCSR
};
} // namespace MipsISA
#endif

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -24,6 +24,8 @@
* 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: Korey Sewell
*/
#ifndef __ARCH_MIPS_INT_REGFILE_HH__
@ -35,7 +37,7 @@
#include "sim/faults.hh"
class Checkpoint;
class ExecContext;
class ThreadContext;
class Regfile;
namespace MipsISA
@ -63,11 +65,6 @@ namespace MipsISA
};
enum MiscIntRegNums {
HI = NumIntArchRegs,
LO
};
} // namespace MipsISA
#endif

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -24,6 +24,8 @@
* 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: Korey Sewell
*/
#ifndef __ARCH_MIPS_MISC_REGFILE_HH__
@ -34,7 +36,7 @@
#include "sim/faults.hh"
class Checkpoint;
class ExecContext;
class ThreadContext;
class Regfile;
namespace MipsISA
@ -43,26 +45,20 @@ namespace MipsISA
protected:
uint64_t fpcr; // floating point condition codes
uint64_t uniq; // process-unique register
bool lock_flag; // lock flag for LL/SC
Addr lock_addr; // lock address for LL/SC
MiscReg miscRegFile[NumMiscRegs];
public:
//These functions should be removed once the simplescalar cpu model
//has been replaced.
int getInstAsid();
int getDataAsid();
void copyMiscRegs(ExecContext *xc);
void copyMiscRegs(ThreadContext *tc);
MiscReg readReg(int misc_reg)
{
return miscRegFile[misc_reg];
}
MiscReg readRegWithEffect(int misc_reg, Fault &fault, ExecContext *xc)
MiscReg readRegWithEffect(int misc_reg, Fault &fault, ThreadContext *tc)
{
return miscRegFile[misc_reg];
}
@ -73,22 +69,11 @@ namespace MipsISA
}
Fault setRegWithEffect(int misc_reg, const MiscReg &val,
ExecContext *xc)
ThreadContext *tc)
{
miscRegFile[misc_reg] = val; return NoFault;
}
#if FULL_SYSTEM
void clearIprs() { }
protected:
InternalProcReg ipr[NumInternalProcRegs]; // Internal processor regs
private:
MiscReg readIpr(int idx, Fault &fault, ExecContext *xc) { }
Fault setIpr(int idx, uint64_t val, ExecContext *xc) { }
#endif
friend class RegFile;
};
} // namespace MipsISA

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -24,6 +24,8 @@
* 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: Korey Sewell
*/
#ifndef __ARCH_MIPS_REGFILE_HH__
@ -37,7 +39,7 @@
#include "sim/faults.hh"
class Checkpoint;
class ExecContext;
class ThreadContext;
namespace MipsISA
{
@ -62,10 +64,10 @@ namespace MipsISA
}
MiscReg readMiscRegWithEffect(int miscReg,
Fault &fault, ExecContext *xc)
Fault &fault, ThreadContext *tc)
{
fault = NoFault;
return miscRegFile.readRegWithEffect(miscReg, fault, xc);
return miscRegFile.readRegWithEffect(miscReg, fault, tc);
}
Fault setMiscReg(int miscReg, const MiscReg &val)
@ -74,17 +76,17 @@ namespace MipsISA
}
Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
ExecContext * xc)
ThreadContext * tc)
{
return miscRegFile.setRegWithEffect(miscReg, val, xc);
return miscRegFile.setRegWithEffect(miscReg, val, tc);
}
FloatReg readFloatReg(int floatReg)
FloatRegVal readFloatReg(int floatReg)
{
return floatRegFile.readReg(floatReg,SingleWidth);
}
FloatReg readFloatReg(int floatReg, int width)
FloatRegVal readFloatReg(int floatReg, int width)
{
return floatRegFile.readReg(floatReg,width);
}
@ -99,12 +101,12 @@ namespace MipsISA
return floatRegFile.readRegBits(floatReg,width);
}
Fault setFloatReg(int floatReg, const FloatReg &val)
Fault setFloatReg(int floatReg, const FloatRegVal &val)
{
return floatRegFile.setReg(floatReg, val, SingleWidth);
}
Fault setFloatReg(int floatReg, const FloatReg &val, int width)
Fault setFloatReg(int floatReg, const FloatRegVal &val, int width)
{
return floatRegFile.setReg(floatReg, val, width);
}
@ -166,16 +168,6 @@ namespace MipsISA
nnpc = val;
}
#if FULL_SYSTEM
IntReg palregs[NumIntRegs]; // PAL shadow registers
InternalProcReg ipr[NumInternalProcRegs]; // internal processor regs
int intrflag; // interrupt flag
bool pal_shadow; // using pal_shadow registers
inline int instAsid() { return MIPS34K::ITB_ASN_ASN(ipr[IPR_ITB_ASN]); }
inline int dataAsid() { return MIPS34K::DTB_ASN_ASN(ipr[IPR_DTB_ASN]); }
#endif // FULL_SYSTEM
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
@ -187,13 +179,10 @@ namespace MipsISA
}
};
void copyRegs(ExecContext *src, ExecContext *dest);
void copyRegs(ThreadContext *src, ThreadContext *dest);
void copyMiscRegs(ExecContext *src, ExecContext *dest);
void copyMiscRegs(ThreadContext *src, ThreadContext *dest);
#if FULL_SYSTEM
void copyIprs(ExecContext *src, ExecContext *dest);
#endif
} // namespace MipsISA
#endif

View file

@ -24,21 +24,23 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Authors: Ali Saidi
*/
#ifndef __ARCH_ALPHA_STACKTRACE_HH__
#define __ARCH_ALPHA_STACKTRACE_HH__
#ifndef __ARCH_MIPS_STACKTRACE_HH__
#define __ARCH_MIPS_STACKTRACE_HH__
#include "base/trace.hh"
#include "cpu/static_inst.hh"
class ExecContext;
class ThreadContext;
class StackTrace;
class ProcessInfo
{
private:
ExecContext *xc;
ThreadContext *tc;
int thread_info_size;
int task_struct_size;
@ -47,7 +49,7 @@ class ProcessInfo
int name_off;
public:
ProcessInfo(ExecContext *_xc);
ProcessInfo(ThreadContext *_tc);
Addr task(Addr ksp) const;
int pid(Addr ksp) const;
@ -59,7 +61,7 @@ class StackTrace
protected:
typedef TheISA::MachInst MachInst;
private:
ExecContext *xc;
ThreadContext *tc;
std::vector<Addr> stack;
private:
@ -68,21 +70,21 @@ class StackTrace
bool decodeSave(MachInst inst, int &reg, int &disp);
bool decodeStack(MachInst inst, int &disp);
void trace(ExecContext *xc, bool is_call);
void trace(ThreadContext *tc, bool is_call);
public:
StackTrace();
StackTrace(ExecContext *xc, StaticInstPtr inst);
StackTrace(ThreadContext *tc, StaticInstPtr inst);
~StackTrace();
void clear()
{
xc = 0;
tc = 0;
stack.clear();
}
bool valid() const { return xc != NULL; }
bool trace(ExecContext *xc, StaticInstPtr inst);
bool valid() const { return tc != NULL; }
bool trace(ThreadContext *tc, StaticInstPtr inst);
public:
const std::vector<Addr> &getstack() const { return stack; }
@ -104,7 +106,7 @@ class StackTrace
};
inline bool
StackTrace::trace(ExecContext *xc, StaticInstPtr inst)
StackTrace::trace(ThreadContext *tc, StaticInstPtr inst)
{
if (!inst->isCall() && !inst->isReturn())
return false;
@ -112,8 +114,8 @@ StackTrace::trace(ExecContext *xc, StaticInstPtr inst)
if (valid())
clear();
trace(xc, !inst->isReturn());
trace(tc, !inst->isReturn());
return true;
}
#endif // __ARCH_ALPHA_STACKTRACE_HH__
#endif // __ARCH_MIPS_STACKTRACE_HH__

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* Copyright (c) 2006 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -24,6 +24,8 @@
* 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: Korey Sewell
*/
#ifndef __ARCH_MIPS_TYPES_HH__
@ -40,14 +42,15 @@ namespace MipsISA
typedef uint32_t IntReg;
// floating point register file entry type
typedef double FloatReg;
typedef uint32_t FloatReg32;
typedef uint64_t FloatReg64;
typedef uint64_t FloatRegBits;
typedef double FloatRegVal;
typedef double FloatReg;
// cop-0/cop-1 system control register
typedef uint64_t MiscReg;
typedef uint64_t InternalProcReg;
typedef union {
IntReg intreg;

Some files were not shown because too many files have changed in this diff Show more