summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConscript192
-rw-r--r--arch/SConscript147
-rw-r--r--arch/alpha/SConscript450
-rw-r--r--arch/alpha/alpha_linux_process.cc602
-rw-r--r--arch/alpha/alpha_linux_process.hh11
-rw-r--r--arch/alpha/alpha_memory.cc6
-rw-r--r--arch/alpha/alpha_memory.hh4
-rw-r--r--arch/alpha/alpha_tru64_process.cc1680
-rw-r--r--arch/alpha/alpha_tru64_process.hh12
-rw-r--r--arch/alpha/arguments.cc2
-rw-r--r--arch/alpha/ev5.cc22
-rw-r--r--arch/alpha/ev5.hh4
-rw-r--r--arch/alpha/faults.cc38
-rw-r--r--arch/alpha/faults.hh8
-rw-r--r--arch/alpha/isa/branch.isa4
-rw-r--r--arch/alpha/isa/fp.isa14
-rw-r--r--arch/alpha/isa/main.isa38
-rw-r--r--arch/alpha/isa/mem.isa72
-rw-r--r--arch/alpha/isa/pal.isa8
-rw-r--r--arch/alpha/isa/unimp.isa4
-rw-r--r--arch/alpha/isa/unknown.isa2
-rw-r--r--arch/alpha/isa_traits.hh97
-rw-r--r--arch/alpha/stacktrace.cc3
-rw-r--r--arch/alpha/stacktrace.hh8
-rw-r--r--arch/alpha/vtophys.cc1
-rwxr-xr-xarch/isa_parser.py78
-rw-r--r--arch/isa_specific.hh62
-rw-r--r--arch/mips/SConscript50
-rw-r--r--arch/mips/isa/base.isa63
-rw-r--r--arch/mips/isa/bitfields.isa4
-rw-r--r--arch/mips/isa/decoder.isa1154
-rw-r--r--arch/mips/isa/formats.isa14
-rw-r--r--arch/mips/isa/formats/basic.isa3
-rw-r--r--arch/mips/isa/formats/branch.isa194
-rw-r--r--arch/mips/isa/formats/int.isa17
-rw-r--r--arch/mips/isa/formats/mem.isa508
-rw-r--r--arch/mips/isa/formats/noop.isa62
-rw-r--r--arch/mips/isa/formats/unimp.isa12
-rw-r--r--arch/mips/isa/formats/util.isa125
-rw-r--r--arch/mips/isa/operands.isa11
-rw-r--r--arch/mips/isa_traits.hh8
-rw-r--r--arch/sparc/SConscript52
-rw-r--r--base/remote_gdb.cc3
-rw-r--r--base/remote_gdb.hh2
-rw-r--r--build/SConstruct14
-rw-r--r--cpu/SConscript99
-rw-r--r--cpu/base.cc10
-rw-r--r--cpu/base.hh6
-rw-r--r--cpu/base_dyn_inst.cc16
-rw-r--r--cpu/base_dyn_inst.hh38
-rw-r--r--cpu/cpu_models.py71
-rw-r--r--cpu/exec_context.cc2
-rw-r--r--cpu/exec_context.hh55
-rw-r--r--cpu/exetrace.hh7
-rw-r--r--cpu/memtest/memtest.cc1
-rw-r--r--cpu/o3/2bit_local_pred.hh2
-rw-r--r--cpu/o3/alpha_cpu.hh37
-rw-r--r--cpu/o3/alpha_cpu_impl.hh12
-rw-r--r--cpu/o3/alpha_dyn_inst.hh47
-rw-r--r--cpu/o3/alpha_dyn_inst_impl.hh10
-rw-r--r--cpu/o3/alpha_impl.hh5
-rw-r--r--cpu/o3/bpred_unit_impl.hh2
-rw-r--r--cpu/o3/btb.cc2
-rw-r--r--cpu/o3/btb.hh2
-rw-r--r--cpu/o3/commit.hh1
-rw-r--r--cpu/o3/commit_impl.hh2
-rw-r--r--cpu/o3/cpu.cc21
-rw-r--r--cpu/o3/cpu.hh5
-rw-r--r--cpu/o3/decode.hh4
-rw-r--r--cpu/o3/fetch.hh7
-rw-r--r--cpu/o3/fetch_impl.hh6
-rw-r--r--cpu/o3/free_list.hh2
-rw-r--r--cpu/o3/iew.hh1
-rw-r--r--cpu/o3/iew_impl.hh2
-rw-r--r--cpu/o3/ras.hh2
-rw-r--r--cpu/o3/regfile.hh297
-rw-r--r--cpu/o3/rename.hh3
-rw-r--r--cpu/o3/rename_map.hh4
-rw-r--r--cpu/o3/rob.hh2
-rw-r--r--cpu/o3/store_set.hh2
-rw-r--r--cpu/o3/tournament_pred.hh2
-rw-r--r--cpu/ozone/cpu.hh65
-rw-r--r--cpu/profile.hh4
-rw-r--r--cpu/simple/cpu.cc97
-rw-r--r--cpu/simple/cpu.hh37
-rw-r--r--cpu/static_inst.cc22
-rw-r--r--cpu/static_inst.hh106
-rw-r--r--cpu/trace/reader/itx_reader.hh1
-rw-r--r--dev/alpha_access.h6
-rw-r--r--dev/alpha_console.cc51
-rw-r--r--dev/alpha_console.hh6
-rw-r--r--dev/baddev.cc5
-rw-r--r--dev/baddev.hh4
-rw-r--r--dev/ide_ctrl.cc5
-rw-r--r--dev/ide_ctrl.hh4
-rw-r--r--dev/ide_disk.cc1
-rw-r--r--dev/isa_fake.cc5
-rw-r--r--dev/isa_fake.hh4
-rw-r--r--dev/ns_gige.cc66
-rw-r--r--dev/ns_gige.hh14
-rw-r--r--dev/pciconfigall.cc5
-rw-r--r--dev/pciconfigall.hh4
-rw-r--r--dev/pcidev.cc28
-rw-r--r--dev/pcidev.hh36
-rw-r--r--dev/platform.cc1
-rw-r--r--dev/simple_disk.hh20
-rw-r--r--dev/sinic.cc54
-rw-r--r--dev/sinic.hh22
-rw-r--r--dev/sinicreg.hh40
-rw-r--r--dev/tsunami.cc2
-rw-r--r--dev/tsunami_cchip.cc6
-rw-r--r--dev/tsunami_cchip.hh4
-rw-r--r--dev/tsunami_io.cc6
-rw-r--r--dev/tsunami_io.hh4
-rw-r--r--dev/tsunami_pchip.cc6
-rw-r--r--dev/tsunami_pchip.hh4
-rw-r--r--dev/uart.hh4
-rw-r--r--dev/uart8250.cc5
-rw-r--r--dev/uart8250.hh4
-rw-r--r--kern/freebsd/freebsd_system.cc1
-rw-r--r--kern/kernel_stats.hh6
-rw-r--r--kern/linux/linux.hh307
-rw-r--r--kern/linux/linux_system.cc1
-rw-r--r--kern/linux/linux_threadinfo.hh2
-rw-r--r--kern/system_events.cc2
-rw-r--r--kern/tru64/dump_mbuf.cc2
-rw-r--r--kern/tru64/tru64.hh1292
-rw-r--r--kern/tru64/tru64_events.cc2
-rw-r--r--python/m5/objects/Ethernet.py1
-rw-r--r--sim/faults.hh19
-rw-r--r--sim/host.hh8
-rw-r--r--sim/process.cc16
-rw-r--r--sim/process.hh9
-rw-r--r--sim/pseudo_inst.cc1
-rw-r--r--sim/syscall_emul.cc49
-rw-r--r--sim/syscall_emul.hh6
-rw-r--r--sim/system.cc9
-rw-r--r--util/pbs/jobfile.py43
138 files changed, 4788 insertions, 4398 deletions
diff --git a/SConscript b/SConscript
index 360f91b3a..966cb6d3e 100644
--- a/SConscript
+++ b/SConscript
@@ -86,31 +86,7 @@ base_sources = Split('''
cpu/exetrace.cc
cpu/pc_event.cc
cpu/static_inst.cc
- cpu/o3/2bit_local_pred.cc
- cpu/o3/alpha_dyn_inst.cc
- cpu/o3/alpha_cpu.cc
- cpu/o3/alpha_cpu_builder.cc
- cpu/o3/bpred_unit.cc
- cpu/o3/btb.cc
- cpu/o3/commit.cc
- cpu/o3/decode.cc
- cpu/o3/fetch.cc
- cpu/o3/free_list.cc
- cpu/o3/cpu.cc
- cpu/o3/iew.cc
- cpu/o3/inst_queue.cc
- cpu/o3/ldstq.cc
- cpu/o3/mem_dep_unit.cc
- cpu/o3/ras.cc
- cpu/o3/rename.cc
- cpu/o3/rename_map.cc
- cpu/o3/rob.cc
- cpu/o3/sat_counter.cc
- cpu/o3/store_set.cc
- cpu/o3/tournament_pred.cc
- cpu/fast/cpu.cc
cpu/sampler/sampler.cc
- cpu/simple/cpu.cc
cpu/trace/reader/mem_trace_reader.cc
cpu/trace/reader/ibm_reader.cc
cpu/trace/reader/itx_reader.cc
@@ -118,41 +94,6 @@ base_sources = Split('''
cpu/trace/opt_cpu.cc
cpu/trace/trace_cpu.cc
- encumbered/cpu/full/bpred.cc
- encumbered/cpu/full/commit.cc
- encumbered/cpu/full/cpu.cc
- encumbered/cpu/full/create_vector.cc
- encumbered/cpu/full/cv_spec_state.cc
- encumbered/cpu/full/dd_queue.cc
- encumbered/cpu/full/dep_link.cc
- encumbered/cpu/full/dispatch.cc
- encumbered/cpu/full/dyn_inst.cc
- encumbered/cpu/full/execute.cc
- encumbered/cpu/full/fetch.cc
- encumbered/cpu/full/floss_reasons.cc
- encumbered/cpu/full/fu_pool.cc
- encumbered/cpu/full/inst_fifo.cc
- encumbered/cpu/full/instpipe.cc
- encumbered/cpu/full/issue.cc
- encumbered/cpu/full/ls_queue.cc
- encumbered/cpu/full/machine_queue.cc
- encumbered/cpu/full/pipetrace.cc
- encumbered/cpu/full/readyq.cc
- encumbered/cpu/full/reg_info.cc
- encumbered/cpu/full/rob_station.cc
- encumbered/cpu/full/spec_memory.cc
- encumbered/cpu/full/spec_state.cc
- encumbered/cpu/full/storebuffer.cc
- encumbered/cpu/full/writeback.cc
- encumbered/cpu/full/iq/iq_station.cc
- encumbered/cpu/full/iq/iqueue.cc
- encumbered/cpu/full/iq/segmented/chain_info.cc
- encumbered/cpu/full/iq/segmented/chain_wire.cc
- encumbered/cpu/full/iq/segmented/iq_seg.cc
- encumbered/cpu/full/iq/segmented/iq_segmented.cc
- encumbered/cpu/full/iq/segmented/seg_chain.cc
- encumbered/cpu/full/iq/seznec/iq_seznec.cc
- encumbered/cpu/full/iq/standard/iq_standard.cc
encumbered/mem/functional/main.cc
mem/base_hier.cc
@@ -223,14 +164,45 @@ base_sources = Split('''
sim/stat_control.cc
sim/trace_context.cc
''')
-# These are now included by the architecture specific SConscript
-# arch/alpha/decoder.cc
-# arch/alpha/alpha_o3_exec.cc
-# arch/alpha/fast_cpu_exec.cc
-# arch/alpha/simple_cpu_exec.cc
-# arch/alpha/full_cpu_exec.cc
-# arch/alpha/faults.cc
-# arch/alpha/isa_traits.cc
+
+# Old FullCPU sources
+full_cpu_sources = Split('''
+ encumbered/cpu/full/bpred.cc
+ encumbered/cpu/full/commit.cc
+ encumbered/cpu/full/cpu.cc
+ encumbered/cpu/full/create_vector.cc
+ encumbered/cpu/full/cv_spec_state.cc
+ encumbered/cpu/full/dd_queue.cc
+ encumbered/cpu/full/dep_link.cc
+ encumbered/cpu/full/dispatch.cc
+ encumbered/cpu/full/dyn_inst.cc
+ encumbered/cpu/full/execute.cc
+ encumbered/cpu/full/fetch.cc
+ encumbered/cpu/full/floss_reasons.cc
+ encumbered/cpu/full/fu_pool.cc
+ encumbered/cpu/full/inst_fifo.cc
+ encumbered/cpu/full/instpipe.cc
+ encumbered/cpu/full/issue.cc
+ encumbered/cpu/full/ls_queue.cc
+ encumbered/cpu/full/machine_queue.cc
+ encumbered/cpu/full/pipetrace.cc
+ encumbered/cpu/full/readyq.cc
+ encumbered/cpu/full/reg_info.cc
+ encumbered/cpu/full/rob_station.cc
+ encumbered/cpu/full/spec_memory.cc
+ encumbered/cpu/full/spec_state.cc
+ encumbered/cpu/full/storebuffer.cc
+ encumbered/cpu/full/writeback.cc
+ encumbered/cpu/full/iq/iq_station.cc
+ encumbered/cpu/full/iq/iqueue.cc
+ encumbered/cpu/full/iq/segmented/chain_info.cc
+ encumbered/cpu/full/iq/segmented/chain_wire.cc
+ encumbered/cpu/full/iq/segmented/iq_seg.cc
+ encumbered/cpu/full/iq/segmented/iq_segmented.cc
+ encumbered/cpu/full/iq/segmented/seg_chain.cc
+ encumbered/cpu/full/iq/seznec/iq_seznec.cc
+ encumbered/cpu/full/iq/standard/iq_standard.cc
+ ''')
# MySql sources
mysql_sources = Split('''
@@ -296,15 +268,6 @@ full_system_sources = Split('''
sim/pseudo_inst.cc
''')
-# These are now included by the architecture specific SConscript
-# arch/alpha/alpha_memory.cc
-# arch/alpha/arguments.cc
-# arch/alpha/ev5.cc
-# arch/alpha/osfpal.cc
-# arch/alpha/pseudo_inst.cc
-# arch/alpha/stacktrace.cc
-# arch/alpha/vtophys.cc
-
# turbolaser encumbered sources
turbolaser_sources = Split('''
encumbered/dev/dma.cc
@@ -331,14 +294,16 @@ syscall_emulation_sources = Split('''
encumbered/eio/eio.cc
encumbered/eio/exolex.cc
encumbered/eio/libexo.cc
+ kern/linux/linux.cc
+ kern/tru64/tru64.cc
sim/process.cc
sim/syscall_emul.cc
''')
-# These are now included by the architecture specific SConscript
-# arch/alpha/alpha_common_syscall_emul.cc
-# arch/alpha/alpha_linux_process.cc
-# arch/alpha/alpha_tru64_process.cc
+# The following stuff (targetarch code and global define of THE_ISA)
+# are legacy things that assume we're only compiling one ISA at a
+# time. These will have to go away if we want to build a binary that
+# supports multiple ISAs.
targetarch_files = Split('''
alpha_linux_process.hh
@@ -352,29 +317,28 @@ targetarch_files = Split('''
stacktrace.hh
vtophys.hh
''')
-# pseudo_inst.hh
-# isa_traits.hh
-# osfpal.hh
-# byte_swap.hh
-# alpha_common_syscall_emul.hh
-# vptr.hh
-# isa_fullsys_traits.hh
# Set up bridging headers to the architecture specific versions
for f in targetarch_files:
env.Command('targetarch/' + f, 'arch/%s/%s' % (env['TARGET_ISA'], f),
'''echo '#include "arch/%s/%s"' > $TARGET''' % (env['TARGET_ISA'], f))
-# Let the target architecture define what sources it needs
-arch_source = SConscript('arch/%s/SConscript' % env['TARGET_ISA'],
- build_dir = 'build/%s/' % env['BUILD_DIR'],
- exports = 'env', duplicate = False)
-
# 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)
+
+cpu_sources = SConscript('cpu/SConscript',
+ exports = 'env', duplicate = False)
+
+# This is outside of cpu/SConscript since the source directory isn't
+# underneath 'cpu'.
+if 'FullCPU' in env['CPU_MODELS']:
+ cpu_sources += full_cpu_sources
+
# Set up complete list of sources based on configuration.
-sources = base_sources + arch_source
+sources = base_sources + arch_sources + cpu_sources
if env['FULL_SYSTEM']:
sources += full_system_sources
@@ -391,27 +355,6 @@ for opt in env.ExportOptions:
###################################################
#
-# Add an SCons scanner for ISA files
-#
-###################################################
-import SCons.Scanner
-
-def ISAScan():
- return SCons.Scanner.Classic("ISAScan",
- "$ISASUFFIXES",
- "SRCDIR",
- '^[ \t]*##[ \t]*include[ \t]*"([^>"]+)"')
-
-def ISAPath(env, dir, target=None, source=None, a=None):
- return (Dir(env['SRCDIR']), Dir('.'))
-
-iscan = Scanner(function = ISAScan().scan, skeys = [".isa", ".ISA"],
- path_function = ISAPath)
-env.Append(SCANNERS = iscan)
-
-
-###################################################
-#
# Special build rules.
#
###################################################
@@ -422,27 +365,6 @@ env.Command(Split('base/traceflags.hh base/traceflags.cc'),
'base/traceflags.py',
'python $SOURCE $TARGET.base')
-# several files are generated from arch/$TARGET_ISA/isa_desc.
-env.Command(Split('''
- arch/%s/decoder.cc
- arch/%s/decoder.hh
- arch/%s/alpha_o3_exec.cc
- arch/%s/fast_cpu_exec.cc
- arch/%s/simple_cpu_exec.cc
- arch/%s/full_cpu_exec.cc''' %
- (env['TARGET_ISA'],
- env['TARGET_ISA'],
- env['TARGET_ISA'],
- env['TARGET_ISA'],
- env['TARGET_ISA'],
- env['TARGET_ISA'])),
- Split('''
- arch/%s/isa/main.isa
- arch/isa_parser.py''' %
- env['TARGET_ISA']),
- '$SRCDIR/arch/isa_parser.py $SOURCE $TARGET.dir arch/%s' % env['TARGET_ISA'])
-
-
# libelf build is described in its own SConscript file.
# SConscript-local is the per-config build, which just copies some
# header files into a place where they can be found.
diff --git a/arch/SConscript b/arch/SConscript
new file mode 100644
index 000000000..d237b0b1f
--- /dev/null
+++ b/arch/SConscript
@@ -0,0 +1,147 @@
+# -*- mode:python -*-
+
+# 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.
+
+import os.path
+
+# Import build environment variable from SConstruct.
+Import('env')
+
+# Right now there are no source files immediately in this directory
+sources = []
+
+#################################################################
+#
+# ISA "switch header" generation.
+#
+# Auto-generate arch headers that include the right ISA-specific
+# header based on the setting of THE_ISA preprocessor variable.
+#
+#################################################################
+
+# List of headers to generate
+isa_switch_hdrs = Split('''
+ isa_traits.hh
+ ''')
+
+# Generate the header. target[0] is the full path of the output
+# header to generate. 'source' is a dummy variable, since we get the
+# list of ISAs from env['ALL_ISA_LIST'].
+def gen_switch_hdr(target, source, env):
+ fname = str(target[0])
+ basename = os.path.basename(fname)
+ f = open(fname, 'w')
+ f.write('#include "arch/isa_specific.hh"\n')
+ cond = '#if'
+ for isa in env['ALL_ISA_LIST']:
+ f.write('%s THE_ISA == %s_ISA\n#include "arch/%s/%s"\n'
+ % (cond, isa.upper(), isa, basename))
+ cond = '#elif'
+ f.write('#else\n#error "THE_ISA not set"\n#endif\n')
+ f.close()
+ return 0
+
+# String to print when generating header
+def gen_switch_hdr_string(target, source, env):
+ return "Generating ISA switch header " + str(target[0])
+
+# Build SCons Action object. 'varlist' specifies env vars that this
+# action depdnds on; when env['ALL_ISA_LIST'] changes these actions
+# should get re-executed.
+switch_hdr_action = Action(gen_switch_hdr, gen_switch_hdr_string,
+ varlist=['ALL_ISA_LIST'])
+
+# Instantiate actions for each header
+for hdr in isa_switch_hdrs:
+ env.Command(hdr, [], switch_hdr_action)
+
+#################################################################
+#
+# Include architecture-specific files.
+#
+#################################################################
+
+#
+# Build a SCons scanner for ISA files
+#
+import SCons.Scanner
+
+def ISAScan():
+ return SCons.Scanner.Classic("ISAScan",
+ "$ISASUFFIXES",
+ "SRCDIR",
+ '^[ \t]*##[ \t]*include[ \t]*"([^>"]+)"')
+
+def ISAPath(env, dir, target=None, source=None, a=None):
+ return (Dir(env['SRCDIR']), Dir('.'))
+
+iscan = Scanner(function = ISAScan().scan, skeys = [".isa", ".ISA"],
+ path_function = ISAPath)
+env.Append(SCANNERS = iscan)
+
+#
+# Now create a Builder object that uses isa_parser.py to generate C++
+# output from the ISA description (*.isa) files.
+#
+
+# Convert to File node to fix path
+isa_parser = File('isa_parser.py')
+cpu_models_file = File('#m5/cpu/cpu_models.py')
+
+# This sucks in the defintions of the CpuModel objects.
+execfile(cpu_models_file.srcnode().abspath)
+
+# Several files are generated from the ISA description.
+# We always get the basic decoder and header file.
+isa_desc_gen_files = Split('decoder.cc decoder.hh')
+# We also get an execute file for each selected CPU model.
+isa_desc_gen_files += [CpuModel.dict[cpu].filename
+ for cpu in env['CPU_MODELS']]
+
+# 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='$SOURCES $TARGET.dir $CPU_MODELS',
+ source_scanner = iscan,
+ emitter = isa_desc_emitter)
+
+env.Append(BUILDERS = { 'ISADesc' : isa_desc_builder })
+
+#
+# Now include other ISA-specific sources from the ISA subdirectories.
+#
+
+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)
+
+Return('sources')
diff --git a/arch/alpha/SConscript b/arch/alpha/SConscript
index 8bf408c06..050dfb9cf 100644
--- a/arch/alpha/SConscript
+++ b/arch/alpha/SConscript
@@ -43,445 +43,45 @@ Import('env')
###################################################
# Base sources used by all configurations.
-arch_base_sources = Split('''
- arch/alpha/decoder.cc
- arch/alpha/alpha_o3_exec.cc
- arch/alpha/fast_cpu_exec.cc
- arch/alpha/simple_cpu_exec.cc
- arch/alpha/full_cpu_exec.cc
- arch/alpha/faults.cc
- arch/alpha/isa_traits.cc
+base_sources = Split('''
+ faults.cc
+ isa_traits.cc
''')
-# base/circlebuf.cc
-# base/copyright.cc
-# base/cprintf.cc
-# base/embedfile.cc
-# base/fast_alloc.cc
-# base/fifo_buffer.cc
-# base/hostinfo.cc
-# base/hybrid_pred.cc
-# base/inifile.cc
-# base/intmath.cc
-# base/match.cc
-# base/misc.cc
-# base/output.cc
-# base/pollevent.cc
-# base/range.cc
-# base/random.cc
-# base/sat_counter.cc
-# base/socket.cc
-# base/statistics.cc
-# base/str.cc
-# base/time.cc
-# base/trace.cc
-# base/traceflags.cc
-# base/userinfo.cc
-# base/compression/lzss_compression.cc
-# base/loader/aout_object.cc
-# base/loader/ecoff_object.cc
-# base/loader/elf_object.cc
-# base/loader/object_file.cc
-# base/loader/symtab.cc
-# base/stats/events.cc
-# base/stats/statdb.cc
-# base/stats/visit.cc
-# base/stats/text.cc
-#
-# cpu/base.cc
-# cpu/base_dyn_inst.cc
-# cpu/exec_context.cc
-# cpu/exetrace.cc
-# cpu/pc_event.cc
-# cpu/static_inst.cc
-# cpu/o3/2bit_local_pred.cc
-# cpu/o3/alpha_dyn_inst.cc
-# cpu/o3/alpha_cpu.cc
-# cpu/o3/alpha_cpu_builder.cc
-# cpu/o3/bpred_unit.cc
-# cpu/o3/btb.cc
-# cpu/o3/commit.cc
-# cpu/o3/decode.cc
-# cpu/o3/fetch.cc
-# cpu/o3/free_list.cc
-# cpu/o3/cpu.cc
-# cpu/o3/iew.cc
-# cpu/o3/inst_queue.cc
-# cpu/o3/ldstq.cc
-# cpu/o3/mem_dep_unit.cc
-# cpu/o3/ras.cc
-# cpu/o3/rename.cc
-# cpu/o3/rename_map.cc
-# cpu/o3/rob.cc
-# cpu/o3/sat_counter.cc
-# cpu/o3/store_set.cc
-# cpu/o3/tournament_pred.cc
-# cpu/fast/cpu.cc
-# cpu/sampler/sampler.cc
-# cpu/simple/cpu.cc
-# cpu/trace/reader/mem_trace_reader.cc
-# cpu/trace/reader/ibm_reader.cc
-# cpu/trace/reader/itx_reader.cc
-# cpu/trace/reader/m5_reader.cc
-# cpu/trace/opt_cpu.cc
-# cpu/trace/trace_cpu.cc
-#
-# encumbered/cpu/full/bpred.cc
-# encumbered/cpu/full/commit.cc
-# encumbered/cpu/full/cpu.cc
-# encumbered/cpu/full/create_vector.cc
-# encumbered/cpu/full/cv_spec_state.cc
-# encumbered/cpu/full/dd_queue.cc
-# encumbered/cpu/full/dep_link.cc
-# encumbered/cpu/full/dispatch.cc
-# encumbered/cpu/full/dyn_inst.cc
-# encumbered/cpu/full/execute.cc
-# encumbered/cpu/full/fetch.cc
-# encumbered/cpu/full/floss_reasons.cc
-# encumbered/cpu/full/fu_pool.cc
-# encumbered/cpu/full/inst_fifo.cc
-# encumbered/cpu/full/instpipe.cc
-# encumbered/cpu/full/issue.cc
-# encumbered/cpu/full/ls_queue.cc
-# encumbered/cpu/full/machine_queue.cc
-# encumbered/cpu/full/pipetrace.cc
-# encumbered/cpu/full/readyq.cc
-# encumbered/cpu/full/reg_info.cc
-# encumbered/cpu/full/rob_station.cc
-# encumbered/cpu/full/spec_memory.cc
-# encumbered/cpu/full/spec_state.cc
-# encumbered/cpu/full/storebuffer.cc
-# encumbered/cpu/full/writeback.cc
-# encumbered/cpu/full/iq/iq_station.cc
-# encumbered/cpu/full/iq/iqueue.cc
-# encumbered/cpu/full/iq/segmented/chain_info.cc
-# encumbered/cpu/full/iq/segmented/chain_wire.cc
-# encumbered/cpu/full/iq/segmented/iq_seg.cc
-# encumbered/cpu/full/iq/segmented/iq_segmented.cc
-# encumbered/cpu/full/iq/segmented/seg_chain.cc
-# encumbered/cpu/full/iq/seznec/iq_seznec.cc
-# encumbered/cpu/full/iq/standard/iq_standard.cc
-# encumbered/mem/functional/main.cc
-#
-# mem/base_hier.cc
-# mem/base_mem.cc
-# mem/hier_params.cc
-# mem/mem_cmd.cc
-# mem/mem_debug.cc
-# mem/mem_req.cc
-# mem/memory_interface.cc
-# mem/bus/base_interface.cc
-# mem/bus/bus.cc
-# mem/bus/bus_bridge.cc
-# mem/bus/bus_bridge_master.cc
-# mem/bus/bus_bridge_slave.cc
-# mem/bus/bus_interface.cc
-# mem/bus/dma_bus_interface.cc
-# mem/bus/dma_interface.cc
-# mem/bus/master_interface.cc
-# mem/bus/slave_interface.cc
-# mem/cache/base_cache.cc
-# mem/cache/cache.cc
-# mem/cache/cache_builder.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/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_lru.cc
-# mem/cache/tags/split_lifo.cc
-# mem/functional/functional.cc
-# mem/timing/base_memory.cc
-# mem/timing/memory_builder.cc
-# mem/timing/simple_mem_bank.cc
-# mem/trace/itx_writer.cc
-# mem/trace/mem_trace_writer.cc
-# mem/trace/m5_writer.cc
-#
-# python/pyconfig.cc
-# python/embedded_py.cc
-#
-# sim/builder.cc
-# sim/configfile.cc
-# sim/debug.cc
-# sim/eventq.cc
-# sim/main.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
-# sim/stat_control.cc
-# sim/trace_context.cc
-# ''')
-
-# MySql sources
-arch_mysql_sources = Split('''
- ''')
-# base/mysql.cc
-# base/stats/mysql.cc
-# ''')
-
# Full-system sources
-arch_full_system_sources = Split('''
- arch/alpha/alpha_memory.cc
- arch/alpha/arguments.cc
- arch/alpha/ev5.cc
- arch/alpha/osfpal.cc
- arch/alpha/stacktrace.cc
- arch/alpha/vtophys.cc
+full_system_sources = Split('''
+ alpha_memory.cc
+ arguments.cc
+ ev5.cc
+ osfpal.cc
+ stacktrace.cc
+ vtophys.cc
''')
-# base/crc.cc
-# base/inet.cc
-# base/remote_gdb.cc
-#
-# cpu/intr_control.cc
-# cpu/profile.cc
-#
-# dev/alpha_console.cc
-# dev/baddev.cc
-# dev/simconsole.cc
-# dev/disk_image.cc
-# dev/etherbus.cc
-# dev/etherdump.cc
-# dev/etherint.cc
-# dev/etherlink.cc
-# dev/etherpkt.cc
-# dev/ethertap.cc
-# dev/ide_ctrl.cc
-# dev/ide_disk.cc
-# dev/io_device.cc
-# dev/ns_gige.cc
-# dev/pciconfigall.cc
-# dev/pcidev.cc
-# dev/pcifake.cc
-# dev/pktfifo.cc
-# dev/platform.cc
-# dev/sinic.cc
-# dev/simple_disk.cc
-# dev/tsunami.cc
-# dev/tsunami_cchip.cc
-# dev/isa_fake.cc
-# dev/tsunami_io.cc
-# dev/tsunami_pchip.cc
-# dev/uart.cc
-# dev/uart8250.cc
-#
-# kern/kernel_binning.cc
-# kern/kernel_stats.cc
-# kern/system_events.cc
-# kern/freebsd/freebsd_system.cc
-# kern/linux/linux_syscalls.cc
-# kern/linux/linux_system.cc
-# kern/linux/printk.cc
-# kern/tru64/dump_mbuf.cc
-# kern/tru64/printf.cc
-# kern/tru64/tru64_events.cc
-# kern/tru64/tru64_syscalls.cc
-# kern/tru64/tru64_system.cc
-#
-# mem/functional/memory_control.cc
-# mem/functional/physical.cc
-#
-# sim/system.cc
-# ''')
-
-# turbolaser encumbered sources
-arch_turbolaser_sources = Split('''
- ''')
-# encumbered/dev/dma.cc
-# encumbered/dev/etherdev.cc
-# encumbered/dev/scsi.cc
-# encumbered/dev/scsi_ctrl.cc
-# encumbered/dev/scsi_disk.cc
-# encumbered/dev/scsi_none.cc
-# encumbered/dev/tlaser_clock.cc
-# encumbered/dev/tlaser_ipi.cc
-# encumbered/dev/tlaser_mbox.cc
-# encumbered/dev/tlaser_mc146818.cc
-# encumbered/dev/tlaser_node.cc
-# encumbered/dev/tlaser_pcia.cc
-# encumbered/dev/tlaser_pcidev.cc
-# encumbered/dev/tlaser_serial.cc
-# encumbered/dev/turbolaser.cc
-# encumbered/dev/uart8530.cc
-# ''')
# Syscall emulation (non-full-system) sources
-arch_syscall_emulation_sources = Split('''
- arch/alpha/alpha_common_syscall_emul.cc
- arch/alpha/alpha_linux_process.cc
- arch/alpha/alpha_tru64_process.cc
+syscall_emulation_sources = Split('''
+ alpha_common_syscall_emul.cc
+ alpha_linux_process.cc
+ alpha_tru64_process.cc
''')
-# cpu/memtest/memtest.cc
-# encumbered/eio/eio.cc
-# encumbered/eio/exolex.cc
-# encumbered/eio/libexo.cc
-# sim/process.cc
-# sim/syscall_emul.cc
-# ''')
-
-#targetarch_files = Split('''
-# alpha_common_syscall_emul.hh
-# alpha_linux_process.hh
-# alpha_memory.hh
-# alpha_tru64_process.hh
-# aout_machdep.h
-# arguments.hh
-# byte_swap.hh
-# ecoff_machdep.h
-# ev5.hh
-# faults.hh
-# isa_fullsys_traits.hh
-# isa_traits.hh
-# osfpal.hh
-# pseudo_inst.hh
-# stacktrace.hh
-# vptr.hh
-# vtophys.hh
-# ''')
-
-#for f in targetarch_files:
-# env.Command('targetarch/' + f, 'arch/alpha/' + f,
-# '''echo '#include "arch/alpha/%s"' > $TARGET''' % f)
-
# Set up complete list of sources based on configuration.
-sources = arch_base_sources
+sources = base_sources
if env['FULL_SYSTEM']:
- sources += arch_full_system_sources
- if env['ALPHA_TLASER']:
- sources += arch_turbolaser_sources
+ sources += full_system_sources
else:
- sources += arch_syscall_emulation_sources
-
-if env['USE_MYSQL']:
- sources += arch_mysql_sources
-
-for opt in env.ExportOptions:
- env.ConfigFile(opt)
-
-###################################################
-#
-# Special build rules.
-#
-###################################################
-
-# base/traceflags.{cc,hh} are generated from base/traceflags.py.
-# $TARGET.base will expand to "<build-dir>/base/traceflags".
-# env.Command(Split('base/traceflags.hh base/traceflags.cc'),
-# 'base/traceflags.py',
-# 'python $SOURCE $TARGET.base')
-
-# several files are generated from arch/$TARGET_ISA/isa_desc.
-#env.Command(Split('''decoder.cc
-# decoder.hh
-# alpha_o3_exec.cc
-# fast_cpu_exec.cc
-# simple_cpu_exec.cc
-# full_cpu_exec.cc'''),
-# Split('''isa_desc
-# ../isa_parser.py'''),
-# '$SRCDIR/arch/isa_parser.py $SOURCE $TARGET.dir arch/alpha')
-
-
-# libelf build is described in its own SConscript file.
-# SConscript-local is the per-config build, which just copies some
-# header files into a place where they can be found.
-# SConscript('libelf/SConscript-local', exports = 'env', duplicate=0)
-# SConscript('python/SConscript', exports = ['env'], duplicate=0)
-
-# This function adds the specified sources to the given build
-# environment, and returns a list of all the corresponding SCons
-# Object nodes (including an extra one for date.cc). We explicitly
-# add the Object nodes so we can set up special dependencies for
-# date.cc.
-# def make_objs(sources, env):
-# objs = [env.Object(s) for s in sources]
-# # make date.cc depend on all other objects so it always gets
-# # recompiled whenever anything else does
-# date_obj = env.Object('base/date.cc')
-# base/traceflags.{cc,hh} are generated from base/traceflags.py.
-# $TARGET.base will expand to "<build-dir>/base/traceflags".
-# env.Command(Split('base/traceflags.hh base/traceflags.cc'),
-# 'base/traceflags.py',
-# 'python $SOURCE $TARGET.base')
-#
-# Split('''arch/alpha/isa_desc
-# arch/isa_parser.py'''),
-# env.Depends(date_obj, objs)
-# objs.append(date_obj)
-# return objs
-
-###################################################
-#
-# Define binaries. Each different build type (debug, opt, etc.) gets
-# a slightly different build environment.
-#
-###################################################
-
-# 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='.')
-
-# Debug binary
-# debugEnv = env.Copy(OBJSUFFIX='.do')
-# debugEnv.Label = 'debug'
-# debugEnv.Append(CCFLAGS=Split('-g -gstabs+ -O0'))
-# debugEnv.Append(CPPDEFINES='DEBUG')
-# tlist = debugEnv.Program(target = 'm5.debug',
-# source = make_objs(sources, debugEnv))
-# debugEnv.M5Binary = tlist[0]
+ sources += syscall_emulation_sources
-# Optimized binary
-# optEnv = env.Copy()
-# optEnv.Label = 'opt'
-# optEnv.Append(CCFLAGS=Split('-g -O5'))
-# tlist = optEnv.Program(target = 'm5.opt',
-# source = make_objs(sources, optEnv))
-# optEnv.M5Binary = tlist[0]
+# Convert file names to SCons File objects. This takes care of the
+# path relative to the top of the directory tree.
+sources = [File(s) for s in sources]
-# "Fast" binary
-# fastEnv = env.Copy(OBJSUFFIX='.fo')
-# fastEnv.Label = 'fast'
-# fastEnv.Append(CCFLAGS=Split('-O5'))
-# 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]
+# Add in files generated by the ISA description.
+isa_desc_files = env.ISADesc('isa/main.isa')
+# Only non-header files need to be compiled.
+isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')]
+sources += isa_desc_sources
-# Profiled binary
-# profEnv = env.Copy(OBJSUFFIX='.po')
-# profEnv.Label = 'prof'
-# profEnv.Append(CCFLAGS=Split('-O5 -g -pg'), LINKFLAGS='-pg')
-# tlist = profEnv.Program(target = 'm5.prof',
-# source = make_objs(sources, profEnv))
-# profEnv.M5Binary = tlist[0]
-#
-# envList = [debugEnv, optEnv, fastEnv, profEnv]
-#
-# Return('envList')
Return('sources')
diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc
index fb5e32e63..16ebcca7b 100644
--- a/arch/alpha/alpha_linux_process.cc
+++ b/arch/alpha/alpha_linux_process.cc
@@ -26,506 +26,122 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h> // for host open() flags
-#include <string.h> // for memset()
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
+#include "arch/alpha/alpha_common_syscall_emul.hh"
+#include "arch/alpha/alpha_linux_process.hh"
+#include "arch/alpha/isa_traits.hh"
-#include "cpu/base.hh"
+#include "base/trace.hh"
#include "cpu/exec_context.hh"
+#include "kern/linux/linux.hh"
#include "mem/functional/functional.hh"
-#include "sim/fake_syscall.hh"
-#include "sim/host.hh"
-#include "sim/process.hh"
-#include "sim/sim_events.hh"
-#include "arch/alpha/isa_traits.hh"
-#include "arch/alpha/alpha_common_syscall_emul.hh"
+#include "sim/process.hh"
#include "sim/syscall_emul.hh"
-#include "sim/root.hh" // for curTick & ticksPerSecond
-
-#include "arch/alpha/alpha_linux_process.hh"
-
-#include "base/trace.hh"
using namespace std;
+using namespace AlphaISA;
+
+/// Target pipe() handler. Even though this is a generic Posix call,
+/// the Alpha return convention is funky, so that makes it
+/// Alpha-specific.
+SyscallReturn
+pipeFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+{
+ int fds[2], sim_fds[2];
+ int pipe_retval = pipe(fds);
-///
-/// This class encapsulates the types, structures, constants,
-/// functions, and syscall-number mappings specific to the Alpha Linux
-/// syscall interface.
-///
-class Linux {
-
- public:
-
- //@{
- /// Basic Linux types.
- typedef uint64_t size_t;
- typedef uint64_t off_t;
- typedef int64_t time_t;
- typedef uint32_t uid_t;
- typedef uint32_t gid_t;
- //@}
-
-#if BSD_HOST
- typedef struct stat hst_stat;
- typedef struct stat hst_stat64;
-#else
- typedef struct stat hst_stat ;
- typedef struct stat64 hst_stat64;
-#endif
-
-
- //@{
- /// open(2) flag values.
- static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY
- static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY
- static const int TGT_O_RDWR = 00000002; //!< O_RDWR
- static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK
- static const int TGT_O_APPEND = 00000010; //!< O_APPEND
- static const int TGT_O_CREAT = 00001000; //!< O_CREAT
- static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC
- static const int TGT_O_EXCL = 00004000; //!< O_EXCL
- static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY
- static const int TGT_O_SYNC = 00040000; //!< O_SYNC
- static const int TGT_O_DRD = 00100000; //!< O_DRD
- static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO
- static const int TGT_O_CACHE = 00400000; //!< O_CACHE
- static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC
- static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC
- //@}
-
- /// This table maps the target open() flags to the corresponding
- /// host open() flags.
- static OpenFlagTransTable openFlagTable[];
-
- /// Number of entries in openFlagTable[].
- static const int NUM_OPEN_FLAGS;
-
- /// Stat buffer. Note that we can't call it 'stat' since that
- /// gets #defined to something else on some systems.
- struct tgt_stat {
- uint32_t st_dev; //!< device
- uint32_t st_ino; //!< inode
- uint32_t st_mode; //!< mode
- uint32_t st_nlink; //!< link count
- uint32_t st_uid; //!< owner's user ID
- uint32_t st_gid; //!< owner's group ID
- uint32_t st_rdev; //!< device number
- int32_t _pad1; //!< for alignment
- int64_t st_size; //!< file size in bytes
- uint64_t st_atimeX; //!< time of last access
- uint64_t st_mtimeX; //!< time of last modification
- uint64_t st_ctimeX; //!< time of last status change
- uint32_t st_blksize; //!< optimal I/O block size
- int32_t st_blocks; //!< number of blocks allocated
- uint32_t st_flags; //!< flags
- uint32_t st_gen; //!< unknown
- };
-
- // same for stat64
- struct tgt_stat64 {
- uint64_t st_dev;
- uint64_t st_ino;
- uint64_t st_rdev;
- int64_t st_size;
- uint64_t st_blocks;
-
- uint32_t st_mode;
- uint32_t st_uid;
- uint32_t st_gid;
- uint32_t st_blksize;
- uint32_t st_nlink;
- uint32_t __pad0;
-
- uint64_t tgt_st_atime;
- uint64_t st_atime_nsec;
- uint64_t tgt_st_mtime;
- uint64_t st_mtime_nsec;
- uint64_t tgt_st_ctime;
- uint64_t st_ctime_nsec;
- int64_t ___unused[3];
- };
-
- /// Length of strings in struct utsname (plus 1 for null char).
- static const int _SYS_NMLN = 65;
-
- /// Interface struct for uname().
- struct utsname {
- char sysname[_SYS_NMLN]; //!< System name.
- char nodename[_SYS_NMLN]; //!< Node name.
- char release[_SYS_NMLN]; //!< OS release.
- char version[_SYS_NMLN]; //!< OS version.
- char machine[_SYS_NMLN]; //!< Machine type.
- };
-
-
- //@{
- /// ioctl() command codes.
- static const unsigned TIOCGETP = 0x40067408;
- static const unsigned TIOCSETP = 0x80067409;
- static const unsigned TIOCSETN = 0x8006740a;
- static const unsigned TIOCSETC = 0x80067411;
- static const unsigned TIOCGETC = 0x40067412;
- static const unsigned FIONREAD = 0x4004667f;
- static const unsigned TIOCISATTY = 0x2000745e;
- static const unsigned TIOCGETS = 0x402c7413;
- static const unsigned TIOCGETA = 0x40127417;
- //@}
-
- /// Resource enumeration for getrlimit().
- enum rlimit_resources {
- TGT_RLIMIT_CPU = 0,
- TGT_RLIMIT_FSIZE = 1,
- TGT_RLIMIT_DATA = 2,
- TGT_RLIMIT_STACK = 3,
- TGT_RLIMIT_CORE = 4,
- TGT_RLIMIT_RSS = 5,
- TGT_RLIMIT_NOFILE = 6,
- TGT_RLIMIT_AS = 7,
- TGT_RLIMIT_VMEM = 7,
- TGT_RLIMIT_NPROC = 8,
- TGT_RLIMIT_MEMLOCK = 9,
- TGT_RLIMIT_LOCKS = 10
- };
-
- /// Limit struct for getrlimit/setrlimit.
- struct rlimit {
- uint64_t rlim_cur; //!< soft limit
- uint64_t rlim_max; //!< hard limit
- };
-
-
- /// For mmap().
- static const unsigned TGT_MAP_ANONYMOUS = 0x10;
-
- /// For gettimeofday().
- struct timeval {
- int64_t tv_sec; //!< seconds
- int64_t tv_usec; //!< microseconds
- };
-
- // For writev/readv
- struct tgt_iovec {
- uint64_t iov_base; // void *
- uint64_t iov_len;
- };
-
- //@{
- /// For getrusage().
- static const int TGT_RUSAGE_SELF = 0;
- static const int TGT_RUSAGE_CHILDREN = -1;
- static const int TGT_RUSAGE_BOTH = -2;
- //@}
-
- /// For getrusage().
- struct rusage {
- struct timeval ru_utime; //!< user time used
- struct timeval ru_stime; //!< system time used
- int64_t ru_maxrss; //!< max rss
- int64_t ru_ixrss; //!< integral shared memory size
- int64_t ru_idrss; //!< integral unshared data "
- int64_t ru_isrss; //!< integral unshared stack "
- int64_t ru_minflt; //!< page reclaims - total vmfaults
- int64_t ru_majflt; //!< page faults
- int64_t ru_nswap; //!< swaps
- int64_t ru_inblock; //!< block input operations
- int64_t ru_oublock; //!< block output operations
- int64_t ru_msgsnd; //!< messages sent
- int64_t ru_msgrcv; //!< messages received
- int64_t ru_nsignals; //!< signals received
- int64_t ru_nvcsw; //!< voluntary context switches
- int64_t ru_nivcsw; //!< involuntary "
- };
-
- /// Helper function to convert a host stat buffer to a target stat
- /// buffer. Also copies the target buffer out to the simulated
- /// memory space. Used by stat(), fstat(), and lstat().
-#if !BSD_HOST
- static void
- copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat *host)
- {
- TypedBufferArg<Linux::tgt_stat> tgt(addr);
-
- tgt->st_dev = htog(host->st_dev);
- tgt->st_ino = htog(host->st_ino);
- tgt->st_mode = htog(host->st_mode);
- tgt->st_nlink = htog(host->st_nlink);
- tgt->st_uid = htog(host->st_uid);
- tgt->st_gid = htog(host->st_gid);
- tgt->st_rdev = htog(host->st_rdev);
- tgt->st_size = htog(host->st_size);
- tgt->st_atimeX = htog(host->st_atime);
- tgt->st_mtimeX = htog(host->st_mtime);
- tgt->st_ctimeX = htog(host->st_ctime);
- tgt->st_blksize = htog(host->st_blksize);
- tgt->st_blocks = htog(host->st_blocks);
-
- tgt.copyOut(mem);
- }
-#else
- // Third version for bsd systems which no longer have any support for
- // the old stat() call and stat() is actually a stat64()
- static void
- copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat64 *host)
- {
- TypedBufferArg<Linux::tgt_stat> tgt(addr);
-
- tgt->st_dev = htog(host->st_dev);
- tgt->st_ino = htog(host->st_ino);
- tgt->st_mode = htog(host->st_mode);
- tgt->st_nlink = htog(host->st_nlink);
- tgt->st_uid = htog(host->st_uid);
- tgt->st_gid = htog(host->st_gid);
- tgt->st_rdev = htog(host->st_rdev);
- tgt->st_size = htog(host->st_size);
- tgt->st_atimeX = htog(host->st_atime);
- tgt->st_mtimeX = htog(host->st_mtime);
- tgt->st_ctimeX = htog(host->st_ctime);
- tgt->st_blksize = htog(host->st_blksize);
- tgt->st_blocks = htog(host->st_blocks);
-
- tgt.copyOut(mem);
- }
-#endif
-
-
- // Same for stat64
- static void
- copyOutStat64Buf(FunctionalMemory *mem, int fd, Addr addr, hst_stat64 *host)
- {
- TypedBufferArg<Linux::tgt_stat64> tgt(addr);
-
- // fd == 1 checks are because libc does some checks
- // that the stdout is interactive vs. a file
- // this makes it work on non-linux systems
- if (fd == 1)
- tgt->st_dev = htog((uint64_t)0xA);
- else
- tgt->st_dev = htog((uint64_t)host->st_dev);
- // XXX What about STAT64_HAS_BROKEN_ST_INO ???
- tgt->st_ino = htog((uint64_t)host->st_ino);
- if (fd == 1)
- tgt->st_rdev = htog((uint64_t)0x880d);
- else
- tgt->st_rdev = htog((uint64_t)host->st_rdev);
- tgt->st_size = htog((int64_t)host->st_size);
- tgt->st_blocks = htog((uint64_t)host->st_blocks);
-
- if (fd == 1)
- tgt->st_mode = htog((uint32_t)0x2190);
- else
- tgt->st_mode = htog((uint32_t)host->st_mode);
- tgt->st_uid = htog((uint32_t)host->st_uid);
- tgt->st_gid = htog((uint32_t)host->st_gid);
- tgt->st_blksize = htog((uint32_t)host->st_blksize);
- tgt->st_nlink = htog((uint32_t)host->st_nlink);
- tgt->tgt_st_atime = htog((uint64_t)host->st_atime);
- tgt->tgt_st_mtime = htog((uint64_t)host->st_mtime);
- tgt->tgt_st_ctime = htog((uint64_t)host->st_ctime);
-#if defined(STAT_HAVE_NSEC)
- tgt->st_atime_nsec = htog(host->st_atime_nsec);
- tgt->st_mtime_nsec = htog(host->st_mtime_nsec);
- tgt->st_ctime_nsec = htog(host->st_ctime_nsec);
-#else
- tgt->st_atime_nsec = 0;
- tgt->st_mtime_nsec = 0;
- tgt->st_ctime_nsec = 0;
-#endif
-
- tgt.copyOut(mem);
- }
-
- /// The target system's hostname.
- static const char *hostname;
-
- /// Target uname() handler.
- static SyscallReturn
- unameFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- TypedBufferArg<Linux::utsname> name(xc->getSyscallArg(0));
-
- strcpy(name->sysname, "Linux");
- strcpy(name->nodename, hostname);
- strcpy(name->release, "2.4.20");
- strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
- strcpy(name->machine, "alpha");
-
- name.copyOut(xc->mem);
- return 0;
- }
-
- /// Target osf_getsysyinfo() handler. Even though this call is
- /// borrowed from Tru64, the subcases that get used appear to be
- /// different in practice from those used by Tru64 processes.
- static SyscallReturn
- osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- unsigned op = xc->getSyscallArg(0);
- // unsigned nbytes = xc->getSyscallArg(2);
-
- switch (op) {
-
- case 45: { // GSI_IEEE_FP_CONTROL
- TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
- // I don't think this exactly matches the HW FPCR
- *fpcr = 0;
- fpcr.copyOut(xc->mem);
- return 0;
- }
-
- default:
- cerr << "osf_getsysinfo: unknown op " << op << endl;
- abort();
- break;
- }
-
- return 1;
- }
-
- /// Target osf_setsysinfo() handler.
- static SyscallReturn
- osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- unsigned op = xc->getSyscallArg(0);
- // unsigned nbytes = xc->getSyscallArg(2);
-
- switch (op) {
-
- case 14: { // SSI_IEEE_FP_CONTROL
- TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
- // I don't think this exactly matches the HW FPCR
- fpcr.copyIn(xc->mem);
- DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
- " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
- return 0;
- }
-
- default:
- cerr << "osf_setsysinfo: unknown op " << op << endl;
- abort();
- break;
- }
-
- return 1;
+ if (pipe_retval < 0) {
+ // error
+ return pipe_retval;
}
- /// Target fnctl() handler.
- static SyscallReturn
- fcntlFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- int fd = xc->getSyscallArg(0);
+ sim_fds[0] = process->alloc_fd(fds[0]);
+ sim_fds[1] = process->alloc_fd(fds[1]);
- if (fd < 0 || process->sim_fd(fd) < 0)
- return -EBADF;
+ // Alpha Linux convention for pipe() is that fd[0] is returned as
+ // the return value of the function, and fd[1] is returned in r20.
+ xc->regs.intRegFile[20] = sim_fds[1];
+ return sim_fds[0];
+}
- int cmd = xc->getSyscallArg(1);
- switch (cmd) {
- case 0: // F_DUPFD
- // if we really wanted to support this, we'd need to do it
- // in the target fd space.
- warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd);
- return -EMFILE;
- case 1: // F_GETFD (get close-on-exec flag)
- case 2: // F_SETFD (set close-on-exec flag)
- return 0;
+/// Target uname() handler.
+static SyscallReturn
+unameFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+{
+ TypedBufferArg<Linux::utsname> name(xc->getSyscallArg(0));
- case 3: // F_GETFL (get file flags)
- case 4: // F_SETFL (set file flags)
- // not sure if this is totally valid, but we'll pass it through
- // to the underlying OS
- warn("fcntl(%d, %d) passed through to host\n", fd, cmd);
- return fcntl(process->sim_fd(fd), cmd);
- // return 0;
+ strcpy(name->sysname, "Linux");
+ strcpy(name->nodename, "m5.eecs.umich.edu");
+ strcpy(name->release, "2.4.20");
+ strcpy(name->version, "#1 Mon Aug 18 11:32:15 EDT 2003");
+ strcpy(name->machine, "alpha");
- case 7: // F_GETLK (get lock)
- case 8: // F_SETLK (set lock)
- case 9: // F_SETLKW (set lock and wait)
- // don't mess with file locking... just act like it's OK
- warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd);
- return 0;
+ name.copyOut(xc->mem);
+ return 0;
+}
- default:
- warn("Unknown fcntl command %d\n", cmd);
- return 0;
- }
+/// Target osf_getsysyinfo() handler. Even though this call is
+/// borrowed from Tru64, the subcases that get used appear to be
+/// different in practice from those used by Tru64 processes.
+static SyscallReturn
+osf_getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+{
+ unsigned op = xc->getSyscallArg(0);
+ // unsigned nbytes = xc->getSyscallArg(2);
+
+ switch (op) {
+
+ case 45: { // GSI_IEEE_FP_CONTROL
+ TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
+ // I don't think this exactly matches the HW FPCR
+ *fpcr = 0;
+ fpcr.copyOut(xc->mem);
+ return 0;
+ }
+
+ default:
+ cerr << "osf_getsysinfo: unknown op " << op << endl;
+ abort();
+ break;
}
- /// Array of syscall descriptors, indexed by call number.
- static SyscallDesc syscallDescs[];
-
- /// Number of syscalls in syscallDescs[].
- static const int Num_Syscall_Descs;
-
- /// Max supported syscall number.
- static const int Max_Syscall_Desc;
-
- /// Do the specified syscall. Just looks the call number up in
- /// the table and invokes the appropriate handler.
- static void
- doSyscall(int callnum, Process *process, ExecContext *xc)
- {
- if (callnum < 0 || callnum > Max_Syscall_Desc) {
- fatal("Syscall %d out of range", callnum);
- }
-
- SyscallDesc *desc = &syscallDescs[callnum];
+ return 1;
+}
- desc->doSyscall(callnum, process, xc);
+/// Target osf_setsysinfo() handler.
+static SyscallReturn
+osf_setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+{
+ unsigned op = xc->getSyscallArg(0);
+ // unsigned nbytes = xc->getSyscallArg(2);
+
+ switch (op) {
+
+ case 14: { // SSI_IEEE_FP_CONTROL
+ TypedBufferArg<uint64_t> fpcr(xc->getSyscallArg(1));
+ // I don't think this exactly matches the HW FPCR
+ fpcr.copyIn(xc->mem);
+ DPRINTFR(SyscallVerbose, "osf_setsysinfo(SSI_IEEE_FP_CONTROL): "
+ " setting FPCR to 0x%x\n", gtoh(*(uint64_t*)fpcr));
+ return 0;
+ }
+
+ default:
+ cerr << "osf_setsysinfo: unknown op " << op << endl;
+ abort();
+ break;
}
-}; // class Linux
-
-// open(2) flags translation table
-OpenFlagTransTable Linux::openFlagTable[] = {
-#ifdef _MSC_VER
- { Linux::TGT_O_RDONLY, _O_RDONLY },
- { Linux::TGT_O_WRONLY, _O_WRONLY },
- { Linux::TGT_O_RDWR, _O_RDWR },
- { Linux::TGT_O_APPEND, _O_APPEND },
- { Linux::TGT_O_CREAT, _O_CREAT },
- { Linux::TGT_O_TRUNC, _O_TRUNC },
- { Linux::TGT_O_EXCL, _O_EXCL },
-#ifdef _O_NONBLOCK
- { Linux::TGT_O_NONBLOCK, _O_NONBLOCK },
-#endif
-#ifdef _O_NOCTTY
- { Linux::TGT_O_NOCTTY, _O_NOCTTY },
-#endif
-#ifdef _O_SYNC
- { Linux::TGT_O_SYNC, _O_SYNC },
-#endif
-#else /* !_MSC_VER */
- { Linux::TGT_O_RDONLY, O_RDONLY },
- { Linux::TGT_O_WRONLY, O_WRONLY },
- { Linux::TGT_O_RDWR, O_RDWR },
- { Linux::TGT_O_APPEND, O_APPEND },
- { Linux::TGT_O_CREAT, O_CREAT },
- { Linux::TGT_O_TRUNC, O_TRUNC },
- { Linux::TGT_O_EXCL, O_EXCL },
- { Linux::TGT_O_NONBLOCK, O_NONBLOCK },
- { Linux::TGT_O_NOCTTY, O_NOCTTY },
-#ifdef O_SYNC
- { Linux::TGT_O_SYNC, O_SYNC },
-#endif
-#endif /* _MSC_VER */
-};
-
-const int Linux::NUM_OPEN_FLAGS =
- (sizeof(Linux::openFlagTable)/sizeof(Linux::openFlagTable[0]));
+ return 1;
+}
-const char *Linux::hostname = "m5.eecs.umich.edu";
-SyscallDesc Linux::syscallDescs[] = {
+SyscallDesc AlphaLinuxProcess::syscallDescs[] = {
/* 0 */ SyscallDesc("osf_syscall", unimplementedFunc),
/* 1 */ SyscallDesc("exit", exitFunc),
/* 2 */ SyscallDesc("fork", unimplementedFunc),
@@ -568,7 +184,7 @@ SyscallDesc Linux::syscallDescs[] = {
/* 39 */ SyscallDesc("setpgid", unimplementedFunc),
/* 40 */ SyscallDesc("osf_old_lstat", unimplementedFunc),
/* 41 */ SyscallDesc("dup", unimplementedFunc),
- /* 42 */ SyscallDesc("pipe", unimplementedFunc),
+ /* 42 */ SyscallDesc("pipe", pipeFunc),
/* 43 */ SyscallDesc("osf_set_program_attributes", unimplementedFunc),
/* 44 */ SyscallDesc("osf_profil", unimplementedFunc),
/* 45 */ SyscallDesc("open", openFunc<Linux>),
@@ -973,23 +589,6 @@ SyscallDesc Linux::syscallDescs[] = {
/* 441 */ SyscallDesc("keyctl", unimplementedFunc)
};
-const int Linux::Num_Syscall_Descs =
- sizeof(Linux::syscallDescs) / sizeof(SyscallDesc);
-
-const int Linux::Max_Syscall_Desc = Linux::Num_Syscall_Descs - 1;
-
-
-void
-AlphaLinuxProcess::syscall(ExecContext *xc)
-{
- num_syscalls++;
-
- int64_t callnum = xc->regs.intRegFile[ReturnValueReg];
-
- Linux::doSyscall(callnum, this, xc);
-}
-
-
AlphaLinuxProcess::AlphaLinuxProcess(const std::string &name,
ObjectFile *objFile,
int stdin_fd,
@@ -997,7 +596,18 @@ AlphaLinuxProcess::AlphaLinuxProcess(const std::string &name,
int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp)
- : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp)
+ : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp),
+ Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
{
init_regs->intRegFile[0] = 0;
}
+
+
+
+SyscallDesc*
+AlphaLinuxProcess::getDesc(int callnum)
+{
+ if (callnum < 0 || callnum > Num_Syscall_Descs)
+ return NULL;
+ return &syscallDescs[callnum];
+}
diff --git a/arch/alpha/alpha_linux_process.hh b/arch/alpha/alpha_linux_process.hh
index b4fe8e8f8..7de1b1ac1 100644
--- a/arch/alpha/alpha_linux_process.hh
+++ b/arch/alpha/alpha_linux_process.hh
@@ -43,8 +43,15 @@ class AlphaLinuxProcess : public LiveProcess
std::vector<std::string> &argv,
std::vector<std::string> &envp);
- /// Syscall emulation function.
- virtual void syscall(ExecContext *xc);
+ virtual SyscallDesc* getDesc(int callnum);
+
+ /// The target system's hostname.
+ static const char *hostname;
+
+ /// Array of syscall descriptors, indexed by call number.
+ static SyscallDesc syscallDescs[];
+
+ const int Num_Syscall_Descs;
};
diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc
index 615ce92a4..d00186d95 100644
--- a/arch/alpha/alpha_memory.cc
+++ b/arch/alpha/alpha_memory.cc
@@ -303,7 +303,7 @@ AlphaITB::fault(Addr pc, ExecContext *xc) const
}
-Fault *
+Fault
AlphaITB::translate(MemReqPtr &req) const
{
InternalProcReg *ipr = req->xc->regs.ipr;
@@ -493,7 +493,7 @@ AlphaDTB::fault(MemReqPtr &req, uint64_t flags) const
}
}
-Fault *
+Fault
AlphaDTB::translate(MemReqPtr &req, bool write) const
{
RegFile *regs = &req->xc->regs;
@@ -575,7 +575,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
fault(req, (write ? MM_STAT_WR_MASK : 0) |
MM_STAT_DTB_MISS_MASK);
if (write) { write_misses++; } else { read_misses++; }
- return (req->flags & VPTE) ? (Fault *)PDtbMissFault : (Fault *)NDtbMissFault;
+ return (req->flags & VPTE) ? (Fault)PDtbMissFault : (Fault)NDtbMissFault;
}
req->paddr = (pte->ppn << AlphaISA::PageShift) +
diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/alpha_memory.hh
index 849063f59..de955fa46 100644
--- a/arch/alpha/alpha_memory.hh
+++ b/arch/alpha/alpha_memory.hh
@@ -94,7 +94,7 @@ class AlphaITB : public AlphaTLB
AlphaITB(const std::string &name, int size);
virtual void regStats();
- Fault * translate(MemReqPtr &req) const;
+ Fault translate(MemReqPtr &req) const;
};
class AlphaDTB : public AlphaTLB
@@ -120,7 +120,7 @@ class AlphaDTB : public AlphaTLB
AlphaDTB(const std::string &name, int size);
virtual void regStats();
- Fault * translate(MemReqPtr &req, bool write) const;
+ Fault translate(MemReqPtr &req, bool write) const;
};
#endif // __ALPHA_MEMORY_HH__
diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc
index 5c24adad9..8121d3452 100644
--- a/arch/alpha/alpha_tru64_process.cc
+++ b/arch/alpha/alpha_tru64_process.cc
@@ -26,1532 +26,139 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__)
-#include <sys/param.h>
-#include <sys/mount.h>
-#else
-#include <sys/statfs.h>
-#endif
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h> // for host open() flags
-#include <string.h> // for memset()
-#include <unistd.h>
-
#include "arch/alpha/isa_traits.hh"
#include "arch/alpha/alpha_common_syscall_emul.hh"
#include "arch/alpha/alpha_tru64_process.hh"
-#include "base/trace.hh"
-#include "cpu/base.hh"
#include "cpu/exec_context.hh"
+#include "kern/tru64/tru64.hh"
#include "mem/functional/functional.hh"
#include "sim/fake_syscall.hh"
-#include "sim/host.hh"
#include "sim/process.hh"
-#include "sim/root.hh"
#include "sim/syscall_emul.hh"
using namespace std;
+using namespace AlphaISA;
-typedef struct stat global_stat;
-typedef struct statfs global_statfs;
-typedef struct dirent global_dirent;
-
-///
-/// This class encapsulates the types, structures, constants,
-/// functions, and syscall-number mappings specific to the Alpha Tru64
-/// syscall interface.
-///
-class Tru64 {
-
- public:
-
- //@{
- /// Basic Tru64 types.
- typedef uint64_t size_t;
- typedef uint64_t off_t;
- typedef uint16_t nlink_t;
- typedef int32_t dev_t;
- typedef uint32_t uid_t;
- typedef uint32_t gid_t;
- typedef uint32_t time_t;
- typedef uint32_t mode_t;
- typedef uint32_t ino_t;
- typedef struct { int val[2]; } quad;
- typedef quad fsid_t;
- //@}
-
- //@{
- /// open(2) flag values.
- static const int TGT_O_RDONLY = 00000000;
- static const int TGT_O_WRONLY = 00000001;
- static const int TGT_O_RDWR = 00000002;
- static const int TGT_O_NONBLOCK = 00000004;
- static const int TGT_O_APPEND = 00000010;
- static const int TGT_O_CREAT = 00001000;
- static const int TGT_O_TRUNC = 00002000;
- static const int TGT_O_EXCL = 00004000;
- static const int TGT_O_NOCTTY = 00010000;
- static const int TGT_O_SYNC = 00040000;
- static const int TGT_O_DRD = 00100000;
- static const int TGT_O_DIRECTIO = 00200000;
- static const int TGT_O_CACHE = 00400000;
- static const int TGT_O_DSYNC = 02000000;
- static const int TGT_O_RSYNC = 04000000;
- //@}
-
- /// This table maps the target open() flags to the corresponding
- /// host open() flags.
- static OpenFlagTransTable openFlagTable[];
-
- /// Number of entries in openFlagTable[].
- static const int NUM_OPEN_FLAGS;
-
- /// Stat buffer. Note that Tru64 v5.0+ use a new "F64" stat
- /// structure, and a new set of syscall numbers for stat calls.
- /// On some hosts (notably Linux) define st_atime, st_mtime, and
- /// st_ctime as macros, so we append an X to get around this.
- struct F64_stat {
- dev_t st_dev; //!< st_dev
- int32_t st_retired1; //!< st_retired1
- mode_t st_mode; //!< st_mode
- nlink_t st_nlink; //!< st_nlink
- uint16_t st_nlink_reserved; //!< st_nlink_reserved
- uid_t st_uid; //!< st_uid
- gid_t st_gid; //!< st_gid
- dev_t st_rdev; //!< st_rdev
- dev_t st_ldev; //!< st_ldev
- off_t st_size; //!< st_size
- time_t st_retired2; //!< st_retired2
- int32_t st_uatime; //!< st_uatime
- time_t st_retired3; //!< st_retired3
- int32_t st_umtime; //!< st_umtime
- time_t st_retired4; //!< st_retired4
- int32_t st_uctime; //!< st_uctime
- int32_t st_retired5; //!< st_retired5
- int32_t st_retired6; //!< st_retired6
- uint32_t st_flags; //!< st_flags
- uint32_t st_gen; //!< st_gen
- uint64_t st_spare[4]; //!< st_spare[4]
- ino_t st_ino; //!< st_ino
- int32_t st_ino_reserved; //!< st_ino_reserved
- time_t st_atimeX; //!< st_atime
- int32_t st_atime_reserved; //!< st_atime_reserved
- time_t st_mtimeX; //!< st_mtime
- int32_t st_mtime_reserved; //!< st_mtime_reserved
- time_t st_ctimeX; //!< st_ctime
- int32_t st_ctime_reserved; //!< st_ctime_reserved
- uint64_t st_blksize; //!< st_blksize
- uint64_t st_blocks; //!< st_blocks
- };
-
-
- /// Old Tru64 v4.x stat struct.
- /// Tru64 maintains backwards compatibility with v4.x by
- /// implementing another set of stat functions using the old
- /// structure definition and binding them to the old syscall
- /// numbers.
- struct pre_F64_stat {
- dev_t st_dev;
- ino_t st_ino;
- mode_t st_mode;
- nlink_t st_nlink;
- uid_t st_uid;
- gid_t st_gid;
- dev_t st_rdev;
- off_t st_size;
- time_t st_atimeX;
- int32_t st_uatime;
- time_t st_mtimeX;
- int32_t st_umtime;
- time_t st_ctimeX;
- int32_t st_uctime;
- uint32_t st_blksize;
- int32_t st_blocks;
- uint32_t st_flags;
- uint32_t st_gen;
- };
-
- /// For statfs().
- struct F64_statfs {
- int16_t f_type;
- int16_t f_flags;
- int32_t f_retired1;
- int32_t f_retired2;
- int32_t f_retired3;
- int32_t f_retired4;
- int32_t f_retired5;
- int32_t f_retired6;
- int32_t f_retired7;
- fsid_t f_fsid;
- int32_t f_spare[9];
- char f_retired8[90];
- char f_retired9[90];
- uint64_t dummy[10]; // was union mount_info mount_info;
- uint64_t f_flags2;
- int64_t f_spare2[14];
- int64_t f_fsize;
- int64_t f_bsize;
- int64_t f_blocks;
- int64_t f_bfree;
- int64_t f_bavail;
- int64_t f_files;
- int64_t f_ffree;
- char f_mntonname[1024];
- char f_mntfromname[1024];
- };
-
- /// For old Tru64 v4.x statfs()
- struct pre_F64_statfs {
- int16_t f_type;
- int16_t f_flags;
- int32_t f_fsize;
- int32_t f_bsize;
- int32_t f_blocks;
- int32_t f_bfree;
- int32_t f_bavail;
- int32_t f_files;
- int32_t f_ffree;
- fsid_t f_fsid;
- int32_t f_spare[9];
- char f_mntonname[90];
- char f_mntfromname[90];
- uint64_t dummy[10]; // was union mount_info mount_info;
- };
-
- /// For getdirentries().
- struct dirent
- {
- ino_t d_ino; //!< file number of entry
- uint16_t d_reclen; //!< length of this record
- uint16_t d_namlen; //!< length of string in d_name
- char d_name[256]; //!< dummy name length
- };
-
-
- /// Length of strings in struct utsname (plus 1 for null char).
- static const int _SYS_NMLN = 32;
-
- /// Interface struct for uname().
- struct utsname {
- char sysname[_SYS_NMLN]; //!< System name.
- char nodename[_SYS_NMLN]; //!< Node name.
- char release[_SYS_NMLN]; //!< OS release.
- char version[_SYS_NMLN]; //!< OS version.
- char machine[_SYS_NMLN]; //!< Machine type.
- };
-
- //@{
- /// ioctl() command codes.
- static const unsigned TIOCGETP = 0x40067408;
- static const unsigned TIOCSETP = 0x80067409;
- static const unsigned TIOCSETN = 0x8006740a;
- static const unsigned TIOCSETC = 0x80067411;
- static const unsigned TIOCGETC = 0x40067412;
- static const unsigned FIONREAD = 0x4004667f;
- static const unsigned TIOCISATTY = 0x2000745e;
- // TIOCGETS not defined in tru64, so I made up a number
- static const unsigned TIOCGETS = 0x40000000;
- static const unsigned TIOCGETA = 0x402c7413;
- //@}
-
- /// Resource enumeration for getrlimit().
- enum rlimit_resources {
- TGT_RLIMIT_CPU = 0,
- TGT_RLIMIT_FSIZE = 1,
- TGT_RLIMIT_DATA = 2,
- TGT_RLIMIT_STACK = 3,
- TGT_RLIMIT_CORE = 4,
- TGT_RLIMIT_RSS = 5,
- TGT_RLIMIT_NOFILE = 6,
- TGT_RLIMIT_AS = 7,
- TGT_RLIMIT_VMEM = 7
- };
-
- /// Limit struct for getrlimit/setrlimit.
- struct rlimit {
- uint64_t rlim_cur; //!< soft limit
- uint64_t rlim_max; //!< hard limit
- };
-
-
- /// For mmap().
- static const unsigned TGT_MAP_ANONYMOUS = 0x10;
-
-
- //@{
- /// For getsysinfo().
- static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
- static const unsigned GSI_CPU_INFO = 59; //!< CPU information
- static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
- static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine
- static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
- static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
- static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
- //@}
-
- /// For getsysinfo() GSI_CPU_INFO option.
- struct cpu_info {
- uint32_t current_cpu; //!< current_cpu
- uint32_t cpus_in_box; //!< cpus_in_box
- uint32_t cpu_type; //!< cpu_type
- uint32_t ncpus; //!< ncpus
- uint64_t cpus_present; //!< cpus_present
- uint64_t cpus_running; //!< cpus_running
- uint64_t cpu_binding; //!< cpu_binding
- uint64_t cpu_ex_binding; //!< cpu_ex_binding
- uint32_t mhz; //!< mhz
- uint32_t unused[3]; //!< future expansion
- };
-
- //@{
- /// For setsysinfo().
- static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
- //@}
-
- /// For gettimeofday.
- struct timeval {
- uint32_t tv_sec; //!< seconds
- uint32_t tv_usec; //!< microseconds
- };
-
- //@{
- /// For getrusage().
- static const int TGT_RUSAGE_THREAD = 1;
- static const int TGT_RUSAGE_SELF = 0;
- static const int TGT_RUSAGE_CHILDREN = -1;
- //@}
-
- /// For getrusage().
- struct rusage {
- struct timeval ru_utime; //!< user time used
- struct timeval ru_stime; //!< system time used
- uint64_t ru_maxrss; //!< ru_maxrss
- uint64_t ru_ixrss; //!< integral shared memory size
- uint64_t ru_idrss; //!< integral unshared data "
- uint64_t ru_isrss; //!< integral unshared stack "
- uint64_t ru_minflt; //!< page reclaims - total vmfaults
- uint64_t ru_majflt; //!< page faults
- uint64_t ru_nswap; //!< swaps
- uint64_t ru_inblock; //!< block input operations
- uint64_t ru_oublock; //!< block output operations
- uint64_t ru_msgsnd; //!< messages sent
- uint64_t ru_msgrcv; //!< messages received
- uint64_t ru_nsignals; //!< signals received
- uint64_t ru_nvcsw; //!< voluntary context switches
- uint64_t ru_nivcsw; //!< involuntary "
- };
-
- /// For sigreturn().
- struct sigcontext {
- int64_t sc_onstack; //!< sigstack state to restore
- int64_t sc_mask; //!< signal mask to restore
- int64_t sc_pc; //!< pc at time of signal
- int64_t sc_ps; //!< psl to retore
- int64_t sc_regs[32]; //!< processor regs 0 to 31
- int64_t sc_ownedfp; //!< fp has been used
- int64_t sc_fpregs[32]; //!< fp regs 0 to 31
- uint64_t sc_fpcr; //!< floating point control reg
- uint64_t sc_fp_control; //!< software fpcr
- int64_t sc_reserved1; //!< reserved for kernel
- uint32_t sc_kreserved1; //!< reserved for kernel
- uint32_t sc_kreserved2; //!< reserved for kernel
- size_t sc_ssize; //!< stack size
- caddr_t sc_sbase; //!< stack start
- uint64_t sc_traparg_a0; //!< a0 argument to trap on exc
- uint64_t sc_traparg_a1; //!< a1 argument to trap on exc
- uint64_t sc_traparg_a2; //!< a2 argument to trap on exc
- uint64_t sc_fp_trap_pc; //!< imprecise pc
- uint64_t sc_fp_trigger_sum; //!< Exception summary at trigg
- uint64_t sc_fp_trigger_inst; //!< Instruction at trigger pc
- };
-
-
- /// For table().
- static const int TBL_SYSINFO = 12;
-
- /// For table().
- struct tbl_sysinfo {
- uint64_t si_user; //!< User time
- uint64_t si_nice; //!< Nice time
- uint64_t si_sys; //!< System time
- uint64_t si_idle; //!< Idle time
- uint64_t si_hz; //!< hz
- uint64_t si_phz; //!< phz
- uint64_t si_boottime; //!< Boot time in seconds
- uint64_t wait; //!< Wait time
- uint32_t si_max_procs; //!< rpb->rpb_numprocs
- uint32_t pad; //!< padding
- };
-
-
- /// For stack_create.
- struct vm_stack {
- // was void *
- Addr address; //!< address hint
- size_t rsize; //!< red zone size
- size_t ysize; //!< yellow zone size
- size_t gsize; //!< green zone size
- size_t swap; //!< amount of swap to reserve
- size_t incr; //!< growth increment
- uint64_t align; //!< address alignment
- uint64_t flags; //!< MAP_FIXED etc.
- // was struct memalloc_attr *
- Addr attr; //!< allocation policy
- uint64_t reserved; //!< reserved
- };
-
- /// Return values for nxm calls.
- enum {
- KERN_NOT_RECEIVER = 7,
- KERN_NOT_IN_SET = 12
- };
-
- /// For nxm_task_init.
- static const int NXM_TASK_INIT_VP = 2; //!< initial thread is VP
-
- /// Task attribute structure.
- struct nxm_task_attr {
- int64_t nxm_callback; //!< nxm_callback
- unsigned int nxm_version; //!< nxm_version
- unsigned short nxm_uniq_offset; //!< nxm_uniq_offset
- unsigned short flags; //!< flags
- int nxm_quantum; //!< nxm_quantum
- int pad1; //!< pad1
- int64_t pad2; //!< pad2
- };
-
- /// Signal set.
- typedef uint64_t sigset_t;
-
- /// Thread state shared between user & kernel.
- struct ushared_state {
- sigset_t sigmask; //!< thread signal mask
- sigset_t sig; //!< thread pending mask
- // struct nxm_pth_state *
- Addr pth_id; //!< out-of-line state
- int flags; //!< shared flags
-#define US_SIGSTACK 0x1 // thread called sigaltstack
-#define US_ONSTACK 0x2 // thread is running on altstack
-#define US_PROFILE 0x4 // thread called profil
-#define US_SYSCALL 0x8 // thread in syscall
-#define US_TRAP 0x10 // thread has trapped
-#define US_YELLOW 0x20 // thread has mellowed yellow
-#define US_YZONE 0x40 // thread has zoned out
-#define US_FP_OWNED 0x80 // thread used floating point
-
- int cancel_state; //!< thread's cancelation state
-#define US_CANCEL 0x1 // cancel pending
-#define US_NOCANCEL 0X2 // synch cancel disabled
-#define US_SYS_NOCANCEL 0x4 // syscall cancel disabled
-#define US_ASYNC_NOCANCEL 0x8 // asynch cancel disabled
-#define US_CANCEL_BITS (US_NOCANCEL|US_SYS_NOCANCEL|US_ASYNC_NOCANCEL)
-#define US_CANCEL_MASK (US_CANCEL|US_NOCANCEL|US_SYS_NOCANCEL| \
- US_ASYNC_NOCANCEL)
-
- // These are semi-shared. They are always visible to
- // the kernel but are never context-switched by the library.
-
- int nxm_ssig; //!< scheduler's synchronous signals
- int reserved1; //!< reserved1
- int64_t nxm_active; //!< scheduler active
- int64_t reserved2; //!< reserved2
- };
-
- struct nxm_sched_state {
- struct ushared_state nxm_u; //!< state own by user thread
- unsigned int nxm_bits; //!< scheduler state / slot
- int nxm_quantum; //!< quantum count-down value
- int nxm_set_quantum; //!< quantum reset value
- int nxm_sysevent; //!< syscall state
- // struct nxm_upcall *
- Addr nxm_uc_ret; //!< stack ptr of null thread
- // void *
- Addr nxm_tid; //!< scheduler's thread id
- int64_t nxm_va; //!< page fault address
- // struct nxm_pth_state *
- Addr nxm_pthid; //!< id of null thread
- uint64_t nxm_bound_pcs_count; //!< bound PCS thread count
- int64_t pad[2]; //!< pad
- };
-
- /// nxm_shared.
- struct nxm_shared {
- int64_t nxm_callback; //!< address of upcall routine
- unsigned int nxm_version; //!< version number
- unsigned short nxm_uniq_offset; //!< correction factor for TEB
- unsigned short pad1; //!< pad1
- int64_t space[2]; //!< future growth
- struct nxm_sched_state nxm_ss[1]; //!< array of shared areas
- };
-
- /// nxm_slot_state_t.
- enum nxm_slot_state_t {
- NXM_SLOT_AVAIL,
- NXM_SLOT_BOUND,
- NXM_SLOT_UNBOUND,
- NXM_SLOT_EMPTY
- };
-
- /// nxm_config_info
- struct nxm_config_info {
- int nxm_nslots_per_rad; //!< max number of VP slots per RAD
- int nxm_nrads; //!< max number of RADs
- // nxm_slot_state_t *
- Addr nxm_slot_state; //!< per-VP slot state
- // struct nxm_shared *
- Addr nxm_rad[1]; //!< per-RAD shared areas
- };
-
- /// For nxm_thread_create.
- enum nxm_thread_type {
- NXM_TYPE_SCS = 0,
- NXM_TYPE_VP = 1,
- NXM_TYPE_MANAGER = 2
- };
-
- /// Thread attributes.
- struct nxm_thread_attr {
- int version; //!< version
- int type; //!< type
- int cancel_flags; //!< cancel_flags
- int priority; //!< priority
- int policy; //!< policy
- int signal_type; //!< signal_type
- // void *
- Addr pthid; //!< pthid
- sigset_t sigmask; //!< sigmask
- /// Initial register values.
- struct {
- uint64_t pc; //!< pc
- uint64_t sp; //!< sp
- uint64_t a0; //!< a0
- } registers;
- uint64_t pad2[2]; //!< pad2
- };
-
- /// Helper function to convert a host stat buffer to a target stat
- /// buffer. Also copies the target buffer out to the simulated
- /// memory space. Used by stat(), fstat(), and lstat().
- template <class T>
- static void
- copyOutStatBuf(FunctionalMemory *mem, Addr addr, global_stat *host)
- {
- TypedBufferArg<T> tgt(addr);
-
- tgt->st_dev = htog(host->st_dev);
- tgt->st_ino = htog(host->st_ino);
- tgt->st_mode = htog(host->st_mode);
- tgt->st_nlink = htog(host->st_nlink);
- tgt->st_uid = htog(host->st_uid);
- tgt->st_gid = htog(host->st_gid);
- tgt->st_rdev = htog(host->st_rdev);
- tgt->st_size = htog(host->st_size);
- tgt->st_atimeX = htog(host->st_atime);
- tgt->st_mtimeX = htog(host->st_mtime);
- tgt->st_ctimeX = htog(host->st_ctime);
- tgt->st_blksize = htog(host->st_blksize);
- tgt->st_blocks = htog(host->st_blocks);
-
- tgt.copyOut(mem);
- }
-
- /// Helper function to convert a host statfs buffer to a target statfs
- /// buffer. Also copies the target buffer out to the simulated
- /// memory space. Used by statfs() and fstatfs().
- template <class T>
- static void
- copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, global_statfs *host)
- {
- TypedBufferArg<T> tgt(addr);
-
-#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__)
- tgt->f_type = 0;
-#else
- tgt->f_type = htog(host->f_type);
-#endif
- tgt->f_bsize = htog(host->f_bsize);
- tgt->f_blocks = htog(host->f_blocks);
- tgt->f_bfree = htog(host->f_bfree);
- tgt->f_bavail = htog(host->f_bavail);
- tgt->f_files = htog(host->f_files);
- tgt->f_ffree = htog(host->f_ffree);
-
- // Is this as string normally?
- memcpy(&tgt->f_fsid, &host->f_fsid, sizeof(host->f_fsid));
-
- tgt.copyOut(mem);
- }
-
- class F64 {
- public:
- static void copyOutStatBuf(FunctionalMemory *mem, Addr addr,
- global_stat *host)
- {
- Tru64::copyOutStatBuf<Tru64::F64_stat>(mem, addr, host);
- }
-
- static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr,
- global_statfs *host)
- {
- Tru64::copyOutStatfsBuf<Tru64::F64_statfs>(mem, addr, host);
- }
- };
-
- class PreF64 {
- public:
- static void copyOutStatBuf(FunctionalMemory *mem, Addr addr,
- global_stat *host)
- {
- Tru64::copyOutStatBuf<Tru64::pre_F64_stat>(mem, addr, host);
- }
-
- static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr,
- global_statfs *host)
- {
- Tru64::copyOutStatfsBuf<Tru64::pre_F64_statfs>(mem, addr, host);
- }
- };
-
- /// Helper function to convert a host stat buffer to an old pre-F64
- /// (4.x) target stat buffer. Also copies the target buffer out to
- /// the simulated memory space. Used by pre_F64_stat(),
- /// pre_F64_fstat(), and pre_F64_lstat().
- static void
- copyOutPreF64StatBuf(FunctionalMemory *mem, Addr addr, struct stat *host)
- {
- TypedBufferArg<Tru64::pre_F64_stat> tgt(addr);
-
- tgt->st_dev = htog(host->st_dev);
- tgt->st_ino = htog(host->st_ino);
- tgt->st_mode = htog(host->st_mode);
- tgt->st_nlink = htog(host->st_nlink);
- tgt->st_uid = htog(host->st_uid);
- tgt->st_gid = htog(host->st_gid);
- tgt->st_rdev = htog(host->st_rdev);
- tgt->st_size = htog(host->st_size);
- tgt->st_atimeX = htog(host->st_atime);
- tgt->st_mtimeX = htog(host->st_mtime);
- tgt->st_ctimeX = htog(host->st_ctime);
- tgt->st_blksize = htog(host->st_blksize);
- tgt->st_blocks = htog(host->st_blocks);
-
- tgt.copyOut(mem);
- }
-
-
- /// The target system's hostname.
- static const char *hostname;
-
- /// Target uname() handler.
- static SyscallReturn
- unameFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- TypedBufferArg<Tru64::utsname> name(xc->getSyscallArg(0));
-
- strcpy(name->sysname, "OSF1");
- strcpy(name->nodename, hostname);
- strcpy(name->release, "V5.1");
- strcpy(name->version, "732");
- strcpy(name->machine, "alpha");
-
- name.copyOut(xc->mem);
- return 0;
- }
-
-
- /// Target getsysyinfo() handler.
- static SyscallReturn
- getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- unsigned op = xc->getSyscallArg(0);
- unsigned nbytes = xc->getSyscallArg(2);
-
- switch (op) {
-
- case Tru64::GSI_MAX_CPU: {
- TypedBufferArg<uint32_t> max_cpu(xc->getSyscallArg(1));
- *max_cpu = htog((uint32_t)process->numCpus());
- max_cpu.copyOut(xc->mem);
- return 1;
- }
-
- case Tru64::GSI_CPUS_IN_BOX: {
- TypedBufferArg<uint32_t> cpus_in_box(xc->getSyscallArg(1));
- *cpus_in_box = htog((uint32_t)process->numCpus());
- cpus_in_box.copyOut(xc->mem);
- return 1;
- }
-
- case Tru64::GSI_PHYSMEM: {
- TypedBufferArg<uint64_t> physmem(xc->getSyscallArg(1));
- *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
- physmem.copyOut(xc->mem);
- return 1;
- }
-
- case Tru64::GSI_CPU_INFO: {
- TypedBufferArg<Tru64::cpu_info> infop(xc->getSyscallArg(1));
-
- infop->current_cpu = htog(0);
- infop->cpus_in_box = htog(process->numCpus());
- infop->cpu_type = htog(57);
- infop->ncpus = htog(process->numCpus());
- uint64_t cpumask = (1 << process->numCpus()) - 1;
- infop->cpus_present = infop->cpus_running = htog(cpumask);
- infop->cpu_binding = htog(0);
- infop->cpu_ex_binding = htog(0);
- infop->mhz = htog(667);
-
- infop.copyOut(xc->mem);
- return 1;
- }
-
- case Tru64::GSI_PROC_TYPE: {
- TypedBufferArg<uint64_t> proc_type(xc->getSyscallArg(1));
- *proc_type = htog((uint64_t)11);
- proc_type.copyOut(xc->mem);
- return 1;
- }
-
- case Tru64::GSI_PLATFORM_NAME: {
- BufferArg bufArg(xc->getSyscallArg(1), nbytes);
- strncpy((char *)bufArg.bufferPtr(),
- "COMPAQ Professional Workstation XP1000",
- nbytes);
- bufArg.copyOut(xc->mem);
- return 1;
- }
-
- case Tru64::GSI_CLK_TCK: {
- TypedBufferArg<uint64_t> clk_hz(xc->getSyscallArg(1));
- *clk_hz = htog((uint64_t)1024);
- clk_hz.copyOut(xc->mem);
- return 1;
- }
-
- default:
- warn("getsysinfo: unknown op %d\n", op);
- break;
- }
-
- return 0;
- }
-
- /// Target setsysyinfo() handler.
- static SyscallReturn
- setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- unsigned op = xc->getSyscallArg(0);
-
- switch (op) {
- case SSI_IEEE_FP_CONTROL:
- warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n",
- xc->getSyscallArg(1));
- break;
-
- default:
- warn("setsysinfo: unknown op %d\n", op);
- break;
- }
-
- return 0;
- }
-
- /// Target fnctl() handler.
- static SyscallReturn
- fcntlFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- int fd = xc->getSyscallArg(0);
-
- if (fd < 0 || process->sim_fd(fd) < 0)
- return -EBADF;
-
- int cmd = xc->getSyscallArg(1);
- switch (cmd) {
- case 0: // F_DUPFD
- // if we really wanted to support this, we'd need to do it
- // in the target fd space.
- warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd);
- return -EMFILE;
-
- case 1: // F_GETFD (get close-on-exec flag)
- case 2: // F_SETFD (set close-on-exec flag)
- return 0;
-
- case 3: // F_GETFL (get file flags)
- case 4: // F_SETFL (set file flags)
- // not sure if this is totally valid, but we'll pass it through
- // to the underlying OS
- warn("fcntl(%d, %d) passed through to host\n", fd, cmd);
- return fcntl(process->sim_fd(fd), cmd);
- // return 0;
-
- case 7: // F_GETLK (get lock)
- case 8: // F_SETLK (set lock)
- case 9: // F_SETLKW (set lock and wait)
- // don't mess with file locking... just act like it's OK
- warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd);
- return 0;
-
- default:
- warn("Unknown fcntl command %d\n", cmd);
- return 0;
- }
- }
-
-
- /// Target getdirentries() handler.
- static SyscallReturn
- getdirentriesFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
-#ifdef __CYGWIN__
- panic("getdirent not implemented on cygwin!");
-#else
- int fd = process->sim_fd(xc->getSyscallArg(0));
- Addr tgt_buf = xc->getSyscallArg(1);
- int tgt_nbytes = xc->getSyscallArg(2);
- Addr tgt_basep = xc->getSyscallArg(3);
-
- char * const host_buf = new char[tgt_nbytes];
-
- // just pass basep through uninterpreted.
- TypedBufferArg<int64_t> basep(tgt_basep);
- basep.copyIn(xc->mem);
- long host_basep = (off_t)htog((int64_t)*basep);
- int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep);
-
- // check for error
- if (host_result < 0) {
- delete [] host_buf;
- return -errno;
- }
-
- // no error: copy results back to target space
- Addr tgt_buf_ptr = tgt_buf;
- char *host_buf_ptr = host_buf;
- char *host_buf_end = host_buf + host_result;
- while (host_buf_ptr < host_buf_end) {
- global_dirent *host_dp = (global_dirent *)host_buf_ptr;
- int namelen = strlen(host_dp->d_name);
-
- // Actual size includes padded string rounded up for alignment.
- // Subtract 256 for dummy char array in Tru64::dirent definition.
- // Add 1 to namelen for terminating null char.
- int tgt_bufsize = sizeof(Tru64::dirent) - 256 + roundUp(namelen+1, 8);
- TypedBufferArg<Tru64::dirent> tgt_dp(tgt_buf_ptr, tgt_bufsize);
- tgt_dp->d_ino = host_dp->d_ino;
- tgt_dp->d_reclen = tgt_bufsize;
- tgt_dp->d_namlen = namelen;
- strcpy(tgt_dp->d_name, host_dp->d_name);
- tgt_dp.copyOut(xc->mem);
-
- tgt_buf_ptr += tgt_bufsize;
- host_buf_ptr += host_dp->d_reclen;
- }
-
- delete [] host_buf;
-
- *basep = htog((int64_t)host_basep);
- basep.copyOut(xc->mem);
-
- return tgt_buf_ptr - tgt_buf;
-#endif
- }
-
- /// Target sigreturn() handler.
- static SyscallReturn
- sigreturnFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- RegFile *regs = &xc->regs;
- TypedBufferArg<Tru64::sigcontext> sc(xc->getSyscallArg(0));
-
- sc.copyIn(xc->mem);
-
- // Restore state from sigcontext structure.
- // Note that we'll advance PC <- NPC before the end of the cycle,
- // so we need to restore the desired PC into NPC.
- // The current regs->pc will get clobbered.
- regs->npc = htog(sc->sc_pc);
-
- for (int i = 0; i < 31; ++i) {
- regs->intRegFile[i] = htog(sc->sc_regs[i]);
- regs->floatRegFile.q[i] = htog(sc->sc_fpregs[i]);
- }
-
- regs->miscRegs.fpcr = htog(sc->sc_fpcr);
-
- return 0;
- }
-
- /// Target table() handler.
- static SyscallReturn
- tableFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- int id = xc->getSyscallArg(0); // table ID
- int index = xc->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
-
- switch (id) {
- case Tru64::TBL_SYSINFO: {
- if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
- return -EINVAL;
- TypedBufferArg<Tru64::tbl_sysinfo> elp(xc->getSyscallArg(2));
-
- const int clk_hz = one_million;
- elp->si_user = htog(curTick / (Clock::Frequency / clk_hz));
- elp->si_nice = htog(0);
- elp->si_sys = htog(0);
- elp->si_idle = htog(0);
- elp->wait = htog(0);
- elp->si_hz = htog(clk_hz);
- 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->mem);
- return 0;
- }
-
- default:
- cerr << "table(): id " << id << " unknown." << endl;
- return -EINVAL;
- }
- }
-
- /// Array of syscall descriptors, indexed by call number.
- static SyscallDesc syscallDescs[];
-
- /// Number of syscalls in syscallDescs[].
- static const int Num_Syscall_Descs;
-
- /// Max supported syscall number.
- static const int Max_Syscall_Desc;
-
- //
- // Mach syscalls -- identified by negated syscall numbers
- //
-
- /// Create a stack region for a thread.
- static SyscallReturn
- stack_createFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- TypedBufferArg<Tru64::vm_stack> argp(xc->getSyscallArg(0));
-
- argp.copyIn(xc->mem);
-
- // if the user chose an address, just let them have it. Otherwise
- // pick one for them.
- if (htog(argp->address) == 0) {
- argp->address = htog(process->next_thread_stack_base);
- int stack_size = (htog(argp->rsize) + htog(argp->ysize) +
- htog(argp->gsize));
- process->next_thread_stack_base -= stack_size;
- argp.copyOut(xc->mem);
- }
-
- return 0;
- }
-
- /// NXM library version stamp.
- static
- const int NXM_LIB_VERSION = 301003;
-
- /// This call sets up the interface between the user and kernel
- /// schedulers by creating a shared-memory region. The shared memory
- /// region has several structs, some global, some per-RAD, some per-VP.
- static SyscallReturn
- nxm_task_initFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- TypedBufferArg<Tru64::nxm_task_attr> attrp(xc->getSyscallArg(0));
- TypedBufferArg<Addr> configptr_ptr(xc->getSyscallArg(1));
-
- attrp.copyIn(xc->mem);
-
- if (gtoh(attrp->nxm_version) != NXM_LIB_VERSION) {
- cerr << "nxm_task_init: thread library version mismatch! "
- << "got " << attrp->nxm_version
- << ", expected " << NXM_LIB_VERSION << endl;
- abort();
- }
-
- if (gtoh(attrp->flags) != Tru64::NXM_TASK_INIT_VP) {
- cerr << "nxm_task_init: bad flag value " << attrp->flags
- << " (expected " << Tru64::NXM_TASK_INIT_VP << ")" << endl;
- abort();
- }
-
- const Addr base_addr = 0x12000; // was 0x3f0000000LL;
- Addr cur_addr = base_addr; // next addresses to use
- // first comes the config_info struct
- Addr config_addr = cur_addr;
- cur_addr += sizeof(Tru64::nxm_config_info);
- // next comes the per-cpu state vector
- Addr slot_state_addr = cur_addr;
- int slot_state_size =
- process->numCpus() * sizeof(Tru64::nxm_slot_state_t);
- cur_addr += slot_state_size;
- // now the per-RAD state struct (we only support one RAD)
- cur_addr = 0x14000; // bump up addr for alignment
- Addr rad_state_addr = cur_addr;
- int rad_state_size =
- (sizeof(Tru64::nxm_shared)
- + (process->numCpus()-1) * sizeof(Tru64::nxm_sched_state));
- cur_addr += rad_state_size;
-
- // now initialize a config_info struct and copy it out to user space
- TypedBufferArg<Tru64::nxm_config_info> config(config_addr);
-
- config->nxm_nslots_per_rad = htog(process->numCpus());
- config->nxm_nrads = htog(1); // only one RAD in our system!
- config->nxm_slot_state = htog(slot_state_addr);
- config->nxm_rad[0] = htog(rad_state_addr);
-
- config.copyOut(xc->mem);
-
- // initialize the slot_state array and copy it out
- TypedBufferArg<Tru64::nxm_slot_state_t> slot_state(slot_state_addr,
- slot_state_size);
- for (int i = 0; i < process->numCpus(); ++i) {
- // CPU 0 is bound to the calling process; all others are available
- // XXX this code should have an endian conversion, but I don't think
- // it works anyway
- slot_state[i] =
- (i == 0) ? Tru64::NXM_SLOT_BOUND : Tru64::NXM_SLOT_AVAIL;
- }
-
- slot_state.copyOut(xc->mem);
-
- // same for the per-RAD "shared" struct. Note that we need to
- // allocate extra bytes for the per-VP array which is embedded at
- // the end.
- TypedBufferArg<Tru64::nxm_shared> rad_state(rad_state_addr,
- rad_state_size);
-
- rad_state->nxm_callback = attrp->nxm_callback;
- rad_state->nxm_version = attrp->nxm_version;
- rad_state->nxm_uniq_offset = attrp->nxm_uniq_offset;
- for (int i = 0; i < process->numCpus(); ++i) {
- Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[i];
- ssp->nxm_u.sigmask = htog(0);
- ssp->nxm_u.sig = htog(0);
- ssp->nxm_u.flags = htog(0);
- ssp->nxm_u.cancel_state = htog(0);
- ssp->nxm_u.nxm_ssig = 0;
- ssp->nxm_bits = htog(0);
- ssp->nxm_quantum = attrp->nxm_quantum;
- ssp->nxm_set_quantum = attrp->nxm_quantum;
- ssp->nxm_sysevent = htog(0);
-
- if (i == 0) {
- uint64_t uniq = xc->regs.miscRegs.uniq;
- ssp->nxm_u.pth_id = htog(uniq + gtoh(attrp->nxm_uniq_offset));
- ssp->nxm_u.nxm_active = htog(uniq | 1);
- }
- else {
- ssp->nxm_u.pth_id = htog(0);
- ssp->nxm_u.nxm_active = htog(0);
- }
- }
-
- rad_state.copyOut(xc->mem);
-
- //
- // copy pointer to shared config area out to user
- //
- *configptr_ptr = htog(config_addr);
- configptr_ptr.copyOut(xc->mem);
-
- // Register this as a valid address range with the process
- process->nxm_start = base_addr;
- process->nxm_end = cur_addr;
-
- return 0;
- }
-
- /// Initialize execution context.
- static void
- init_exec_context(ExecContext *ec,
- Tru64::nxm_thread_attr *attrp, uint64_t uniq_val)
- {
- memset(&ec->regs, 0, sizeof(ec->regs));
-
- ec->regs.intRegFile[ArgumentReg0] = gtoh(attrp->registers.a0);
- ec->regs.intRegFile[27/*t12*/] = gtoh(attrp->registers.pc);
- ec->regs.intRegFile[StackPointerReg] = gtoh(attrp->registers.sp);
- ec->regs.miscRegs.uniq = uniq_val;
-
- ec->regs.pc = gtoh(attrp->registers.pc);
- ec->regs.npc = gtoh(attrp->registers.pc) + sizeof(MachInst);
-
- ec->activate();
- }
-
- /// Create thread.
- static SyscallReturn
- nxm_thread_createFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- TypedBufferArg<Tru64::nxm_thread_attr> attrp(xc->getSyscallArg(0));
- TypedBufferArg<uint64_t> kidp(xc->getSyscallArg(1));
- int thread_index = xc->getSyscallArg(2);
-
- // get attribute args
- attrp.copyIn(xc->mem);
-
- if (gtoh(attrp->version) != NXM_LIB_VERSION) {
- cerr << "nxm_thread_create: thread library version mismatch! "
- << "got " << attrp->version
- << ", expected " << NXM_LIB_VERSION << endl;
- abort();
- }
-
- if (thread_index < 0 | thread_index > process->numCpus()) {
- cerr << "nxm_thread_create: bad thread index " << thread_index
- << endl;
- abort();
- }
-
- // On a real machine, the per-RAD shared structure is in
- // shared memory, so both the user and kernel can get at it.
- // We don't have that luxury, so we just copy it in and then
- // back out again.
- int rad_state_size =
- (sizeof(Tru64::nxm_shared) +
- (process->numCpus()-1) * sizeof(Tru64::nxm_sched_state));
-
- TypedBufferArg<Tru64::nxm_shared> rad_state(0x14000,
- rad_state_size);
- rad_state.copyIn(xc->mem);
-
- uint64_t uniq_val = gtoh(attrp->pthid) - gtoh(rad_state->nxm_uniq_offset);
-
- if (gtoh(attrp->type) == Tru64::NXM_TYPE_MANAGER) {
- // DEC pthreads seems to always create one of these (in
- // addition to N application threads), but we don't use it,
- // so don't bother creating it.
-
- // This is supposed to be a port number. Make something up.
- *kidp = htog(99);
- kidp.copyOut(xc->mem);
-
- return 0;
- } else if (gtoh(attrp->type) == Tru64::NXM_TYPE_VP) {
- // A real "virtual processor" kernel thread. Need to fork
- // this thread on another CPU.
- Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[thread_index];
-
- if (gtoh(ssp->nxm_u.nxm_active) != 0)
- return (int) Tru64::KERN_NOT_RECEIVER;
-
- ssp->nxm_u.pth_id = attrp->pthid;
- ssp->nxm_u.nxm_active = htog(uniq_val | 1);
-
- rad_state.copyOut(xc->mem);
-
- Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info);
- int slot_state_size =
- process->numCpus() * sizeof(Tru64::nxm_slot_state_t);
-
- TypedBufferArg<Tru64::nxm_slot_state_t>
- slot_state(slot_state_addr,
- slot_state_size);
-
- slot_state.copyIn(xc->mem);
-
- if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) {
- cerr << "nxm_thread_createFunc: requested VP slot "
- << thread_index << " not available!" << endl;
- fatal("");
- }
-
- // XXX This should have an endian conversion but I think this code
- // doesn't work anyway
- slot_state[thread_index] = Tru64::NXM_SLOT_BOUND;
-
- slot_state.copyOut(xc->mem);
-
- // Find a free simulator execution context.
- for (int i = 0; i < process->numCpus(); ++i) {
- ExecContext *xc = process->execContexts[i];
-
- if (xc->status() == ExecContext::Unallocated) {
- // inactive context... grab it
- init_exec_context(xc, attrp, uniq_val);
-
- // This is supposed to be a port number, but we'll try
- // and get away with just sticking the thread index
- // here.
- *kidp = htog(thread_index);
- kidp.copyOut(xc->mem);
-
- return 0;
- }
- }
-
- // fell out of loop... no available inactive context
- cerr << "nxm_thread_create: no idle contexts available." << endl;
- abort();
- } else {
- cerr << "nxm_thread_create: can't handle thread type "
- << attrp->type << endl;
- abort();
- }
-
- return 0;
- }
-
- /// Thread idle call (like yield()).
- static SyscallReturn
- nxm_idleFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- return 0;
- }
-
- /// Block thread.
- static SyscallReturn
- nxm_thread_blockFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- uint64_t tid = xc->getSyscallArg(0);
- uint64_t secs = xc->getSyscallArg(1);
- uint64_t flags = xc->getSyscallArg(2);
- uint64_t action = xc->getSyscallArg(3);
- uint64_t usecs = xc->getSyscallArg(4);
-
- cout << xc->cpu->name() << ": nxm_thread_block " << tid << " " << secs
- << " " << flags << " " << action << " " << usecs << endl;
-
- return 0;
- }
-
- /// block.
- static SyscallReturn
- nxm_blockFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- Addr uaddr = xc->getSyscallArg(0);
- uint64_t val = xc->getSyscallArg(1);
- uint64_t secs = xc->getSyscallArg(2);
- uint64_t usecs = xc->getSyscallArg(3);
- uint64_t flags = xc->getSyscallArg(4);
-
- BaseCPU *cpu = xc->cpu;
-
- cout << cpu->name() << ": nxm_block "
- << hex << uaddr << dec << " " << val
- << " " << secs << " " << usecs
- << " " << flags << endl;
-
- return 0;
- }
-
- /// Unblock thread.
- static SyscallReturn
- nxm_unblockFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- Addr uaddr = xc->getSyscallArg(0);
-
- cout << xc->cpu->name() << ": nxm_unblock "
- << hex << uaddr << dec << endl;
-
- return 0;
- }
-
- /// Switch thread priority.
- static SyscallReturn
- swtch_priFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- // Attempts to switch to another runnable thread (if there is
- // one). Returns false if there are no other threads to run
- // (i.e., the thread can reasonably spin-wait) or true if there
- // are other threads.
- //
- // Since we assume at most one "kernel" thread per CPU, it's
- // always safe to return false here.
- return 0; //false;
- }
-
-
- /// Activate exec context waiting on a channel. Just activate one
- /// by default.
- static int
- activate_waiting_context(Addr uaddr, Process *process,
- bool activate_all = false)
- {
- int num_activated = 0;
-
- list<Process::WaitRec>::iterator i = process->waitList.begin();
- list<Process::WaitRec>::iterator end = process->waitList.end();
-
- while (i != end && (num_activated == 0 || activate_all)) {
- if (i->waitChan == uaddr) {
- // found waiting process: make it active
- ExecContext *newCtx = i->waitingContext;
- assert(newCtx->status() == ExecContext::Suspended);
- newCtx->activate();
-
- // get rid of this record
- i = process->waitList.erase(i);
-
- ++num_activated;
- } else {
- ++i;
- }
- }
-
- return num_activated;
- }
-
- /// M5 hacked-up lock acquire.
- static void
- m5_lock_mutex(Addr uaddr, Process *process, ExecContext *xc)
- {
- TypedBufferArg<uint64_t> lockp(uaddr);
-
- lockp.copyIn(xc->mem);
-
- if (gtoh(*lockp) == 0) {
- // lock is free: grab it
- *lockp = htog(1);
- lockp.copyOut(xc->mem);
- } else {
- // lock is busy: disable until free
- process->waitList.push_back(Process::WaitRec(uaddr, xc));
- xc->suspend();
- }
- }
-
- /// M5 unlock call.
- static void
- m5_unlock_mutex(Addr uaddr, Process *process, ExecContext *xc)
- {
- TypedBufferArg<uint64_t> lockp(uaddr);
-
- lockp.copyIn(xc->mem);
- assert(*lockp != 0);
-
- // Check for a process waiting on the lock.
- int num_waiting = activate_waiting_context(uaddr, process);
-
- // clear lock field if no waiting context is taking over the lock
- if (num_waiting == 0) {
- *lockp = 0;
- lockp.copyOut(xc->mem);
- }
- }
-
- /// Lock acquire syscall handler.
- static SyscallReturn
- m5_mutex_lockFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- Addr uaddr = xc->getSyscallArg(0);
-
- m5_lock_mutex(uaddr, process, xc);
-
- // Return 0 since we will always return to the user with the lock
- // acquired. We will just keep the context inactive until that is
- // true.
- return 0;
- }
-
- /// Try lock (non-blocking).
- static SyscallReturn
- m5_mutex_trylockFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- Addr uaddr = xc->getSyscallArg(0);
- TypedBufferArg<uint64_t> lockp(uaddr);
-
- lockp.copyIn(xc->mem);
-
- if (gtoh(*lockp) == 0) {
- // lock is free: grab it
- *lockp = htog(1);
- lockp.copyOut(xc->mem);
- return 0;
- } else {
- return 1;
- }
- }
-
- /// Unlock syscall handler.
- static SyscallReturn
- m5_mutex_unlockFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- Addr uaddr = xc->getSyscallArg(0);
-
- m5_unlock_mutex(uaddr, process, xc);
-
- return 0;
- }
-
- /// Signal ocndition.
- static SyscallReturn
- m5_cond_signalFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- Addr cond_addr = xc->getSyscallArg(0);
-
- // Wake up one process waiting on the condition variable.
- activate_waiting_context(cond_addr, process);
-
- return 0;
- }
-
- /// Wake up all processes waiting on the condition variable.
- static SyscallReturn
- m5_cond_broadcastFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- Addr cond_addr = xc->getSyscallArg(0);
-
- activate_waiting_context(cond_addr, process, true);
-
- return 0;
- }
-
- /// Wait on a condition.
- static SyscallReturn
- m5_cond_waitFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- Addr cond_addr = xc->getSyscallArg(0);
- Addr lock_addr = xc->getSyscallArg(1);
- TypedBufferArg<uint64_t> condp(cond_addr);
- TypedBufferArg<uint64_t> lockp(lock_addr);
-
- // user is supposed to acquire lock before entering
- lockp.copyIn(xc->mem);
- assert(gtoh(*lockp) != 0);
-
- m5_unlock_mutex(lock_addr, process, xc);
-
- process->waitList.push_back(Process::WaitRec(cond_addr, xc));
- xc->suspend();
-
- return 0;
- }
-
- /// Thread exit.
- static SyscallReturn
- m5_thread_exitFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- assert(xc->status() == ExecContext::Active);
- xc->deallocate();
-
- return 0;
- }
-
- /// Array of syscall descriptors for Mach syscalls, indexed by
- /// (negated) call number.
- static SyscallDesc machSyscallDescs[];
-
- /// Number of syscalls in machSyscallDescs[].
- static const int Num_Mach_Syscall_Descs;
-
- /// Max supported Mach syscall number.
- static const int Max_Mach_Syscall_Desc;
-
- /// Since negated values are used to identify Mach syscalls, the
- /// minimum (signed) valid syscall number is the negated max Mach
- /// syscall number.
- static const int Min_Syscall_Desc;
+/// Target uname() handler.
+static SyscallReturn
+unameFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+{
+ TypedBufferArg<Tru64::utsname> name(xc->getSyscallArg(0));
- /// Do the specified syscall. Just looks the call number up in
- /// the table and invokes the appropriate handler.
- static void
- doSyscall(int callnum, Process *process, ExecContext *xc)
- {
- if (callnum < Min_Syscall_Desc || callnum > Max_Syscall_Desc) {
- fatal("Syscall %d out of range\n", callnum);
- }
+ strcpy(name->sysname, "OSF1");
+ strcpy(name->nodename, "m5.eecs.umich.edu");
+ strcpy(name->release, "V5.1");
+ strcpy(name->version, "732");
+ strcpy(name->machine, "alpha");
- SyscallDesc *desc =
- (callnum < 0) ?
- &machSyscallDescs[-callnum] : &syscallDescs[callnum];
+ name.copyOut(xc->mem);
+ return 0;
+}
- desc->doSyscall(callnum, process, xc);
+/// Target getsysyinfo() handler.
+static SyscallReturn
+getsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+{
+ unsigned op = xc->getSyscallArg(0);
+ unsigned nbytes = xc->getSyscallArg(2);
+
+ switch (op) {
+
+ case Tru64::GSI_MAX_CPU: {
+ TypedBufferArg<uint32_t> max_cpu(xc->getSyscallArg(1));
+ *max_cpu = htog((uint32_t)process->numCpus());
+ max_cpu.copyOut(xc->mem);
+ return 1;
+ }
+
+ case Tru64::GSI_CPUS_IN_BOX: {
+ TypedBufferArg<uint32_t> cpus_in_box(xc->getSyscallArg(1));
+ *cpus_in_box = htog((uint32_t)process->numCpus());
+ cpus_in_box.copyOut(xc->mem);
+ return 1;
+ }
+
+ case Tru64::GSI_PHYSMEM: {
+ TypedBufferArg<uint64_t> physmem(xc->getSyscallArg(1));
+ *physmem = htog((uint64_t)1024 * 1024); // physical memory in KB
+ physmem.copyOut(xc->mem);
+ return 1;
+ }
+
+ case Tru64::GSI_CPU_INFO: {
+ TypedBufferArg<Tru64::cpu_info> infop(xc->getSyscallArg(1));
+
+ infop->current_cpu = htog(0);
+ infop->cpus_in_box = htog(process->numCpus());
+ infop->cpu_type = htog(57);
+ infop->ncpus = htog(process->numCpus());
+ uint64_t cpumask = (1 << process->numCpus()) - 1;
+ infop->cpus_present = infop->cpus_running = htog(cpumask);
+ infop->cpu_binding = htog(0);
+ infop->cpu_ex_binding = htog(0);
+ infop->mhz = htog(667);
+
+ infop.copyOut(xc->mem);
+ return 1;
+ }
+
+ case Tru64::GSI_PROC_TYPE: {
+ TypedBufferArg<uint64_t> proc_type(xc->getSyscallArg(1));
+ *proc_type = htog((uint64_t)11);
+ proc_type.copyOut(xc->mem);
+ return 1;
+ }
+
+ case Tru64::GSI_PLATFORM_NAME: {
+ BufferArg bufArg(xc->getSyscallArg(1), nbytes);
+ strncpy((char *)bufArg.bufferPtr(),
+ "COMPAQ Professional Workstation XP1000",
+ nbytes);
+ bufArg.copyOut(xc->mem);
+ return 1;
+ }
+
+ case Tru64::GSI_CLK_TCK: {
+ TypedBufferArg<uint64_t> clk_hz(xc->getSyscallArg(1));
+ *clk_hz = htog((uint64_t)1024);
+ clk_hz.copyOut(xc->mem);
+ return 1;
+ }
+
+ default:
+ warn("getsysinfo: unknown op %d\n", op);
+ break;
}
- /// Indirect syscall invocation (call #0).
- static SyscallReturn
- indirectSyscallFunc(SyscallDesc *desc, int callnum, Process *process,
- ExecContext *xc)
- {
- int new_callnum = xc->getSyscallArg(0);
+ return 0;
+}
- for (int i = 0; i < 5; ++i)
- xc->setSyscallArg(i, xc->getSyscallArg(i+1));
+/// Target setsysyinfo() handler.
+static SyscallReturn
+setsysinfoFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+{
+ unsigned op = xc->getSyscallArg(0);
- doSyscall(new_callnum, process, xc);
+ switch (op) {
+ case Tru64::SSI_IEEE_FP_CONTROL:
+ warn("setsysinfo: ignoring ieee_set_fp_control() arg 0x%x\n",
+ xc->getSyscallArg(1));
+ break;
- return 0;
+ default:
+ warn("setsysinfo: unknown op %d\n", op);
+ break;
}
-}; // class Tru64
-
-
-// open(2) flags translation table
-OpenFlagTransTable Tru64::openFlagTable[] = {
-#ifdef _MSC_VER
- { Tru64::TGT_O_RDONLY, _O_RDONLY },
- { Tru64::TGT_O_WRONLY, _O_WRONLY },
- { Tru64::TGT_O_RDWR, _O_RDWR },
- { Tru64::TGT_O_APPEND, _O_APPEND },
- { Tru64::TGT_O_CREAT, _O_CREAT },
- { Tru64::TGT_O_TRUNC, _O_TRUNC },
- { Tru64::TGT_O_EXCL, _O_EXCL },
-#ifdef _O_NONBLOCK
- { Tru64::TGT_O_NONBLOCK, _O_NONBLOCK },
-#endif
-#ifdef _O_NOCTTY
- { Tru64::TGT_O_NOCTTY, _O_NOCTTY },
-#endif
-#ifdef _O_SYNC
- { Tru64::TGT_O_SYNC, _O_SYNC },
-#endif
-#else /* !_MSC_VER */
- { Tru64::TGT_O_RDONLY, O_RDONLY },
- { Tru64::TGT_O_WRONLY, O_WRONLY },
- { Tru64::TGT_O_RDWR, O_RDWR },
- { Tru64::TGT_O_APPEND, O_APPEND },
- { Tru64::TGT_O_CREAT, O_CREAT },
- { Tru64::TGT_O_TRUNC, O_TRUNC },
- { Tru64::TGT_O_EXCL, O_EXCL },
- { Tru64::TGT_O_NONBLOCK, O_NONBLOCK },
- { Tru64::TGT_O_NOCTTY, O_NOCTTY },
-#ifdef O_SYNC
- { Tru64::TGT_O_SYNC, O_SYNC },
-#endif
-#endif /* _MSC_VER */
-};
-
-const int Tru64::NUM_OPEN_FLAGS = (sizeof(Tru64::openFlagTable)/sizeof(Tru64::openFlagTable[0]));
+ return 0;
+}
-const char *Tru64::hostname = "m5.eecs.umich.edu";
-SyscallDesc Tru64::syscallDescs[] = {
- /* 0 */ SyscallDesc("syscall (#0)", indirectSyscallFunc,
+SyscallDesc AlphaTru64Process::syscallDescs[] = {
+ /* 0 */ SyscallDesc("syscall (#0)", Tru64::indirectSyscallFunc,
SyscallDesc::SuppressReturnValue),
/* 1 */ SyscallDesc("exit", exitFunc),
/* 2 */ SyscallDesc("fork", unimplementedFunc),
@@ -1637,7 +244,7 @@ SyscallDesc Tru64::syscallDescs[] = {
/* 82 */ SyscallDesc("setpgrp", unimplementedFunc),
/* 83 */ SyscallDesc("setitimer", unimplementedFunc),
/* 84 */ SyscallDesc("old_wait", unimplementedFunc),
- /* 85 */ SyscallDesc("table", tableFunc),
+ /* 85 */ SyscallDesc("table", Tru64::tableFunc),
/* 86 */ SyscallDesc("getitimer", unimplementedFunc),
/* 87 */ SyscallDesc("gethostname", gethostnameFunc),
/* 88 */ SyscallDesc("sethostname", unimplementedFunc),
@@ -1655,7 +262,7 @@ SyscallDesc Tru64::syscallDescs[] = {
/* 100 */ SyscallDesc("getpriority", unimplementedFunc),
/* 101 */ SyscallDesc("old_send", unimplementedFunc),
/* 102 */ SyscallDesc("old_recv", unimplementedFunc),
- /* 103 */ SyscallDesc("sigreturn", sigreturnFunc,
+ /* 103 */ SyscallDesc("sigreturn", Tru64::sigreturnFunc,
SyscallDesc::SuppressReturnValue),
/* 104 */ SyscallDesc("bind", unimplementedFunc),
/* 105 */ SyscallDesc("setsockopt", unimplementedFunc),
@@ -1712,7 +319,7 @@ SyscallDesc Tru64::syscallDescs[] = {
/* 156 */ SyscallDesc("sigaction", ignoreFunc),
/* 157 */ SyscallDesc("sigwaitprim", unimplementedFunc),
/* 158 */ SyscallDesc("nfssvc", unimplementedFunc),
- /* 159 */ SyscallDesc("getdirentries", getdirentriesFunc),
+ /* 159 */ SyscallDesc("getdirentries", Tru64::getdirentriesFunc),
/* 160 */ SyscallDesc("pre_F64_statfs", statfsFunc<Tru64::PreF64>),
/* 161 */ SyscallDesc("pre_F64_fstatfs", fstatfsFunc<Tru64::PreF64>),
/* 162 */ SyscallDesc("unknown #162", unimplementedFunc),
@@ -1822,20 +429,17 @@ SyscallDesc Tru64::syscallDescs[] = {
/* 266 */ SyscallDesc("sendfile", unimplementedFunc),
};
-const int Tru64::Num_Syscall_Descs =
- sizeof(Tru64::syscallDescs) / sizeof(SyscallDesc);
-const int Tru64::Max_Syscall_Desc = Tru64::Num_Syscall_Descs - 1;
-SyscallDesc Tru64::machSyscallDescs[] = {
+SyscallDesc AlphaTru64Process::machSyscallDescs[] = {
/* 0 */ SyscallDesc("kern_invalid", unimplementedFunc),
- /* 1 */ SyscallDesc("m5_mutex_lock", m5_mutex_lockFunc),
- /* 2 */ SyscallDesc("m5_mutex_trylock", m5_mutex_trylockFunc),
- /* 3 */ SyscallDesc("m5_mutex_unlock", m5_mutex_unlockFunc),
- /* 4 */ SyscallDesc("m5_cond_signal", m5_cond_signalFunc),
- /* 5 */ SyscallDesc("m5_cond_broadcast", m5_cond_broadcastFunc),
- /* 6 */ SyscallDesc("m5_cond_wait", m5_cond_waitFunc),
- /* 7 */ SyscallDesc("m5_thread_exit", m5_thread_exitFunc),
+ /* 1 */ SyscallDesc("m5_mutex_lock", Tru64::m5_mutex_lockFunc),
+ /* 2 */ SyscallDesc("m5_mutex_trylock", Tru64::m5_mutex_trylockFunc),
+ /* 3 */ SyscallDesc("m5_mutex_unlock", Tru64::m5_mutex_unlockFunc),
+ /* 4 */ SyscallDesc("m5_cond_signal", Tru64::m5_cond_signalFunc),
+ /* 5 */ SyscallDesc("m5_cond_broadcast", Tru64::m5_cond_broadcastFunc),
+ /* 6 */ SyscallDesc("m5_cond_wait", Tru64::m5_cond_waitFunc),
+ /* 7 */ SyscallDesc("m5_thread_exit", Tru64::m5_thread_exitFunc),
/* 8 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 9 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 10 */ SyscallDesc("task_self", unimplementedFunc),
@@ -1852,22 +456,22 @@ SyscallDesc Tru64::machSyscallDescs[] = {
/* 21 */ SyscallDesc("msg_receive_trap", unimplementedFunc),
/* 22 */ SyscallDesc("msg_rpc_trap", unimplementedFunc),
/* 23 */ SyscallDesc("kern_invalid", unimplementedFunc),
- /* 24 */ SyscallDesc("nxm_block", nxm_blockFunc),
- /* 25 */ SyscallDesc("nxm_unblock", nxm_unblockFunc),
+ /* 24 */ SyscallDesc("nxm_block", Tru64::nxm_blockFunc),
+ /* 25 */ SyscallDesc("nxm_unblock", Tru64::nxm_unblockFunc),
/* 26 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 27 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 28 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 29 */ SyscallDesc("nxm_thread_destroy", unimplementedFunc),
/* 30 */ SyscallDesc("lw_wire", unimplementedFunc),
/* 31 */ SyscallDesc("lw_unwire", unimplementedFunc),
- /* 32 */ SyscallDesc("nxm_thread_create", nxm_thread_createFunc),
- /* 33 */ SyscallDesc("nxm_task_init", nxm_task_initFunc),
+ /* 32 */ SyscallDesc("nxm_thread_create", Tru64::nxm_thread_createFunc),
+ /* 33 */ SyscallDesc("nxm_task_init", Tru64::nxm_task_initFunc),
/* 34 */ SyscallDesc("kern_invalid", unimplementedFunc),
- /* 35 */ SyscallDesc("nxm_idle", nxm_idleFunc),
+ /* 35 */ SyscallDesc("nxm_idle", Tru64::nxm_idleFunc),
/* 36 */ SyscallDesc("nxm_wakeup_idle", unimplementedFunc),
/* 37 */ SyscallDesc("nxm_set_pthid", unimplementedFunc),
/* 38 */ SyscallDesc("nxm_thread_kill", unimplementedFunc),
- /* 39 */ SyscallDesc("nxm_thread_block", nxm_thread_blockFunc),
+ /* 39 */ SyscallDesc("nxm_thread_block", Tru64::nxm_thread_blockFunc),
/* 40 */ SyscallDesc("nxm_thread_wakeup", unimplementedFunc),
/* 41 */ SyscallDesc("init_process", unimplementedFunc),
/* 42 */ SyscallDesc("nxm_get_binding", unimplementedFunc),
@@ -1875,7 +479,7 @@ SyscallDesc Tru64::machSyscallDescs[] = {
/* 44 */ SyscallDesc("nxm_resched", unimplementedFunc),
/* 45 */ SyscallDesc("nxm_set_cancel", unimplementedFunc),
/* 46 */ SyscallDesc("nxm_set_binding", unimplementedFunc),
- /* 47 */ SyscallDesc("stack_create", stack_createFunc),
+ /* 47 */ SyscallDesc("stack_create", Tru64::stack_createFunc),
/* 48 */ SyscallDesc("nxm_get_state", unimplementedFunc),
/* 49 */ SyscallDesc("nxm_thread_suspend", unimplementedFunc),
/* 50 */ SyscallDesc("nxm_thread_resume", unimplementedFunc),
@@ -1887,7 +491,7 @@ SyscallDesc Tru64::machSyscallDescs[] = {
/* 56 */ SyscallDesc("host_priv_self", unimplementedFunc),
/* 57 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 58 */ SyscallDesc("kern_invalid", unimplementedFunc),
- /* 59 */ SyscallDesc("swtch_pri", swtch_priFunc),
+ /* 59 */ SyscallDesc("swtch_pri", Tru64::swtch_priFunc),
/* 60 */ SyscallDesc("swtch", unimplementedFunc),
/* 61 */ SyscallDesc("thread_switch", unimplementedFunc),
/* 62 */ SyscallDesc("semop_fast", unimplementedFunc),
@@ -1895,7 +499,7 @@ SyscallDesc Tru64::machSyscallDescs[] = {
/* 64 */ SyscallDesc("nxm_pshared_block", unimplementedFunc),
/* 65 */ SyscallDesc("nxm_pshared_unblock", unimplementedFunc),
/* 66 */ SyscallDesc("nxm_pshared_destroy", unimplementedFunc),
- /* 67 */ SyscallDesc("nxm_swtch_pri", swtch_priFunc),
+ /* 67 */ SyscallDesc("nxm_swtch_pri", Tru64::swtch_priFunc),
/* 68 */ SyscallDesc("lw_syscall", unimplementedFunc),
/* 69 */ SyscallDesc("kern_invalid", unimplementedFunc),
/* 70 */ SyscallDesc("mach_sctimes_0", unimplementedFunc),
@@ -1913,20 +517,16 @@ SyscallDesc Tru64::machSyscallDescs[] = {
/* 82 */ SyscallDesc("mach_sctimes_port_alloc_dealloc", unimplementedFunc)
};
-const int Tru64::Num_Mach_Syscall_Descs =
- sizeof(Tru64::machSyscallDescs) / sizeof(SyscallDesc);
-const int Tru64::Max_Mach_Syscall_Desc = Tru64::Num_Mach_Syscall_Descs - 1;
-const int Tru64::Min_Syscall_Desc = -Tru64::Max_Mach_Syscall_Desc;
-
-
-void
-AlphaTru64Process::syscall(ExecContext *xc)
+SyscallDesc*
+AlphaTru64Process::getDesc(int callnum)
{
- num_syscalls++;
-
- int64_t callnum = xc->regs.intRegFile[ReturnValueReg];
+ if (callnum < -Num_Mach_Syscall_Descs || callnum > Num_Syscall_Descs)
+ return NULL;
- Tru64::doSyscall(callnum, this, xc);
+ if (callnum < 0)
+ return &machSyscallDescs[-callnum];
+ else
+ return &syscallDescs[callnum];
}
@@ -1937,6 +537,8 @@ AlphaTru64Process::AlphaTru64Process(const std::string &name,
int stderr_fd,
std::vector<std::string> &argv,
std::vector<std::string> &envp)
- : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp)
+ : LiveProcess(name, objFile, stdin_fd, stdout_fd, stderr_fd, argv, envp),
+ Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc)),
+ Num_Mach_Syscall_Descs(sizeof(machSyscallDescs) / sizeof(SyscallDesc))
{
}
diff --git a/arch/alpha/alpha_tru64_process.hh b/arch/alpha/alpha_tru64_process.hh
index 49979806c..051760702 100644
--- a/arch/alpha/alpha_tru64_process.hh
+++ b/arch/alpha/alpha_tru64_process.hh
@@ -42,8 +42,16 @@ class AlphaTru64Process : public LiveProcess
std::vector<std::string> &argv,
std::vector<std::string> &envp);
- /// Syscall emulation function.
- virtual void syscall(ExecContext *xc);
+ /// Array of syscall descriptors, indexed by call number.
+ static SyscallDesc syscallDescs[];
+
+ /// Array of mach syscall descriptors, indexed by call number.
+ static SyscallDesc machSyscallDescs[];
+
+ const int Num_Syscall_Descs;
+ const int Num_Mach_Syscall_Descs;
+
+ virtual SyscallDesc* getDesc(int callnum);
};
diff --git a/arch/alpha/arguments.cc b/arch/alpha/arguments.cc
index a340a2053..4e8190cbc 100644
--- a/arch/alpha/arguments.cc
+++ b/arch/alpha/arguments.cc
@@ -31,6 +31,8 @@
#include "cpu/exec_context.hh"
#include "mem/functional/physical.hh"
+using namespace AlphaISA;
+
AlphaArguments::Data::~Data()
{
while (!data.empty()) {
diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc
index 72f48bfb2..14b87b16f 100644
--- a/arch/alpha/ev5.cc
+++ b/arch/alpha/ev5.cc
@@ -70,12 +70,15 @@ AlphaISA::swap_palshadow(RegFile *regs, bool use_shadow)
// Machine dependent functions
//
void
-AlphaISA::initCPU(RegFile *regs)
+AlphaISA::initCPU(RegFile *regs, int cpuId)
{
- initIPRs(regs);
+ initIPRs(regs, cpuId);
// CPU comes up with PAL regs enabled
swap_palshadow(regs, true);
+ regs->intRegFile[16] = cpuId;
+ regs->intRegFile[0] = cpuId;
+
regs->pc = regs->ipr[IPR_PAL_BASE] + fault_addr(ResetFault);
regs->npc = regs->pc + sizeof(MachInst);
}
@@ -85,7 +88,7 @@ AlphaISA::initCPU(RegFile *regs)
// alpha exceptions - value equals trap address, update with MD_FAULT_TYPE
//
const Addr
-AlphaISA::fault_addr(Fault * fault)
+AlphaISA::fault_addr(Fault fault)
{
//Check for the system wide faults
if(fault == NoFault) return 0x0000;
@@ -106,13 +109,14 @@ const int AlphaISA::reg_redir[AlphaISA::NumIntRegs] = {
//
//
void
-AlphaISA::initIPRs(RegFile *regs)
+AlphaISA::initIPRs(RegFile *regs, int cpuId)
{
uint64_t *ipr = regs->ipr;
bzero((char *)ipr, NumInternalProcRegs * sizeof(InternalProcReg));
ipr[IPR_PAL_BASE] = PalBase;
ipr[IPR_MCSR] = 0x6;
+ ipr[IPR_PALtemp16] = cpuId;
}
@@ -177,7 +181,7 @@ AlphaISA::zeroRegisters(CPU *cpu)
}
void
-ExecContext::ev5_trap(Fault * fault)
+ExecContext::ev5_trap(Fault fault)
{
DPRINTF(Fault, "Fault %s at PC: %#x\n", fault->name, regs.pc);
cpu->recordEvent(csprintf("Fault %s", fault->name));
@@ -209,7 +213,7 @@ ExecContext::ev5_trap(Fault * fault)
void
-AlphaISA::intr_post(RegFile *regs, Fault * fault, Addr pc)
+AlphaISA::intr_post(RegFile *regs, Fault fault, Addr pc)
{
InternalProcReg *ipr = regs->ipr;
bool use_pc = (fault == NoFault);
@@ -235,7 +239,7 @@ AlphaISA::intr_post(RegFile *regs, Fault * fault, Addr pc)
// that's it! (orders of magnitude less painful than x86)
}
-Fault *
+Fault
ExecContext::hwrei()
{
uint64_t *ipr = regs.ipr;
@@ -259,7 +263,7 @@ ExecContext::hwrei()
}
uint64_t
-ExecContext::readIpr(int idx, Fault * &fault)
+ExecContext::readIpr(int idx, Fault &fault)
{
uint64_t *ipr = regs.ipr;
uint64_t retval = 0; // return value, default 0
@@ -370,7 +374,7 @@ ExecContext::readIpr(int idx, Fault * &fault)
int break_ipl = -1;
#endif
-Fault *
+Fault
ExecContext::setIpr(int idx, uint64_t val)
{
uint64_t *ipr = regs.ipr;
diff --git a/arch/alpha/ev5.hh b/arch/alpha/ev5.hh
index 5173b364f..7c8465cfb 100644
--- a/arch/alpha/ev5.hh
+++ b/arch/alpha/ev5.hh
@@ -30,9 +30,13 @@
#define __ARCH_ALPHA_EV5_HH__
#include "config/alpha_tlaser.hh"
+#include "arch/alpha/isa_traits.hh"
namespace EV5 {
+//It seems like a safe assumption EV5 only applies to alpha
+using namespace AlphaISA;
+
#if ALPHA_TLASER
const uint64_t AsnMask = ULL(0x7f);
#else
diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc
index e05b3fe59..fa4950198 100644
--- a/arch/alpha/faults.cc
+++ b/arch/alpha/faults.cc
@@ -57,24 +57,24 @@ PalFaultType * const PalFault =
IntegerOverflowFaultType * const IntegerOverflowFault =
new IntegerOverflowFaultType("intover", 16, 0x0501);
-Fault ** ListOfFaults[] = {
- (Fault **)&NoFault,
- (Fault **)&ResetFault,
- (Fault **)&MachineCheckFault,
- (Fault **)&ArithmeticFault,
- (Fault **)&InterruptFault,
- (Fault **)&NDtbMissFault,
- (Fault **)&PDtbMissFault,
- (Fault **)&AlignmentFault,
- (Fault **)&DtbPageFault,
- (Fault **)&DtbAcvFault,
- (Fault **)&ItbMissFault,
- (Fault **)&ItbPageFault,
- (Fault **)&ItbAcvFault,
- (Fault **)&UnimplementedOpcodeFault,
- (Fault **)&FloatEnableFault,
- (Fault **)&PalFault,
- (Fault **)&IntegerOverflowFault,
+Fault * ListOfFaults[] = {
+ (Fault *)&NoFault,
+ (Fault *)&ResetFault,
+ (Fault *)&MachineCheckFault,
+ (Fault *)&ArithmeticFault,
+ (Fault *)&InterruptFault,
+ (Fault *)&NDtbMissFault,
+ (Fault *)&PDtbMissFault,
+ (Fault *)&AlignmentFault,
+ (Fault *)&DtbPageFault,
+ (Fault *)&DtbAcvFault,
+ (Fault *)&ItbMissFault,
+ (Fault *)&ItbPageFault,
+ (Fault *)&ItbAcvFault,
+ (Fault *)&UnimplementedOpcodeFault,
+ (Fault *)&FloatEnableFault,
+ (Fault *)&PalFault,
+ (Fault *)&IntegerOverflowFault,
};
-int NumFaults = sizeof(ListOfFaults) / sizeof(Fault **);
+int NumFaults = sizeof(ListOfFaults) / sizeof(Fault *);
diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh
index 06605861a..3e25adc4e 100644
--- a/arch/alpha/faults.hh
+++ b/arch/alpha/faults.hh
@@ -32,14 +32,14 @@
#include "sim/faults.hh"
#include "arch/isa_traits.hh" //For the Addr type
-class AlphaFault : public Fault
+class AlphaFault : public FaultBase
{
public:
AlphaFault(char * newName, int newId, Addr newVect)
- : Fault(newName, newId), vect(newVect)
+ : FaultBase(newName, newId), vect(newVect)
{;}
- TheISA::Addr vect;
+ Addr vect;
};
extern class ResetFaultType : public AlphaFault
@@ -154,7 +154,7 @@ extern class IntegerOverflowFaultType : public AlphaFault
{;}
} * const IntegerOverflowFault;
-extern Fault ** ListOfFaults[];
+extern Fault * ListOfFaults[];
extern int NumFaults;
#endif // __FAULTS_HH__
diff --git a/arch/alpha/isa/branch.isa b/arch/alpha/isa/branch.isa
index e9c790c53..9a7fb9d79 100644
--- a/arch/alpha/isa/branch.isa
+++ b/arch/alpha/isa/branch.isa
@@ -205,8 +205,8 @@ output decoder {{
def template JumpOrBranchDecode {{
return (RA == 31)
- ? (StaticInst<AlphaISA> *)new %(class_name)s(machInst)
- : (StaticInst<AlphaISA> *)new %(class_name)sAndLink(machInst);
+ ? (StaticInst *)new %(class_name)s(machInst)
+ : (StaticInst *)new %(class_name)sAndLink(machInst);
}};
def format CondBranch(code) {{
diff --git a/arch/alpha/isa/fp.isa b/arch/alpha/isa/fp.isa
index c718c5524..7e81fb830 100644
--- a/arch/alpha/isa/fp.isa
+++ b/arch/alpha/isa/fp.isa
@@ -32,16 +32,16 @@ output exec {{
/// @retval Full-system mode: NoFault if FP is enabled, FenFault
/// if not. Non-full-system mode: always returns NoFault.
#if FULL_SYSTEM
- inline Fault * checkFpEnableFault(%(CPU_exec_context)s *xc)
+ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
{
- Fault * fault = NoFault; // dummy... this ipr access should not fault
+ Fault fault = NoFault; // dummy... this ipr access should not fault
if (!EV5::ICSR_FPE(xc->readIpr(AlphaISA::IPR_ICSR, fault))) {
fault = FloatEnableFault;
}
return fault;
}
#else
- inline Fault * checkFpEnableFault(%(CPU_exec_context)s *xc)
+ inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
{
return NoFault;
}
@@ -199,7 +199,7 @@ output decoder {{
// FP instruction class execute method template. Handles non-standard
// rounding modes.
def template FloatingPointExecute {{
- Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
if (trappingMode != Imprecise && !warnedOnTrapping) {
@@ -208,7 +208,7 @@ def template FloatingPointExecute {{
warnedOnTrapping = true;
}
- Fault * fault = NoFault;
+ Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
@@ -242,7 +242,7 @@ def template FloatingPointExecute {{
// rounding mode control is needed. Like BasicExecute, but includes
// check & warning for non-standard trapping mode.
def template FPFixedRoundingExecute {{
- Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
if (trappingMode != Imprecise && !warnedOnTrapping) {
@@ -251,7 +251,7 @@ def template FPFixedRoundingExecute {{
warnedOnTrapping = true;
}
- Fault * fault = NoFault;
+ Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa
index 42fb29404..b8d03c0be 100644
--- a/arch/alpha/isa/main.isa
+++ b/arch/alpha/isa/main.isa
@@ -45,6 +45,8 @@ output decoder {{
#include "cpu/exec_context.hh" // for Jump::branchTarget()
#include <math.h>
+
+using namespace AlphaISA;
}};
output exec {{
@@ -58,6 +60,8 @@ output exec {{
#include "cpu/base.hh"
#include "cpu/exetrace.hh"
#include "sim/sim_exit.hh"
+
+using namespace AlphaISA;
}};
////////////////////////////////////////////////////////////////////
@@ -179,7 +183,7 @@ output header {{
/**
* Base class for all Alpha static instructions.
*/
- class AlphaStaticInst : public StaticInst<AlphaISA>
+ class AlphaStaticInst : public StaticInst
{
protected:
@@ -196,7 +200,7 @@ output header {{
/// Constructor.
AlphaStaticInst(const char *mnem, MachInst _machInst,
OpClass __opClass)
- : StaticInst<AlphaISA>(mnem, _machInst, __opClass)
+ : StaticInst(mnem, _machInst, __opClass)
{
}
@@ -254,7 +258,7 @@ output decoder {{
// Declarations for execute() methods.
def template BasicExecDeclare {{
- Fault * execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+ Fault execute(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
// Basic instruction class declaration template.
@@ -283,10 +287,10 @@ def template BasicConstructor {{
// Basic instruction class execute method template.
def template BasicExecute {{
- Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
- Fault * fault = NoFault;
+ Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
@@ -352,6 +356,17 @@ output header {{
%(BasicExecDeclare)s
};
+
+ /// Helper function for decoding nops. Substitute Nop object
+ /// for original inst passed in as arg (and delete latter).
+ static inline
+ AlphaStaticInst *
+ makeNop(AlphaStaticInst *inst)
+ {
+ AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst);
+ delete inst;
+ return nop;
+ }
}};
output decoder {{
@@ -364,21 +379,10 @@ output decoder {{
return csprintf("%-10s (%s)", "nop", originalDisassembly);
#endif
}
-
- /// Helper function for decoding nops. Substitute Nop object
- /// for original inst passed in as arg (and delete latter).
- inline
- AlphaStaticInst *
- makeNop(AlphaStaticInst *inst)
- {
- AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst);
- delete inst;
- return nop;
- }
}};
output exec {{
- Fault *
+ Fault
Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const
{
return NoFault;
diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa
index df26a534d..61d6ea8fa 100644
--- a/arch/alpha/isa/mem.isa
+++ b/arch/alpha/isa/mem.isa
@@ -37,14 +37,14 @@ output header {{
/// Memory request flags. See mem_req_base.hh.
unsigned memAccessFlags;
/// Pointer to EAComp object.
- const StaticInstPtr<AlphaISA> eaCompPtr;
+ const StaticInstPtr eaCompPtr;
/// Pointer to MemAcc object.
- const StaticInstPtr<AlphaISA> memAccPtr;
+ const StaticInstPtr memAccPtr;
/// Constructor
Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
- StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
- StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr)
+ StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+ StaticInstPtr _memAccPtr = nullStaticInstPtr)
: AlphaStaticInst(mnem, _machInst, __opClass),
memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr)
{
@@ -55,8 +55,8 @@ output header {{
public:
- const StaticInstPtr<AlphaISA> &eaCompInst() const { return eaCompPtr; }
- const StaticInstPtr<AlphaISA> &memAccInst() const { return memAccPtr; }
+ const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
+ const StaticInstPtr &memAccInst() const { return memAccPtr; }
};
/**
@@ -71,8 +71,8 @@ output header {{
/// Constructor.
MemoryDisp32(const char *mnem, MachInst _machInst, OpClass __opClass,
- StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
- StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr)
+ StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+ StaticInstPtr _memAccPtr = nullStaticInstPtr)
: Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
disp(MEMDISP)
{
@@ -90,8 +90,8 @@ output header {{
protected:
/// Constructor
MemoryNoDisp(const char *mnem, MachInst _machInst, OpClass __opClass,
- StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
- StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr)
+ StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+ StaticInstPtr _memAccPtr = nullStaticInstPtr)
: Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr)
{
}
@@ -173,12 +173,12 @@ def template LoadStoreDeclare {{
def template InitiateAccDeclare {{
- Fault * initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+ Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
def template CompleteAccDeclare {{
- Fault * completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+ Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
}};
@@ -208,12 +208,12 @@ def template LoadStoreConstructor {{
def template EACompExecute {{
- Fault *
+ Fault
%(class_name)s::EAComp::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
- Fault * fault = NoFault;
+ Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
@@ -230,12 +230,12 @@ def template EACompExecute {{
}};
def template LoadMemAccExecute {{
- Fault *
+ Fault
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
- Fault * fault = NoFault;
+ Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
@@ -257,11 +257,11 @@ def template LoadMemAccExecute {{
def template LoadExecute {{
- Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
- Fault * fault = NoFault;
+ Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
@@ -283,11 +283,11 @@ def template LoadExecute {{
def template LoadInitiateAcc {{
- Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
- Fault * fault = NoFault;
+ Fault fault = NoFault;
%(fp_enable_check)s;
%(op_src_decl)s;
@@ -304,11 +304,11 @@ def template LoadInitiateAcc {{
def template LoadCompleteAcc {{
- Fault * %(class_name)s::completeAcc(uint8_t *data,
+ Fault %(class_name)s::completeAcc(uint8_t *data,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
- Fault * fault = NoFault;
+ Fault fault = NoFault;
%(fp_enable_check)s;
%(op_src_decl)s;
@@ -330,12 +330,12 @@ def template LoadCompleteAcc {{
def template StoreMemAccExecute {{
- Fault *
+ Fault
%(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
- Fault * fault = NoFault;
+ Fault fault = NoFault;
uint64_t write_result = 0;
%(fp_enable_check)s;
@@ -367,11 +367,11 @@ def template StoreMemAccExecute {{
def template StoreExecute {{
- Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
- Fault * fault = NoFault;
+ Fault fault = NoFault;
uint64_t write_result = 0;
%(fp_enable_check)s;
@@ -402,11 +402,11 @@ def template StoreExecute {{
}};
def template StoreInitiateAcc {{
- Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
- Fault * fault = NoFault;
+ Fault fault = NoFault;
uint64_t write_result = 0;
%(fp_enable_check)s;
@@ -431,11 +431,11 @@ def template StoreInitiateAcc {{
def template StoreCompleteAcc {{
- Fault * %(class_name)s::completeAcc(uint8_t *data,
+ Fault %(class_name)s::completeAcc(uint8_t *data,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
- Fault * fault = NoFault;
+ Fault fault = NoFault;
uint64_t write_result = 0;
%(fp_enable_check)s;
@@ -457,11 +457,11 @@ def template StoreCompleteAcc {{
def template MiscMemAccExecute {{
- Fault * %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+ Fault %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
- Fault * fault = NoFault;
+ Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
@@ -477,11 +477,11 @@ def template MiscMemAccExecute {{
}};
def template MiscExecute {{
- Fault * %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
Addr EA;
- Fault * fault = NoFault;
+ Fault fault = NoFault;
%(fp_enable_check)s;
%(op_decl)s;
@@ -497,7 +497,7 @@ def template MiscExecute {{
}};
def template MiscInitiateAcc {{
- Fault * %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
panic("Misc instruction does not support split access method!");
@@ -507,7 +507,7 @@ def template MiscInitiateAcc {{
def template MiscCompleteAcc {{
- Fault * %(class_name)s::completeAcc(uint8_t *data,
+ Fault %(class_name)s::completeAcc(uint8_t *data,
%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
diff --git a/arch/alpha/isa/pal.isa b/arch/alpha/isa/pal.isa
index b68a7c19f..49e5bff12 100644
--- a/arch/alpha/isa/pal.isa
+++ b/arch/alpha/isa/pal.isa
@@ -149,8 +149,8 @@ output header {{
/// Constructor
HwLoadStore(const char *mnem, MachInst _machInst, OpClass __opClass,
- StaticInstPtr<AlphaISA> _eaCompPtr = nullStaticInstPtr,
- StaticInstPtr<AlphaISA> _memAccPtr = nullStaticInstPtr);
+ StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+ StaticInstPtr _memAccPtr = nullStaticInstPtr);
std::string
generateDisassembly(Addr pc, const SymbolTable *symtab) const;
@@ -162,8 +162,8 @@ output decoder {{
inline
HwLoadStore::HwLoadStore(const char *mnem, MachInst _machInst,
OpClass __opClass,
- StaticInstPtr<AlphaISA> _eaCompPtr,
- StaticInstPtr<AlphaISA> _memAccPtr)
+ StaticInstPtr _eaCompPtr,
+ StaticInstPtr _memAccPtr)
: Memory(mnem, _machInst, __opClass, _eaCompPtr, _memAccPtr),
disp(HW_LDST_DISP)
{
diff --git a/arch/alpha/isa/unimp.isa b/arch/alpha/isa/unimp.isa
index ce8197708..de4ac3eaf 100644
--- a/arch/alpha/isa/unimp.isa
+++ b/arch/alpha/isa/unimp.isa
@@ -105,7 +105,7 @@ output decoder {{
}};
output exec {{
- Fault *
+ Fault
FailUnimplemented::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
@@ -114,7 +114,7 @@ output exec {{
return UnimplementedOpcodeFault;
}
- Fault *
+ Fault
WarnUnimplemented::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
diff --git a/arch/alpha/isa/unknown.isa b/arch/alpha/isa/unknown.isa
index e7f8bc8db..4601b3684 100644
--- a/arch/alpha/isa/unknown.isa
+++ b/arch/alpha/isa/unknown.isa
@@ -36,7 +36,7 @@ output decoder {{
}};
output exec {{
- Fault *
+ Fault
Unknown::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
{
diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh
index a6e34acbb..f47e90f86 100644
--- a/arch/alpha/isa_traits.hh
+++ b/arch/alpha/isa_traits.hh
@@ -44,20 +44,19 @@ class Checkpoint;
#define TARGET_ALPHA
-template <class ISA> class StaticInst;
-template <class ISA> class StaticInstPtr;
+class StaticInst;
+class StaticInstPtr;
namespace EV5 {
int DTB_ASN_ASN(uint64_t reg);
int ITB_ASN_ASN(uint64_t reg);
}
-class AlphaISA
+namespace AlphaISA
{
- public:
typedef uint32_t MachInst;
- typedef uint64_t Addr;
+// typedef uint64_t Addr;
typedef uint8_t RegIndex;
enum {
@@ -133,10 +132,10 @@ class AlphaISA
Addr lock_addr; // lock address for LL/SC
} MiscRegFile;
-static const Addr PageShift = 13;
-static const Addr PageBytes = ULL(1) << PageShift;
-static const Addr PageMask = ~(PageBytes - 1);
-static const Addr PageOffset = PageBytes - 1;
+extern const Addr PageShift;
+extern const Addr PageBytes;
+extern const Addr PageMask;
+extern const Addr PageOffset;
#if FULL_SYSTEM
@@ -184,10 +183,10 @@ static const Addr PageOffset = PageBytes - 1;
void unserialize(Checkpoint *cp, const std::string &section);
};
- static StaticInstPtr<AlphaISA> decodeInst(MachInst);
+ StaticInstPtr decodeInst(MachInst);
// return a no-op instruction... used for instruction fetch faults
- static const MachInst NoopMachInst;
+ extern const MachInst NoopMachInst;
enum annotes {
ANNOTE_NONE = 0,
@@ -242,10 +241,10 @@ static const Addr PageOffset = PageBytes - 1;
// Machine operations
- static void saveMachineReg(AnyReg &savereg, const RegFile &reg_file,
+ void saveMachineReg(AnyReg &savereg, const RegFile &reg_file,
int regnum);
- static void restoreMachineReg(RegFile &regs, const AnyReg &reg,
+ void restoreMachineReg(RegFile &regs, const AnyReg &reg,
int regnum);
#if 0
@@ -263,41 +262,41 @@ static const Addr PageOffset = PageBytes - 1;
* @param xc The execution context.
*/
template <class XC>
- static void zeroRegisters(XC *xc);
+ void zeroRegisters(XC *xc);
+
+
+//typedef AlphaISA TheISA;
+
+//typedef TheISA::MachInst MachInst;
+//typedef TheISA::Addr Addr;
+//typedef TheISA::RegIndex RegIndex;
+//typedef TheISA::IntReg IntReg;
+//typedef TheISA::IntRegFile IntRegFile;
+//typedef TheISA::FloatReg FloatReg;
+//typedef TheISA::FloatRegFile FloatRegFile;
+//typedef TheISA::MiscReg MiscReg;
+//typedef TheISA::MiscRegFile MiscRegFile;
+//typedef TheISA::AnyReg AnyReg;
+//typedef TheISA::RegFile RegFile;
+
+//const int NumIntRegs = TheISA::NumIntRegs;
+//const int NumFloatRegs = TheISA::NumFloatRegs;
+//const int NumMiscRegs = TheISA::NumMiscRegs;
+//const int TotalNumRegs = TheISA::TotalNumRegs;
+//const int VMPageSize = TheISA::VMPageSize;
+//const int LogVMPageSize = TheISA::LogVMPageSize;
+//const int ZeroReg = TheISA::ZeroReg;
+//const int StackPointerReg = TheISA::StackPointerReg;
+//const int GlobalPointerReg = TheISA::GlobalPointerReg;
+//const int ReturnAddressReg = TheISA::ReturnAddressReg;
+//const int ReturnValueReg = TheISA::ReturnValueReg;
+//const int ArgumentReg0 = TheISA::ArgumentReg0;
+//const int ArgumentReg1 = TheISA::ArgumentReg1;
+//const int ArgumentReg2 = TheISA::ArgumentReg2;
+//const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt;
+const Addr MaxAddr = (Addr)-1;
};
-
-typedef AlphaISA TheISA;
-
-typedef TheISA::MachInst MachInst;
-typedef TheISA::Addr Addr;
-typedef TheISA::RegIndex RegIndex;
-typedef TheISA::IntReg IntReg;
-typedef TheISA::IntRegFile IntRegFile;
-typedef TheISA::FloatReg FloatReg;
-typedef TheISA::FloatRegFile FloatRegFile;
-typedef TheISA::MiscReg MiscReg;
-typedef TheISA::MiscRegFile MiscRegFile;
-typedef TheISA::AnyReg AnyReg;
-typedef TheISA::RegFile RegFile;
-
-const int NumIntRegs = TheISA::NumIntRegs;
-const int NumFloatRegs = TheISA::NumFloatRegs;
-const int NumMiscRegs = TheISA::NumMiscRegs;
-const int TotalNumRegs = TheISA::TotalNumRegs;
-const int VMPageSize = TheISA::VMPageSize;
-const int LogVMPageSize = TheISA::LogVMPageSize;
-const int ZeroReg = TheISA::ZeroReg;
-const int StackPointerReg = TheISA::StackPointerReg;
-const int GlobalPointerReg = TheISA::GlobalPointerReg;
-const int ReturnAddressReg = TheISA::ReturnAddressReg;
-const int ReturnValueReg = TheISA::ReturnValueReg;
-const int ArgumentReg0 = TheISA::ArgumentReg0;
-const int ArgumentReg1 = TheISA::ArgumentReg1;
-const int ArgumentReg2 = TheISA::ArgumentReg2;
-const int BranchPredAddrShiftAmt = TheISA::BranchPredAddrShiftAmt;
-const int MaxAddr = (Addr)-1;
-
#if !FULL_SYSTEM
class SyscallReturn {
public:
@@ -336,9 +335,9 @@ class SyscallReturn {
#if FULL_SYSTEM
-typedef TheISA::InternalProcReg InternalProcReg;
-const int NumInternalProcRegs = TheISA::NumInternalProcRegs;
-const int NumInterruptLevels = TheISA::NumInterruptLevels;
+//typedef TheISA::InternalProcReg InternalProcReg;
+//const int NumInternalProcRegs = TheISA::NumInternalProcRegs;
+//const int NumInterruptLevels = TheISA::NumInterruptLevels;
#include "arch/alpha/ev5.hh"
#endif
diff --git a/arch/alpha/stacktrace.cc b/arch/alpha/stacktrace.cc
index 5a8df3d35..30ed07d9d 100644
--- a/arch/alpha/stacktrace.cc
+++ b/arch/alpha/stacktrace.cc
@@ -37,6 +37,7 @@
#include "cpu/exec_context.hh"
using namespace std;
+using namespace AlphaISA;
ProcessInfo::ProcessInfo(ExecContext *_xc)
: xc(_xc)
@@ -108,7 +109,7 @@ StackTrace::StackTrace()
{
}
-StackTrace::StackTrace(ExecContext *_xc, StaticInstPtr<TheISA> inst)
+StackTrace::StackTrace(ExecContext *_xc, StaticInstPtr inst)
: xc(0), stack(64)
{
trace(_xc, inst);
diff --git a/arch/alpha/stacktrace.hh b/arch/alpha/stacktrace.hh
index 244e574b6..1d8d97a79 100644
--- a/arch/alpha/stacktrace.hh
+++ b/arch/alpha/stacktrace.hh
@@ -56,6 +56,8 @@ class ProcessInfo
class StackTrace
{
+ protected:
+ typedef TheISA::MachInst MachInst;
private:
ExecContext *xc;
std::vector<Addr> stack;
@@ -70,7 +72,7 @@ class StackTrace
public:
StackTrace();
- StackTrace(ExecContext *xc, StaticInstPtr<TheISA> inst);
+ StackTrace(ExecContext *xc, StaticInstPtr inst);
~StackTrace();
void clear()
@@ -80,7 +82,7 @@ class StackTrace
}
bool valid() const { return xc != NULL; }
- bool trace(ExecContext *xc, StaticInstPtr<TheISA> inst);
+ bool trace(ExecContext *xc, StaticInstPtr inst);
public:
const std::vector<Addr> &getstack() const { return stack; }
@@ -102,7 +104,7 @@ class StackTrace
};
inline bool
-StackTrace::trace(ExecContext *xc, StaticInstPtr<TheISA> inst)
+StackTrace::trace(ExecContext *xc, StaticInstPtr inst)
{
if (!inst->isCall() && !inst->isReturn())
return false;
diff --git a/arch/alpha/vtophys.cc b/arch/alpha/vtophys.cc
index 27014164c..3ffa4bd14 100644
--- a/arch/alpha/vtophys.cc
+++ b/arch/alpha/vtophys.cc
@@ -34,6 +34,7 @@
#include "mem/functional/physical.hh"
using namespace std;
+using namespace AlphaISA;
AlphaISA::PageTableEntry
kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, AlphaISA::VAddr vaddr)
diff --git a/arch/isa_parser.py b/arch/isa_parser.py
index bcef77ddf..6508ca02a 100755
--- a/arch/isa_parser.py
+++ b/arch/isa_parser.py
@@ -224,7 +224,7 @@ def p_specification(t):
namespace = isa_name + "Inst"
# wrap the decode block as a function definition
t[4].wrap_decode_block('''
-StaticInstPtr<%(isa_name)s>
+StaticInstPtr
%(isa_name)s::decodeInst(%(isa_name)s::MachInst machInst)
{
using namespace %(namespace)s;
@@ -712,43 +712,6 @@ yacc.yacc()
#
#####################################################################
-################
-# CpuModel class
-#
-# The CpuModel class encapsulates everything we need to know about a
-# particular CPU model.
-
-class CpuModel:
- # List of all CPU models. Accessible as CpuModel.list.
- list = []
-
- # Constructor. Automatically adds models to CpuModel.list.
- def __init__(self, name, filename, includes, strings):
- self.name = name
- self.filename = filename # filename for output exec code
- self.includes = includes # include files needed in exec file
- # The 'strings' dict holds all the per-CPU symbols we can
- # substitute into templates etc.
- self.strings = strings
- # Add self to list.
- CpuModel.list.append(self)
-
-# Define CPU models. The following lines should contain the only
-# CPU-model-specific information in this file. Note that the ISA
-# description itself should have *no* CPU-model-specific content.
-CpuModel('SimpleCPU', 'simple_cpu_exec.cc',
- '#include "cpu/simple/cpu.hh"',
- { 'CPU_exec_context': 'SimpleCPU' })
-CpuModel('FastCPU', 'fast_cpu_exec.cc',
- '#include "cpu/fast/cpu.hh"',
- { 'CPU_exec_context': 'FastCPU' })
-CpuModel('FullCPU', 'full_cpu_exec.cc',
- '#include "encumbered/cpu/full/dyn_inst.hh"',
- { 'CPU_exec_context': 'DynInst' })
-CpuModel('AlphaFullCPU', 'alpha_o3_exec.cc',
- '#include "cpu/o3/alpha_dyn_inst.hh"',
- { 'CPU_exec_context': 'AlphaDynInst<AlphaSimpleImpl>' })
-
# Expand template with CPU-specific references into a dictionary with
# an entry for each CPU model name. The entry key is the model name
# and the corresponding value is the template with the CPU-specific
@@ -757,7 +720,7 @@ def expand_cpu_symbols_to_dict(template):
# Protect '%'s that don't go with CPU-specific terms
t = re.sub(r'%(?!\(CPU_)', '%%', template)
result = {}
- for cpu in CpuModel.list:
+ for cpu in cpu_models:
result[cpu.name] = t % cpu.strings
return result
@@ -816,7 +779,7 @@ class GenCode:
# concatenates all the individual strings in the operands.
def __add__(self, other):
exec_output = {}
- for cpu in CpuModel.list:
+ for cpu in cpu_models:
n = cpu.name
exec_output[n] = self.exec_output[n] + other.exec_output[n]
return GenCode(self.header_output + other.header_output,
@@ -830,7 +793,7 @@ class GenCode:
self.header_output = pre + self.header_output
self.decoder_output = pre + self.decoder_output
self.decode_block = pre + self.decode_block
- for cpu in CpuModel.list:
+ for cpu in cpu_models:
self.exec_output[cpu.name] = pre + self.exec_output[cpu.name]
# Wrap the decode block in a pair of strings (e.g., 'case foo:'
@@ -1351,6 +1314,7 @@ class MemOperand(Operand):
def makeAccSize(self):
return self.size
+
class NPCOperand(Operand):
def makeConstructor(self):
return ''
@@ -1361,6 +1325,15 @@ class NPCOperand(Operand):
def makeWrite(self):
return 'xc->setNextPC(%s);\n' % self.base_name
+class NNPCOperand(Operand):
+ def makeConstructor(self):
+ return ''
+
+ def makeRead(self):
+ return '%s = xc->readPC() + 8;\n' % self.base_name
+
+ def makeWrite(self):
+ return 'xc->setNextNPC(%s);\n' % self.base_name
def buildOperandNameMap(userDict, lineno):
global operandNameMap
@@ -1686,6 +1659,8 @@ namespace %(namespace)s {
%(namespace_output)s
} // namespace %(namespace)s
+
+%(decode_function)s
'''
@@ -1739,7 +1714,7 @@ def preprocess_isa_desc(isa_desc):
#
# Read in and parse the ISA description.
#
-def parse_isa_desc(isa_desc_file, output_dir, include_path):
+def parse_isa_desc(isa_desc_file, output_dir):
# set a global var for the input filename... used in error messages
global input_filename
input_filename = isa_desc_file
@@ -1765,24 +1740,33 @@ def parse_isa_desc(isa_desc_file, output_dir, include_path):
includes = '#include "base/bitfield.hh" // for bitfield support'
global_output = global_code.header_output
namespace_output = namespace_code.header_output
+ decode_function = ''
update_if_needed(output_dir + '/decoder.hh', file_template % vars())
# generate decoder.cc
- includes = '#include "%s/decoder.hh"' % include_path
+ includes = '#include "decoder.hh"'
global_output = global_code.decoder_output
namespace_output = namespace_code.decoder_output
- namespace_output += namespace_code.decode_block
+ # namespace_output += namespace_code.decode_block
+ decode_function = namespace_code.decode_block
update_if_needed(output_dir + '/decoder.cc', file_template % vars())
# generate per-cpu exec files
- for cpu in CpuModel.list:
- includes = '#include "%s/decoder.hh"\n' % include_path
+ for cpu in cpu_models:
+ includes = '#include "decoder.hh"\n'
includes += cpu.includes
global_output = global_code.exec_output[cpu.name]
namespace_output = namespace_code.exec_output[cpu.name]
+ decode_function = ''
update_if_needed(output_dir + '/' + cpu.filename,
file_template % vars())
+# global list of CpuModel objects (see cpu_models.py)
+cpu_models = []
+
# Called as script: get args from command line.
+# Args are: <path to cpu_models.py> <isa desc file> <output dir> <cpu models>
if __name__ == '__main__':
- parse_isa_desc(sys.argv[1], sys.argv[2], sys.argv[3])
+ execfile(sys.argv[1]) # read in CpuModel definitions
+ cpu_models = [CpuModel.dict[cpu] for cpu in sys.argv[4:]]
+ parse_isa_desc(sys.argv[2], sys.argv[3])
diff --git a/arch/isa_specific.hh b/arch/isa_specific.hh
new file mode 100644
index 000000000..44f8e9d64
--- /dev/null
+++ b/arch/isa_specific.hh
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2003-2005 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.
+ */
+
+#ifndef __ARCH_ISA_SPECIFIC_HH__
+#define __ARCH_ISA_SPECIFIC_HH__
+
+//This file provides a mechanism for other source code to bring in
+//files from the ISA being compiled with
+
+//These are constants so you can selective compile code based on the isa
+//To use them, do something like
+//
+//#if THE_ISA == YOUR_FAVORITE_ISA
+// conditional_code
+//#endif
+//
+//Note that this is how this file sets up the other isa "hooks"
+
+//These macros have numerical values because otherwise the preprocessor
+//would treat them as 0 in comparisons.
+#define ALPHA_ISA 21064
+#define SPARC_ISA 42
+#define MIPS_ISA 1337
+
+//These tell the preprocessor where to find the files of a particular
+//ISA, and set the "TheISA" macro for use elsewhere.
+#if THE_ISA == ALPHA_ISA
+ #define TheISA AlphaISA
+#elif THE_ISA == SPARC_ISA
+ #define TheISA SparcISA
+#elif THE_ISA == MIPS_ISA
+ #define TheISA MipsISA
+#else
+ #error "THE_ISA not set"
+#endif
+
+#endif
diff --git a/arch/mips/SConscript b/arch/mips/SConscript
index bd67c98e9..b8efa7ef9 100644
--- a/arch/mips/SConscript
+++ b/arch/mips/SConscript
@@ -40,42 +40,44 @@ Import('env')
###################################################
# Base sources used by all configurations.
-arch_base_sources = Split('''
- arch/mips/decoder.cc
- arch/mips/alpha_o3_exec.cc
- arch/mips/fast_cpu_exec.cc
- arch/mips/simple_cpu_exec.cc
- arch/mips/full_cpu_exec.cc
- arch/mips/faults.cc
- arch/mips/isa_traits.cc
+base_sources = Split('''
+ faults.cc
+ isa_traits.cc
''')
# Full-system sources
-arch_full_system_sources = Split('''
- arch/mips/alpha_memory.cc
- arch/mips/arguments.cc
- arch/mips/ev5.cc
- arch/mips/osfpal.cc
- arch/mips/stacktrace.cc
- arch/mips/vtophys.cc
+full_system_sources = Split('''
+ memory.cc
+ arguments.cc
+ mips34k.cc
+ osfpal.cc
+ stacktrace.cc
+ vtophys.cc
''')
# Syscall emulation (non-full-system) sources
-arch_syscall_emulation_sources = Split('''
- arch/mips/alpha_common_syscall_emul.cc
- arch/mips/alpha_linux_process.cc
- arch/mips/alpha_tru64_process.cc
+syscall_emulation_sources = Split('''
+ common_syscall_emul.cc
+ linux_process.cc
+ tru64_process.cc
''')
# Set up complete list of sources based on configuration.
-sources = arch_base_sources
+sources = base_sources
if env['FULL_SYSTEM']:
- sources += arch_full_system_sources
+ sources += full_system_sources
else:
- sources += arch_syscall_emulation_sources
+ sources += syscall_emulation_sources
-for opt in env.ExportOptions:
- env.ConfigFile(opt)
+# Convert file names to SCons File objects. This takes care of the
+# path relative to the top of the directory tree.
+sources = [File(s) for s in sources]
+
+# Add in files generated by the ISA description.
+isa_desc_files = env.ISADesc('isa/main.isa')
+# Only non-header files need to be compiled.
+isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')]
+sources += isa_desc_sources
Return('sources')
diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa
new file mode 100644
index 000000000..846d161b9
--- /dev/null
+++ b/arch/mips/isa/base.isa
@@ -0,0 +1,63 @@
+// -*- mode:c++ -*-
+
+////////////////////////////////////////////////////////////////////
+//
+// Base class for MIPS instructions, and some support functions
+//
+
+//Outputs to decoder.hh
+output header {{
+ /**
+ * Base class for all MIPS static instructions.
+ */
+ class MipsStaticInst : public StaticInst<MIPSISA>
+ {
+ protected:
+
+ // Constructor.
+ MipsStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : StaticInst<MIPSISA>(mnem, _machInst, __opClass)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ };
+
+}};
+
+//Ouputs to decoder.cc
+output decoder {{
+
+ std::string MipsStaticInst::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ std::stringstream ss;
+
+ ccprintf(ss, "%-10s ", mnemonic);
+
+ // 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]);
+ }
+
+ // just print the first dest... if there's a second one,
+ // it's generally implicit
+ if(_numDestRegs > 0)
+ {
+ if(_numSrcRegs > 0)
+ ss << ",";
+ printReg(ss, _destRegIdx[0]);
+ }
+
+ return ss.str();
+ }
+
+}};
+
diff --git a/arch/mips/isa/bitfields.isa b/arch/mips/isa/bitfields.isa
index bead9c151..532b3793a 100644
--- a/arch/mips/isa/bitfields.isa
+++ b/arch/mips/isa/bitfields.isa
@@ -1,3 +1,5 @@
+// -*- mode:c++ -*-
+
////////////////////////////////////////////////////////////////////
//
// Bitfield definitions.
@@ -41,7 +43,7 @@ def bitfield SC < 5: 5>;
// Branch format
def bitfield OFFSET <15: 0>; // displacement
-// Memory-format jumps
+// Jmp format
def bitfield JMPTARG <25: 0>;
def bitfield JMPHINT <10: 6>;
diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa
index 6bb5bf4d8..7dd08ac49 100644
--- a/arch/mips/isa/decoder.isa
+++ b/arch/mips/isa/decoder.isa
@@ -1,3 +1,5 @@
+// -*- mode:c++ -*-
+
////////////////////////////////////////////////////////////////////
//
// The actual MIPS32 ISA decoder
@@ -12,183 +14,196 @@
decode OPCODE_HI default Unknown::unknown() {
// Derived From ... Table A-2 MIPS32 ISA Manual
- 0x0: decode OPCODE_LO default FailUnimpl::reserved(){
+ 0x0: decode OPCODE_LO {
0x0: decode FUNCTION_HI {
0x0: decode FUNCTION_LO {
- 0x1: decode MOVCI {
- format BasicOp {
- 0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}});
- 1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}});
+ 0x1: decode MOVCI {
+ format BasicOp {
+ 0: movf({{ if( xc->miscRegs.fpcr == 0) Rd = Rs}});
+ 1: movt({{ if( xc->miscRegs.fpcr == 1) Rd = Rs}});
+ }
}
- }
- format BasicOp {
+ format BasicOp {
- //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
- //are used to distinguish among the SLL, NOP, SSNOP and EHB functions."
+ //Table A-3 Note: "1. Specific encodings of the rt, rd, and sa fields
+ //are used to distinguish among the SLL, NOP, SSNOP and EHB functions."
- 0x0: sll({{ Rd = Rt.uw << SA; }});
+ 0x0: sll({{ Rd = Rt.uw << SA; }});
- 0x2: decode SRL {
- 0: srl({{ Rd = Rt.uw >> SA; }});
+ 0x2: decode SRL {
+ 0: srl({{ Rd = Rt.uw >> SA; }});
- //Hardcoded assuming 32-bit ISA, probably need parameter here
- 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}});
- }
+ //Hardcoded assuming 32-bit ISA, probably need parameter here
+ 1: rotr({{ Rd = (Rt.uw << (32 - SA)) | (Rt.uw >> SA);}});
+ }
- 0x3: sra({{ Rd = Rt.sw >> SA; }});
+ 0x3: sra({{ Rd = Rt.sw >> SA; }});
- 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }});
+ 0x4: sllv({{ Rd = Rt.uw << Rs<4:0>; }});
- 0x6: decode SRLV {
- 0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }});
+ 0x6: decode SRLV {
+ 0: srlv({{ Rd = Rt.uw >> Rs<4:0>; }});
- //Hardcoded assuming 32-bit ISA, probably need parameter here
- 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}});
- }
+ //Hardcoded assuming 32-bit ISA, probably need parameter here
+ 1: rotrv({{ Rd = (Rt.uw << (32 - Rs<4:0>)) | (Rt.uw >> Rs<4:0>);}});
+ }
- 0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }});
- }
+ 0x7: srav({{ Rd = Rt.sw >> Rs<4:0>; }});
+ }
}
0x1: decode FUNCTION_LO {
- //Table A-3 Note: "Specific encodings of the hint field are used
- //to distinguish JR from JR.HB and JALR from JALR.HB"
- format Jump {
- 0x0: jr(IsReturn);
- 0x1: jalr(IsCall,IsReturn);
- }
+ //Table A-3 Note: "Specific encodings of the hint field are used
+ //to distinguish JR from JR.HB and JALR from JALR.HB"
+ format Jump {
+ 0x0: decode HINT {
+ 0:jr({{ NNPC = Rs; }},IsReturn);
+
+ 1:jr_hb({{ NNPC = Rs; clear_exe_inst_hazards(); }},IsReturn);
+ }
+
+ 0x1: decode HINT {
+ 0: jalr({{ NNPC = Rs; }},IsCall,IsReturn);
- format BasicOp {
- 0x2: movz({{ if (Rt == 0) Rd = Rs; }});
- 0x3: movn({{ if (Rt != 0) Rd = Rs; }});
- }
+ 1: jalr_hb({{ NNPC = Rs; clear_exe_inst_hazards();}},IsCall,IsReturn);
+ }
+ }
+ format BasicOp {
+ 0x2: movz({{ if (Rt == 0) Rd = Rs; }});
+ 0x3: movn({{ if (Rt != 0) Rd = Rs; }});
+ }
- format WarnUnimpl {
- 0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative
- 0x5: break();
- 0x7: sync();
- }
+ format WarnUnimpl {
+ 0x4: syscall();//{{ xc->syscall()}},IsNonSpeculative
+ 0x5: break();
+ 0x7: sync();
+ }
}
0x2: decode FUNCTION_LO {
- format BasicOp {
- 0x0: mfhi({{ Rd = xc->miscRegs.hi; }});
- 0x1: mthi({{ xc->miscRegs.hi = Rs; }});
- 0x2: mflo({{ Rd = xc->miscRegs.lo; }});
- 0x3: mtlo({{ xc->miscRegs.lo = Rs; }});
- }
+ format BasicOp {
+ 0x0: mfhi({{ Rd = xc->miscRegs.hi; }});
+ 0x1: mthi({{ xc->miscRegs.hi = Rs; }});
+ 0x2: mflo({{ Rd = xc->miscRegs.lo; }});
+ 0x3: mtlo({{ xc->miscRegs.lo = Rs; }});
+ }
}
0x3: decode FUNCTION_LO {
- format IntOp {
- 0x0: mult({{
+ format IntOp {
+ 0x0: mult({{
INT64 temp1 = Rs.sw * Rt.sw;
xc->miscRegs.hi->temp1<63:32>;
xc->miscRegs.lo->temp1<31:0>;
- }});
+ }});
- 0x1: multu({{
+ 0x1: multu({{
INT64 temp1 = Rs.uw * Rt.uw;
xc->miscRegs.hi->temp1<63:32>;
xc->miscRegs.lo->temp1<31:0>
- Rd.sw = Rs.uw * Rt.uw;
- }});
+ Rd.sw = Rs.uw * Rt.uw;
+ }});
- 0x2: div({{
+ 0x2: div({{
xc->miscRegs.hi = Rs.sw % Rt.sw;
xc->miscRegs.lo = Rs.sw / Rt.sw;
- }});
+ }});
- 0x3: divu({{
+ 0x3: divu({{
xc->miscRegs.hi = Rs.uw % Rt.uw;
xc->miscRegs.lo = Rs.uw / Rt.uw;
- }});
- }
+ }});
+ }
}
0x4: decode FUNCTION_LO {
- format IntOp {
- 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;}});
- 0x1: addu({{ Rd.uw = Rs.uw + Rt.uw;}});
- 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;}});
- 0x3: subu({{ Rd.uw = Rs.uw - Rt.uw;}});
- 0x4: and({{ Rd.sw = Rs.uw & Rt.uw;}});
- 0x5: or({{ Rd.sw = Rs.uw | Rt.uw;}});
- 0x6: xor({{ Rd.sw = Rs.uw ^ Rt.uw;}});
- 0x7: nor({{ Rd.sw = ~(Rs.uw | Rt.uw);}});
- }
+ format IntOp {
+ 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;}});
+ 0x1: addu({{ Rd.uw = Rs.uw + Rt.uw;}});
+ 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw;}});
+ 0x3: subu({{ Rd.uw = Rs.uw - Rt.uw;}});
+ 0x4: and({{ Rd.sw = Rs.uw & Rt.uw;}});
+ 0x5: or({{ Rd.sw = Rs.uw | Rt.uw;}});
+ 0x6: xor({{ Rd.sw = Rs.uw ^ Rt.uw;}});
+ 0x7: nor({{ Rd.sw = ~(Rs.uw | Rt.uw);}});
+ }
}
0x5: decode FUNCTION_LO {
- format IntOp{
- 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}});
- 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}});
- }
+ format IntOp{
+ 0x2: slt({{ Rd.sw = ( Rs.sw < Rt.sw ) ? 1 : 0}});
+ 0x3: sltu({{ Rd.uw = ( Rs.uw < Rt.uw ) ? 1 : 0}});
+ }
}
0x6: decode FUNCTION_LO {
- format Trap {
- 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }});
- 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }});
- 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }});
- 0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }});
- 0x4: teq({{ cond = (Rs.sw == Rt.sw); }});
- 0x6: tne({{ cond = (Rs.sw != Rt.sw); }});
- }
+ format Trap {
+ 0x0: tge({{ cond = (Rs.sw >= Rt.sw); }});
+ 0x1: tgeu({{ cond = (Rs.uw >= Rt.uw); }});
+ 0x2: tlt({{ cond = (Rs.sw < Rt.sw); }});
+ 0x3: tltu({{ cond = (Rs.uw >= Rt.uw); }});
+ 0x4: teq({{ cond = (Rs.sw == Rt.sw); }});
+ 0x6: tne({{ cond = (Rs.sw != Rt.sw); }});
+ }
}
}
0x1: decode REGIMM_HI {
0x0: decode REGIMM_LO {
- format CondBranch {
- 0x0: bltz({{ cond = (Rs.sw < 0); }});
- 0x1: bgez({{ cond = (Rs.sw >= 0); }});
-
- //MIPS obsolete instructions
- 0x2: bltzl({{ cond = (Rs.sw < 0); }});
- 0x3: bgezl({{ cond = (Rs.sw >= 0); }});
- }
+ format Branch {
+ 0x0: bltz({{ cond = (Rs.sw < 0); }});
+ 0x1: bgez({{ cond = (Rs.sw >= 0); }});
+ }
+
+ format BranchLikely {
+ //MIPS obsolete instructions
+ 0x2: bltzl({{ cond = (Rs.sw < 0); }});
+ 0x3: bgezl({{ cond = (Rs.sw >= 0); }});
+ }
}
0x1: decode REGIMM_LO {
- format Trap {
- 0x0: tgei({{ cond = (Rs.sw >= INTIMM; }});
- 0x1: tgeiu({{ cond = (Rs.uw < INTIMM); }});
- 0x2: tlti({{ cond = (Rs.sw < INTIMM); }});
- 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }});
- 0x4: teqi({{ cond = (Rs.sw == INTIMM); }});
- 0x6: tnei({{ cond = (Rs.sw != INTIMM); }});
- }
+ format Trap {
+ 0x0: tgei( {{ cond = (Rs.sw >= INTIMM); }});
+ 0x1: tgeiu({{ cond = (Rs.uw >= INTIMM); }});
+ 0x2: tlti( {{ cond = (Rs.sw < INTIMM); }});
+ 0x3: tltiu({{ cond = (Rs.uw < INTIMM); }});
+ 0x4: teqi( {{ cond = (Rs.sw == INTIMM);}});
+ 0x6: tnei( {{ cond = (Rs.sw != INTIMM);}});
+ }
}
0x2: decode REGIMM_LO {
- format CondBranch {
- 0x0: bltzal({{ cond = (Rs.sw < 0); }});
- 0x1: bgezal({{ cond = (Rs.sw >= 0); }});
-
- //MIPS obsolete instructions
- 0x2: bltzall({{ cond = (Rs.sw < 0); }});
- 0x3: bgezall({{ cond = (Rs.sw >= 0); }});
- }
+ format Branch {
+ 0x0: bltzal({{ cond = (Rs.sw < 0); }}, IsLink);
+ 0x1: bgezal({{ cond = (Rs.sw >= 0); }}, IsLink);
+ }
+
+ format BranchLikely {
+ //Will be removed in future MIPS releases
+ 0x2: bltzall({{ cond = (Rs.sw < 0); }}, IsLink);
+ 0x3: bgezall({{ cond = (Rs.sw >= 0); }}, IsLink);
+ }
}
0x3: decode REGIMM_LO {
- format WarnUnimpl {
- 0x7: synci();
- }
+ format WarnUnimpl {
+ 0x7: synci();
+ }
}
}
format Jump {
- 0x2: j();
- 0x3: jal(IsCall);
+ 0x2: j({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}});
+
+ 0x3: jal({{ NNPC = (NPC & 0xF0000000) & (0x00000000 & JMPTARG << 2);}},IsCall,IsReturn);
}
- format CondBranch {
+ format Branch {
0x4: beq({{ cond = (Rs.sw == 0); }});
0x5: bne({{ cond = (Rs.sw != 0); }});
0x6: blez({{ cond = (Rs.sw <= 0); }});
@@ -196,7 +211,7 @@ decode OPCODE_HI default Unknown::unknown() {
}
}
- 0x1: decode OPCODE_LO default FailUnimpl::reserved(){
+ 0x1: decode OPCODE_LO {
format IntOp {
0x0: addi({{ Rt.sw = Rs.sw + INTIMM; }});
0x1: addiu({{ Rt.uw = Rs.uw + INTIMM;}});
@@ -209,539 +224,534 @@ decode OPCODE_HI default Unknown::unknown() {
}
}
- 0x2: decode OPCODE_LO default FailUnimpl::reserved(){
-
- //Table A-11 MIPS32 COP0 Encoding of rs Field
- 0x0: decode RS_MSB {
- 0x0: decode RS {
+ 0x2: decode OPCODE_LO {
- format BasicOp {
- 0x0: mfc0({{
+ //Table A-11 MIPS32 COP0 Encoding of rs Field
+ 0x0: decode RS_MSB {
+ 0x0: decode RS {
+ format BasicOp {
+ 0x0: mfc0({{
//The contents of the coprocessor 0 register specified by the
//combination of rd and sel are loaded into general register
//rt. Note that not all coprocessor 0 registers support the
//sel field. In those instances, the sel field must be zero.
if (SEL > 0)
- panic("Can't Handle Cop0 with register select yet\n");
+ panic("Can't Handle Cop0 with register select yet\n");
uint64_t reg_num = Rd.uw;
Rt = xc->miscRegs.cop0[reg_num];
- }});
+ }});
- 0x4: mtc0({{
+ 0x4: mtc0({{
//The contents of the coprocessor 0 register specified by the
//combination of rd and sel are loaded into general register
//rt. Note that not all coprocessor 0 registers support the
//sel field. In those instances, the sel field must be zero.
if (SEL > 0)
- panic("Can't Handle Cop0 with register select yet\n");
+ panic("Can't Handle Cop0 with register select yet\n");
uint64_t reg_num = Rd.uw;
xc->miscRegs.cop0[reg_num] = Rt;
- }});
+ }});
- 0x8: mftr({{
+ 0x8: mftr({{
//The contents of the coprocessor 0 register specified by the
//combination of rd and sel are loaded into general register
//rt. Note that not all coprocessor 0 registers support the
//sel field. In those instances, the sel field must be zero.
//MT Code Needed Here
- }});
+ }});
- 0xC: mttr({{
+ 0xC: mttr({{
//The contents of the coprocessor 0 register specified by the
//combination of rd and sel are loaded into general register
//rt. Note that not all coprocessor 0 registers support the
//sel field. In those instances, the sel field must be zero.
//MT Code Needed Here
- }});
+ }});
- 0xA: rdpgpr({{
+ 0xA: rdpgpr({{
//Accessing Previous Shadow Set Register Number
uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS];
uint64_t reg_num = Rt.uw;
Rd = xc->shadowIntRegFile[prev][reg_num];
- }});
- }
+ }});
- 0xB: decode RD {
+ 0xB: decode RD {
- 0x0: decode SC {
- format BasicOp {
- 0x0: dvpe({{
- Rt.sw = xc->miscRegs.cop0.MVPControl;
- xc->miscRegs.cop0.MVPControl[EVP] = 0;
- }});
+ 0x0: decode SC {
+ 0x0: dvpe({{
+ Rt.sw = xc->miscRegs.cop0.MVPControl;
+ xc->miscRegs.cop0.MVPControl[EVP] = 0;
+ }});
- 0x1: evpe({{
- Rt.sw = xc->miscRegs.cop0.MVPControl;
- xc->miscRegs.cop0.MVPControl[EVP] = 1;
- }});
- }
- }
+ 0x1: evpe({{
+ Rt.sw = xc->miscRegs.cop0.MVPControl;
+ xc->miscRegs.cop0.MVPControl[EVP] = 1;
+ }});
+ }
- 0x1: decode SC {
- format BasicOp {
- 0x0: dmt({{
- Rt.sw = xc->miscRegs.cop0.VPEControl;
- xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 0;
- }});
+ 0x1: decode SC {
+ 0x0: dmt({{
+ Rt.sw = xc->miscRegs.cop0.VPEControl;
+ xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 0;
+ }});
- 0x1: emt({{
- Rt.sw = xc->miscRegs.cop0.VPEControl;
- xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 1;
- }});
- }
- }
+ 0x1: emt({{
+ Rt.sw = xc->miscRegs.cop0.VPEControl;
+ xc->miscRegs.cop0.VPEControl[THREAD_ENABLE] = 1;
+ }});
+ }
- 0xC: decode SC {
- format BasicOp {
- 0x0: di({{
- Rt.sw = xc->miscRegs.cop0.Status;
- xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 0;
- }});
+ 0xC: decode SC {
+ 0x0: di({{
+ Rt.sw = xc->miscRegs.cop0.Status;
+ xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 0;
+ }});
- 0x1: ei({{
- Rt.sw = xc->miscRegs.cop0.Status;
- xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 1;
- }});
- }
- }
- }
+ 0x1: ei({{
+ Rt.sw = xc->miscRegs.cop0.Status;
+ xc->miscRegs.cop0.Status[INTERRUPT_ENABLE] = 1;
+ }});
+ }
+ }
- 0xE: BasicOp::wrpgpr({{
+ 0xE: wrpgpr({{
//Accessing Previous Shadow Set Register Number
uint64_t prev = xc->miscRegs.cop0[SRSCtl][PSS];
uint64_t reg_num = Rd.uw;
xc->shadowIntRegFile[prev][reg_num] = Rt;
- }});
- }
-
- //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
- 0x1: decode FUNCTION {
- format Trap {
- 0x01: tlbr({{ }});
- 0x02: tlbwi({{ }});
- 0x06: tlbwr({{ }});
- 0x08: tlbp({{ }});
- }
-
- format WarnUnimpl {
- 0x18: eret();
- 0x1F: deret();
- 0x20: wait();
- }
- }
- }
-
- //Table A-13 MIPS32 COP1 Encoding of rs Field
- 0x1: decode RS_MSB {
-
- 0x0: decode RS_HI {
- 0x0: decode RS_LO {
- format FloatOp {
- 0x0: mfc1({{ Rt = Fs<31:0>; }});
- 0x2: cfc1({{ Rt = xc->miscRegs.fpcr[Fs];}});
- 0x3: mfhc1({{ Rt = Fs<63:32>;}});
- 0x4: mtc1({{ Fs<31:0> = Rt}});
- 0x6: ctc1({{ xc->miscRegs.fpcr[Fs] = Rt;}});
- 0x7: mftc1({{ Fs<63:32> = Rt}});
- }
- }
-
- 0x1: decode ND {
- 0x0: decode TF {
- format CondBranch {
- 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }});
- 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }});
- }
+ }});
+ }
}
- 0x1: decode TF {
- format CondBranch {
- 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }});
- 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }});
- }
+ //Table A-12 MIPS32 COP0 Encoding of Function Field When rs=CO
+ 0x1: decode FUNCTION {
+ format Trap {
+ 0x01: tlbr({{ }});
+ 0x02: tlbwi({{ }});
+ 0x06: tlbwr({{ }});
+ 0x08: tlbp({{ }});
+ }
+
+ format WarnUnimpl {
+ 0x18: eret();
+ 0x1F: deret();
+ 0x20: wait();
+ }
}
- }
}
- 0x1: decode RS_HI {
- 0x2: decode RS_LO {
+ //Table A-13 MIPS32 COP1 Encoding of rs Field
+ 0x1: decode RS_MSB {
- //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
- //(( single-word ))
0x0: decode RS_HI {
- 0x0: decode RS_LO {
- format FloatOp {
- 0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}});
- 0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}});
- 0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}});
- 0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}});
- 0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}});
- 0x5: abss({{ Fd.sf = abs(Fs.sf);}});
- 0x6: movs({{ Fd.sf = Fs.sf;}});
- 0x7: negs({{ Fd.sf = -1 * Fs.sf;}});
- }
- }
-
- 0x1: decode RS_LO {
- //only legal for 64 bit-FP
- format Float64Op {
- 0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}});
- 0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}});
- 0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}});
- 0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}});
- }
-
- format FloatOp {
- 0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}});
- 0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}});
- 0x6: ceil_w_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}});
- 0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}});
- }
- }
-
- 0x2: decode RS_LO {
- 0x1: decode MOVCF {
- format FloatOp {
- 0x0: movfs({{ if ( FPConditionCode(CC) == 0 ) Fd = Fs; }});
- 0x1: movts({{ if ( FPConditionCode(CC) == 1 ) Fd = Fs;}});
- }
+ 0x0: decode RS_LO {
+ format FloatOp {
+ 0x0: mfc1({{ Rt = Fs<31:0>; }});
+ 0x2: cfc1({{ Rt = xc->miscRegs.fpcr[Fs];}});
+ 0x3: mfhc1({{ Rt = Fs<63:32>;}});
+ 0x4: mtc1({{ Fs<31:0> = Rt}});
+ 0x6: ctc1({{ xc->miscRegs.fpcr[Fs] = Rt;}});
+ 0x7: mftc1({{ Fs<63:32> = Rt}});
+ }
}
- format BasicOp {
- 0x2: movzs({{ if (Rt == 0) Fd = Fs; }});
- 0x3: movns({{ if (Rt != 0) Fd = Fs; }});
- }
+ 0x1: decode ND {
+ 0x0: decode TF {
+ format Branch {
+ 0x0: bc1f({{ cond = (xc->miscRegs.fpcr == 0); }});
+ 0x1: bc1t({{ cond = (xc->miscRegs.fpcr == 1); }});
+ }
+ }
- format Float64Op {
- 0x2: recips({{ Fd = 1 / Fs; }});
- 0x3: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}});
+ 0x1: decode TF {
+ format BranchLikely {
+ 0x0: bc1fl({{ cond = (xc->miscRegs.fpcr == 0); }});
+ 0x1: bc1tl({{ cond = (xc->miscRegs.fpcr == 1); }});
+ }
+ }
}
- }
+ }
+
+ 0x1: decode RS_HI {
+ 0x2: decode RS_LO {
+
+ //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S
+ //(( single-word ))
+ 0x0: decode RS_HI {
+ 0x0: decode RS_LO {
+ format FloatOp {
+ 0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}});
+ 0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}});
+ 0x2: muls({{ Fd.sf = Fs.sf * Ft.sf;}});
+ 0x3: divs({{ Fd.sf = Fs.sf / Ft.sf;}});
+ 0x4: sqrts({{ Fd.sf = sqrt(Fs.sf);}});
+ 0x5: abss({{ Fd.sf = abs(Fs.sf);}});
+ 0x6: movs({{ Fd.sf = Fs.sf;}});
+ 0x7: negs({{ Fd.sf = -1 * Fs.sf;}});
+ }
+ }
+
+ 0x1: decode RS_LO {
+ //only legal for 64 bit-FP
+ format Float64Op {
+ 0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}});
+ 0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}});
+ 0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}});
+ 0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}});
+ }
+
+ format FloatOp {
+ 0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}});
+ 0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}});
+ 0x6: ceil_w_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}});
+ 0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}});
+ }
+ }
+
+ 0x2: decode RS_LO {
+ 0x1: decode MOVCF {
+ format FloatOp {
+ 0x0: movfs({{ if ( FPConditionCode(CC) == 0 ) Fd = Fs; }});
+ 0x1: movts({{ if ( FPConditionCode(CC) == 1 ) Fd = Fs;}});
+ }
+ }
+
+ format BasicOp {
+ 0x2: movzs({{ if (Rt == 0) Fd = Fs; }});
+ 0x3: movns({{ if (Rt != 0) Fd = Fs; }});
+ }
+
+ format Float64Op {
+ 0x2: recips({{ Fd = 1 / Fs; }});
+ 0x3: rsqrts({{ Fd = 1 / sqrt(Fs.ud);}});
+ }
+ }
- 0x4: decode RS_LO {
+ 0x4: decode RS_LO {
- format FloatOp {
- 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr;
+ format FloatOp {
+ 0x1: cvt_d_s({{ int rnd_mode = xc->miscRegs.fcsr;
Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE);
- }});
+ }});
- 0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr;
+ 0x4: cvt_w_s({{ int rnd_mode = xc->miscRegs.fcsr;
Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE);
- }});
- }
+ }});
+ }
- //only legal for 64 bit
- format Float64Op {
- 0x5: cvt_l_s({{ int rnd_mode = xc->miscRegs.fcsr;
+ //only legal for 64 bit
+ format Float64Op {
+ 0x5: cvt_l_s({{ int rnd_mode = xc->miscRegs.fcsr;
Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE);
- }});
-
- 0x6: cvt_ps_s({{ Fd.df = Fs.df<31:0> | Ft.df<31:0>; }});
- }
- }
- }
+ }});
- //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
- 0x1: decode RS_HI {
- 0x0: decode RS_LO {
- format FloatOp {
- 0x0: addd({{ Fd.df = Fs.df + Ft.df;}});
- 0x1: subd({{ Fd.df = Fs.df - Ft.df;}});
- 0x2: muld({{ Fd.df = Fs.df * Ft.df;}});
- 0x3: divd({{ Fd.df = Fs.df / Ft.df;}});
- 0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}});
- 0x5: absd({{ Fd.df = abs(Fs.df);}});
- 0x6: movd({{ Fd.df = Fs.df;}});
- 0x7: negd({{ Fd.df = -1 * Fs.df;}});
- }
- }
-
- 0x1: decode RS_LO {
- //only legal for 64 bit
- format Float64Op {
- 0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
- 0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}});
- 0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}});
- 0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}});
- }
-
- format FloatOp {
- 0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
- 0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }});
- 0x6: ceil_w_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }});
- 0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }});
- }
- }
-
- 0x2: decode RS_LO {
- 0x1: decode MOVCF {
- format FloatOp {
- 0x0: movfd({{ if (FPConditionCode(CC) == 0) Fd.df = Fs.df; }});
- 0x1: movtd({{ if (FPConditionCode(CC) == 1) Fd.df = Fs.df; }});
- }
- }
+ 0x6: cvt_ps_s({{ Fd.df = Fs.df<31:0> | Ft.df<31:0>; }});
+ }
+ }
+ }
+
+ //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D
+ 0x1: decode RS_HI {
+ 0x0: decode RS_LO {
+ format FloatOp {
+ 0x0: addd({{ Fd.df = Fs.df + Ft.df;}});
+ 0x1: subd({{ Fd.df = Fs.df - Ft.df;}});
+ 0x2: muld({{ Fd.df = Fs.df * Ft.df;}});
+ 0x3: divd({{ Fd.df = Fs.df / Ft.df;}});
+ 0x4: sqrtd({{ Fd.df = sqrt(Fs.df);}});
+ 0x5: absd({{ Fd.df = abs(Fs.df);}});
+ 0x6: movd({{ Fd.df = Fs.df;}});
+ 0x7: negd({{ Fd.df = -1 * Fs.df;}});
+ }
+ }
- format BasicOp {
- 0x2: movz({{ if (Rt == 0) Fd.df = Fs.df; }});
- 0x3: movn({{ if (Rt != 0) Fd.df = Fs.df; }});
- }
+ 0x1: decode RS_LO {
+ //only legal for 64 bit
+ format Float64Op {
+ 0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
+ 0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}});
+ 0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}});
+ 0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}});
+ }
+
+ format FloatOp {
+ 0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }});
+ 0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }});
+ 0x6: ceil_w_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }});
+ 0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }});
+ }
+ }
- format Float64Op {
- 0x5: recipd({{ Fd.df = 1 / Fs.df}});
- 0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }});
- }
- }
+ 0x2: decode RS_LO {
+ 0x1: decode MOVCF {
+ format FloatOp {
+ 0x0: movfd({{ if (FPConditionCode(CC) == 0) Fd.df = Fs.df; }});
+ 0x1: movtd({{ if (FPConditionCode(CC) == 1) Fd.df = Fs.df; }});
+ }
+ }
+
+ format BasicOp {
+ 0x2: movz({{ if (Rt == 0) Fd.df = Fs.df; }});
+ 0x3: movn({{ if (Rt != 0) Fd.df = Fs.df; }});
+ }
+
+ format Float64Op {
+ 0x5: recipd({{ Fd.df = 1 / Fs.df}});
+ 0x6: rsqrtd({{ Fd.df = 1 / sqrt(Fs.df) }});
+ }
+ }
- 0x4: decode RS_LO {
- format FloatOp {
- 0x0: cvt_s_d({{
- int rnd_mode = xc->miscRegs.fcsr;
- Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE);
- }});
+ 0x4: decode RS_LO {
+ format FloatOp {
+ 0x0: cvt_s_d({{
+ int rnd_mode = xc->miscRegs.fcsr;
+ Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE);
+ }});
- 0x4: cvt_w_d({{
- int rnd_mode = xc->miscRegs.fcsr;
- Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE);
- }});
- }
+ 0x4: cvt_w_d({{
+ int rnd_mode = xc->miscRegs.fcsr;
+ Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE);
+ }});
+ }
- //only legal for 64 bit
- format Float64Op {
- 0x5: cvt_l_d({{
- int rnd_mode = xc->miscRegs.fcsr;
- Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE);
- }});
- }
- }
- }
+ //only legal for 64 bit
+ format Float64Op {
+ 0x5: cvt_l_d({{
+ int rnd_mode = xc->miscRegs.fcsr;
+ Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE);
+ }});
+ }
+ }
+ }
- //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
- 0x4: decode FUNCTION {
- format FloatOp {
- 0x10: cvt_s({{
+ //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W
+ 0x4: decode FUNCTION {
+ format FloatOp {
+ 0x10: cvt_s({{
int rnd_mode = xc->miscRegs.fcsr;
Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD);
}});
- 0x10: cvt_d({{
+ 0x10: cvt_d({{
int rnd_mode = xc->miscRegs.fcsr;
Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD);
}});
- }
- }
-
- //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1
- //Note: "1. Format type L is legal only if 64-bit floating point operations
- //are enabled."
- 0x5: decode FUNCTION_HI {
- format FloatOp {
- 0x10: cvt_s_l({{
+ }
+ }
+
+ //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=L1
+ //Note: "1. Format type L is legal only if 64-bit floating point operations
+ //are enabled."
+ 0x5: decode FUNCTION_HI {
+ format FloatOp {
+ 0x10: cvt_s_l({{
int rnd_mode = xc->miscRegs.fcsr;
Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG);
}});
- 0x11: cvt_d_l({{
+ 0x11: cvt_d_l({{
int rnd_mode = xc->miscRegs.fcsr;
Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG);
}});
- }
- }
+ }
+ }
+
+ //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
+ //Note: "1. Format type PS is legal only if 64-bit floating point operations
+ //are enabled. "
+ 0x6: decode RS_HI {
+ 0x0: decode RS_LO {
+ format Float64Op {
+ 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = Fs.df + Ft.df;
+ }});
- //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1
- //Note: "1. Format type PS is legal only if 64-bit floating point operations
- //are enabled. "
- 0x6: decode RS_HI {
- 0x0: decode RS_LO {
- format Float64Op {
- 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = Fs.df + Ft.df;
- }});
-
- 0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = Fs.df - Ft.df;
- }});
+ 0x1: subps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = Fs.df - Ft.df;
+ }});
- 0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = Fs.df * Ft.df;
- }});
+ 0x2: mulps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = Fs.df * Ft.df;
+ }});
- 0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = abs(Fs.df);
- }});
+ 0x5: absps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = abs(Fs.df);
+ }});
- 0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = Fs<31:0> | Ft<31:0>;
- }});
+ 0x6: movps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = Fs<31:0> | Ft<31:0>;
+ }});
- 0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = -1 * Fs.df;
- }});
- }
- }
+ 0x7: negps({{ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = -1 * Fs.df;
+ }});
+ }
+ }
- 0x2: decode RS_LO {
- 0x1: decode MOVCF {
- format Float64Op {
- 0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}});
- 0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}});
- }
- }
+ 0x2: decode RS_LO {
+ 0x1: decode MOVCF {
+ format Float64Op {
+ 0x0: movfps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}});
+ 0x1: movtps({{ if ( FPConditionCode(CC) == 0) Fd = Fs;}});
+ }
+ }
- }
+ }
- 0x4: decode RS_LO {
- 0x0: Float64Op::cvt_s_pu({{
+ 0x4: decode RS_LO {
+ 0x0: Float64Op::cvt_s_pu({{
int rnd_mode = xc->miscRegs.fcsr;
Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI);
- }});
- }
+ }});
+ }
- 0x5: decode RS_LO {
- format Float64Op {
- 0x0: cvt_s_pl({{
- int rnd_mode = xc->miscRegs.fcsr;
- Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO);
- }});
- 0x4: pll({{ Fd.df = Fs<31:0> | Ft<31:0>}});
- 0x5: plu({{ Fd.df = Fs<31:0> | Ft<63:32>}});
- 0x6: pul({{ Fd.df = Fs<63:32> | Ft<31:0>}});
- 0x7: puu({{ Fd.df = Fs<63:32 | Ft<63:32>}});
- }
- }
- }
- }
-
- //Table A-19 MIPS32 COP2 Encoding of rs Field
- 0x2: decode RS_MSB {
- 0x0: decode RS_HI {
- 0x0: decode RS_LO {
- format WarnUnimpl {
- 0x0: mfc2();
- 0x2: cfc2();
- 0x3: mfhc2();
- 0x4: mtc2();
- 0x6: ctc2();
- 0x7: mftc2();
- }
- }
-
- 0x1: decode ND {
- 0x0: decode TF {
- format WarnUnimpl {
- 0x0: bc2f();
- 0x1: bc2t();
- }
+ 0x5: decode RS_LO {
+ format Float64Op {
+ 0x0: cvt_s_pl({{
+ int rnd_mode = xc->miscRegs.fcsr;
+ Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO);
+ }});
+ 0x4: pll({{ Fd.df = Fs<31:0> | Ft<31:0>}});
+ 0x5: plu({{ Fd.df = Fs<31:0> | Ft<63:32>}});
+ 0x6: pul({{ Fd.df = Fs<63:32> | Ft<31:0>}});
+ 0x7: puu({{ Fd.df = Fs<63:32 | Ft<63:32>}});
+ }
+ }
+ }
+ }
}
+ }
+
+ //Table A-19 MIPS32 COP2 Encoding of rs Field
+ 0x2: decode RS_MSB {
+ 0x0: decode RS_HI {
+ 0x0: decode RS_LO {
+ format WarnUnimpl {
+ 0x0: mfc2();
+ 0x2: cfc2();
+ 0x3: mfhc2();
+ 0x4: mtc2();
+ 0x6: ctc2();
+ 0x7: mftc2();
+ }
+ }
+
+ 0x1: decode ND {
+ 0x0: decode TF {
+ format WarnUnimpl {
+ 0x0: bc2f();
+ 0x1: bc2t();
+ }
+ }
- 0x1: decode TF {
- format WarnUnimpl {
- 0x0: bc2fl();
- 0x1: bc2tl();
- }
+ 0x1: decode TF {
+ format WarnUnimpl {
+ 0x0: bc2fl();
+ 0x1: bc2tl();
+ }
+ }
+ }
}
- }
}
- }
-
- //Table A-20 MIPS64 COP1X Encoding of Function Field 1
- //Note: "COP1X instructions are legal only if 64-bit floating point
- //operations are enabled."
- 0x3: decode FUNCTION_HI {
- 0x0: decode FUNCTION_LO {
- format Memory {
- 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.uf; }});
- 0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }});
- 0x5: luxc1({{ //Need to make EA<2:0> = 0
- EA = Rs + Rt;
- }},
- {{ Ft<31:0> = Mem.df; }});
+
+ //Table A-20 MIPS64 COP1X Encoding of Function Field 1
+ //Note: "COP1X instructions are legal only if 64-bit floating point
+ //operations are enabled."
+ 0x3: decode FUNCTION_HI {
+ 0x0: decode FUNCTION_LO {
+ format LoadMemory2 {
+ 0x0: lwxc1({{ EA = Rs + Rt; }},{{ Ft<31:0> = Mem.sf; }});
+ 0x1: ldxc1({{ EA = Rs + Rt; }},{{ Ft<63:0> = Mem.df; }});
+ 0x5: luxc1({{ //Need to make EA<2:0> = 0
+ EA = Rs + Rt;
+ }},
+ {{ Ft<31:0> = Mem.df; }});
}
- }
+ }
- 0x1: decode FUNCTION_LO {
- format Memory {
- 0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<31:0>; }});
- 0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.uf = Ft<63:0>}});
- 0x5: suxc1({{ //Need to make EA<2:0> = 0
- EA = Rs + Rt;
- }},
- {{ Mem.df = Ft<63:0>;}});
+ 0x1: decode FUNCTION_LO {
+ format StoreMemory2 {
+ 0x0: swxc1({{ EA = Rs + Rt; }},{{ Mem.sf = Ft<31:0>; }});
+ 0x1: sdxc1({{ EA = Rs + Rt; }},{{ Mem.df = Ft<63:0>}});
+ 0x5: suxc1({{ //Need to make EA<2:0> = 0
+ EA = Rs + Rt;
+ }},
+ {{ Mem.df = Ft<63:0>;}});
}
0x7: WarnUnimpl::prefx();
- }
+ }
- format FloatOp {
+ format FloatOp {
0x3: WarnUnimpl::alnv_ps();
format BasicOp {
- 0x4: decode FUNCTION_LO {
- 0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }});
- 0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }});
- 0x6: madd_ps({{
- //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = (Fs.df * Fs.df) + Fr.df;
- }});
- }
-
- 0x5: decode FUNCTION_LO {
- 0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }});
- 0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }});
- 0x6: msub_ps({{
- //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = (Fs.df * Fs.df) - Fr.df;
- }});
- }
-
- 0x6: decode FUNCTION_LO {
- 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
- 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }});
- 0x6: nmadd_ps({{
- //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
- }});
- }
-
- 0x7: decode FUNCTION_LO {
- 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
- 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }});
- 0x6: nmsub_ps({{
- //Must Check for Exception Here... Supposed to Operate on Upper and
- //Lower Halves Independently but we take simulator shortcut
- Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
- }});
- }
+ 0x4: decode FUNCTION_LO {
+ 0x0: madd_s({{ Fd.sf = (Fs.sf * Fs.sf) + Fr.sf; }});
+ 0x1: madd_d({{ Fd.df = (Fs.df * Fs.df) + Fr.df; }});
+ 0x6: madd_ps({{
+ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = (Fs.df * Fs.df) + Fr.df;
+ }});
+ }
+
+ 0x5: decode FUNCTION_LO {
+ 0x0: msub_s({{ Fd.sf = (Fs.sf * Fs.sf) - Fr.sf; }});
+ 0x1: msub_d({{ Fd.df = (Fs.df * Fs.df) - Fr.df; }});
+ 0x6: msub_ps({{
+ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = (Fs.df * Fs.df) - Fr.df;
+ }});
+ }
+
+ 0x6: decode FUNCTION_LO {
+ 0x0: nmadd_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
+ 0x1: nmadd_d({{ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df; }});
+ 0x6: nmadd_ps({{
+ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
+ }});
+ }
+
+ 0x7: decode FUNCTION_LO {
+ 0x0: nmsub_s({{ Fd.sf = (-1 * Fs.sf * Fs.sf) - Fr.sf; }});
+ 0x1: nmsub_d({{ Fd.df = (-1 * Fs.df * Fs.df) - Fr.df; }});
+ 0x6: nmsub_ps({{
+ //Must Check for Exception Here... Supposed to Operate on Upper and
+ //Lower Halves Independently but we take simulator shortcut
+ Fd.df = (-1 * Fs.df * Fs.df) + Fr.df;
+ }});
+ }
}
+ }
}
- }
-
- //MIPS obsolete instructions
- format CondBranch {
- 0x4: beql({{ cond = (Rs.sw == 0); }});
- 0x5: bnel({{ cond = (Rs.sw != 0); }});
- 0x6: blezl({{ cond = (Rs.sw <= 0); }});
- 0x7: bgtzl({{ cond = (Rs.sw > 0); }});
+
+ //MIPS obsolete instructions
+ format BranchLikely {
+ 0x4: beql({{ cond = (Rs.sw == 0); }});
+ 0x5: bnel({{ cond = (Rs.sw != 0); }});
+ 0x6: blezl({{ cond = (Rs.sw <= 0); }});
+ 0x7: bgtzl({{ cond = (Rs.sw > 0); }});
}
}
@@ -752,89 +762,89 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode FUNCTION_LO {
format IntOp {
- 0x0: madd({{
+ 0x0: madd({{
INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32;
temp1 = temp1 + (Rs.sw * Rt.sw);
xc->miscRegs.hi->temp1<63:32>;
xc->miscRegs.lo->temp1<31:0>
- }});
+ }});
- 0x1: maddu({{
+ 0x1: maddu({{
INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32;
temp1 = temp1 + (Rs.uw * Rt.uw);
xc->miscRegs.hi->temp1<63:32>;
xc->miscRegs.lo->temp1<31:0>
- }});
+ }});
- 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }});
+ 0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }});
- 0x4: msub({{
+ 0x4: msub({{
INT64 temp1 = Hi.sw << 32 | Lo.sw >> 32;
temp1 = temp1 - (Rs.sw * Rt.sw);
xc->miscRegs.hi->temp1<63:32>;
xc->miscRegs.lo->temp1<31:0>
- }});
+ }});
- 0x5: msubu({{
+ 0x5: msubu({{
INT64 temp1 = Hi.uw << 32 | Lo.uw >> 32;
temp1 = temp1 - (Rs.uw * Rt.uw);
xc->miscRegs.hi->temp1<63:32>;
xc->miscRegs.lo->temp1<31:0>
- }});
+ }});
}
}
0x4: decode FUNCTION_LO {
- format BasicOp {
- 0x0: clz({{
+ format BasicOp {
+ 0x0: clz({{
int cnt = 0;
int idx = 0;
while ( Rs.uw<idx>!= 1) {
- cnt++;
- idx--;
+ cnt++;
+ idx--;
}
Rd.uw = cnt;
- }});
+ }});
- 0x1: clo({{
+ 0x1: clo({{
int cnt = 0;
int idx = 0;
while ( Rs.uw<idx>!= 0) {
- cnt++;
- idx--;
+ cnt++;
+ idx--;
}
Rd.uw = cnt;
- }});
- }
+ }});
+ }
}
0x7: decode FUNCTION_LO {
- 0x7: WarnUnimpl::sdbbp();
+ 0x7: WarnUnimpl::sdbbp();
}
}
//Table A-6 MIPS32 SPECIAL3 Encoding of Function Field for Release 2 of the Architecture
0x7: decode FUNCTION_HI {
- 0x0: decode FUNCTION_LO {
+ 0x0: decode FUNCTION_LO {
format WarnUnimpl {
0x1: ext();
0x4: ins();
}
- }
+ }
- 0x1: decode FUNCTION_LO {
+ 0x1: decode FUNCTION_LO {
format WarnUnimpl {
0x0: fork();
0x1: yield();
}
- }
+ }
- //Table A-10 MIPS32 BSHFL Encoding of sa Field
- 0x4: decode SA {
+ //Table A-10 MIPS32 BSHFL Encoding of sa Field
+ 0x4: decode SA {
0x02: WarnUnimpl::wsbh();
@@ -842,35 +852,35 @@ decode OPCODE_HI default Unknown::unknown() {
0x10: seb({{ Rd.sw = /* sext32(Rt<7>,24) | */ Rt<7:0>}});
0x18: seh({{ Rd.sw = /* sext32(Rt<15>,16) | */ Rt<15:0>}});
}
- }
+ }
- 0x6: decode FUNCTION_LO {
- 0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}});
- }
+ 0x6: decode FUNCTION_LO {
+ 0x7: BasicOp::rdhwr({{ Rt = xc->hwRegs[RD];}});
+ }
}
}
0x4: decode OPCODE_LO default FailUnimpl::reserved() {
- format Memory {
- 0x0: lb({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sb; }});
- 0x1: lh({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sh; }});
- 0x2: lwl({{ EA = Rs + disp; }}, {{ Rb.sw = Mem.sw; }});//, WordAlign);
- 0x3: lw({{ EA = Rs + disp; }}, {{ Rb.uq = Mem.sb; }});
- 0x4: lbu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.ub; }});
- 0x5: lhu({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uh; }});
- 0x6: lwr({{ EA = Rs + disp; }}, {{ Rb.uw = Mem.uw; }});//, WordAlign);
+ format LoadMemory {
+ 0x0: lb({{ Rb.sw = Mem.sb; }});
+ 0x1: lh({{ Rb.sw = Mem.sh; }});
+ 0x2: lwl({{ Rb.sw = Mem.sw; }});//, WordAlign);
+ 0x3: lw({{ Rb.uq = Mem.sb; }});
+ 0x4: lbu({{ Rb.uw = Mem.ub; }});
+ 0x5: lhu({{ Rb.uw = Mem.uh; }});
+ 0x6: lwr({{ Rb.uw = Mem.uw; }});//, WordAlign);
}
0x7: FailUnimpl::reserved();
}
0x5: decode OPCODE_LO default FailUnimpl::reserved() {
- format Memory {
- 0x0: sb({{ EA = Rs + disp; }}, {{ Mem.ub = Rt<7:0>; }});
- 0x1: sh({{ EA = Rs + disp; }},{{ Mem.uh = Rt<15:0>; }});
- 0x2: swl({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});//,WordAlign);
- 0x3: sw({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});
- 0x6: swr({{ EA = Rs + disp; }},{{ Mem.ub = Rt<31:0>; }});//,WordAlign);
+ format StoreMemory {
+ 0x0: sb({{ Mem.ub = Rt<7:0>; }});
+ 0x1: sh({{ Mem.uh = Rt<15:0>; }});
+ 0x2: swl({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
+ 0x3: sw({{ Mem.ub = Rt<31:0>; }});
+ 0x6: swr({{ Mem.ub = Rt<31:0>; }});//,WordAlign);
}
format WarnUnimpl {
@@ -880,20 +890,20 @@ decode OPCODE_HI default Unknown::unknown() {
}
0x6: decode OPCODE_LO default FailUnimpl::reserved() {
- 0x0: WarnUnimpl::ll();
+ 0x0: WarnUnimpl::ll();
- format Memory {
- 0x1: lwc1({{ EA = Rs + disp; }},{{ Ft<31:0> = Mem.uf; }});
- 0x5: ldc1({{ EA = Rs + disp; }},{{ Ft<63:0> = Mem.df; }});
+ format LoadMemory {
+ 0x1: lwc1({{ Ft<31:0> = Mem.sf; }});
+ 0x5: ldc1({{ Ft<63:0> = Mem.df; }});
}
}
0x7: decode OPCODE_LO default FailUnimpl::reserved() {
0x0: WarnUnimpl::sc();
- format Memory {
- 0x1: swc1({{ EA = Rs + disp; }},{{ Mem.uf = Ft<31:0>; }});
- 0x5: sdc1({{ EA = Rs + disp; }},{{ Mem.df = Ft<63:0>; }});
+ format StoreMemory {
+ 0x1: swc1({{ Mem.sf = Ft<31:0>; }});
+ 0x5: sdc1({{ Mem.df = Ft<63:0>; }});
}
}
diff --git a/arch/mips/isa/formats.isa b/arch/mips/isa/formats.isa
index 20ef49d82..c244013df 100644
--- a/arch/mips/isa/formats.isa
+++ b/arch/mips/isa/formats.isa
@@ -1,7 +1,15 @@
-//Include the basic format
+// -*- mode:c++ -*-
+
//Templates from this format are used later
+//Include the basic format
##include "m5/arch/mips/isa/formats/basic.isa"
+//Include the basic format
+##include "m5/arch/mips/isa/formats/noop.isa"
+
+//Include utility formats/functions
+##include "m5/arch/mips/isa/formats/util.isa"
+
//Include the integerOp and integerOpCc format
##include "m5/arch/mips/isa/formats/int.isa"
@@ -18,10 +26,6 @@
##include "m5/arch/mips/isa/formats/branch.isa"
//Include the noop format
-##include "m5/arch/mips/isa/formats/noop.isa"
-
-
-//Include the noop format
##include "m5/arch/mips/isa/formats/unimp.isa"
//Include the noop format
diff --git a/arch/mips/isa/formats/basic.isa b/arch/mips/isa/formats/basic.isa
index fc97c6ffa..3b62aa5c3 100644
--- a/arch/mips/isa/formats/basic.isa
+++ b/arch/mips/isa/formats/basic.isa
@@ -1,3 +1,4 @@
+// -*- mode:c++ -*-
// Declarations for execute() methods.
def template BasicExecDeclare {{
@@ -39,7 +40,7 @@ def template BasicExecute {{
if(fault == No_Fault)
{
- %(op_wb)s;
+ %(op_wb)s;
}
return fault;
}
diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa
index e9c790c53..fc207fd3f 100644
--- a/arch/mips/isa/formats/branch.isa
+++ b/arch/mips/isa/formats/branch.isa
@@ -1,30 +1,9 @@
// -*- mode:c++ -*-
-// Copyright (c) 2003-2005 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.
+// Control transfer instructions
//
-// 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.
output header {{
@@ -37,18 +16,19 @@ output header {{
* where the disassembly string includes the target address (which
* may depend on the PC and/or symbol table).
*/
- class PCDependentDisassembly : public AlphaStaticInst
+ class PCDependentDisassembly : public MipsStaticInst
{
protected:
/// Cached program counter from last disassembly
mutable Addr cachedPC;
+
/// Cached symbol table pointer from last disassembly
mutable const SymbolTable *cachedSymtab;
/// Constructor
PCDependentDisassembly(const char *mnem, MachInst _machInst,
OpClass __opClass)
- : AlphaStaticInst(mnem, _machInst, __opClass),
+ : MipsStaticInst(mnem, _machInst, __opClass),
cachedPC(0), cachedSymtab(0)
{
}
@@ -64,13 +44,35 @@ output header {{
class Branch : public PCDependentDisassembly
{
protected:
- /// Displacement to target address (signed).
+ /// target address (signed) Displacement .
int32_t disp;
/// Constructor.
Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
: PCDependentDisassembly(mnem, _machInst, __opClass),
- disp(BRDISP << 2)
+ disp(OFFSET << 2)
+ {
+ }
+
+ Addr branchTarget(Addr branchPC) const;
+
+ std::string
+ 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.
+ Branch(const char *mnem, MachInst _machInst, OpClass __opClass)
+ : PCDependentDisassembly(mnem, _machInst, __opClass),
+ disp(OFFSET << 2)
{
}
@@ -82,7 +84,7 @@ output header {{
/**
* Base class for jumps (register-indirect control transfers). In
- * the Alpha ISA, these are always unconditional.
+ * the Mips ISA, these are always unconditional.
*/
class Jump : public PCDependentDisassembly
{
@@ -95,7 +97,7 @@ output header {{
/// Constructor
Jump(const char *mnem, MachInst _machInst, OpClass __opClass)
: PCDependentDisassembly(mnem, _machInst, __opClass),
- disp(BRDISP)
+ disp(OFFSET)
{
}
@@ -114,6 +116,12 @@ output decoder {{
}
Addr
+ BranchLikely::branchTarget(Addr branchPC) const
+ {
+ return branchPC + 4 + disp;
+ }
+
+ Addr
Jump::branchTarget(ExecContext *xc) const
{
Addr NPC = xc->readPC() + 4;
@@ -179,6 +187,44 @@ output decoder {{
}
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 << ",";
+ }
+
+#ifdef SS_COMPATIBLE_DISASSEMBLY
+ if (_numSrcRegs == 0 && _numDestRegs == 0) {
+ printReg(ss, 31);
+ ss << ",";
+ }
+#endif
+
+ Addr target = pc + 4 + disp;
+
+ std::string str;
+ if (symtab && symtab->findSymbol(target, str))
+ ss << str;
+ else
+ ccprintf(ss, "0x%x", target);
+
+ return ss.str();
+ }
+
+ std::string
Jump::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
std::stringstream ss;
@@ -203,57 +249,69 @@ output decoder {{
}
}};
-def template JumpOrBranchDecode {{
- return (RA == 31)
- ? (StaticInst<AlphaISA> *)new %(class_name)s(machInst)
- : (StaticInst<AlphaISA> *)new %(class_name)sAndLink(machInst);
-}};
+def format Branch(code,*flags) {{
+ #Add Link Code if Link instruction
+ strlen = len(name)
+ if name[strlen-2:] == 'al':
+ code += 'R31 = NNPC;\n'
+
+ #Condition code
+ code = 'bool cond;\n' + code
+ code += 'if (cond) {\n'
+ #code += '//NPC=NPC: just placeholder to force parser to writeback NPC\n'
+ #code += ' NPC = NPC; \n'
+ code += ' NNPC = NPC + disp;\n'
+ code += '} \n'
-def format CondBranch(code) {{
- code = 'bool cond;\n' + code + '\nif (cond) NPC = NPC + disp;\n';
iop = InstObjParams(name, Name, 'Branch', CodeBlock(code),
('IsDirectControl', 'IsCondControl'))
+
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
decode_block = BasicDecode.subst(iop)
exec_output = BasicExecute.subst(iop)
}};
-let {{
-def UncondCtrlBase(name, Name, base_class, npc_expr, flags):
- # Declare basic control transfer w/o link (i.e. link reg is R31)
- nolink_code = 'NPC = %s;\n' % npc_expr
- nolink_iop = InstObjParams(name, Name, base_class,
- CodeBlock(nolink_code), flags)
- header_output = BasicDeclare.subst(nolink_iop)
- decoder_output = BasicConstructor.subst(nolink_iop)
- exec_output = BasicExecute.subst(nolink_iop)
-
- # Generate declaration of '*AndLink' version, append to decls
- link_code = 'Ra = NPC & ~3;\n' + nolink_code
- link_iop = InstObjParams(name, Name + 'AndLink', base_class,
- CodeBlock(link_code), flags)
- header_output += BasicDeclare.subst(link_iop)
- decoder_output += BasicConstructor.subst(link_iop)
- exec_output += BasicExecute.subst(link_iop)
-
- # need to use link_iop for the decode template since it is expecting
- # the shorter version of class_name (w/o "AndLink")
-
- return (header_output, decoder_output,
- JumpOrBranchDecode.subst(nolink_iop), exec_output)
-}};
-def format UncondBranch(*flags) {{
- flags += ('IsUncondControl', 'IsDirectControl')
- (header_output, decoder_output, decode_block, exec_output) = \
- UncondCtrlBase(name, Name, 'Branch', 'NPC + disp', flags)
+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 += '//NPC=NPC: just placeholder to force parser to writeback NPC\n'
+ #code += 'NPC = NPC; \n'
+ 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(*flags) {{
- flags += ('IsUncondControl', 'IsIndirectControl')
- (header_output, decoder_output, decode_block, exec_output) = \
- UncondCtrlBase(name, Name, 'Jump', '(Rb & ~3) | (NPC & 1)', flags)
+def format Jump(code,*flags) {{
+ #Add Link Code if Link instruction
+ strlen = len(name)
+ if strlen >= 3 and name[2:3] == 'al':
+ code = 'R31 = NNPC;\n' + code
+
+ iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\
+ ('IsIndirectControl', 'IsUncondControl'))
+
+ header_output = BasicDeclare.subst(iop)
+ decoder_output = BasicConstructor.subst(iop)
+ decode_block = BasicDecode.subst(iop)
+ exec_output = BasicExecute.subst(iop)
}};
+
+
diff --git a/arch/mips/isa/formats/int.isa b/arch/mips/isa/formats/int.isa
index 521f3a130..cf06741a1 100644
--- a/arch/mips/isa/formats/int.isa
+++ b/arch/mips/isa/formats/int.isa
@@ -1,8 +1,11 @@
+// -*- mode:c++ -*-
+
////////////////////////////////////////////////////////////////////
//
// Integer operate instructions
//
+//Outputs to decoder.hh
output header {{
/**
* Base class for integer operations.
@@ -12,7 +15,7 @@ output header {{
protected:
/// Constructor
- IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ IntOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass)
{
}
@@ -26,7 +29,7 @@ output header {{
uint16_t imm;
/// Constructor
- IntegerOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
+ IntImmOp(const char *mnem, MachInst _machInst, OpClass __opClass) :
MipsStaticInst(mnem, _machInst, __opClass),imm(INTIMM)
{
}
@@ -36,6 +39,7 @@ output header {{
}};
+//Outputs to decoder.cc
output decoder {{
std::string IntOp::generateDisassembly(Addr pc, const SymbolTable *symtab) const
{
@@ -48,17 +52,18 @@ output decoder {{
}
}};
-// Primary format for integer operate instructions:
+
+//Used by decoder.isa
def format IntOp(code, *opt_flags) {{
orig_code = code
cblk = CodeBlock(code)
# 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, 'IntOp', cblk, opt_flags)
- else:
- iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags)
+ iop = InstObjParams(name, Name, 'IntImmOp', cblk, opt_flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
diff --git a/arch/mips/isa/formats/mem.isa b/arch/mips/isa/formats/mem.isa
index e3028eb7c..134548746 100644
--- a/arch/mips/isa/formats/mem.isa
+++ b/arch/mips/isa/formats/mem.isa
@@ -1,78 +1,462 @@
-////////////////////////////////////////////////////////////////////
+// -*- mode:c++ -*-
+
+// Copyright (c) 2003-2005 The Regents of The University of Michigan
+// All rights reserved.
//
-// Mem instructions
+// 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.
output header {{
+ /**
+ * Base class for general Mips memory-format instructions.
+ */
+ class Memory : public MipsStaticInst
+ {
+ protected:
+
+ /// Memory request flags. See mem_req_base.hh.
+ unsigned memAccessFlags;
+ /// Pointer to EAComp object.
+ const StaticInstPtr eaCompPtr;
+ /// Pointer to MemAcc object.
+ const StaticInstPtr memAccPtr;
+ /// Displacement for EA calculation (signed).
+ int32_t disp;
+
+ /// Constructor
+ Memory(const char *mnem, MachInst _machInst, OpClass __opClass,
+ StaticInstPtr _eaCompPtr = nullStaticInstPtr,
+ StaticInstPtr _memAccPtr = nullStaticInstPtr)
+ : MipsStaticInst(mnem, _machInst, __opClass),
+ memAccessFlags(0), eaCompPtr(_eaCompPtr), memAccPtr(_memAccPtr),
+ disp(OFFSET)
+ {
+ }
+
+ std::string
+ generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+
+ public:
+
+ const StaticInstPtr &eaCompInst() const { return eaCompPtr; }
+ const StaticInstPtr &memAccInst() const { return memAccPtr; }
+ };
+
+}};
+
+
+output decoder {{
+ std::string
+ Memory::generateDisassembly(Addr pc, const SymbolTable *symtab) const
+ {
+ return csprintf("%-10s %c%d,%d(r%d)", mnemonic,
+ flags[IsFloating] ? 'f' : 'r', RA, MEMDISP, RB);
+ }
+
+}};
+
+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".
+ */
+ class %(class_name)s : public %(base_class)s
+ {
+ protected:
+
/**
- * Base class for integer operations.
+ * "Fake" effective address computation class for "%(mnemonic)s".
*/
- class Mem : public MipsStaticInst
+ class EAComp : public %(base_class)s
{
- protected:
+ public:
+ /// Constructor
+ EAComp(MachInst machInst);
- /// Constructor
- Mem(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
- {
- }
+ %(BasicExecDeclare)s
+ };
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
+ /**
+ * "Fake" memory access instruction class for "%(mnemonic)s".
+ */
+ class MemAcc : public %(base_class)s
+ {
+ public:
+ /// Constructor
+ MemAcc(MachInst machInst);
+
+ %(BasicExecDeclare)s
};
+
+ public:
+
+ /// Constructor.
+ %(class_name)s(MachInst machInst);
+
+ %(BasicExecDeclare)s
+
+ %(InitiateAccDeclare)s
+
+ %(CompleteAccDeclare)s
+ };
}};
-output decoder {{
- std::string Mem::generateDisassembly(Addr pc, const SymbolTable *symtab) const
- {
- return "Disassembly of integer instruction\n";
+
+def template InitiateAccDeclare {{
+ Fault initiateAcc(%(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+
+def template CompleteAccDeclare {{
+ Fault completeAcc(uint8_t *, %(CPU_exec_context)s *, Trace::InstRecord *) const;
+}};
+
+
+def template LoadStoreConstructor {{
+ /** TODO: change op_class to AddrGenOp or something (requires
+ * creating new member of OpClass enum in op_class.hh, updating
+ * config files, etc.). */
+ inline %(class_name)s::EAComp::EAComp(MachInst machInst)
+ : %(base_class)s("%(mnemonic)s (EAComp)", machInst, IntAluOp)
+ {
+ %(ea_constructor)s;
+ }
+
+ inline %(class_name)s::MemAcc::MemAcc(MachInst machInst)
+ : %(base_class)s("%(mnemonic)s (MemAcc)", machInst, %(op_class)s)
+ {
+ %(memacc_constructor)s;
+ }
+
+ inline %(class_name)s::%(class_name)s(MachInst machInst)
+ : %(base_class)s("%(mnemonic)s", machInst, %(op_class)s,
+ new EAComp(machInst), new MemAcc(machInst))
+ {
+ %(constructor)s;
+ }
+}};
+
+
+def template EACompExecute {{
+ Fault
+ %(class_name)s::EAComp::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;
+ %(code)s;
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ xc->setEA(EA);
}
+
+ return fault;
+ }
}};
-def template MemExecute {{
- Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
- {
- //Attempt to execute the instruction
- try
- {
-
- %(op_decl)s;
- %(op_rd)s;
- ea_code
- %(code)s;
- }
- //If we have an exception for some reason,
- //deal with it
- catch(MipsException except)
- {
- //Deal with exception
- return No_Fault;
- }
-
- //Write the resulting state to the execution context
- %(op_wb)s;
-
- return No_Fault;
- }
-}};
-
-// Primary format for integer operate instructions:
-def format Memory(code, ea_code = {{ EA = Rb + disp; }},*opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
- exec_output = MemExecute.subst(iop)
- exec_output.replace('ea_code', 'EA = I ? (R1 + SIMM13) : R1 + R2;');
-}};
-
-def format Cas(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
- exec_output = MemExecute.subst(iop)
- exec_output.replace('ea_code', 'EA = R1;');
+def template LoadMemAccExecute {{
+ 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) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
+ %(code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
}};
+
+
+def template LoadExecute {{
+ 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) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template LoadInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_src_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
+ }
+
+ return fault;
+ }
+}};
+
+
+def template LoadCompleteAcc {{
+ Fault %(class_name)s::completeAcc(uint8_t *data,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+
+ %(fp_enable_check)s;
+ %(op_src_decl)s;
+ %(op_dest_decl)s;
+
+ memcpy(&Mem, data, sizeof(Mem));
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreMemAccExecute {{
+ Fault
+ %(class_name)s::MemAcc::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+ uint64_t write_result = 0;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ EA = xc->getEA();
+
+ if (fault == NoFault) {
+ %(code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, &write_result);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreExecute {{
+ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+ uint64_t write_result = 0;
+
+ %(fp_enable_check)s;
+ %(op_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, &write_result);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+def template StoreInitiateAcc {{
+ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Addr EA;
+ Fault fault = NoFault;
+ uint64_t write_result = 0;
+
+ %(fp_enable_check)s;
+ %(op_src_decl)s;
+ %(op_dest_decl)s;
+ %(op_rd)s;
+ %(ea_code)s;
+
+ if (fault == NoFault) {
+ %(memacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
+ memAccessFlags, &write_result);
+ if (traceData) { traceData->setData(Mem); }
+ }
+
+ return fault;
+ }
+}};
+
+
+def template StoreCompleteAcc {{
+ Fault %(class_name)s::completeAcc(uint8_t *data,
+ %(CPU_exec_context)s *xc,
+ Trace::InstRecord *traceData) const
+ {
+ Fault fault = NoFault;
+ uint64_t write_result = 0;
+
+ %(fp_enable_check)s;
+ %(op_dest_decl)s;
+
+ memcpy(&write_result, data, sizeof(write_result));
+
+ if (fault == NoFault) {
+ %(postacc_code)s;
+ }
+
+ if (fault == NoFault) {
+ %(op_wb)s;
+ }
+
+ return fault;
+ }
+}};
+
+// 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 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,
+ 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) = \
+ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ exec_template_base = 'Store')
+}};
+
+//FP loads are offloaded to these formats for now ...
+def format LoadMemory2(ea_code = {{ EA = Rs + disp; }}, memacc_code = {{ }},
+ 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,
+ exec_template_base = 'Load')
+}};
+
+
+//FP stores are offloaded to these formats for now ...
+def format StoreMemory2(ea_code = {{ EA = Rs + disp; }},memacc_code = {{ }},
+ 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,
+ exec_template_base = 'Store')
+}};
+
diff --git a/arch/mips/isa/formats/noop.isa b/arch/mips/isa/formats/noop.isa
index 6d45ba9b6..d366461e2 100644
--- a/arch/mips/isa/formats/noop.isa
+++ b/arch/mips/isa/formats/noop.isa
@@ -1,50 +1,4 @@
-////////////////////////////////////////////////////////////////////
-//
-// Noop instruction
-//
-
-output header {{
- /**
- * Base class for integer operations.
- */
- class Noop : public MipsStaticInst
- {
- protected:
-
- /// Constructor
- Noop(const char *mnem, MachInst _machInst, OpClass __opClass) : MipsStaticInst(mnem, _machInst, __opClass)
- {
- }
-
- std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const;
- };
-}};
-
-output decoder {{
- std::string Noop::generateDisassembly(Addr pc, const SymbolTable *symtab) const
- {
- return "Disassembly of integer instruction\n";
- }
-}};
-
-def template NoopExecute {{
- Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
- {
- //Nothing to see here, move along
- return No_Fault;
- }
-}};
-
-// Primary format for integer operate instructions:
-def format Noop(code, *opt_flags) {{
- orig_code = code
- cblk = CodeBlock(code)
- iop = InstObjParams(name, Name, 'MipsStaticInst', cblk, opt_flags)
- header_output = BasicDeclare.subst(iop)
- decoder_output = BasicConstructor.subst(iop)
- decode_block = BasicDecodeWithMnemonic.subst(iop)
- exec_output = NoopExecute.subst(iop)
-}};
+// -*- mode:c++ -*-
////////////////////////////////////////////////////////////////////
//
@@ -55,7 +9,7 @@ output header {{
/**
* Static instruction class for no-ops. This is a leaf class.
*/
- class Nop : public AlphaStaticInst
+ class Nop : public MipsStaticInst
{
/// Disassembly of original instruction.
const std::string originalDisassembly;
@@ -63,7 +17,7 @@ output header {{
public:
/// Constructor
Nop(const std::string _originalDisassembly, MachInst _machInst)
- : AlphaStaticInst("nop", _machInst, No_OpClass),
+ : MipsStaticInst("nop", _machInst, No_OpClass),
originalDisassembly(_originalDisassembly)
{
flags[IsNop] = true;
@@ -92,10 +46,10 @@ output decoder {{
/// Helper function for decoding nops. Substitute Nop object
/// for original inst passed in as arg (and delete latter).
inline
- AlphaStaticInst *
- makeNop(AlphaStaticInst *inst)
+ MipsStaticInst *
+ makeNop(MipsStaticInst *inst)
{
- AlphaStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst);
+ MipsStaticInst *nop = new Nop(inst->disassemble(0), inst->machInst);
delete inst;
return nop;
}
@@ -113,7 +67,7 @@ output exec {{
// Rc == 31 to detect nops
def template OperateNopCheckDecode {{
{
- AlphaStaticInst *i = new %(class_name)s(machInst);
+ MipsStaticInst *i = new %(class_name)s(machInst);
if (RC == 31) {
i = makeNop(i);
}
@@ -124,7 +78,7 @@ def template OperateNopCheckDecode {{
// Like BasicOperate format, but generates NOP if RC/FC == 31
def format BasicOperateWithNopCheck(code, *opt_args) {{
- iop = InstObjParams(name, Name, 'AlphaStaticInst', CodeBlock(code),
+ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code),
opt_args)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
diff --git a/arch/mips/isa/formats/unimp.isa b/arch/mips/isa/formats/unimp.isa
index 767888157..a7a71c681 100644
--- a/arch/mips/isa/formats/unimp.isa
+++ b/arch/mips/isa/formats/unimp.isa
@@ -34,12 +34,12 @@ output header {{
* 'Unknown' class is used for unrecognized/illegal instructions.
* This is a leaf class.
*/
- class FailUnimplemented : public AlphaStaticInst
+ class FailUnimplemented : public MipsStaticInst
{
public:
/// Constructor
FailUnimplemented(const char *_mnemonic, MachInst _machInst)
- : AlphaStaticInst(_mnemonic, _machInst, No_OpClass)
+ : MipsStaticInst(_mnemonic, _machInst, No_OpClass)
{
// don't call execute() (which panics) if we're on a
// speculative path
@@ -61,7 +61,7 @@ output header {{
* probably make the 'warned' flag a static member of the derived
* class.
*/
- class WarnUnimplemented : public AlphaStaticInst
+ class WarnUnimplemented : public MipsStaticInst
{
private:
/// Have we warned on this instruction yet?
@@ -70,7 +70,7 @@ output header {{
public:
/// Constructor
WarnUnimplemented(const char *_mnemonic, MachInst _machInst)
- : AlphaStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
+ : MipsStaticInst(_mnemonic, _machInst, No_OpClass), warned(false)
{
// don't call execute() (which panics) if we're on a
// speculative path
@@ -144,12 +144,12 @@ output header {{
* These cause simulator termination if they are executed in a
* non-speculative mode. This is a leaf class.
*/
- class Unknown : public AlphaStaticInst
+ class Unknown : public MipsStaticInst
{
public:
/// Constructor
Unknown(MachInst _machInst)
- : AlphaStaticInst("unknown", _machInst, No_OpClass)
+ : MipsStaticInst("unknown", _machInst, No_OpClass)
{
// don't call execute() (which panics) if we're on a
// speculative path
diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa
new file mode 100644
index 000000000..f0671726c
--- /dev/null
+++ b/arch/mips/isa/formats/util.isa
@@ -0,0 +1,125 @@
+// -*- mode:c++ -*-
+
+let {{
+def UncondCtrlBase(name, Name, base_class, npc_expr, flags):
+ # Declare basic control transfer w/o link (i.e. link reg is R31)
+ nolink_code = 'NPC = %s;\n' % npc_expr
+ nolink_iop = InstObjParams(name, Name, base_class,
+ CodeBlock(nolink_code), flags)
+ header_output = BasicDeclare.subst(nolink_iop)
+ decoder_output = BasicConstructor.subst(nolink_iop)
+ exec_output = BasicExecute.subst(nolink_iop)
+
+ # Generate declaration of '*AndLink' version, append to decls
+ link_code = 'Ra = NPC & ~3;\n' + nolink_code
+ link_iop = InstObjParams(name, Name + 'AndLink', base_class,
+ CodeBlock(link_code), flags)
+ header_output += BasicDeclare.subst(link_iop)
+ decoder_output += BasicConstructor.subst(link_iop)
+ exec_output += BasicExecute.subst(link_iop)
+
+ # need to use link_iop for the decode template since it is expecting
+ # the shorter version of class_name (w/o "AndLink")
+
+ return (header_output, decoder_output,
+ JumpOrBranchDecode.subst(nolink_iop), exec_output)
+
+def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags,
+ postacc_code = '', base_class = 'Memory',
+ decode_template = BasicDecode, exec_template_base = ''):
+ # Make sure flags are in lists (convert to lists if not).
+ mem_flags = makeList(mem_flags)
+ inst_flags = makeList(inst_flags)
+
+ # add hook to get effective addresses into execution trace output.
+ ea_code += '\nif (traceData) { traceData->setAddr(EA); }\n'
+
+ # generate code block objects
+ ea_cblk = CodeBlock(ea_code)
+ memacc_cblk = CodeBlock(memacc_code)
+ postacc_cblk = CodeBlock(postacc_code)
+
+ # Some CPU models execute the memory operation as an atomic unit,
+ # while others want to separate them into an effective address
+ # computation and a memory access operation. As a result, we need
+ # to generate three StaticInst objects. Note that the latter two
+ # are nested inside the larger "atomic" one.
+
+ # generate InstObjParams for EAComp object
+ ea_iop = InstObjParams(name, Name, base_class, ea_cblk, inst_flags)
+
+ # generate InstObjParams for MemAcc object
+ memacc_iop = InstObjParams(name, Name, base_class, memacc_cblk, inst_flags)
+ # in the split execution model, the MemAcc portion is responsible
+ # for the post-access code.
+ memacc_iop.postacc_code = postacc_cblk.code
+
+ # generate InstObjParams for InitiateAcc, CompleteAcc object
+ # The code used depends on the template being used
+ if (exec_template_base == 'Load'):
+ initiateacc_cblk = CodeBlock(ea_code + memacc_code)
+ completeacc_cblk = CodeBlock(memacc_code + postacc_code)
+ elif (exec_template_base == 'Store'):
+ initiateacc_cblk = CodeBlock(ea_code + memacc_code)
+ completeacc_cblk = CodeBlock(postacc_code)
+ else:
+ initiateacc_cblk = ''
+ completeacc_cblk = ''
+
+ initiateacc_iop = InstObjParams(name, Name, base_class, initiateacc_cblk,
+ inst_flags)
+
+ completeacc_iop = InstObjParams(name, Name, base_class, completeacc_cblk,
+ inst_flags)
+
+ if (exec_template_base == 'Load'):
+ initiateacc_iop.ea_code = ea_cblk.code
+ initiateacc_iop.memacc_code = memacc_cblk.code
+ completeacc_iop.memacc_code = memacc_cblk.code
+ completeacc_iop.postacc_code = postacc_cblk.code
+ elif (exec_template_base == 'Store'):
+ initiateacc_iop.ea_code = ea_cblk.code
+ initiateacc_iop.memacc_code = memacc_cblk.code
+ completeacc_iop.postacc_code = postacc_cblk.code
+
+ # generate InstObjParams for unified execution
+ cblk = CodeBlock(ea_code + memacc_code + postacc_code)
+ iop = InstObjParams(name, Name, base_class, cblk, inst_flags)
+
+ iop.ea_constructor = ea_cblk.constructor
+ iop.ea_code = ea_cblk.code
+ iop.memacc_constructor = memacc_cblk.constructor
+ iop.memacc_code = memacc_cblk.code
+ iop.postacc_code = postacc_cblk.code
+
+ if mem_flags:
+ s = '\n\tmemAccessFlags = ' + string.join(mem_flags, '|') + ';'
+ iop.constructor += s
+ memacc_iop.constructor += s
+
+ # select templates
+ memAccExecTemplate = eval(exec_template_base + 'MemAccExecute')
+ fullExecTemplate = eval(exec_template_base + 'Execute')
+ initiateAccTemplate = eval(exec_template_base + 'InitiateAcc')
+ completeAccTemplate = eval(exec_template_base + 'CompleteAcc')
+
+ # (header_output, decoder_output, decode_block, exec_output)
+ return (LoadStoreDeclare.subst(iop), LoadStoreConstructor.subst(iop),
+ decode_template.subst(iop),
+ EACompExecute.subst(ea_iop)
+ + memAccExecTemplate.subst(memacc_iop)
+ + fullExecTemplate.subst(iop)
+ + initiateAccTemplate.subst(initiateacc_iop)
+ + completeAccTemplate.subst(completeacc_iop))
+}};
+
+
+output exec {{
+
+ /// CLEAR ALL CPU INST/EXE HAZARDS
+ inline void
+ clear_exe_inst_hazards()
+ {
+ //CODE HERE
+ }
+}
diff --git a/arch/mips/isa/operands.isa b/arch/mips/isa/operands.isa
index cf6f10e0b..65ef2245f 100644
--- a/arch/mips/isa/operands.isa
+++ b/arch/mips/isa/operands.isa
@@ -1,8 +1,8 @@
def operand_types {{
'sb' : ('signed int', 8),
'ub' : ('unsigned int', 8),
- 'shw' : ('signed int', 16),
- 'uhw' : ('unsigned int', 16),
+ 'sh' : ('signed int', 16),
+ 'uh' : ('unsigned int', 16),
'sw' : ('signed int', 32),
'uw' : ('unsigned int', 32),
'sd' : ('signed int', 64),
@@ -16,6 +16,7 @@ def operands {{
'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1),
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2),
'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3),
+ 'R31': ('IntReg', 'uw','R31','IsInteger', 4),
'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
'Sa': ('IntReg', 'uw', 'SA', 'IsInteger', 4),
@@ -24,12 +25,12 @@ def operands {{
'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2),
'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3),
- 'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4)
+ 'Mem': ('Mem', 'ud', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
- #'NPC': ('NPC', 'uq', None, ( None, None, 'IsControl' ), 4),
+ 'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4),
+ 'NNPC': ('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4)
#'Runiq': ('ControlReg', 'uq', 'Uniq', None, 1),
#'FPCR': ('ControlReg', 'uq', 'Fpcr', None, 1),
# The next two are hacks for non-full-system call-pal emulation
#'R0': ('IntReg', 'uq', '0', None, 1),
- #'R16': ('IntReg', 'uq', '16', None, 1)
}};
diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh
index 55e9c0dcb..603af60e2 100644
--- a/arch/mips/isa_traits.hh
+++ b/arch/mips/isa_traits.hh
@@ -46,7 +46,7 @@ class Checkpoint;
template <class ISA> class StaticInst;
template <class ISA> class StaticInstPtr;
-//namespace EV5
+//namespace MIPS34K
//{
// int DTB_ASN_ASN(uint64_t reg);
// int ITB_ASN_ASN(uint64_t reg);
@@ -430,12 +430,14 @@ class MipsISA
Addr pc; // Program Counter
Addr npc; // Next Program Counter
+ Addr nnpc; // Next next program Counter
+
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
};
- static StaticInstPtr<AlphaISA> decodeInst(MachInst);
+ static StaticInstPtr<MipsISA> decodeInst(MachInst);
// return a no-op instruction... used for instruction fetch faults
static const MachInst NoopMachInst;
@@ -526,7 +528,7 @@ class SyscallReturn {
#ifdef FULL_SYSTEM
-#include "arch/alpha/ev5.hh"
+#include "arch/mips/mips34k.hh"
#endif
#endif // __ARCH_MIPS_ISA_TRAITS_HH__
diff --git a/arch/sparc/SConscript b/arch/sparc/SConscript
index d8a3749a1..fea31fd5d 100644
--- a/arch/sparc/SConscript
+++ b/arch/sparc/SConscript
@@ -40,43 +40,43 @@ Import('env')
###################################################
# Base sources used by all configurations.
-arch_base_sources = Split('''
- arch/sparc/decoder.cc
- arch/sparc/alpha_o3_exec.cc
- arch/sparc/fast_cpu_exec.cc
- arch/sparc/simple_cpu_exec.cc
- arch/sparc/full_cpu_exec.cc
- arch/sparc/faults.cc
- arch/sparc/isa_traits.cc
+base_sources = Split('''
+ faults.cc
+ isa_traits.cc
''')
# Full-system sources
-arch_full_system_sources = Split('''
- arch/sparc/alpha_memory.cc
- arch/sparc/arguments.cc
- arch/sparc/ev5.cc
- arch/sparc/osfpal.cc
- arch/sparc/stacktrace.cc
- arch/sparc/vtophys.cc
+full_system_sources = Split('''
+ alpha_memory.cc
+ arguments.cc
+ ev5.cc
+ osfpal.cc
+ stacktrace.cc
+ vtophys.cc
''')
# Syscall emulation (non-full-system) sources
-arch_syscall_emulation_sources = Split('''
- arch/sparc/alpha_common_syscall_emul.cc
- arch/sparc/alpha_linux_process.cc
- arch/sparc/alpha_tru64_process.cc
+syscall_emulation_sources = Split('''
+ alpha_common_syscall_emul.cc
+ alpha_linux_process.cc
+ alpha_tru64_process.cc
''')
-sources = arch_base_sources
+sources = base_sources
if env['FULL_SYSTEM']:
- sources += arch_full_system_sources
- if env['ALPHA_TLASER']:
- sources += arch_turbolaser_sources
+ sources += full_system_sources
else:
- sources += arch_syscall_emulation_sources
+ sources += syscall_emulation_sources
-for opt in env.ExportOptions:
- env.ConfigFile(opt)
+# Convert file names to SCons File objects. This takes care of the
+# path relative to the top of the directory tree.
+sources = [File(s) for s in sources]
+
+# Add in files generated by the ISA description.
+isa_desc_files = env.ISADesc('isa/main.isa')
+# Only non-header files need to be compiled.
+isa_desc_sources = [f for f in isa_desc_files if not f.path.endswith('.hh')]
+sources += isa_desc_sources
Return('sources')
diff --git a/base/remote_gdb.cc b/base/remote_gdb.cc
index 67d745d43..17ec21fed 100644
--- a/base/remote_gdb.cc
+++ b/base/remote_gdb.cc
@@ -132,6 +132,7 @@
#include "targetarch/vtophys.hh"
using namespace std;
+using namespace TheISA;
#ifndef NDEBUG
vector<RemoteGDB *> debuggers;
@@ -494,7 +495,7 @@ RemoteGDB::setSingleStep()
// User was stopped at pc, e.g. the instruction at pc was not
// executed.
MachInst inst = read<MachInst>(pc);
- StaticInstPtr<TheISA> si(inst);
+ StaticInstPtr si(inst);
if (si->hasBranchTarget(pc, context, bpc)) {
// Don't bother setting a breakpoint on the taken branch if it
// is the same as the next pc
diff --git a/base/remote_gdb.hh b/base/remote_gdb.hh
index 652a58317..b7abf5116 100644
--- a/base/remote_gdb.hh
+++ b/base/remote_gdb.hh
@@ -43,6 +43,8 @@ class PhysicalMemory;
class GDBListener;
class RemoteGDB
{
+ protected:
+ typedef TheISA::MachInst MachInst;
private:
friend void debugger();
friend class GDBListener;
diff --git a/build/SConstruct b/build/SConstruct
index c552e5639..2d64afb3e 100644
--- a/build/SConstruct
+++ b/build/SConstruct
@@ -218,12 +218,18 @@ if have_mysql:
env = conf.Finish()
+# Define the universe of supported ISAs
+env['ALL_ISA_LIST'] = ['alpha', 'sparc', 'mips']
+
+# Define the universe of supported CPU models
+env['ALL_CPU_LIST'] = ['SimpleCPU', 'FastCPU', 'FullCPU', 'AlphaFullCPU']
+
# Sticky options get saved in the options file so they persist from
# one invocation to the next (unless overridden, in which case the new
# value becomes sticky).
sticky_opts = Options(args=ARGUMENTS)
sticky_opts.AddOptions(
- EnumOption('TARGET_ISA', 'Target ISA', 'alpha', ('alpha', 'sparc', 'mips')),
+ EnumOption('TARGET_ISA', 'Target ISA', 'alpha', env['ALL_ISA_LIST']),
BoolOption('FULL_SYSTEM', 'Full-system support', False),
BoolOption('ALPHA_TLASER',
'Model Alpha TurboLaser platform (vs. Tsunami)', False),
@@ -248,6 +254,12 @@ sticky_opts.AddOptions(
# Non-sticky options only apply to the current build.
nonsticky_opts = Options(args=ARGUMENTS)
nonsticky_opts.AddOptions(
+ # This really should be a sticky option, but there's a bug in
+ # scons 0.96.1 that causes ListOptions not to be able to be
+ # restored from a saved option file. It looks like this is fixed
+ # in 0.96.9, but there's a different bug in that version that means we
+ # can't just upgrade.
+ ListOption('CPU_MODELS', 'CPU models', 'all', env['ALL_CPU_LIST']),
BoolOption('update_ref', 'Update test reference outputs', False)
)
diff --git a/cpu/SConscript b/cpu/SConscript
new file mode 100644
index 000000000..dbe174660
--- /dev/null
+++ b/cpu/SConscript
@@ -0,0 +1,99 @@
+# -*- mode:python -*-
+
+# 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.
+
+import os
+import os.path
+
+# Import build environment variable from SConstruct.
+Import('env')
+
+models_db = File('cpu_models.py')
+execfile(models_db.srcnode().abspath)
+
+exec_sig_template = '''
+virtual Fault execute(%s *xc, Trace::InstRecord *traceData) const = 0;
+'''
+
+def gen_cpu_exec_signatures(target, source, env):
+ f = open(str(target[0]), 'w')
+ print >> f, '''
+#ifndef __CPU_STATIC_INST_EXEC_SIGS_HH__
+#define __CPU_STATIC_INST_EXEC_SIGS_HH__
+'''
+ for cpu in env['CPU_MODELS']:
+ xc_type = CpuModel.dict[cpu].strings['CPU_exec_context']
+ print >> f, exec_sig_template % xc_type
+ print >> f, '''
+#endif // __CPU_STATIC_INST_EXEC_SIGS_HH__
+'''
+
+env.Command('static_inst_exec_sigs.hh', models_db, gen_cpu_exec_signatures)
+
+sources = []
+
+if 'SimpleCPU' in env['CPU_MODELS']:
+ sources += Split('simple/cpu.cc')
+
+if 'FastCPU' in env['CPU_MODELS']:
+ sources += Split('fast/cpu.cc')
+
+if 'AlphaFullCPU' in env['CPU_MODELS']:
+ sources += Split('''
+ o3/2bit_local_pred.cc
+ o3/alpha_dyn_inst.cc
+ o3/alpha_cpu.cc
+ o3/alpha_cpu_builder.cc
+ o3/bpred_unit.cc
+ o3/btb.cc
+ o3/commit.cc
+ o3/decode.cc
+ o3/fetch.cc
+ o3/free_list.cc
+ o3/cpu.cc
+ o3/iew.cc
+ o3/inst_queue.cc
+ o3/ldstq.cc
+ o3/mem_dep_unit.cc
+ o3/ras.cc
+ o3/rename.cc
+ o3/rename_map.cc
+ o3/rob.cc
+ o3/sat_counter.cc
+ o3/store_set.cc
+ o3/tournament_pred.cc
+ ''')
+
+# FullCPU sources are included from m5/SConscript since they're not
+# below this point in the file hierarchy.
+
+# Convert file names to SCons File objects. This takes care of the
+# path relative to the top of the directory tree.
+sources = [File(s) for s in sources]
+
+Return('sources')
+
diff --git a/cpu/base.cc b/cpu/base.cc
index 8b94b8533..5a7ecf152 100644
--- a/cpu/base.cc
+++ b/cpu/base.cc
@@ -250,7 +250,7 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
}
#if FULL_SYSTEM
- for (int i = 0; i < NumInterruptLevels; ++i)
+ for (int i = 0; i < TheISA::NumInterruptLevels; ++i)
interrupts[i] = oldCPU->interrupts[i];
intstatus = oldCPU->intstatus;
@@ -285,7 +285,7 @@ BaseCPU::post_interrupt(int int_num, int index)
{
DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index);
- if (int_num < 0 || int_num >= NumInterruptLevels)
+ if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
panic("int_num out of bounds\n");
if (index < 0 || index >= sizeof(uint64_t) * 8)
@@ -301,7 +301,7 @@ BaseCPU::clear_interrupt(int int_num, int index)
{
DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index);
- if (int_num < 0 || int_num >= NumInterruptLevels)
+ if (int_num < 0 || int_num >= TheISA::NumInterruptLevels)
panic("int_num out of bounds\n");
if (index < 0 || index >= sizeof(uint64_t) * 8)
@@ -325,14 +325,14 @@ BaseCPU::clear_interrupts()
void
BaseCPU::serialize(std::ostream &os)
{
- SERIALIZE_ARRAY(interrupts, NumInterruptLevels);
+ SERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
SERIALIZE_SCALAR(intstatus);
}
void
BaseCPU::unserialize(Checkpoint *cp, const std::string &section)
{
- UNSERIALIZE_ARRAY(interrupts, NumInterruptLevels);
+ UNSERIALIZE_ARRAY(interrupts, TheISA::NumInterruptLevels);
UNSERIALIZE_SCALAR(intstatus);
}
diff --git a/cpu/base.hh b/cpu/base.hh
index 2bd1210d8..d5764d495 100644
--- a/cpu/base.hh
+++ b/cpu/base.hh
@@ -58,7 +58,7 @@ class BaseCPU : public SimObject
#if FULL_SYSTEM
protected:
- uint64_t interrupts[NumInterruptLevels];
+ uint64_t interrupts[TheISA::NumInterruptLevels];
uint64_t intstatus;
public:
@@ -68,7 +68,7 @@ class BaseCPU : public SimObject
bool checkInterrupts;
bool check_interrupt(int int_num) const {
- if (int_num > NumInterruptLevels)
+ if (int_num > TheISA::NumInterruptLevels)
panic("int_num out of bounds\n");
return interrupts[int_num] != 0;
@@ -140,6 +140,8 @@ class BaseCPU : public SimObject
virtual void startup();
virtual void regStats();
+ virtual void activateWhenReady(int tid) {};
+
void registerExecContexts();
/// Prepare for another CPU to take over execution. When it is
diff --git a/cpu/base_dyn_inst.cc b/cpu/base_dyn_inst.cc
index 59a12f2d0..86314bef1 100644
--- a/cpu/base_dyn_inst.cc
+++ b/cpu/base_dyn_inst.cc
@@ -79,7 +79,7 @@ BaseDynInst<Impl>::BaseDynInst(MachInst machInst, Addr inst_PC,
}
template <class Impl>
-BaseDynInst<Impl>::BaseDynInst(StaticInstPtr<ISA> &_staticInst)
+BaseDynInst<Impl>::BaseDynInst(StaticInstPtr &_staticInst)
: staticInst(_staticInst), traceData(NULL)
{
initVars();
@@ -145,7 +145,7 @@ BaseDynInst<Impl>::prefetch(Addr addr, unsigned flags)
fault = NoFault;
// note this is a local, not BaseDynInst::fault
- Fault * trans_fault = xc->translateDataReadReq(req);
+ Fault trans_fault = xc->translateDataReadReq(req);
if (trans_fault == NoFault && !(req->flags & UNCACHEABLE)) {
// It's a valid address to cacheable space. Record key MemReq
@@ -208,14 +208,14 @@ BaseDynInst<Impl>::writeHint(Addr addr, int size, unsigned flags)
* @todo Need to find a way to get the cache block size here.
*/
template <class Impl>
-Fault *
+Fault
BaseDynInst<Impl>::copySrcTranslate(Addr src)
{
MemReqPtr req = new MemReq(src, xc, 64);
req->asid = asid;
// translate to physical address
- Fault * fault = xc->translateDataReadReq(req);
+ Fault fault = xc->translateDataReadReq(req);
if (fault == NoFault) {
xc->copySrcAddr = src;
@@ -231,7 +231,7 @@ BaseDynInst<Impl>::copySrcTranslate(Addr src)
* @todo Need to find a way to get the cache block size here.
*/
template <class Impl>
-Fault *
+Fault
BaseDynInst<Impl>::copy(Addr dest)
{
uint8_t data[64];
@@ -241,7 +241,7 @@ BaseDynInst<Impl>::copy(Addr dest)
req->asid = asid;
// translate to physical address
- Fault * fault = xc->translateDataWriteReq(req);
+ Fault fault = xc->translateDataWriteReq(req);
if (fault == NoFault) {
Addr dest_addr = req->paddr;
@@ -277,10 +277,10 @@ BaseDynInst<Impl>::dump(std::string &outstring)
#if 0
template <class Impl>
-Fault *
+Fault
BaseDynInst<Impl>::mem_access(mem_cmd cmd, Addr addr, void *p, int nbytes)
{
- Fault * fault;
+ Fault fault;
// check alignments, even speculative this test should always pass
if ((nbytes & nbytes - 1) != 0 || (addr & nbytes - 1) != 0) {
diff --git a/cpu/base_dyn_inst.hh b/cpu/base_dyn_inst.hh
index 2c91db99c..e94c44151 100644
--- a/cpu/base_dyn_inst.hh
+++ b/cpu/base_dyn_inst.hh
@@ -51,7 +51,6 @@
*/
// Forward declaration.
-template <class ISA>
class StaticInstPtr;
template <class Impl>
@@ -61,25 +60,20 @@ class BaseDynInst : public FastAlloc, public RefCounted
// Typedef for the CPU.
typedef typename Impl::FullCPU FullCPU;
- //Typedef to get the ISA.
- typedef typename Impl::ISA ISA;
-
/// Binary machine instruction type.
- typedef typename ISA::MachInst MachInst;
- /// Memory address type.
- typedef typename ISA::Addr Addr;
+ typedef TheISA::MachInst MachInst;
/// Logical register index type.
- typedef typename ISA::RegIndex RegIndex;
+ typedef TheISA::RegIndex RegIndex;
/// Integer register index type.
- typedef typename ISA::IntReg IntReg;
+ typedef TheISA::IntReg IntReg;
enum {
- MaxInstSrcRegs = ISA::MaxInstSrcRegs, //< Max source regs
- MaxInstDestRegs = ISA::MaxInstDestRegs, //< Max dest regs
+ MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
+ MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs
};
/** The static inst used by this dyn inst. */
- StaticInstPtr<ISA> staticInst;
+ StaticInstPtr staticInst;
////////////////////////////////////////////
//
@@ -89,16 +83,16 @@ class BaseDynInst : public FastAlloc, public RefCounted
Trace::InstRecord *traceData;
template <class T>
- Fault * read(Addr addr, T &data, unsigned flags);
+ Fault read(Addr addr, T &data, unsigned flags);
template <class T>
- Fault * write(T data, Addr addr, unsigned flags,
+ Fault write(T data, Addr addr, unsigned flags,
uint64_t *res);
void prefetch(Addr addr, unsigned flags);
void writeHint(Addr addr, int size, unsigned flags);
- Fault * copySrcTranslate(Addr src);
- Fault * copy(Addr dest);
+ Fault copySrcTranslate(Addr src);
+ Fault copy(Addr dest);
/** @todo: Consider making this private. */
public:
@@ -154,7 +148,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
ExecContext *xc;
/** The kind of fault this instruction has generated. */
- Fault * fault;
+ Fault fault;
/** The effective virtual address (lds & stores only). */
Addr effAddr;
@@ -214,7 +208,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
FullCPU *cpu);
/** BaseDynInst constructor given a static inst pointer. */
- BaseDynInst(StaticInstPtr<ISA> &_staticInst);
+ BaseDynInst(StaticInstPtr &_staticInst);
/** BaseDynInst destructor. */
~BaseDynInst();
@@ -225,7 +219,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
public:
void
- trace_mem(Fault * fault, // last fault
+ trace_mem(Fault fault, // last fault
MemCmd cmd, // last command
Addr addr, // virtual address of access
void *p, // memory accessed
@@ -238,7 +232,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
void dump(std::string &outstring);
/** Returns the fault type. */
- Fault * getFault() { return fault; }
+ Fault getFault() { return fault; }
/** Checks whether or not this instruction has had its branch target
* calculated yet. For now it is not utilized and is hacked to be
@@ -447,7 +441,7 @@ class BaseDynInst : public FastAlloc, public RefCounted
template<class Impl>
template<class T>
-inline Fault *
+inline Fault
BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags)
{
MemReqPtr req = new MemReq(addr, xc, sizeof(T), flags);
@@ -490,7 +484,7 @@ BaseDynInst<Impl>::read(Addr addr, T &data, unsigned flags)
template<class Impl>
template<class T>
-inline Fault *
+inline Fault
BaseDynInst<Impl>::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
if (traceData) {
diff --git a/cpu/cpu_models.py b/cpu/cpu_models.py
new file mode 100644
index 000000000..675204e5b
--- /dev/null
+++ b/cpu/cpu_models.py
@@ -0,0 +1,71 @@
+# 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.
+
+################
+# CpuModel class
+#
+# The CpuModel class encapsulates everything the ISA parser needs to
+# know about a particular CPU model.
+
+class CpuModel:
+ # Dict of available CPU model objects. Accessible as CpuModel.dict.
+ dict = {}
+
+ # Constructor. Automatically adds models to CpuModel.dict.
+ def __init__(self, name, filename, includes, strings):
+ self.name = name
+ self.filename = filename # filename for output exec code
+ self.includes = includes # include files needed in exec file
+ # The 'strings' dict holds all the per-CPU symbols we can
+ # substitute into templates etc.
+ self.strings = strings
+ # Add self to dict
+ CpuModel.dict[name] = self
+
+
+#
+# Define CPU models.
+#
+# Parameters are:
+# - name of model
+# - filename for generated ISA execution file
+# - includes needed for generated ISA execution file
+# - substitution strings for ISA description templates
+#
+
+CpuModel('SimpleCPU', 'simple_cpu_exec.cc',
+ '#include "cpu/simple/cpu.hh"',
+ { 'CPU_exec_context': 'SimpleCPU' })
+CpuModel('FastCPU', 'fast_cpu_exec.cc',
+ '#include "cpu/fast/cpu.hh"',
+ { 'CPU_exec_context': 'FastCPU' })
+CpuModel('FullCPU', 'full_cpu_exec.cc',
+ '#include "encumbered/cpu/full/dyn_inst.hh"',
+ { 'CPU_exec_context': 'DynInst' })
+CpuModel('AlphaFullCPU', 'alpha_o3_exec.cc',
+ '#include "cpu/o3/alpha_dyn_inst.hh"',
+ { 'CPU_exec_context': 'AlphaDynInst<AlphaSimpleImpl>' })
+
diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc
index e7facbebb..9bed3ba47 100644
--- a/cpu/exec_context.cc
+++ b/cpu/exec_context.cc
@@ -221,7 +221,7 @@ ExecContext::regStats(const string &name)
}
void
-ExecContext::trap(Fault * fault)
+ExecContext::trap(Fault fault)
{
//TheISA::trap(fault); //One possible way to do it...
diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh
index 7e195af23..3e0d77254 100644
--- a/cpu/exec_context.hh
+++ b/cpu/exec_context.hh
@@ -35,6 +35,7 @@
#include "sim/host.hh"
#include "sim/serialize.hh"
#include "arch/isa_traits.hh"
+//#include "arch/isa_registers.hh"
#include "sim/byteswap.hh"
// forward declaration: see functional_memory.hh
@@ -66,6 +67,10 @@ namespace Kernel { class Binning; class Statistics; }
class ExecContext
{
+ protected:
+ typedef TheISA::RegFile RegFile;
+ typedef TheISA::MachInst MachInst;
+ typedef TheISA::MiscRegFile MiscRegFile;
public:
enum Status
{
@@ -80,7 +85,7 @@ class ExecContext
Active,
/// Temporarily inactive. Entered while waiting for
- /// synchronization, etc.
+ /// initialization,synchronization, etc.
Suspended,
/// Permanently shut down. Entered when target executes
@@ -95,6 +100,8 @@ class ExecContext
public:
Status status() const { return _status; }
+ void setStatus(Status newStatus) { _status = newStatus; }
+
/// Set the status to Active. Optional delay indicates number of
/// cycles to wait before beginning execution.
void activate(int delay = 1);
@@ -206,17 +213,17 @@ class ExecContext
int getInstAsid() { return regs.instAsid(); }
int getDataAsid() { return regs.dataAsid(); }
- Fault * translateInstReq(MemReqPtr &req)
+ Fault translateInstReq(MemReqPtr &req)
{
return itb->translate(req);
}
- Fault * translateDataReadReq(MemReqPtr &req)
+ Fault translateDataReadReq(MemReqPtr &req)
{
return dtb->translate(req, false);
}
- Fault * translateDataWriteReq(MemReqPtr &req)
+ Fault translateDataWriteReq(MemReqPtr &req)
{
return dtb->translate(req, true);
}
@@ -231,7 +238,7 @@ class ExecContext
int getInstAsid() { return asid; }
int getDataAsid() { return asid; }
- Fault * dummyTranslation(MemReqPtr &req)
+ Fault dummyTranslation(MemReqPtr &req)
{
#if 0
assert((req->vaddr >> 48 & 0xffff) == 0);
@@ -242,15 +249,15 @@ class ExecContext
req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
return NoFault;
}
- Fault * translateInstReq(MemReqPtr &req)
+ Fault translateInstReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
- Fault * translateDataReadReq(MemReqPtr &req)
+ Fault translateDataReadReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
- Fault * translateDataWriteReq(MemReqPtr &req)
+ Fault translateDataWriteReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
@@ -258,7 +265,7 @@ class ExecContext
#endif
template <class T>
- Fault * read(MemReqPtr &req, T &data)
+ Fault read(MemReqPtr &req, T &data)
{
#if FULL_SYSTEM && defined(TARGET_ALPHA)
if (req->flags & LOCKED) {
@@ -268,14 +275,14 @@ class ExecContext
}
#endif
- Fault * error;
+ Fault error;
error = mem->read(req, data);
data = LittleEndianGuest::gtoh(data);
return error;
}
template <class T>
- Fault * write(MemReqPtr &req, T &data)
+ Fault write(MemReqPtr &req, T &data)
{
#if FULL_SYSTEM && defined(TARGET_ALPHA)
@@ -333,7 +340,7 @@ class ExecContext
inst = new_inst;
}
- Fault * instRead(MemReqPtr &req)
+ Fault instRead(MemReqPtr &req)
{
return mem->read(req, inst);
}
@@ -412,13 +419,13 @@ class ExecContext
}
#if FULL_SYSTEM
- uint64_t readIpr(int idx, Fault * &fault);
- Fault * setIpr(int idx, uint64_t val);
+ uint64_t readIpr(int idx, Fault &fault);
+ Fault setIpr(int idx, uint64_t val);
int readIntrFlag() { return regs.intrflag; }
void setIntrFlag(int val) { regs.intrflag = val; }
- Fault * hwrei();
+ Fault hwrei();
bool inPalMode() { return AlphaISA::PcPAL(regs.pc); }
- void ev5_trap(Fault * fault);
+ void ev5_trap(Fault fault);
bool simPalCheck(int palFunc);
#endif
@@ -428,18 +435,18 @@ class ExecContext
* @todo How to do this properly so it's dependent upon ISA only?
*/
- void trap(Fault * fault);
+ void trap(Fault fault);
#if !FULL_SYSTEM
- IntReg getSyscallArg(int i)
+ TheISA::IntReg getSyscallArg(int i)
{
- return regs.intRegFile[ArgumentReg0 + i];
+ return regs.intRegFile[TheISA::ArgumentReg0 + i];
}
// used to shift args for indirect syscall
- void setSyscallArg(int i, IntReg val)
+ void setSyscallArg(int i, TheISA::IntReg val)
{
- regs.intRegFile[ArgumentReg0 + i] = val;
+ regs.intRegFile[TheISA::ArgumentReg0 + i] = val;
}
void setSyscallReturn(SyscallReturn return_value)
@@ -451,11 +458,11 @@ class ExecContext
if (return_value.successful()) {
// no error
regs.intRegFile[RegA3] = 0;
- regs.intRegFile[ReturnValueReg] = return_value.value();
+ regs.intRegFile[TheISA::ReturnValueReg] = return_value.value();
} else {
// got an error, return details
- regs.intRegFile[RegA3] = (IntReg) -1;
- regs.intRegFile[ReturnValueReg] = -return_value.value();
+ regs.intRegFile[RegA3] = (TheISA::IntReg) -1;
+ regs.intRegFile[TheISA::ReturnValueReg] = -return_value.value();
}
}
diff --git a/cpu/exetrace.hh b/cpu/exetrace.hh
index 48d8966d8..67d042ec8 100644
--- a/cpu/exetrace.hh
+++ b/cpu/exetrace.hh
@@ -46,13 +46,14 @@ namespace Trace {
class InstRecord : public Record
{
protected:
+ typedef TheISA::IntRegFile IntRegFile;
// The following fields are initialized by the constructor and
// thus guaranteed to be valid.
BaseCPU *cpu;
// need to make this ref-counted so it doesn't go away before we
// dump the record
- StaticInstPtr<TheISA> staticInst;
+ StaticInstPtr staticInst;
Addr PC;
bool misspeculating;
unsigned thread;
@@ -92,7 +93,7 @@ class InstRecord : public Record
public:
InstRecord(Tick _cycle, BaseCPU *_cpu,
- const StaticInstPtr<TheISA> &_staticInst,
+ const StaticInstPtr &_staticInst,
Addr _pc, bool spec, int _thread)
: Record(_cycle), cpu(_cpu), staticInst(_staticInst), PC(_pc),
misspeculating(spec), thread(_thread)
@@ -169,7 +170,7 @@ InstRecord::setRegs(const IntRegFile &regs)
inline
InstRecord *
getInstRecord(Tick cycle, ExecContext *xc, BaseCPU *cpu,
- const StaticInstPtr<TheISA> staticInst,
+ const StaticInstPtr staticInst,
Addr pc, int thread = 0)
{
if (DTRACE(InstExec) &&
diff --git a/cpu/memtest/memtest.cc b/cpu/memtest/memtest.cc
index 27f790fac..5a4024587 100644
--- a/cpu/memtest/memtest.cc
+++ b/cpu/memtest/memtest.cc
@@ -44,6 +44,7 @@
#include "sim/stats.hh"
using namespace std;
+using namespace TheISA;
int TESTER_ALLOCATOR=0;
diff --git a/cpu/o3/2bit_local_pred.hh b/cpu/o3/2bit_local_pred.hh
index a97ce455c..97433e542 100644
--- a/cpu/o3/2bit_local_pred.hh
+++ b/cpu/o3/2bit_local_pred.hh
@@ -30,7 +30,7 @@
#define __CPU_O3_CPU_2BIT_LOCAL_PRED_HH__
// For Addr type.
-#include "arch/alpha/isa_traits.hh"
+#include "arch/isa_traits.hh"
#include "cpu/o3/sat_counter.hh"
class DefaultBP
diff --git a/cpu/o3/alpha_cpu.hh b/cpu/o3/alpha_cpu.hh
index 606f9fa0a..b35bcf9e3 100644
--- a/cpu/o3/alpha_cpu.hh
+++ b/cpu/o3/alpha_cpu.hh
@@ -39,8 +39,9 @@
template <class Impl>
class AlphaFullCPU : public FullO3CPU<Impl>
{
+ protected:
+ typedef TheISA::IntReg IntReg;
public:
- typedef typename Impl::ISA AlphaISA;
typedef typename Impl::Params Params;
public:
@@ -62,23 +63,23 @@ class AlphaFullCPU : public FullO3CPU<Impl>
// void clear_interrupt(int int_num, int index);
// void clear_interrupts();
- Fault * translateInstReq(MemReqPtr &req)
+ Fault translateInstReq(MemReqPtr &req)
{
return itb->translate(req);
}
- Fault * translateDataReadReq(MemReqPtr &req)
+ Fault translateDataReadReq(MemReqPtr &req)
{
return dtb->translate(req, false);
}
- Fault * translateDataWriteReq(MemReqPtr &req)
+ Fault translateDataWriteReq(MemReqPtr &req)
{
return dtb->translate(req, true);
}
#else
- Fault * dummyTranslation(MemReqPtr &req)
+ Fault dummyTranslation(MemReqPtr &req)
{
#if 0
assert((req->vaddr >> 48 & 0xffff) == 0);
@@ -90,17 +91,17 @@ class AlphaFullCPU : public FullO3CPU<Impl>
return NoFault;
}
- Fault * translateInstReq(MemReqPtr &req)
+ Fault translateInstReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
- Fault * translateDataReadReq(MemReqPtr &req)
+ Fault translateDataReadReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
- Fault * translateDataWriteReq(MemReqPtr &req)
+ Fault translateDataWriteReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
@@ -135,16 +136,16 @@ class AlphaFullCPU : public FullO3CPU<Impl>
// look like.
#if FULL_SYSTEM
uint64_t *getIpr();
- uint64_t readIpr(int idx, Fault * &fault);
- Fault * setIpr(int idx, uint64_t val);
+ uint64_t readIpr(int idx, Fault &fault);
+ Fault setIpr(int idx, uint64_t val);
int readIntrFlag();
void setIntrFlag(int val);
- Fault * hwrei();
+ Fault hwrei();
bool inPalMode() { return AlphaISA::PcPAL(this->regFile.readPC()); }
bool inPalMode(uint64_t PC)
{ return AlphaISA::PcPAL(PC); }
- void trap(Fault * fault);
+ void trap(Fault fault);
bool simPalCheck(int palFunc);
void processInterrupts();
@@ -197,7 +198,7 @@ class AlphaFullCPU : public FullO3CPU<Impl>
bool palShadowEnabled;
// Not sure this is used anywhere.
- void intr_post(RegFile *regs, Fault * fault, Addr pc);
+ void intr_post(RegFile *regs, Fault fault, Addr pc);
// Actually used within exec files. Implement properly.
void swapPALShadow(bool use_shadow);
// Called by CPU constructor. Can implement as I please.
@@ -210,7 +211,7 @@ class AlphaFullCPU : public FullO3CPU<Impl>
template <class T>
- Fault * read(MemReqPtr &req, T &data)
+ Fault read(MemReqPtr &req, T &data)
{
#if FULL_SYSTEM && defined(TARGET_ALPHA)
if (req->flags & LOCKED) {
@@ -220,20 +221,20 @@ class AlphaFullCPU : public FullO3CPU<Impl>
}
#endif
- Fault * error;
+ Fault error;
error = this->mem->read(req, data);
data = gtoh(data);
return error;
}
template <class T>
- Fault * read(MemReqPtr &req, T &data, int load_idx)
+ Fault read(MemReqPtr &req, T &data, int load_idx)
{
return this->iew.ldstQueue.read(req, data, load_idx);
}
template <class T>
- Fault * write(MemReqPtr &req, T &data)
+ Fault write(MemReqPtr &req, T &data)
{
#if FULL_SYSTEM && defined(TARGET_ALPHA)
@@ -283,7 +284,7 @@ class AlphaFullCPU : public FullO3CPU<Impl>
}
template <class T>
- Fault * write(MemReqPtr &req, T &data, int store_idx)
+ Fault write(MemReqPtr &req, T &data, int store_idx)
{
return this->iew.ldstQueue.write(req, data, store_idx);
}
diff --git a/cpu/o3/alpha_cpu_impl.hh b/cpu/o3/alpha_cpu_impl.hh
index 408676331..7ec1ba663 100644
--- a/cpu/o3/alpha_cpu_impl.hh
+++ b/cpu/o3/alpha_cpu_impl.hh
@@ -246,13 +246,13 @@ AlphaFullCPU<Impl>::getIpr()
template <class Impl>
uint64_t
-AlphaFullCPU<Impl>::readIpr(int idx, Fault * &fault)
+AlphaFullCPU<Impl>::readIpr(int idx, Fault &fault)
{
return this->regFile.readIpr(idx, fault);
}
template <class Impl>
-Fault *
+Fault
AlphaFullCPU<Impl>::setIpr(int idx, uint64_t val)
{
return this->regFile.setIpr(idx, val);
@@ -274,7 +274,7 @@ AlphaFullCPU<Impl>::setIntrFlag(int val)
// Can force commit stage to squash and stuff.
template <class Impl>
-Fault *
+Fault
AlphaFullCPU<Impl>::hwrei()
{
uint64_t *ipr = getIpr();
@@ -282,7 +282,7 @@ AlphaFullCPU<Impl>::hwrei()
if (!inPalMode())
return UnimplementedOpcodeFault;
- setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]);
+ this->setNextPC(ipr[AlphaISA::IPR_EXC_ADDR]);
// kernelStats.hwrei();
@@ -323,7 +323,7 @@ AlphaFullCPU<Impl>::simPalCheck(int palFunc)
// stage.
template <class Impl>
void
-AlphaFullCPU<Impl>::trap(Fault * fault)
+AlphaFullCPU<Impl>::trap(Fault fault)
{
// Keep in mind that a trap may be initiated by fetch if there's a TLB
// miss
@@ -337,7 +337,7 @@ AlphaFullCPU<Impl>::trap(Fault * fault)
if (fault == ArithmeticFault)
panic("Arithmetic traps are unimplemented!");
- typename AlphaISA::InternalProcReg *ipr = getIpr();
+ AlphaISA::InternalProcReg *ipr = getIpr();
// exception restart address - Get the commit PC
if (fault != InterruptFault || !inPalMode(PC))
diff --git a/cpu/o3/alpha_dyn_inst.hh b/cpu/o3/alpha_dyn_inst.hh
index 77dcbaf74..f282c287c 100644
--- a/cpu/o3/alpha_dyn_inst.hh
+++ b/cpu/o3/alpha_dyn_inst.hh
@@ -48,21 +48,16 @@ class AlphaDynInst : public BaseDynInst<Impl>
/** Typedef for the CPU. */
typedef typename Impl::FullCPU FullCPU;
- /** Typedef to get the ISA. */
- typedef typename Impl::ISA ISA;
-
/** Binary machine instruction type. */
- typedef typename ISA::MachInst MachInst;
- /** Memory address type. */
- typedef typename ISA::Addr Addr;
+ typedef TheISA::MachInst MachInst;
/** Logical register index type. */
- typedef typename ISA::RegIndex RegIndex;
+ typedef TheISA::RegIndex RegIndex;
/** Integer register index type. */
- typedef typename ISA::IntReg IntReg;
+ typedef TheISA::IntReg IntReg;
enum {
- MaxInstSrcRegs = ISA::MaxInstSrcRegs, //< Max source regs
- MaxInstDestRegs = ISA::MaxInstDestRegs, //< Max dest regs
+ MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
+ MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs
};
public:
@@ -71,10 +66,10 @@ class AlphaDynInst : public BaseDynInst<Impl>
FullCPU *cpu);
/** BaseDynInst constructor given a static inst pointer. */
- AlphaDynInst(StaticInstPtr<AlphaISA> &_staticInst);
+ AlphaDynInst(StaticInstPtr &_staticInst);
/** Executes the instruction.*/
- Fault * execute()
+ Fault execute()
{
return this->fault = this->staticInst->execute(this, this->traceData);
}
@@ -87,13 +82,13 @@ class AlphaDynInst : public BaseDynInst<Impl>
void setFpcr(uint64_t val);
#if FULL_SYSTEM
- uint64_t readIpr(int idx, Fault * &fault);
- Fault * setIpr(int idx, uint64_t val);
- Fault * hwrei();
+ uint64_t readIpr(int idx, Fault &fault);
+ Fault setIpr(int idx, uint64_t val);
+ Fault hwrei();
int readIntrFlag();
void setIntrFlag(int val);
bool inPalMode();
- void trap(Fault * fault);
+ void trap(Fault fault);
bool simPalCheck(int palFunc);
#else
void syscall();
@@ -130,22 +125,22 @@ class AlphaDynInst : public BaseDynInst<Impl>
// storage (which is pretty hard to imagine they would have reason
// to do).
- uint64_t readIntReg(const StaticInst<ISA> *si, int idx)
+ uint64_t readIntReg(const StaticInst *si, int idx)
{
return this->cpu->readIntReg(_srcRegIdx[idx]);
}
- float readFloatRegSingle(const StaticInst<ISA> *si, int idx)
+ float readFloatRegSingle(const StaticInst *si, int idx)
{
return this->cpu->readFloatRegSingle(_srcRegIdx[idx]);
}
- double readFloatRegDouble(const StaticInst<ISA> *si, int idx)
+ double readFloatRegDouble(const StaticInst *si, int idx)
{
return this->cpu->readFloatRegDouble(_srcRegIdx[idx]);
}
- uint64_t readFloatRegInt(const StaticInst<ISA> *si, int idx)
+ uint64_t readFloatRegInt(const StaticInst *si, int idx)
{
return this->cpu->readFloatRegInt(_srcRegIdx[idx]);
}
@@ -153,25 +148,25 @@ class AlphaDynInst : public BaseDynInst<Impl>
/** @todo: Make results into arrays so they can handle multiple dest
* registers.
*/
- void setIntReg(const StaticInst<ISA> *si, int idx, uint64_t val)
+ void setIntReg(const StaticInst *si, int idx, uint64_t val)
{
this->cpu->setIntReg(_destRegIdx[idx], val);
this->instResult.integer = val;
}
- void setFloatRegSingle(const StaticInst<ISA> *si, int idx, float val)
+ void setFloatRegSingle(const StaticInst *si, int idx, float val)
{
this->cpu->setFloatRegSingle(_destRegIdx[idx], val);
this->instResult.fp = val;
}
- void setFloatRegDouble(const StaticInst<ISA> *si, int idx, double val)
+ void setFloatRegDouble(const StaticInst *si, int idx, double val)
{
this->cpu->setFloatRegDouble(_destRegIdx[idx], val);
this->instResult.dbl = val;
}
- void setFloatRegInt(const StaticInst<ISA> *si, int idx, uint64_t val)
+ void setFloatRegInt(const StaticInst *si, int idx, uint64_t val)
{
this->cpu->setFloatRegInt(_destRegIdx[idx], val);
this->instResult.integer = val;
@@ -220,12 +215,12 @@ class AlphaDynInst : public BaseDynInst<Impl>
}
public:
- Fault * calcEA()
+ Fault calcEA()
{
return this->staticInst->eaCompInst()->execute(this, this->traceData);
}
- Fault * memAccess()
+ Fault memAccess()
{
return this->staticInst->memAccInst()->execute(this, this->traceData);
}
diff --git a/cpu/o3/alpha_dyn_inst_impl.hh b/cpu/o3/alpha_dyn_inst_impl.hh
index b20af48cd..eebe7675a 100644
--- a/cpu/o3/alpha_dyn_inst_impl.hh
+++ b/cpu/o3/alpha_dyn_inst_impl.hh
@@ -50,7 +50,7 @@ AlphaDynInst<Impl>::AlphaDynInst(MachInst inst, Addr PC, Addr Pred_PC,
}
template <class Impl>
-AlphaDynInst<Impl>::AlphaDynInst(StaticInstPtr<AlphaISA> &_staticInst)
+AlphaDynInst<Impl>::AlphaDynInst(StaticInstPtr &_staticInst)
: BaseDynInst<Impl>(_staticInst)
{
// Make sure to have the renamed register entries set to the same
@@ -98,20 +98,20 @@ AlphaDynInst<Impl>::setFpcr(uint64_t val)
#if FULL_SYSTEM
template <class Impl>
uint64_t
-AlphaDynInst<Impl>::readIpr(int idx, Fault * &fault)
+AlphaDynInst<Impl>::readIpr(int idx, Fault &fault)
{
return this->cpu->readIpr(idx, fault);
}
template <class Impl>
-Fault *
+Fault
AlphaDynInst<Impl>::setIpr(int idx, uint64_t val)
{
return this->cpu->setIpr(idx, val);
}
template <class Impl>
-Fault *
+Fault
AlphaDynInst<Impl>::hwrei()
{
return this->cpu->hwrei();
@@ -140,7 +140,7 @@ AlphaDynInst<Impl>::inPalMode()
template <class Impl>
void
-AlphaDynInst<Impl>::trap(Fault * fault)
+AlphaDynInst<Impl>::trap(Fault fault)
{
this->cpu->trap(fault);
}
diff --git a/cpu/o3/alpha_impl.hh b/cpu/o3/alpha_impl.hh
index 6c1156041..5e39fcb37 100644
--- a/cpu/o3/alpha_impl.hh
+++ b/cpu/o3/alpha_impl.hh
@@ -51,11 +51,8 @@ class AlphaFullCPU;
*/
struct AlphaSimpleImpl
{
- /** The ISA to be used. */
- typedef AlphaISA ISA;
-
/** The type of MachInst. */
- typedef ISA::MachInst MachInst;
+ typedef TheISA::MachInst MachInst;
/** The CPU policy to be used (ie fetch, decode, etc.). */
typedef SimpleCPUPolicy<AlphaSimpleImpl> CPUPol;
diff --git a/cpu/o3/bpred_unit_impl.hh b/cpu/o3/bpred_unit_impl.hh
index 9cb2e0490..8d16a0cdf 100644
--- a/cpu/o3/bpred_unit_impl.hh
+++ b/cpu/o3/bpred_unit_impl.hh
@@ -98,6 +98,8 @@ TwobitBPredUnit<Impl>::predict(DynInstPtr &inst, Addr &PC)
// Save off record of branch stuff so the RAS can be fixed
// up once it's done.
+ using TheISA::MachInst;
+
bool pred_taken = false;
Addr target;
diff --git a/cpu/o3/btb.cc b/cpu/o3/btb.cc
index 7671e61e2..2d39c3856 100644
--- a/cpu/o3/btb.cc
+++ b/cpu/o3/btb.cc
@@ -30,6 +30,8 @@
#include "base/trace.hh"
#include "cpu/o3/btb.hh"
+using namespace TheISA;
+
DefaultBTB::DefaultBTB(unsigned _numEntries,
unsigned _tagBits,
unsigned _instShiftAmt)
diff --git a/cpu/o3/btb.hh b/cpu/o3/btb.hh
index a4ddfecb4..77bdc32ea 100644
--- a/cpu/o3/btb.hh
+++ b/cpu/o3/btb.hh
@@ -30,7 +30,7 @@
#define __CPU_O3_CPU_BTB_HH__
// For Addr type.
-#include "arch/alpha/isa_traits.hh"
+#include "arch/isa_traits.hh"
class DefaultBTB
{
diff --git a/cpu/o3/commit.hh b/cpu/o3/commit.hh
index 6ddc8d6b9..580c1a316 100644
--- a/cpu/o3/commit.hh
+++ b/cpu/o3/commit.hh
@@ -52,7 +52,6 @@ class SimpleCommit
{
public:
// Typedefs from the Impl.
- typedef typename Impl::ISA ISA;
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::Params Params;
diff --git a/cpu/o3/commit_impl.hh b/cpu/o3/commit_impl.hh
index 47b4dfd00..e289bc0c0 100644
--- a/cpu/o3/commit_impl.hh
+++ b/cpu/o3/commit_impl.hh
@@ -393,7 +393,7 @@ SimpleCommit<Impl>::commitHead(DynInstPtr &head_inst, unsigned inst_num)
}
// Check if the instruction caused a fault. If so, trap.
- Fault * inst_fault = head_inst->getFault();
+ Fault inst_fault = head_inst->getFault();
if (inst_fault != NoFault) {
if (!head_inst->isNop()) {
diff --git a/cpu/o3/cpu.cc b/cpu/o3/cpu.cc
index adc7b6bbc..706657887 100644
--- a/cpu/o3/cpu.cc
+++ b/cpu/o3/cpu.cc
@@ -84,14 +84,14 @@ FullO3CPU<Impl>::FullO3CPU(Params &params)
regFile(params.numPhysIntRegs, params.numPhysFloatRegs),
- freeList(Impl::ISA::NumIntRegs, params.numPhysIntRegs,
- Impl::ISA::NumFloatRegs, params.numPhysFloatRegs),
+ freeList(TheISA::NumIntRegs, params.numPhysIntRegs,
+ TheISA::NumFloatRegs, params.numPhysFloatRegs),
- renameMap(Impl::ISA::NumIntRegs, params.numPhysIntRegs,
- Impl::ISA::NumFloatRegs, params.numPhysFloatRegs,
- Impl::ISA::NumMiscRegs,
- Impl::ISA::ZeroReg,
- Impl::ISA::ZeroReg + Impl::ISA::NumIntRegs),
+ renameMap(TheISA::NumIntRegs, params.numPhysIntRegs,
+ TheISA::NumFloatRegs, params.numPhysFloatRegs,
+ TheISA::NumMiscRegs,
+ TheISA::ZeroReg,
+ TheISA::ZeroReg + TheISA::NumIntRegs),
rob(params.numROBEntries, params.squashWidth),
@@ -137,8 +137,6 @@ FullO3CPU<Impl>::FullO3CPU(Params &params)
system->execContexts[i] =
new ExecContext(this, i, system, itb, dtb, mem);
- // initialize CPU, including PC
- TheISA::initCPU(&system->execContexts[i]->regs);
execContexts.push_back(system->execContexts[i]);
#else
if (i < params.workload.size()) {
@@ -250,17 +248,18 @@ FullO3CPU<Impl>::init()
// that it can start properly.
#if FULL_SYSTEM
ExecContext *src_xc = system->execContexts[0];
+ TheISA::initCPU(&src_xc->regs, src_xc->cpu_id);
#else
ExecContext *src_xc = thread[0];
#endif
// First loop through the integer registers.
- for (int i = 0; i < Impl::ISA::NumIntRegs; ++i)
+ for (int i = 0; i < TheISA::NumIntRegs; ++i)
{
regFile.intRegFile[i] = src_xc->regs.intRegFile[i];
}
// Then loop through the floating point registers.
- for (int i = 0; i < Impl::ISA::NumFloatRegs; ++i)
+ for (int i = 0; i < TheISA::NumFloatRegs; ++i)
{
regFile.floatRegFile[i].d = src_xc->regs.floatRegFile.d[i];
regFile.floatRegFile[i].q = src_xc->regs.floatRegFile.q[i];
diff --git a/cpu/o3/cpu.hh b/cpu/o3/cpu.hh
index 75dca5056..321d61dce 100644
--- a/cpu/o3/cpu.hh
+++ b/cpu/o3/cpu.hh
@@ -78,7 +78,6 @@ class FullO3CPU : public BaseFullCPU
{
public:
//Put typedefs from the Impl here.
- typedef typename Impl::ISA ISA;
typedef typename Impl::CPUPol CPUPolicy;
typedef typename Impl::Params Params;
typedef typename Impl::DynInstPtr DynInstPtr;
@@ -153,11 +152,11 @@ class FullO3CPU : public BaseFullCPU
/** Get instruction asid. */
int getInstAsid()
- { return ITB_ASN_ASN(regFile.getIpr()[ISA::IPR_ITB_ASN]); }
+ { return ITB_ASN_ASN(regFile.getIpr()[TheISA::IPR_ITB_ASN]); }
/** Get data asid. */
int getDataAsid()
- { return DTB_ASN_ASN(regFile.getIpr()[ISA::IPR_DTB_ASN]); }
+ { return DTB_ASN_ASN(regFile.getIpr()[TheISA::IPR_DTB_ASN]); }
#else
bool validInstAddr(Addr addr)
{ return thread[0]->validInstAddr(addr); }
diff --git a/cpu/o3/decode.hh b/cpu/o3/decode.hh
index 42313d83a..5b9a0f822 100644
--- a/cpu/o3/decode.hh
+++ b/cpu/o3/decode.hh
@@ -39,7 +39,6 @@ class SimpleDecode
{
private:
// Typedefs from the Impl.
- typedef typename Impl::ISA ISA;
typedef typename Impl::FullCPU FullCPU;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::Params Params;
@@ -50,9 +49,6 @@ class SimpleDecode
typedef typename CPUPol::DecodeStruct DecodeStruct;
typedef typename CPUPol::TimeStruct TimeStruct;
- // Typedefs from the ISA.
- typedef typename ISA::Addr Addr;
-
public:
// The only time decode will become blocked is if dispatch becomes
// blocked, which means IQ or ROB is probably full.
diff --git a/cpu/o3/fetch.hh b/cpu/o3/fetch.hh
index 5443d274e..cc64800d9 100644
--- a/cpu/o3/fetch.hh
+++ b/cpu/o3/fetch.hh
@@ -49,7 +49,6 @@ class SimpleFetch
{
public:
/** Typedefs from Impl. */
- typedef typename Impl::ISA ISA;
typedef typename Impl::CPUPol CPUPol;
typedef typename Impl::DynInst DynInst;
typedef typename Impl::DynInstPtr DynInstPtr;
@@ -61,7 +60,7 @@ class SimpleFetch
typedef typename CPUPol::TimeStruct TimeStruct;
/** Typedefs from ISA. */
- typedef typename ISA::MachInst MachInst;
+ typedef TheISA::MachInst MachInst;
public:
enum Status {
@@ -123,7 +122,7 @@ class SimpleFetch
* @param fetch_PC The PC address that is being fetched from.
* @return Any fault that occured.
*/
- Fault * fetchCacheLine(Addr fetch_PC);
+ Fault fetchCacheLine(Addr fetch_PC);
inline void doSquash(const Addr &new_PC);
@@ -141,7 +140,7 @@ class SimpleFetch
// We fold in the PISA 64- to 32-bit conversion here as well.
Addr icacheBlockAlignPC(Addr addr)
{
- addr = ISA::realPCToFetchPC(addr);
+ addr = TheISA::realPCToFetchPC(addr);
return (addr & ~(cacheBlkMask));
}
diff --git a/cpu/o3/fetch_impl.hh b/cpu/o3/fetch_impl.hh
index e8d333ed4..8029fc732 100644
--- a/cpu/o3/fetch_impl.hh
+++ b/cpu/o3/fetch_impl.hh
@@ -221,7 +221,7 @@ SimpleFetch<Impl>::lookupAndUpdateNextPC(DynInstPtr &inst, Addr &next_PC)
}
template <class Impl>
-Fault *
+Fault
SimpleFetch<Impl>::fetchCacheLine(Addr fetch_PC)
{
// Check if the instruction exists within the cache.
@@ -236,7 +236,7 @@ SimpleFetch<Impl>::fetchCacheLine(Addr fetch_PC)
unsigned flags = 0;
#endif // FULL_SYSTEM
- Fault * fault = NoFault;
+ Fault fault = NoFault;
// Align the fetch PC so it's at the start of a cache block.
fetch_PC = icacheBlockAlignPC(fetch_PC);
@@ -468,7 +468,7 @@ SimpleFetch<Impl>::fetch()
Addr fetch_PC = cpu->readPC();
// Fault code for memory access.
- Fault * fault = NoFault;
+ Fault fault = NoFault;
// If returning from the delay of a cache miss, then update the status
// to running, otherwise do the cache access. Possibly move this up
diff --git a/cpu/o3/free_list.hh b/cpu/o3/free_list.hh
index 733d142fc..0b85dba1e 100644
--- a/cpu/o3/free_list.hh
+++ b/cpu/o3/free_list.hh
@@ -32,7 +32,7 @@
#include <iostream>
#include <queue>
-#include "arch/alpha/isa_traits.hh"
+#include "arch/isa_traits.hh"
#include "base/trace.hh"
#include "base/traceflags.hh"
#include "cpu/o3/comm.hh"
diff --git a/cpu/o3/iew.hh b/cpu/o3/iew.hh
index af23c6f45..1e370d4e6 100644
--- a/cpu/o3/iew.hh
+++ b/cpu/o3/iew.hh
@@ -45,7 +45,6 @@ class SimpleIEW
{
private:
//Typedefs from Impl
- typedef typename Impl::ISA ISA;
typedef typename Impl::CPUPol CPUPol;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::FullCPU FullCPU;
diff --git a/cpu/o3/iew_impl.hh b/cpu/o3/iew_impl.hh
index b8a2b4dc9..85217dd10 100644
--- a/cpu/o3/iew_impl.hh
+++ b/cpu/o3/iew_impl.hh
@@ -256,7 +256,7 @@ SimpleIEW<Impl>::squashDueToBranch(DynInstPtr &inst)
toCommit->branchMispredict = true;
// Prediction was incorrect, so send back inverse.
toCommit->branchTaken = inst->readNextPC() !=
- (inst->readPC() + sizeof(MachInst));
+ (inst->readPC() + sizeof(TheISA::MachInst));
}
template<class Impl>
diff --git a/cpu/o3/ras.hh b/cpu/o3/ras.hh
index bbc4162a6..46d98181e 100644
--- a/cpu/o3/ras.hh
+++ b/cpu/o3/ras.hh
@@ -30,7 +30,7 @@
#define __CPU_O3_CPU_RAS_HH__
// For Addr type.
-#include "arch/alpha/isa_traits.hh"
+#include "arch/isa_traits.hh"
class ReturnAddrStack
{
diff --git a/cpu/o3/regfile.hh b/cpu/o3/regfile.hh
index 5aafd5495..ee7b8858e 100644
--- a/cpu/o3/regfile.hh
+++ b/cpu/o3/regfile.hh
@@ -52,6 +52,10 @@ using namespace EV5;
template <class Impl>
class PhysRegFile
{
+ protected:
+ typedef TheISA::IntReg IntReg;
+ typedef TheISA::FloatReg FloatReg;
+ typedef TheISA::MiscRegFile MiscRegFile;
//Note that most of the definitions of the IntReg, FloatReg, etc. exist
//within the Impl/ISA class and not within this PhysRegFile class.
@@ -62,7 +66,6 @@ class PhysRegFile
//Will make these registers public for now, but they probably should
//be private eventually with some accessor functions.
public:
- typedef typename Impl::ISA ISA;
typedef typename Impl::FullCPU FullCPU;
PhysRegFile(unsigned _numPhysicalIntRegs,
@@ -212,8 +215,8 @@ class PhysRegFile
}
#if FULL_SYSTEM
- uint64_t readIpr(int idx, Fault * &fault);
- Fault * setIpr(int idx, uint64_t val);
+ uint64_t readIpr(int idx, Fault &fault);
+ Fault setIpr(int idx, uint64_t val);
InternalProcReg *getIpr() { return ipr; }
int readIntrFlag() { return intrflag; }
void setIntrFlag(int val) { intrflag = val; }
@@ -276,78 +279,78 @@ PhysRegFile<Impl>::PhysRegFile(unsigned _numPhysicalIntRegs,
//the DynInst level.
template <class Impl>
uint64_t
-PhysRegFile<Impl>::readIpr(int idx, Fault * &fault)
+PhysRegFile<Impl>::readIpr(int idx, Fault &fault)
{
uint64_t retval = 0; // return value, default 0
switch (idx) {
- case ISA::IPR_PALtemp0:
- case ISA::IPR_PALtemp1:
- case ISA::IPR_PALtemp2:
- case ISA::IPR_PALtemp3:
- case ISA::IPR_PALtemp4:
- case ISA::IPR_PALtemp5:
- case ISA::IPR_PALtemp6:
- case ISA::IPR_PALtemp7:
- case ISA::IPR_PALtemp8:
- case ISA::IPR_PALtemp9:
- case ISA::IPR_PALtemp10:
- case ISA::IPR_PALtemp11:
- case ISA::IPR_PALtemp12:
- case ISA::IPR_PALtemp13:
- case ISA::IPR_PALtemp14:
- case ISA::IPR_PALtemp15:
- case ISA::IPR_PALtemp16:
- case ISA::IPR_PALtemp17:
- case ISA::IPR_PALtemp18:
- case ISA::IPR_PALtemp19:
- case ISA::IPR_PALtemp20:
- case ISA::IPR_PALtemp21:
- case ISA::IPR_PALtemp22:
- case ISA::IPR_PALtemp23:
- case ISA::IPR_PAL_BASE:
-
- case ISA::IPR_IVPTBR:
- case ISA::IPR_DC_MODE:
- case ISA::IPR_MAF_MODE:
- case ISA::IPR_ISR:
- case ISA::IPR_EXC_ADDR:
- case ISA::IPR_IC_PERR_STAT:
- case ISA::IPR_DC_PERR_STAT:
- case ISA::IPR_MCSR:
- case ISA::IPR_ASTRR:
- case ISA::IPR_ASTER:
- case ISA::IPR_SIRR:
- case ISA::IPR_ICSR:
- case ISA::IPR_ICM:
- case ISA::IPR_DTB_CM:
- case ISA::IPR_IPLR:
- case ISA::IPR_INTID:
- case ISA::IPR_PMCTR:
+ case TheISA::IPR_PALtemp0:
+ case TheISA::IPR_PALtemp1:
+ case TheISA::IPR_PALtemp2:
+ case TheISA::IPR_PALtemp3:
+ case TheISA::IPR_PALtemp4:
+ case TheISA::IPR_PALtemp5:
+ case TheISA::IPR_PALtemp6:
+ case TheISA::IPR_PALtemp7:
+ case TheISA::IPR_PALtemp8:
+ case TheISA::IPR_PALtemp9:
+ case TheISA::IPR_PALtemp10:
+ case TheISA::IPR_PALtemp11:
+ case TheISA::IPR_PALtemp12:
+ case TheISA::IPR_PALtemp13:
+ case TheISA::IPR_PALtemp14:
+ case TheISA::IPR_PALtemp15:
+ case TheISA::IPR_PALtemp16:
+ case TheISA::IPR_PALtemp17:
+ case TheISA::IPR_PALtemp18:
+ case TheISA::IPR_PALtemp19:
+ case TheISA::IPR_PALtemp20:
+ case TheISA::IPR_PALtemp21:
+ case TheISA::IPR_PALtemp22:
+ case TheISA::IPR_PALtemp23:
+ case TheISA::IPR_PAL_BASE:
+
+ case TheISA::IPR_IVPTBR:
+ case TheISA::IPR_DC_MODE:
+ case TheISA::IPR_MAF_MODE:
+ case TheISA::IPR_ISR:
+ case TheISA::IPR_EXC_ADDR:
+ case TheISA::IPR_IC_PERR_STAT:
+ case TheISA::IPR_DC_PERR_STAT:
+ case TheISA::IPR_MCSR:
+ case TheISA::IPR_ASTRR:
+ case TheISA::IPR_ASTER:
+ case TheISA::IPR_SIRR:
+ case TheISA::IPR_ICSR:
+ case TheISA::IPR_ICM:
+ case TheISA::IPR_DTB_CM:
+ case TheISA::IPR_IPLR:
+ case TheISA::IPR_INTID:
+ case TheISA::IPR_PMCTR:
// no side-effect
retval = ipr[idx];
break;
- case ISA::IPR_CC:
+ case TheISA::IPR_CC:
retval |= ipr[idx] & ULL(0xffffffff00000000);
retval |= curTick & ULL(0x00000000ffffffff);
break;
- case ISA::IPR_VA:
+ case TheISA::IPR_VA:
retval = ipr[idx];
break;
- case ISA::IPR_VA_FORM:
- case ISA::IPR_MM_STAT:
- case ISA::IPR_IFAULT_VA_FORM:
- case ISA::IPR_EXC_MASK:
- case ISA::IPR_EXC_SUM:
+ case TheISA::IPR_VA_FORM:
+ case TheISA::IPR_MM_STAT:
+ case TheISA::IPR_IFAULT_VA_FORM:
+ case TheISA::IPR_EXC_MASK:
+ case TheISA::IPR_EXC_SUM:
retval = ipr[idx];
break;
- case ISA::IPR_DTB_PTE:
+ case TheISA::IPR_DTB_PTE:
{
- typename ISA::PTE &pte = cpu->dtb->index(1);
+ TheISA::PTE &pte = cpu->dtb->index(1);
retval |= ((u_int64_t)pte.ppn & ULL(0x7ffffff)) << 32;
retval |= ((u_int64_t)pte.xre & ULL(0xf)) << 8;
@@ -360,15 +363,15 @@ PhysRegFile<Impl>::readIpr(int idx, Fault * &fault)
break;
// write only registers
- case ISA::IPR_HWINT_CLR:
- case ISA::IPR_SL_XMIT:
- case ISA::IPR_DC_FLUSH:
- case ISA::IPR_IC_FLUSH:
- case ISA::IPR_ALT_MODE:
- case ISA::IPR_DTB_IA:
- case ISA::IPR_DTB_IAP:
- case ISA::IPR_ITB_IA:
- case ISA::IPR_ITB_IAP:
+ case TheISA::IPR_HWINT_CLR:
+ case TheISA::IPR_SL_XMIT:
+ case TheISA::IPR_DC_FLUSH:
+ case TheISA::IPR_IC_FLUSH:
+ case TheISA::IPR_ALT_MODE:
+ case TheISA::IPR_DTB_IA:
+ case TheISA::IPR_DTB_IAP:
+ case TheISA::IPR_ITB_IA:
+ case TheISA::IPR_ITB_IAP:
fault = UnimplementedOpcodeFault;
break;
@@ -384,201 +387,201 @@ PhysRegFile<Impl>::readIpr(int idx, Fault * &fault)
extern int break_ipl;
template <class Impl>
-Fault *
+Fault
PhysRegFile<Impl>::setIpr(int idx, uint64_t val)
{
uint64_t old;
switch (idx) {
- case ISA::IPR_PALtemp0:
- case ISA::IPR_PALtemp1:
- case ISA::IPR_PALtemp2:
- case ISA::IPR_PALtemp3:
- case ISA::IPR_PALtemp4:
- case ISA::IPR_PALtemp5:
- case ISA::IPR_PALtemp6:
- case ISA::IPR_PALtemp7:
- case ISA::IPR_PALtemp8:
- case ISA::IPR_PALtemp9:
- case ISA::IPR_PALtemp10:
- case ISA::IPR_PALtemp11:
- case ISA::IPR_PALtemp12:
- case ISA::IPR_PALtemp13:
- case ISA::IPR_PALtemp14:
- case ISA::IPR_PALtemp15:
- case ISA::IPR_PALtemp16:
- case ISA::IPR_PALtemp17:
- case ISA::IPR_PALtemp18:
- case ISA::IPR_PALtemp19:
- case ISA::IPR_PALtemp20:
- case ISA::IPR_PALtemp21:
- case ISA::IPR_PALtemp22:
- case ISA::IPR_PAL_BASE:
- case ISA::IPR_IC_PERR_STAT:
- case ISA::IPR_DC_PERR_STAT:
- case ISA::IPR_PMCTR:
+ case TheISA::IPR_PALtemp0:
+ case TheISA::IPR_PALtemp1:
+ case TheISA::IPR_PALtemp2:
+ case TheISA::IPR_PALtemp3:
+ case TheISA::IPR_PALtemp4:
+ case TheISA::IPR_PALtemp5:
+ case TheISA::IPR_PALtemp6:
+ case TheISA::IPR_PALtemp7:
+ case TheISA::IPR_PALtemp8:
+ case TheISA::IPR_PALtemp9:
+ case TheISA::IPR_PALtemp10:
+ case TheISA::IPR_PALtemp11:
+ case TheISA::IPR_PALtemp12:
+ case TheISA::IPR_PALtemp13:
+ case TheISA::IPR_PALtemp14:
+ case TheISA::IPR_PALtemp15:
+ case TheISA::IPR_PALtemp16:
+ case TheISA::IPR_PALtemp17:
+ case TheISA::IPR_PALtemp18:
+ case TheISA::IPR_PALtemp19:
+ case TheISA::IPR_PALtemp20:
+ case TheISA::IPR_PALtemp21:
+ case TheISA::IPR_PALtemp22:
+ case TheISA::IPR_PAL_BASE:
+ case TheISA::IPR_IC_PERR_STAT:
+ case TheISA::IPR_DC_PERR_STAT:
+ case TheISA::IPR_PMCTR:
// write entire quad w/ no side-effect
ipr[idx] = val;
break;
- case ISA::IPR_CC_CTL:
+ case TheISA::IPR_CC_CTL:
// This IPR resets the cycle counter. We assume this only
// happens once... let's verify that.
assert(ipr[idx] == 0);
ipr[idx] = 1;
break;
- case ISA::IPR_CC:
+ case TheISA::IPR_CC:
// This IPR only writes the upper 64 bits. It's ok to write
// all 64 here since we mask out the lower 32 in rpcc (see
// isa_desc).
ipr[idx] = val;
break;
- case ISA::IPR_PALtemp23:
+ case TheISA::IPR_PALtemp23:
// write entire quad w/ no side-effect
old = ipr[idx];
ipr[idx] = val;
break;
- case ISA::IPR_DTB_PTE:
+ case TheISA::IPR_DTB_PTE:
// write entire quad w/ no side-effect, tag is forthcoming
ipr[idx] = val;
break;
- case ISA::IPR_EXC_ADDR:
+ case TheISA::IPR_EXC_ADDR:
// second least significant bit in PC is always zero
ipr[idx] = val & ~2;
break;
- case ISA::IPR_ASTRR:
- case ISA::IPR_ASTER:
+ case TheISA::IPR_ASTRR:
+ case TheISA::IPR_ASTER:
// only write least significant four bits - privilege mask
ipr[idx] = val & 0xf;
break;
- case ISA::IPR_IPLR:
+ case TheISA::IPR_IPLR:
// only write least significant five bits - interrupt level
ipr[idx] = val & 0x1f;
break;
- case ISA::IPR_DTB_CM:
+ case TheISA::IPR_DTB_CM:
- case ISA::IPR_ICM:
+ case TheISA::IPR_ICM:
// only write two mode bits - processor mode
ipr[idx] = val & 0x18;
break;
- case ISA::IPR_ALT_MODE:
+ case TheISA::IPR_ALT_MODE:
// only write two mode bits - processor mode
ipr[idx] = val & 0x18;
break;
- case ISA::IPR_MCSR:
+ case TheISA::IPR_MCSR:
// more here after optimization...
ipr[idx] = val;
break;
- case ISA::IPR_SIRR:
+ case TheISA::IPR_SIRR:
// only write software interrupt mask
ipr[idx] = val & 0x7fff0;
break;
- case ISA::IPR_ICSR:
+ case TheISA::IPR_ICSR:
ipr[idx] = val & ULL(0xffffff0300);
break;
- case ISA::IPR_IVPTBR:
- case ISA::IPR_MVPTBR:
+ case TheISA::IPR_IVPTBR:
+ case TheISA::IPR_MVPTBR:
ipr[idx] = val & ULL(0xffffffffc0000000);
break;
- case ISA::IPR_DC_TEST_CTL:
+ case TheISA::IPR_DC_TEST_CTL:
ipr[idx] = val & 0x1ffb;
break;
- case ISA::IPR_DC_MODE:
- case ISA::IPR_MAF_MODE:
+ case TheISA::IPR_DC_MODE:
+ case TheISA::IPR_MAF_MODE:
ipr[idx] = val & 0x3f;
break;
- case ISA::IPR_ITB_ASN:
+ case TheISA::IPR_ITB_ASN:
ipr[idx] = val & 0x7f0;
break;
- case ISA::IPR_DTB_ASN:
+ case TheISA::IPR_DTB_ASN:
ipr[idx] = val & ULL(0xfe00000000000000);
break;
- case ISA::IPR_EXC_SUM:
- case ISA::IPR_EXC_MASK:
+ case TheISA::IPR_EXC_SUM:
+ case TheISA::IPR_EXC_MASK:
// any write to this register clears it
ipr[idx] = 0;
break;
- case ISA::IPR_INTID:
- case ISA::IPR_SL_RCV:
- case ISA::IPR_MM_STAT:
- case ISA::IPR_ITB_PTE_TEMP:
- case ISA::IPR_DTB_PTE_TEMP:
+ case TheISA::IPR_INTID:
+ case TheISA::IPR_SL_RCV:
+ case TheISA::IPR_MM_STAT:
+ case TheISA::IPR_ITB_PTE_TEMP:
+ case TheISA::IPR_DTB_PTE_TEMP:
// read-only registers
return UnimplementedOpcodeFault;
- case ISA::IPR_HWINT_CLR:
- case ISA::IPR_SL_XMIT:
- case ISA::IPR_DC_FLUSH:
- case ISA::IPR_IC_FLUSH:
+ case TheISA::IPR_HWINT_CLR:
+ case TheISA::IPR_SL_XMIT:
+ case TheISA::IPR_DC_FLUSH:
+ case TheISA::IPR_IC_FLUSH:
// the following are write only
ipr[idx] = val;
break;
- case ISA::IPR_DTB_IA:
+ case TheISA::IPR_DTB_IA:
// really a control write
ipr[idx] = 0;
cpu->dtb->flushAll();
break;
- case ISA::IPR_DTB_IAP:
+ case TheISA::IPR_DTB_IAP:
// really a control write
ipr[idx] = 0;
cpu->dtb->flushProcesses();
break;
- case ISA::IPR_DTB_IS:
+ case TheISA::IPR_DTB_IS:
// really a control write
ipr[idx] = val;
- cpu->dtb->flushAddr(val, DTB_ASN_ASN(ipr[ISA::IPR_DTB_ASN]));
+ cpu->dtb->flushAddr(val, DTB_ASN_ASN(ipr[TheISA::IPR_DTB_ASN]));
break;
- case ISA::IPR_DTB_TAG: {
- struct ISA::PTE pte;
+ case TheISA::IPR_DTB_TAG: {
+ struct TheISA::PTE pte;
// FIXME: granularity hints NYI...
- if (DTB_PTE_GH(ipr[ISA::IPR_DTB_PTE]) != 0)
+ if (DTB_PTE_GH(ipr[TheISA::IPR_DTB_PTE]) != 0)
panic("PTE GH field != 0");
// write entire quad
ipr[idx] = val;
// construct PTE for new entry
- pte.ppn = DTB_PTE_PPN(ipr[ISA::IPR_DTB_PTE]);
- pte.xre = DTB_PTE_XRE(ipr[ISA::IPR_DTB_PTE]);
- pte.xwe = DTB_PTE_XWE(ipr[ISA::IPR_DTB_PTE]);
- pte.fonr = DTB_PTE_FONR(ipr[ISA::IPR_DTB_PTE]);
- pte.fonw = DTB_PTE_FONW(ipr[ISA::IPR_DTB_PTE]);
- pte.asma = DTB_PTE_ASMA(ipr[ISA::IPR_DTB_PTE]);
- pte.asn = DTB_ASN_ASN(ipr[ISA::IPR_DTB_ASN]);
+ pte.ppn = DTB_PTE_PPN(ipr[TheISA::IPR_DTB_PTE]);
+ pte.xre = DTB_PTE_XRE(ipr[TheISA::IPR_DTB_PTE]);
+ pte.xwe = DTB_PTE_XWE(ipr[TheISA::IPR_DTB_PTE]);
+ pte.fonr = DTB_PTE_FONR(ipr[TheISA::IPR_DTB_PTE]);
+ pte.fonw = DTB_PTE_FONW(ipr[TheISA::IPR_DTB_PTE]);
+ pte.asma = DTB_PTE_ASMA(ipr[TheISA::IPR_DTB_PTE]);
+ pte.asn = DTB_ASN_ASN(ipr[TheISA::IPR_DTB_ASN]);
// insert new TAG/PTE value into data TLB
cpu->dtb->insert(val, pte);
}
break;
- case ISA::IPR_ITB_PTE: {
- struct ISA::PTE pte;
+ case TheISA::IPR_ITB_PTE: {
+ struct TheISA::PTE pte;
// FIXME: granularity hints NYI...
if (ITB_PTE_GH(val) != 0)
@@ -594,32 +597,32 @@ PhysRegFile<Impl>::setIpr(int idx, uint64_t val)
pte.fonr = ITB_PTE_FONR(val);
pte.fonw = ITB_PTE_FONW(val);
pte.asma = ITB_PTE_ASMA(val);
- pte.asn = ITB_ASN_ASN(ipr[ISA::IPR_ITB_ASN]);
+ pte.asn = ITB_ASN_ASN(ipr[TheISA::IPR_ITB_ASN]);
// insert new TAG/PTE value into data TLB
- cpu->itb->insert(ipr[ISA::IPR_ITB_TAG], pte);
+ cpu->itb->insert(ipr[TheISA::IPR_ITB_TAG], pte);
}
break;
- case ISA::IPR_ITB_IA:
+ case TheISA::IPR_ITB_IA:
// really a control write
ipr[idx] = 0;
cpu->itb->flushAll();
break;
- case ISA::IPR_ITB_IAP:
+ case TheISA::IPR_ITB_IAP:
// really a control write
ipr[idx] = 0;
cpu->itb->flushProcesses();
break;
- case ISA::IPR_ITB_IS:
+ case TheISA::IPR_ITB_IS:
// really a control write
ipr[idx] = val;
- cpu->itb->flushAddr(val, ITB_ASN_ASN(ipr[ISA::IPR_ITB_ASN]));
+ cpu->itb->flushAddr(val, ITB_ASN_ASN(ipr[TheISA::IPR_ITB_ASN]));
break;
default:
diff --git a/cpu/o3/rename.hh b/cpu/o3/rename.hh
index a17ec7311..07b442964 100644
--- a/cpu/o3/rename.hh
+++ b/cpu/o3/rename.hh
@@ -46,7 +46,6 @@ class SimpleRename
{
public:
// Typedefs from the Impl.
- typedef typename Impl::ISA ISA;
typedef typename Impl::CPUPol CPUPol;
typedef typename Impl::DynInstPtr DynInstPtr;
typedef typename Impl::FullCPU FullCPU;
@@ -62,7 +61,7 @@ class SimpleRename
typedef typename CPUPol::RenameMap RenameMap;
// Typedefs from the ISA.
- typedef typename ISA::Addr Addr;
+ typedef TheISA::RegIndex RegIndex;
public:
// Rename will block if ROB becomes full or issue queue becomes full,
diff --git a/cpu/o3/rename_map.hh b/cpu/o3/rename_map.hh
index c44c7a1ea..57be4a64a 100644
--- a/cpu/o3/rename_map.hh
+++ b/cpu/o3/rename_map.hh
@@ -38,9 +38,13 @@
#include <vector>
#include "cpu/o3/free_list.hh"
+//For RegIndex
+#include "arch/isa_traits.hh"
class SimpleRenameMap
{
+ protected:
+ typedef TheISA::RegIndex RegIndex;
public:
/**
* Pair of a logical register and a physical register. Tells the
diff --git a/cpu/o3/rob.hh b/cpu/o3/rob.hh
index 29ec48007..1185564ad 100644
--- a/cpu/o3/rob.hh
+++ b/cpu/o3/rob.hh
@@ -47,6 +47,8 @@
template <class Impl>
class ROB
{
+ protected:
+ typedef TheISA::RegIndex RegIndex;
public:
//Typedefs from the Impl.
typedef typename Impl::FullCPU FullCPU;
diff --git a/cpu/o3/store_set.hh b/cpu/o3/store_set.hh
index bcd590384..5a885d838 100644
--- a/cpu/o3/store_set.hh
+++ b/cpu/o3/store_set.hh
@@ -31,7 +31,7 @@
#include <vector>
-#include "arch/alpha/isa_traits.hh"
+#include "arch/isa_traits.hh"
#include "cpu/inst_seq.hh"
class StoreSet
diff --git a/cpu/o3/tournament_pred.hh b/cpu/o3/tournament_pred.hh
index 58ea1a7d9..cb93c2f67 100644
--- a/cpu/o3/tournament_pred.hh
+++ b/cpu/o3/tournament_pred.hh
@@ -30,7 +30,7 @@
#define __CPU_O3_CPU_TOURNAMENT_PRED_HH__
// For Addr type.
-#include "arch/alpha/isa_traits.hh"
+#include "arch/isa_traits.hh"
#include "cpu/o3/sat_counter.hh"
class TournamentBP
diff --git a/cpu/ozone/cpu.hh b/cpu/ozone/cpu.hh
index 21fe05b6a..667e2b3f8 100644
--- a/cpu/ozone/cpu.hh
+++ b/cpu/ozone/cpu.hh
@@ -77,7 +77,6 @@ class OoOCPU : public BaseCPU
private:
typedef typename Impl::DynInst DynInst;
typedef typename Impl::DynInstPtr DynInstPtr;
- typedef typename Impl::ISA ISA;
public:
// main simulation loop (one cycle)
@@ -286,17 +285,17 @@ class OoOCPU : public BaseCPU
int getInstAsid() { return xc->regs.instAsid(); }
int getDataAsid() { return xc->regs.dataAsid(); }
- Fault * translateInstReq(MemReqPtr &req)
+ Fault translateInstReq(MemReqPtr &req)
{
return itb->translate(req);
}
- Fault * translateDataReadReq(MemReqPtr &req)
+ Fault translateDataReadReq(MemReqPtr &req)
{
return dtb->translate(req, false);
}
- Fault * translateDataWriteReq(MemReqPtr &req)
+ Fault translateDataWriteReq(MemReqPtr &req)
{
return dtb->translate(req, true);
}
@@ -311,7 +310,7 @@ class OoOCPU : public BaseCPU
int getInstAsid() { return xc->asid; }
int getDataAsid() { return xc->asid; }
- Fault * dummyTranslation(MemReqPtr &req)
+ Fault dummyTranslation(MemReqPtr &req)
{
#if 0
assert((req->vaddr >> 48 & 0xffff) == 0);
@@ -322,15 +321,15 @@ class OoOCPU : public BaseCPU
req->paddr = req->paddr | (Addr)req->asid << sizeof(Addr) * 8 - 16;
return NoFault;
}
- Fault * translateInstReq(MemReqPtr &req)
+ Fault translateInstReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
- Fault * translateDataReadReq(MemReqPtr &req)
+ Fault translateDataReadReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
- Fault * translateDataWriteReq(MemReqPtr &req)
+ Fault translateDataWriteReq(MemReqPtr &req)
{
return dummyTranslation(req);
}
@@ -338,10 +337,10 @@ class OoOCPU : public BaseCPU
#endif
template <class T>
- Fault * read(Addr addr, T &data, unsigned flags, DynInstPtr inst);
+ Fault read(Addr addr, T &data, unsigned flags, DynInstPtr inst);
template <class T>
- Fault * write(T data, Addr addr, unsigned flags,
+ Fault write(T data, Addr addr, unsigned flags,
uint64_t *res, DynInstPtr inst);
void prefetch(Addr addr, unsigned flags)
@@ -354,9 +353,9 @@ class OoOCPU : public BaseCPU
// need to do this...
}
- Fault * copySrcTranslate(Addr src);
+ Fault copySrcTranslate(Addr src);
- Fault * copy(Addr dest);
+ Fault copy(Addr dest);
private:
bool executeInst(DynInstPtr &inst);
@@ -369,7 +368,7 @@ class OoOCPU : public BaseCPU
bool getOneInst();
- Fault * fetchCacheLine();
+ Fault fetchCacheLine();
InstSeqNum getAndIncrementInstSeq();
@@ -378,12 +377,12 @@ class OoOCPU : public BaseCPU
private:
InstSeqNum globalSeqNum;
- DynInstPtr renameTable[ISA::TotalNumRegs];
- DynInstPtr commitTable[ISA::TotalNumRegs];
+ DynInstPtr renameTable[TheISA::TotalNumRegs];
+ DynInstPtr commitTable[TheISA::TotalNumRegs];
// Might need a table of the shadow registers as well.
#if FULL_SYSTEM
- DynInstPtr palShadowTable[ISA::NumIntRegs];
+ DynInstPtr palShadowTable[TheISA::NumIntRegs];
#endif
public:
@@ -402,47 +401,47 @@ class OoOCPU : public BaseCPU
// rename table of DynInsts. Also these likely shouldn't be called very
// often, other than when adding things into the xc during say a syscall.
- uint64_t readIntReg(StaticInst<TheISA> *si, int idx)
+ uint64_t readIntReg(StaticInst *si, int idx)
{
return xc->readIntReg(si->srcRegIdx(idx));
}
- float readFloatRegSingle(StaticInst<TheISA> *si, int idx)
+ float readFloatRegSingle(StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return xc->readFloatRegSingle(reg_idx);
}
- double readFloatRegDouble(StaticInst<TheISA> *si, int idx)
+ double readFloatRegDouble(StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return xc->readFloatRegDouble(reg_idx);
}
- uint64_t readFloatRegInt(StaticInst<TheISA> *si, int idx)
+ uint64_t readFloatRegInt(StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return xc->readFloatRegInt(reg_idx);
}
- void setIntReg(StaticInst<TheISA> *si, int idx, uint64_t val)
+ void setIntReg(StaticInst *si, int idx, uint64_t val)
{
xc->setIntReg(si->destRegIdx(idx), val);
}
- void setFloatRegSingle(StaticInst<TheISA> *si, int idx, float val)
+ void setFloatRegSingle(StaticInst *si, int idx, float val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
xc->setFloatRegSingle(reg_idx, val);
}
- void setFloatRegDouble(StaticInst<TheISA> *si, int idx, double val)
+ void setFloatRegDouble(StaticInst *si, int idx, double val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
xc->setFloatRegDouble(reg_idx, val);
}
- void setFloatRegInt(StaticInst<TheISA> *si, int idx, uint64_t val)
+ void setFloatRegInt(StaticInst *si, int idx, uint64_t val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
xc->setFloatRegInt(reg_idx, val);
@@ -479,7 +478,7 @@ class OoOCPU : public BaseCPU
// We fold in the PISA 64- to 32-bit conversion here as well.
Addr icacheBlockAlignPC(Addr addr)
{
- addr = ISA::realPCToFetchPC(addr);
+ addr = TheISA::realPCToFetchPC(addr);
return (addr & ~(cacheBlkMask));
}
@@ -512,13 +511,13 @@ class OoOCPU : public BaseCPU
void setFpcr(uint64_t val) { xc->setFpcr(val); }
#if FULL_SYSTEM
- uint64_t readIpr(int idx, Fault * &fault) { return xc->readIpr(idx, fault); }
- Fault * setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); }
- Fault * hwrei() { return xc->hwrei(); }
+ uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); }
+ Fault setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); }
+ Fault hwrei() { return xc->hwrei(); }
int readIntrFlag() { return xc->readIntrFlag(); }
void setIntrFlag(int val) { xc->setIntrFlag(val); }
bool inPalMode() { return xc->inPalMode(); }
- void ev5_trap(Fault * fault) { xc->ev5_trap(fault); }
+ void ev5_trap(Fault fault) { xc->ev5_trap(fault); }
bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); }
#else
void syscall() { xc->syscall(); }
@@ -531,7 +530,7 @@ class OoOCPU : public BaseCPU
// precise architected memory state accessor macros
template <class Impl>
template <class T>
-Fault *
+Fault
OoOCPU<Impl>::read(Addr addr, T &data, unsigned flags, DynInstPtr inst)
{
MemReqPtr readReq = new MemReq();
@@ -542,7 +541,7 @@ OoOCPU<Impl>::read(Addr addr, T &data, unsigned flags, DynInstPtr inst)
readReq->reset(addr, sizeof(T), flags);
// translate to physical address - This might be an ISA impl call
- Fault * fault = translateDataReadReq(readReq);
+ Fault fault = translateDataReadReq(readReq);
// do functional access
if (fault == NoFault)
@@ -576,7 +575,7 @@ OoOCPU<Impl>::read(Addr addr, T &data, unsigned flags, DynInstPtr inst)
template <class Impl>
template <class T>
-Fault *
+Fault
OoOCPU<Impl>::write(T data, Addr addr, unsigned flags,
uint64_t *res, DynInstPtr inst)
{
@@ -595,7 +594,7 @@ OoOCPU<Impl>::write(T data, Addr addr, unsigned flags,
writeReq->reset(addr, sizeof(T), flags);
// translate to physical address
- Fault * fault = translateDataWriteReq(writeReq);
+ Fault fault = translateDataWriteReq(writeReq);
// do functional access
if (fault == NoFault)
diff --git a/cpu/profile.hh b/cpu/profile.hh
index 58cd7e79f..18061f9bf 100644
--- a/cpu/profile.hh
+++ b/cpu/profile.hh
@@ -68,7 +68,7 @@ class FunctionProfile
FunctionProfile(const SymbolTable *symtab);
~FunctionProfile();
- ProfileNode *consume(ExecContext *xc, StaticInstPtr<TheISA> inst);
+ ProfileNode *consume(ExecContext *xc, StaticInstPtr inst);
ProfileNode *consume(const std::vector<Addr> &stack);
void clear();
void dump(ExecContext *xc, std::ostream &out) const;
@@ -76,7 +76,7 @@ class FunctionProfile
};
inline ProfileNode *
-FunctionProfile::consume(ExecContext *xc, StaticInstPtr<TheISA> inst)
+FunctionProfile::consume(ExecContext *xc, StaticInstPtr inst)
{
if (!trace.trace(xc, inst))
return NULL;
diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc
index 6aff94abd..944bdbb0a 100644
--- a/cpu/simple/cpu.cc
+++ b/cpu/simple/cpu.cc
@@ -76,7 +76,7 @@
using namespace std;
//The SimpleCPU does alpha only
-using namespace LittleEndianGuest;
+using namespace AlphaISA;
SimpleCPU::TickEvent::TickEvent(SimpleCPU *c, int w)
@@ -84,6 +84,21 @@ SimpleCPU::TickEvent::TickEvent(SimpleCPU *c, int w)
{
}
+
+void
+SimpleCPU::init()
+{
+ BaseCPU::init();
+#if FULL_SYSTEM
+ for (int i = 0; i < execContexts.size(); ++i) {
+ ExecContext *xc = execContexts[i];
+
+ // initialize CPU, including PC
+ TheISA::initCPU(&xc->regs, xc->cpu_id);
+ }
+#endif
+}
+
void
SimpleCPU::TickEvent::process()
{
@@ -124,8 +139,6 @@ SimpleCPU::SimpleCPU(Params *p)
#if FULL_SYSTEM
xc = new ExecContext(this, 0, p->system, p->itb, p->dtb, p->mem);
- // initialize CPU, including PC
- TheISA::initCPU(&xc->regs);
#else
xc = new ExecContext(this, /* thread_num */ 0, p->process, /* asid */ 0);
#endif // !FULL_SYSTEM
@@ -312,7 +325,7 @@ change_thread_state(int thread_number, int activate, int priority)
{
}
-Fault *
+Fault
SimpleCPU::copySrcTranslate(Addr src)
{
static bool no_warn = true;
@@ -323,7 +336,7 @@ SimpleCPU::copySrcTranslate(Addr src)
// Make sure block doesn't span page
if (no_warn &&
- (src & TheISA::PageMask) != ((src + blk_size) & TheISA::PageMask) &&
+ (src & PageMask) != ((src + blk_size) & PageMask) &&
(src >> 40) != 0xfffffc) {
warn("Copied block source spans pages %x.", src);
no_warn = false;
@@ -332,7 +345,7 @@ SimpleCPU::copySrcTranslate(Addr src)
memReq->reset(src & ~(blk_size - 1), blk_size);
// translate to physical address
- Fault * fault = xc->translateDataReadReq(memReq);
+ Fault fault = xc->translateDataReadReq(memReq);
assert(fault != AlignmentFault);
@@ -346,7 +359,7 @@ SimpleCPU::copySrcTranslate(Addr src)
return fault;
}
-Fault *
+Fault
SimpleCPU::copy(Addr dest)
{
static bool no_warn = true;
@@ -359,7 +372,7 @@ SimpleCPU::copy(Addr dest)
// Make sure block doesn't span page
if (no_warn &&
- (dest & TheISA::PageMask) != ((dest + blk_size) & TheISA::PageMask) &&
+ (dest & PageMask) != ((dest + blk_size) & PageMask) &&
(dest >> 40) != 0xfffffc) {
no_warn = false;
warn("Copied block destination spans pages %x. ", dest);
@@ -367,7 +380,7 @@ SimpleCPU::copy(Addr dest)
memReq->reset(dest & ~(blk_size -1), blk_size);
// translate to physical address
- Fault * fault = xc->translateDataWriteReq(memReq);
+ Fault fault = xc->translateDataWriteReq(memReq);
assert(fault != AlignmentFault);
@@ -394,11 +407,11 @@ SimpleCPU::copy(Addr dest)
// precise architected memory state accessor macros
template <class T>
-Fault *
+Fault
SimpleCPU::read(Addr addr, T &data, unsigned flags)
{
if (status() == DcacheMissStall || status() == DcacheMissSwitch) {
- Fault * fault = xc->read(memReq,data);
+ Fault fault = xc->read(memReq,data);
if (traceData) {
traceData->setAddr(addr);
@@ -409,7 +422,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
memReq->reset(addr, sizeof(T), flags);
// translate to physical address
- Fault * fault = xc->translateDataReadReq(memReq);
+ Fault fault = xc->translateDataReadReq(memReq);
// if we have a cache, do cache access too
if (fault == NoFault && dcacheInterface) {
@@ -447,32 +460,32 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags)
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template
-Fault *
+Fault
SimpleCPU::read(Addr addr, uint64_t &data, unsigned flags);
template
-Fault *
+Fault
SimpleCPU::read(Addr addr, uint32_t &data, unsigned flags);
template
-Fault *
+Fault
SimpleCPU::read(Addr addr, uint16_t &data, unsigned flags);
template
-Fault *
+Fault
SimpleCPU::read(Addr addr, uint8_t &data, unsigned flags);
#endif //DOXYGEN_SHOULD_SKIP_THIS
template<>
-Fault *
+Fault
SimpleCPU::read(Addr addr, double &data, unsigned flags)
{
return read(addr, *(uint64_t*)&data, flags);
}
template<>
-Fault *
+Fault
SimpleCPU::read(Addr addr, float &data, unsigned flags)
{
return read(addr, *(uint32_t*)&data, flags);
@@ -480,7 +493,7 @@ SimpleCPU::read(Addr addr, float &data, unsigned flags)
template<>
-Fault *
+Fault
SimpleCPU::read(Addr addr, int32_t &data, unsigned flags)
{
return read(addr, (uint32_t&)data, flags);
@@ -488,13 +501,13 @@ SimpleCPU::read(Addr addr, int32_t &data, unsigned flags)
template <class T>
-Fault *
+Fault
SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
{
memReq->reset(addr, sizeof(T), flags);
// translate to physical address
- Fault * fault = xc->translateDataWriteReq(memReq);
+ Fault fault = xc->translateDataWriteReq(memReq);
// do functional access
if (fault == NoFault)
@@ -531,32 +544,32 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res)
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template
-Fault *
+Fault
SimpleCPU::write(uint64_t data, Addr addr, unsigned flags, uint64_t *res);
template
-Fault *
+Fault
SimpleCPU::write(uint32_t data, Addr addr, unsigned flags, uint64_t *res);
template
-Fault *
+Fault
SimpleCPU::write(uint16_t data, Addr addr, unsigned flags, uint64_t *res);
template
-Fault *
+Fault
SimpleCPU::write(uint8_t data, Addr addr, unsigned flags, uint64_t *res);
#endif //DOXYGEN_SHOULD_SKIP_THIS
template<>
-Fault *
+Fault
SimpleCPU::write(double data, Addr addr, unsigned flags, uint64_t *res)
{
return write(*(uint64_t*)&data, addr, flags, res);
}
template<>
-Fault *
+Fault
SimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res)
{
return write(*(uint32_t*)&data, addr, flags, res);
@@ -564,7 +577,7 @@ SimpleCPU::write(float data, Addr addr, unsigned flags, uint64_t *res)
template<>
-Fault *
+Fault
SimpleCPU::write(int32_t data, Addr addr, unsigned flags, uint64_t *res)
{
return write((uint32_t)data, addr, flags, res);
@@ -638,7 +651,7 @@ SimpleCPU::tick()
traceData = NULL;
- Fault * fault = NoFault;
+ Fault fault = NoFault;
#if FULL_SYSTEM
if (checkInterrupts && check_interrupts() && !xc->inPalMode() &&
@@ -648,20 +661,20 @@ SimpleCPU::tick()
checkInterrupts = false;
IntReg *ipr = xc->regs.ipr;
- if (xc->regs.ipr[TheISA::IPR_SIRR]) {
- for (int i = TheISA::INTLEVEL_SOFTWARE_MIN;
- i < TheISA::INTLEVEL_SOFTWARE_MAX; i++) {
- if (ipr[TheISA::IPR_SIRR] & (ULL(1) << i)) {
+ if (xc->regs.ipr[IPR_SIRR]) {
+ for (int i = INTLEVEL_SOFTWARE_MIN;
+ i < INTLEVEL_SOFTWARE_MAX; i++) {
+ if (ipr[IPR_SIRR] & (ULL(1) << i)) {
// See table 4-19 of 21164 hardware reference
- ipl = (i - TheISA::INTLEVEL_SOFTWARE_MIN) + 1;
+ ipl = (i - INTLEVEL_SOFTWARE_MIN) + 1;
summary |= (ULL(1) << i);
}
}
}
uint64_t interrupts = xc->cpu->intr_status();
- for (int i = TheISA::INTLEVEL_EXTERNAL_MIN;
- i < TheISA::INTLEVEL_EXTERNAL_MAX; i++) {
+ for (int i = INTLEVEL_EXTERNAL_MIN;
+ i < INTLEVEL_EXTERNAL_MAX; i++) {
if (interrupts & (ULL(1) << i)) {
// See table 4-19 of 21164 hardware reference
ipl = i;
@@ -669,16 +682,16 @@ SimpleCPU::tick()
}
}
- if (ipr[TheISA::IPR_ASTRR])
+ if (ipr[IPR_ASTRR])
panic("asynchronous traps not implemented\n");
- if (ipl && ipl > xc->regs.ipr[TheISA::IPR_IPLR]) {
- ipr[TheISA::IPR_ISR] = summary;
- ipr[TheISA::IPR_INTID] = ipl;
+ if (ipl && ipl > xc->regs.ipr[IPR_IPLR]) {
+ ipr[IPR_ISR] = summary;
+ ipr[IPR_INTID] = ipl;
xc->ev5_trap(InterruptFault);
DPRINTF(Flow, "Interrupt! IPLR=%d ipl=%d summary=%x\n",
- ipr[TheISA::IPR_IPLR], ipl, summary);
+ ipr[IPR_IPLR], ipl, summary);
}
}
#endif
@@ -749,7 +762,7 @@ SimpleCPU::tick()
// decode the instruction
inst = gtoh(inst);
- curStaticInst = StaticInst<TheISA>::decode(inst);
+ curStaticInst = StaticInst::decode(inst);
traceData = Trace::getInstRecord(curTick, xc, this, curStaticInst,
xc->regs.pc);
diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh
index e7a447117..ed7b1e29b 100644
--- a/cpu/simple/cpu.hh
+++ b/cpu/simple/cpu.hh
@@ -63,9 +63,12 @@ namespace Trace {
class SimpleCPU : public BaseCPU
{
+ protected:
+ typedef TheISA::MachInst MachInst;
public:
// main simulation loop (one cycle)
void tick();
+ virtual void init();
private:
struct TickEvent : public Event
@@ -172,7 +175,7 @@ class SimpleCPU : public BaseCPU
// the next switchover
Sampler *sampler;
- StaticInstPtr<TheISA> curStaticInst;
+ StaticInstPtr curStaticInst;
class CacheCompletionEvent : public Event
{
@@ -234,10 +237,10 @@ class SimpleCPU : public BaseCPU
virtual void unserialize(Checkpoint *cp, const std::string &section);
template <class T>
- Fault * read(Addr addr, T &data, unsigned flags);
+ Fault read(Addr addr, T &data, unsigned flags);
template <class T>
- Fault * write(T data, Addr addr, unsigned flags, uint64_t *res);
+ Fault write(T data, Addr addr, unsigned flags, uint64_t *res);
// These functions are only used in CPU models that split
// effective address computation from the actual memory access.
@@ -254,9 +257,9 @@ class SimpleCPU : public BaseCPU
// need to do this...
}
- Fault * copySrcTranslate(Addr src);
+ Fault copySrcTranslate(Addr src);
- Fault * copy(Addr dest);
+ Fault copy(Addr dest);
// The register accessor methods provide the index of the
// instruction's operand (e.g., 0 or 1), not the architectural
@@ -269,47 +272,47 @@ class SimpleCPU : public BaseCPU
// storage (which is pretty hard to imagine they would have reason
// to do).
- uint64_t readIntReg(const StaticInst<TheISA> *si, int idx)
+ uint64_t readIntReg(const StaticInst *si, int idx)
{
return xc->readIntReg(si->srcRegIdx(idx));
}
- float readFloatRegSingle(const StaticInst<TheISA> *si, int idx)
+ float readFloatRegSingle(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return xc->readFloatRegSingle(reg_idx);
}
- double readFloatRegDouble(const StaticInst<TheISA> *si, int idx)
+ double readFloatRegDouble(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return xc->readFloatRegDouble(reg_idx);
}
- uint64_t readFloatRegInt(const StaticInst<TheISA> *si, int idx)
+ uint64_t readFloatRegInt(const StaticInst *si, int idx)
{
int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag;
return xc->readFloatRegInt(reg_idx);
}
- void setIntReg(const StaticInst<TheISA> *si, int idx, uint64_t val)
+ void setIntReg(const StaticInst *si, int idx, uint64_t val)
{
xc->setIntReg(si->destRegIdx(idx), val);
}
- void setFloatRegSingle(const StaticInst<TheISA> *si, int idx, float val)
+ void setFloatRegSingle(const StaticInst *si, int idx, float val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
xc->setFloatRegSingle(reg_idx, val);
}
- void setFloatRegDouble(const StaticInst<TheISA> *si, int idx, double val)
+ void setFloatRegDouble(const StaticInst *si, int idx, double val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
xc->setFloatRegDouble(reg_idx, val);
}
- void setFloatRegInt(const StaticInst<TheISA> *si, int idx, uint64_t val)
+ void setFloatRegInt(const StaticInst *si, int idx, uint64_t val)
{
int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag;
xc->setFloatRegInt(reg_idx, val);
@@ -325,13 +328,13 @@ class SimpleCPU : public BaseCPU
void setFpcr(uint64_t val) { xc->setFpcr(val); }
#if FULL_SYSTEM
- uint64_t readIpr(int idx, Fault * &fault) { return xc->readIpr(idx, fault); }
- Fault * setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); }
- Fault * hwrei() { return xc->hwrei(); }
+ uint64_t readIpr(int idx, Fault &fault) { return xc->readIpr(idx, fault); }
+ Fault setIpr(int idx, uint64_t val) { return xc->setIpr(idx, val); }
+ Fault hwrei() { return xc->hwrei(); }
int readIntrFlag() { return xc->readIntrFlag(); }
void setIntrFlag(int val) { xc->setIntrFlag(val); }
bool inPalMode() { return xc->inPalMode(); }
- void ev5_trap(Fault * fault) { xc->ev5_trap(fault); }
+ void ev5_trap(Fault fault) { xc->ev5_trap(fault); }
bool simPalCheck(int palFunc) { return xc->simPalCheck(palFunc); }
#else
void syscall() { xc->syscall(); }
diff --git a/cpu/static_inst.cc b/cpu/static_inst.cc
index 54bd9914e..c307dc6fc 100644
--- a/cpu/static_inst.cc
+++ b/cpu/static_inst.cc
@@ -30,19 +30,13 @@
#include "cpu/static_inst.hh"
#include "sim/root.hh"
-template <class ISA>
-StaticInstPtr<ISA> StaticInst<ISA>::nullStaticInstPtr;
-
-template <class ISA>
-typename StaticInst<ISA>::DecodeCache StaticInst<ISA>::decodeCache;
+StaticInstPtr StaticInst::nullStaticInstPtr;
// Define the decode cache hash map.
-template StaticInst<AlphaISA>::DecodeCache
-StaticInst<AlphaISA>::decodeCache;
+StaticInst::DecodeCache StaticInst::decodeCache;
-template <class ISA>
void
-StaticInst<ISA>::dumpDecodeCacheStats()
+StaticInst::dumpDecodeCacheStats()
{
using namespace std;
@@ -62,13 +56,8 @@ StaticInst<ISA>::dumpDecodeCacheStats()
}
}
-
-template StaticInstPtr<AlphaISA>
-StaticInst<AlphaISA>::nullStaticInstPtr;
-
-template <class ISA>
bool
-StaticInst<ISA>::hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt) const
+StaticInst::hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt) const
{
if (isDirectCtrl()) {
tgt = branchTarget(pc);
@@ -83,6 +72,3 @@ StaticInst<ISA>::hasBranchTarget(Addr pc, ExecContext *xc, Addr &tgt) const
return false;
}
-
-// force instantiation of template function(s) above
-template class StaticInst<AlphaISA>;
diff --git a/cpu/static_inst.hh b/cpu/static_inst.hh
index 24997eadc..a0287a2de 100644
--- a/cpu/static_inst.hh
+++ b/cpu/static_inst.hh
@@ -113,6 +113,8 @@ class StaticInstBase : public RefCounted
IsSerializing, ///< Serializes pipeline: won't execute until all
/// older instructions have committed.
+ IsSerializeBefore,
+ IsSerializeAfter,
IsMemBarrier, ///< Is a memory barrier
IsWriteBarrier, ///< Is a write barrier
@@ -196,7 +198,11 @@ class StaticInstBase : public RefCounted
bool isUncondCtrl() const { return flags[IsUncondControl]; }
bool isThreadSync() const { return flags[IsThreadSync]; }
- bool isSerializing() const { return flags[IsSerializing]; }
+ bool isSerializing() const { return flags[IsSerializing] ||
+ flags[IsSerializeBefore] ||
+ flags[IsSerializeAfter]; }
+ bool isSerializeBefore() const { return flags[IsSerializeBefore]; }
+ bool isSerializeAfter() const { return flags[IsSerializeAfter]; }
bool isMemBarrier() const { return flags[IsMemBarrier]; }
bool isWriteBarrier() const { return flags[IsWriteBarrier]; }
bool isNonSpeculative() const { return flags[IsNonSpeculative]; }
@@ -208,7 +214,6 @@ class StaticInstBase : public RefCounted
// forward declaration
-template <class ISA>
class StaticInstPtr;
/**
@@ -218,21 +223,18 @@ class StaticInstPtr;
* that are generic across all ISAs but that differ in details
* according to the specific ISA being used.
*/
-template <class ISA>
class StaticInst : public StaticInstBase
{
public:
/// Binary machine instruction type.
- typedef typename ISA::MachInst MachInst;
- /// Memory address type.
- typedef typename ISA::Addr Addr;
+ typedef TheISA::MachInst MachInst;
/// Logical register index type.
- typedef typename ISA::RegIndex RegIndex;
+ typedef TheISA::RegIndex RegIndex;
enum {
- MaxInstSrcRegs = ISA::MaxInstSrcRegs, //< Max source regs
- MaxInstDestRegs = ISA::MaxInstDestRegs, //< Max dest regs
+ MaxInstSrcRegs = TheISA::MaxInstSrcRegs, //< Max source regs
+ MaxInstDestRegs = TheISA::MaxInstDestRegs, //< Max dest regs
};
@@ -247,7 +249,7 @@ class StaticInst : public StaticInstBase
/// Pointer to a statically allocated "null" instruction object.
/// Used to give eaCompInst() and memAccInst() something to return
/// when called on non-memory instructions.
- static StaticInstPtr<ISA> nullStaticInstPtr;
+ static StaticInstPtr nullStaticInstPtr;
/**
* Memory references only: returns "fake" instruction representing
@@ -256,7 +258,7 @@ class StaticInst : public StaticInstBase
* just the EA computation.
*/
virtual const
- StaticInstPtr<ISA> &eaCompInst() const { return nullStaticInstPtr; }
+ StaticInstPtr &eaCompInst() const { return nullStaticInstPtr; }
/**
* Memory references only: returns "fake" instruction representing
@@ -265,7 +267,7 @@ class StaticInst : public StaticInstBase
* just the memory access (not the EA computation).
*/
virtual const
- StaticInstPtr<ISA> &memAccInst() const { return nullStaticInstPtr; }
+ StaticInstPtr &memAccInst() const { return nullStaticInstPtr; }
/// The binary machine instruction.
const MachInst machInst;
@@ -312,7 +314,11 @@ class StaticInst : public StaticInstBase
delete cachedDisassembly;
}
-#include "static_inst_impl.hh"
+/**
+ * The execute() signatures are auto-generated by scons based on the
+ * set of CPU models we are compiling in today.
+ */
+#include "cpu/static_inst_exec_sigs.hh"
/**
* Return the target address for a PC-relative branch.
@@ -364,7 +370,7 @@ class StaticInst : public StaticInstBase
/// Decoded instruction cache type.
/// For now we're using a generic hash_map; this seems to work
/// pretty well.
- typedef m5::hash_map<MachInst, StaticInstPtr<ISA> > DecodeCache;
+ typedef m5::hash_map<MachInst, StaticInstPtr> DecodeCache;
/// A cache of decoded instruction objects.
static DecodeCache decodeCache;
@@ -378,63 +384,40 @@ class StaticInst : public StaticInstBase
/// Decode a machine instruction.
/// @param mach_inst The binary instruction to decode.
/// @retval A pointer to the corresponding StaticInst object.
- static
- StaticInstPtr<ISA> decode(MachInst mach_inst)
- {
-#ifdef DECODE_CACHE_HASH_STATS
- // Simple stats on decode hash_map. Turns out the default
- // hash function is as good as anything I could come up with.
- const int dump_every_n = 10000000;
- static int decodes_til_dump = dump_every_n;
-
- if (--decodes_til_dump == 0) {
- dumpDecodeCacheStats();
- decodes_til_dump = dump_every_n;
- }
-#endif
-
- typename DecodeCache::iterator iter = decodeCache.find(mach_inst);
- if (iter != decodeCache.end()) {
- return iter->second;
- }
-
- StaticInstPtr<ISA> si = ISA::decodeInst(mach_inst);
- decodeCache[mach_inst] = si;
- return si;
- }
+ //This is defined as inline below.
+ static StaticInstPtr decode(MachInst mach_inst);
};
typedef RefCountingPtr<StaticInstBase> StaticInstBasePtr;
/// Reference-counted pointer to a StaticInst object.
-/// This type should be used instead of "StaticInst<ISA> *" so that
+/// This type should be used instead of "StaticInst *" so that
/// StaticInst objects can be properly reference-counted.
-template <class ISA>
-class StaticInstPtr : public RefCountingPtr<StaticInst<ISA> >
+class StaticInstPtr : public RefCountingPtr<StaticInst>
{
public:
/// Constructor.
StaticInstPtr()
- : RefCountingPtr<StaticInst<ISA> >()
+ : RefCountingPtr<StaticInst>()
{
}
- /// Conversion from "StaticInst<ISA> *".
- StaticInstPtr(StaticInst<ISA> *p)
- : RefCountingPtr<StaticInst<ISA> >(p)
+ /// Conversion from "StaticInst *".
+ StaticInstPtr(StaticInst *p)
+ : RefCountingPtr<StaticInst>(p)
{
}
/// Copy constructor.
StaticInstPtr(const StaticInstPtr &r)
- : RefCountingPtr<StaticInst<ISA> >(r)
+ : RefCountingPtr<StaticInst>(r)
{
}
/// Construct directly from machine instruction.
- /// Calls StaticInst<ISA>::decode().
- StaticInstPtr(typename ISA::MachInst mach_inst)
- : RefCountingPtr<StaticInst<ISA> >(StaticInst<ISA>::decode(mach_inst))
+ /// Calls StaticInst::decode().
+ StaticInstPtr(TheISA::MachInst mach_inst)
+ : RefCountingPtr<StaticInst>(StaticInst::decode(mach_inst))
{
}
@@ -445,4 +428,29 @@ class StaticInstPtr : public RefCountingPtr<StaticInst<ISA> >
}
};
+inline StaticInstPtr
+StaticInst::decode(StaticInst::MachInst mach_inst)
+{
+#ifdef DECODE_CACHE_HASH_STATS
+ // Simple stats on decode hash_map. Turns out the default
+ // hash function is as good as anything I could come up with.
+ const int dump_every_n = 10000000;
+ static int decodes_til_dump = dump_every_n;
+
+ if (--decodes_til_dump == 0) {
+ dumpDecodeCacheStats();
+ decodes_til_dump = dump_every_n;
+ }
+#endif
+
+ DecodeCache::iterator iter = decodeCache.find(mach_inst);
+ if (iter != decodeCache.end()) {
+ return iter->second;
+ }
+
+ StaticInstPtr si = TheISA::decodeInst(mach_inst);
+ decodeCache[mach_inst] = si;
+ return si;
+}
+
#endif // __CPU_STATIC_INST_HH__
diff --git a/cpu/trace/reader/itx_reader.hh b/cpu/trace/reader/itx_reader.hh
index faec73138..a16a08085 100644
--- a/cpu/trace/reader/itx_reader.hh
+++ b/cpu/trace/reader/itx_reader.hh
@@ -46,6 +46,7 @@
*/
class ITXReader : public MemTraceReader
{
+ private:
/** Trace file. */
FILE *trace;
diff --git a/dev/alpha_access.h b/dev/alpha_access.h
index a20a05535..5a1df6f39 100644
--- a/dev/alpha_access.h
+++ b/dev/alpha_access.h
@@ -33,7 +33,7 @@
* System Console Memory Mapped Register Definition
*/
-#define ALPHA_ACCESS_VERSION (1303)
+#define ALPHA_ACCESS_VERSION (1305)
#ifdef CONSOLE
typedef unsigned uint32_t;
@@ -67,9 +67,7 @@ struct AlphaAccess
uint64_t inputChar; // 68: Placeholder for input
// MP boot
- uint64_t bootStrapImpure; // 70:
- uint32_t bootStrapCPU; // 78:
- uint32_t align2; // 7C: Dummy placeholder for alignment
+ uint64_t cpuStack[64]; // 70:
};
#endif // __ALPHA_ACCESS_H__
diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc
index 38fbbdef0..2e8bbd1dd 100644
--- a/dev/alpha_console.cc
+++ b/dev/alpha_console.cc
@@ -53,6 +53,7 @@
#include "sim/system.hh"
using namespace std;
+using namespace AlphaISA;
AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
System *s, BaseCPU *c, Platform *p,
@@ -80,9 +81,7 @@ AlphaConsole::AlphaConsole(const string &name, SimConsole *cons, SimpleDisk *d,
alphaAccess->diskOperation = 0;
alphaAccess->outputChar = 0;
alphaAccess->inputChar = 0;
- alphaAccess->bootStrapImpure = 0;
- alphaAccess->bootStrapCPU = 0;
- alphaAccess->align2 = 0;
+ bzero(alphaAccess->cpuStack, sizeof(alphaAccess->cpuStack));
system->setAlphaAccess(addr);
}
@@ -99,7 +98,7 @@ AlphaConsole::startup()
alphaAccess->intrClockFrequency = platform->intrFrequency();
}
-Fault *
+Fault
AlphaConsole::read(MemReqPtr &req, uint8_t *data)
{
memset(data, 0, req->size);
@@ -122,9 +121,6 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data)
case offsetof(AlphaAccess, numCPUs):
*(uint32_t*)data = alphaAccess->numCPUs;
break;
- case offsetof(AlphaAccess, bootStrapCPU):
- *(uint32_t*)data = alphaAccess->bootStrapCPU;
- break;
case offsetof(AlphaAccess, intrClockFrequency):
*(uint32_t*)data = alphaAccess->intrClockFrequency;
break;
@@ -175,11 +171,14 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data)
case offsetof(AlphaAccess, outputChar):
*(uint64_t*)data = alphaAccess->outputChar;
break;
- case offsetof(AlphaAccess, bootStrapImpure):
- *(uint64_t*)data = alphaAccess->bootStrapImpure;
- break;
default:
- panic("Unknown 64bit access, %#x\n", daddr);
+ int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
+ sizeof(alphaAccess->cpuStack[0]);
+
+ if (cpunum >= 0 && cpunum < 64)
+ *(uint64_t*)data = alphaAccess->cpuStack[cpunum];
+ else
+ panic("Unknown 64bit access, %#x\n", daddr);
}
break;
default:
@@ -189,7 +188,7 @@ AlphaConsole::read(MemReqPtr &req, uint8_t *data)
return NoFault;
}
-Fault *
+Fault
AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
{
uint64_t val;
@@ -239,24 +238,18 @@ AlphaConsole::write(MemReqPtr &req, const uint8_t *data)
console->out((char)(val & 0xff));
break;
- case offsetof(AlphaAccess, bootStrapImpure):
- alphaAccess->bootStrapImpure = val;
- break;
-
- case offsetof(AlphaAccess, bootStrapCPU):
- warn("%d: Trying to launch another CPU!", curTick);
- assert(val > 0 && "Must not access primary cpu");
-
- other_xc = req->xc->system->execContexts[val];
- other_xc->regs.intRegFile[16] = val;
- other_xc->regs.ipr[TheISA::IPR_PALtemp16] = val;
- other_xc->regs.intRegFile[0] = val;
- other_xc->regs.intRegFile[30] = alphaAccess->bootStrapImpure;
other_xc->activate(); //Start the cpu
break;
default:
- return MachineCheckFault;
+ int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) /
+ sizeof(alphaAccess->cpuStack[0]);
+ warn("%d: Trying to launch CPU number %d!", curTick, cpunum);
+ assert(val > 0 && "Must not access primary cpu");
+ if (cpunum >= 0 && cpunum < 64)
+ alphaAccess->cpuStack[cpunum] = val;
+ else
+ panic("Unknown 64bit access, %#x\n", daddr);
}
return NoFault;
@@ -287,8 +280,7 @@ AlphaConsole::Access::serialize(ostream &os)
SERIALIZE_SCALAR(diskOperation);
SERIALIZE_SCALAR(outputChar);
SERIALIZE_SCALAR(inputChar);
- SERIALIZE_SCALAR(bootStrapImpure);
- SERIALIZE_SCALAR(bootStrapCPU);
+ SERIALIZE_ARRAY(cpuStack,64);
}
void
@@ -310,8 +302,7 @@ AlphaConsole::Access::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(diskOperation);
UNSERIALIZE_SCALAR(outputChar);
UNSERIALIZE_SCALAR(inputChar);
- UNSERIALIZE_SCALAR(bootStrapImpure);
- UNSERIALIZE_SCALAR(bootStrapCPU);
+ UNSERIALIZE_ARRAY(cpuStack, 64);
}
void
diff --git a/dev/alpha_console.hh b/dev/alpha_console.hh
index 75f0a3a67..2d1c1e634 100644
--- a/dev/alpha_console.hh
+++ b/dev/alpha_console.hh
@@ -96,7 +96,7 @@ class AlphaConsole : public PioDevice
BaseCPU *cpu;
Addr addr;
- static const Addr size = 0x80; // equal to sizeof(alpha_access);
+ static const Addr size = sizeof(struct AlphaAccess);
public:
/** Standard Constructor */
@@ -110,8 +110,8 @@ class AlphaConsole : public PioDevice
/**
* memory mapped reads and writes
*/
- virtual Fault * read(MemReqPtr &req, uint8_t *data);
- virtual Fault * write(MemReqPtr &req, const uint8_t *data);
+ virtual Fault read(MemReqPtr &req, uint8_t *data);
+ virtual Fault write(MemReqPtr &req, const uint8_t *data);
/**
* standard serialization routines for checkpointing
diff --git a/dev/baddev.cc b/dev/baddev.cc
index b6ca919e4..87d683a5d 100644
--- a/dev/baddev.cc
+++ b/dev/baddev.cc
@@ -46,6 +46,7 @@
#include "sim/system.hh"
using namespace std;
+using namespace TheISA;
BadDevice::BadDevice(const string &name, Addr a, MemoryController *mmu,
HierParams *hier, Bus *pio_bus, const string &devicename)
@@ -61,7 +62,7 @@ BadDevice::BadDevice(const string &name, Addr a, MemoryController *mmu,
}
-Fault *
+Fault
BadDevice::read(MemReqPtr &req, uint8_t *data)
{
@@ -69,7 +70,7 @@ BadDevice::read(MemReqPtr &req, uint8_t *data)
return NoFault;
}
-Fault *
+Fault
BadDevice::write(MemReqPtr &req, const uint8_t *data)
{
panic("Device %s not imlpmented\n", devname);
diff --git a/dev/baddev.hh b/dev/baddev.hh
index b7b67e31a..c2a204c05 100644
--- a/dev/baddev.hh
+++ b/dev/baddev.hh
@@ -71,7 +71,7 @@ class BadDevice : public PioDevice
* @param data A pointer to write the read data to.
* @return The fault condition of the access.
*/
- virtual Fault * read(MemReqPtr &req, uint8_t *data);
+ virtual Fault read(MemReqPtr &req, uint8_t *data);
/**
* On a write event we just panic aand hopefully print a
@@ -80,7 +80,7 @@ class BadDevice : public PioDevice
* @param data The data to write.
* @return The fault condition of the access.
*/
- virtual Fault * write(MemReqPtr &req, const uint8_t *data);
+ virtual Fault write(MemReqPtr &req, const uint8_t *data);
/**
* Return how long this access will take.
diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc
index a5cb0dfd8..56682a224 100644
--- a/dev/ide_ctrl.cc
+++ b/dev/ide_ctrl.cc
@@ -48,6 +48,7 @@
#include "sim/sim_object.hh"
using namespace std;
+using namespace TheISA;
////
// Initialization and destruction
@@ -390,7 +391,7 @@ IdeController::writeConfig(int offset, int size, const uint8_t *data)
}
}
-Fault *
+Fault
IdeController::read(MemReqPtr &req, uint8_t *data)
{
Addr offset;
@@ -460,7 +461,7 @@ IdeController::read(MemReqPtr &req, uint8_t *data)
return NoFault;
}
-Fault *
+Fault
IdeController::write(MemReqPtr &req, const uint8_t *data)
{
Addr offset;
diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh
index 72523f57c..0fbaf9207 100644
--- a/dev/ide_ctrl.hh
+++ b/dev/ide_ctrl.hh
@@ -213,7 +213,7 @@ class IdeController : public PciDev
* @param data Return the field read.
* @return The fault condition of the access.
*/
- virtual Fault * read(MemReqPtr &req, uint8_t *data);
+ virtual Fault read(MemReqPtr &req, uint8_t *data);
/**
* Write to the mmapped I/O control registers.
@@ -221,7 +221,7 @@ class IdeController : public PciDev
* @param data The data to write.
* @return The fault condition of the access.
*/
- virtual Fault * write(MemReqPtr &req, const uint8_t *data);
+ virtual Fault write(MemReqPtr &req, const uint8_t *data);
/**
* Serialize this object to the given output stream.
diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc
index 9d8bb8825..41400c590 100644
--- a/dev/ide_disk.cc
+++ b/dev/ide_disk.cc
@@ -53,6 +53,7 @@
#include "arch/isa_traits.hh"
using namespace std;
+using namespace TheISA;
IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys,
int id, Tick delay)
diff --git a/dev/isa_fake.cc b/dev/isa_fake.cc
index 93c9eedbf..2afebbded 100644
--- a/dev/isa_fake.cc
+++ b/dev/isa_fake.cc
@@ -45,6 +45,7 @@
#include "sim/system.hh"
using namespace std;
+using namespace TheISA;
IsaFake::IsaFake(const string &name, Addr a, MemoryController *mmu,
HierParams *hier, Bus *pio_bus, Addr size)
@@ -59,7 +60,7 @@ IsaFake::IsaFake(const string &name, Addr a, MemoryController *mmu,
}
}
-Fault *
+Fault
IsaFake::read(MemReqPtr &req, uint8_t *data)
{
DPRINTF(Tsunami, "read va=%#x size=%d\n",
@@ -92,7 +93,7 @@ IsaFake::read(MemReqPtr &req, uint8_t *data)
return NoFault;
}
-Fault *
+Fault
IsaFake::write(MemReqPtr &req, const uint8_t *data)
{
DPRINTF(Tsunami, "write - va=%#x size=%d \n",
diff --git a/dev/isa_fake.hh b/dev/isa_fake.hh
index 60ca5f90a..290b24b54 100644
--- a/dev/isa_fake.hh
+++ b/dev/isa_fake.hh
@@ -65,14 +65,14 @@ class IsaFake : public PioDevice
* @param req The memory request.
* @param data Where to put the data.
*/
- virtual Fault * read(MemReqPtr &req, uint8_t *data);
+ virtual Fault read(MemReqPtr &req, uint8_t *data);
/**
* All writes are simply ignored.
* @param req The memory request.
* @param data the data to not write.
*/
- virtual Fault * write(MemReqPtr &req, const uint8_t *data);
+ virtual Fault write(MemReqPtr &req, const uint8_t *data);
/**
* Return how long this access will take.
diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc
index c28615438..4b08d8497 100644
--- a/dev/ns_gige.cc
+++ b/dev/ns_gige.cc
@@ -84,6 +84,7 @@ const char *NsDmaState[] =
using namespace std;
using namespace Net;
+using namespace TheISA;
///////////////////////////////////////////////////////////////////////
//
@@ -130,8 +131,6 @@ NSGigE::NSGigE(Params *p)
} else if (p->payload_bus)
panic("Must define a header bus if defining a payload bus");
- pioDelayWrite = p->pio_delay_write && pioInterface;
-
intrDelay = p->intr_delay;
dmaReadDelay = p->dma_read_delay;
dmaWriteDelay = p->dma_write_delay;
@@ -558,7 +557,7 @@ NSGigE::writeConfig(int offset, int size, const uint8_t* data)
* This reads the device registers, which are detailed in the NS83820
* spec sheet
*/
-Fault *
+Fault
NSGigE::read(MemReqPtr &req, uint8_t *data)
{
assert(ioEnable);
@@ -787,7 +786,7 @@ NSGigE::read(MemReqPtr &req, uint8_t *data)
return NoFault;
}
-Fault *
+Fault
NSGigE::write(MemReqPtr &req, const uint8_t *data)
{
assert(ioEnable);
@@ -804,13 +803,6 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
} else if (daddr > 0x3FC)
panic("Something is messed up!\n");
- if (pioDelayWrite) {
- int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff;
- if (cpu >= writeQueue.size())
- writeQueue.resize(cpu + 1);
- writeQueue[cpu].push_back(RegWriteData(daddr, *(uint32_t *)data));
- }
-
if (req->size == sizeof(uint32_t)) {
uint32_t reg = *(uint32_t *)data;
uint16_t rfaddr;
@@ -823,24 +815,20 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data)
if (reg & CR_TXD) {
txEnable = false;
} else if (reg & CR_TXE) {
- if (!pioDelayWrite) {
- txEnable = true;
+ txEnable = true;
- // the kernel is enabling the transmit machine
- if (txState == txIdle)
- txKick();
- }
+ // the kernel is enabling the transmit machine
+ if (txState == txIdle)
+ txKick();
}
if (reg & CR_RXD) {
rxEnable = false;
} else if (reg & CR_RXE) {
- if (!pioDelayWrite) {
- rxEnable = true;
+ rxEnable = true;
- if (rxState == rxIdle)
- rxKick();
- }
+ if (rxState == rxIdle)
+ rxKick();
}
if (reg & CR_TXR)
@@ -2948,38 +2936,9 @@ NSGigE::unserialize(Checkpoint *cp, const std::string &section)
Tick
NSGigE::cacheAccess(MemReqPtr &req)
{
- Addr daddr = req->paddr & 0xfff;
DPRINTF(EthernetPIO, "timing access to paddr=%#x (daddr=%#x)\n",
- req->paddr, daddr);
-
- if (!pioDelayWrite || !req->cmd.isWrite())
- return curTick + pioLatency;
-
- int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff;
- std::list<RegWriteData> &wq = writeQueue[cpu];
- if (wq.empty())
- panic("WriteQueue for cpu %d empty timing daddr=%#x", cpu, daddr);
-
- const RegWriteData &data = wq.front();
- if (data.daddr != daddr)
- panic("read mismatch on cpu %d, daddr functional=%#x timing=%#x",
- cpu, data.daddr, daddr);
-
- if (daddr == CR) {
- if ((data.value & (CR_TXD | CR_TXE)) == CR_TXE) {
- txEnable = true;
- if (txState == txIdle)
- txKick();
- }
-
- if ((data.value & (CR_RXD | CR_RXE)) == CR_RXE) {
- rxEnable = true;
- if (rxState == rxIdle)
- rxKick();
- }
- }
+ req->paddr, req->paddr & 0xfff);
- wq.pop_front();
return curTick + pioLatency;
}
@@ -3039,7 +2998,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
Param<Tick> dma_write_factor;
Param<bool> dma_no_allocate;
Param<Tick> pio_latency;
- Param<bool> pio_delay_write;
Param<Tick> intr_delay;
Param<Tick> rx_delay;
@@ -3080,7 +3038,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
INIT_PARAM(dma_write_factor, "multiplier for dma writes"),
INIT_PARAM(dma_no_allocate, "Should DMA reads allocate cache lines"),
INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"),
- INIT_PARAM(pio_delay_write, ""),
INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"),
INIT_PARAM(rx_delay, "Receive Delay"),
@@ -3125,7 +3082,6 @@ CREATE_SIM_OBJECT(NSGigE)
params->dma_write_factor = dma_write_factor;
params->dma_no_allocate = dma_no_allocate;
params->pio_latency = pio_latency;
- params->pio_delay_write = pio_delay_write;
params->intr_delay = intr_delay;
params->rx_delay = rx_delay;
diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh
index 181837c8d..cdd8e4b9e 100644
--- a/dev/ns_gige.hh
+++ b/dev/ns_gige.hh
@@ -236,15 +236,6 @@ class NSGigE : public PciDev
uint32_t rxDescCnt;
DmaState rxDmaState;
- struct RegWriteData {
- Addr daddr;
- uint32_t value;
- RegWriteData(Addr da, uint32_t val) : daddr(da), value(val) {}
- };
-
- std::vector<std::list<RegWriteData> > writeQueue;
- bool pioDelayWrite;
-
bool extstsEnable;
/** EEPROM State Machine */
@@ -382,7 +373,6 @@ class NSGigE : public PciDev
Tick tx_delay;
Tick rx_delay;
Tick pio_latency;
- bool pio_delay_write;
bool dma_desc_free;
bool dma_data_free;
Tick dma_read_delay;
@@ -405,8 +395,8 @@ class NSGigE : public PciDev
virtual void writeConfig(int offset, int size, const uint8_t *data);
virtual void readConfig(int offset, int size, uint8_t *data);
- virtual Fault * read(MemReqPtr &req, uint8_t *data);
- virtual Fault * write(MemReqPtr &req, const uint8_t *data);
+ virtual Fault read(MemReqPtr &req, uint8_t *data);
+ virtual Fault write(MemReqPtr &req, const uint8_t *data);
bool cpuIntrPending() const;
void cpuIntrAck() { cpuIntrClear(); }
diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc
index 1175172c4..d55084fa5 100644
--- a/dev/pciconfigall.cc
+++ b/dev/pciconfigall.cc
@@ -47,6 +47,7 @@
#include "sim/system.hh"
using namespace std;
+using namespace TheISA;
PciConfigAll::PciConfigAll(const string &name,
Addr a, MemoryController *mmu,
@@ -95,7 +96,7 @@ PciConfigAll::startup()
}
-Fault *
+Fault
PciConfigAll::read(MemReqPtr &req, uint8_t *data)
{
@@ -143,7 +144,7 @@ PciConfigAll::read(MemReqPtr &req, uint8_t *data)
return NoFault;
}
-Fault *
+Fault
PciConfigAll::write(MemReqPtr &req, const uint8_t *data)
{
Addr daddr = (req->paddr - (addr & EV5::PAddrImplMask));
diff --git a/dev/pciconfigall.hh b/dev/pciconfigall.hh
index 6df033286..c6a0241d8 100644
--- a/dev/pciconfigall.hh
+++ b/dev/pciconfigall.hh
@@ -103,7 +103,7 @@ class PciConfigAll : public PioDevice
* @param data Return the field read.
* @return The fault condition of the access.
*/
- virtual Fault * read(MemReqPtr &req, uint8_t *data);
+ virtual Fault read(MemReqPtr &req, uint8_t *data);
/**
* Write to PCI config spcae. If the device does not exit the simulator
@@ -114,7 +114,7 @@ class PciConfigAll : public PioDevice
* @return The fault condition of the access.
*/
- virtual Fault * write(MemReqPtr &req, const uint8_t *data);
+ virtual Fault write(MemReqPtr &req, const uint8_t *data);
/**
* Start up function to check if more than one person is using an interrupt line
diff --git a/dev/pcidev.cc b/dev/pcidev.cc
index c469e716a..a05ee3803 100644
--- a/dev/pcidev.cc
+++ b/dev/pcidev.cc
@@ -70,59 +70,59 @@ PciDev::PciDev(Params *p)
p->configSpace->registerDevice(p->deviceNum, p->functionNum, this);
}
-Fault *
+Fault
PciDev::read(MemReqPtr &req, uint8_t *data)
{ return NoFault; }
-Fault *
+Fault
PciDev::write(MemReqPtr &req, const uint8_t *data)
{ return NoFault; }
-Fault *
+Fault
PciDev::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data)
{ panic("not implemented"); }
-Fault *
+Fault
PciDev::readBar1(MemReqPtr &req, Addr daddr, uint8_t *data)
{ panic("not implemented"); }
-Fault *
+Fault
PciDev::readBar2(MemReqPtr &req, Addr daddr, uint8_t *data)
{ panic("not implemented"); }
-Fault *
+Fault
PciDev::readBar3(MemReqPtr &req, Addr daddr, uint8_t *data)
{ panic("not implemented"); }
-Fault *
+Fault
PciDev::readBar4(MemReqPtr &req, Addr daddr, uint8_t *data)
{ panic("not implemented"); }
-Fault *
+Fault
PciDev::readBar5(MemReqPtr &req, Addr daddr, uint8_t *data)
{ panic("not implemented"); }
-Fault *
+Fault
PciDev::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
{ panic("not implemented"); }
-Fault *
+Fault
PciDev::writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data)
{ panic("not implemented"); }
-Fault *
+Fault
PciDev::writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data)
{ panic("not implemented"); }
-Fault *
+Fault
PciDev::writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data)
{ panic("not implemented"); }
-Fault *
+Fault
PciDev::writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data)
{ panic("not implemented"); }
-Fault *
+Fault
PciDev::writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data)
{ panic("not implemented"); }
diff --git a/dev/pcidev.hh b/dev/pcidev.hh
index c8d9685c1..9427463bf 100644
--- a/dev/pcidev.hh
+++ b/dev/pcidev.hh
@@ -189,37 +189,37 @@ class PciDev : public DmaDevice
*/
PciDev(Params *params);
- virtual Fault * read(MemReqPtr &req, uint8_t *data);
- virtual Fault * write(MemReqPtr &req, const uint8_t *data);
+ virtual Fault read(MemReqPtr &req, uint8_t *data);
+ virtual Fault write(MemReqPtr &req, const uint8_t *data);
public:
/**
* Implement the read/write as BAR accesses
*/
- Fault * readBar(MemReqPtr &req, uint8_t *data);
- Fault * writeBar(MemReqPtr &req, const uint8_t *data);
+ Fault readBar(MemReqPtr &req, uint8_t *data);
+ Fault writeBar(MemReqPtr &req, const uint8_t *data);
public:
/**
* Read from a specific BAR
*/
- virtual Fault * readBar0(MemReqPtr &req, Addr daddr, uint8_t *data);
- virtual Fault * readBar1(MemReqPtr &req, Addr daddr, uint8_t *data);
- virtual Fault * readBar2(MemReqPtr &req, Addr daddr, uint8_t *data);
- virtual Fault * readBar3(MemReqPtr &req, Addr daddr, uint8_t *data);
- virtual Fault * readBar4(MemReqPtr &req, Addr daddr, uint8_t *data);
- virtual Fault * readBar5(MemReqPtr &req, Addr daddr, uint8_t *data);
+ virtual Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data);
+ virtual Fault readBar1(MemReqPtr &req, Addr daddr, uint8_t *data);
+ virtual Fault readBar2(MemReqPtr &req, Addr daddr, uint8_t *data);
+ virtual Fault readBar3(MemReqPtr &req, Addr daddr, uint8_t *data);
+ virtual Fault readBar4(MemReqPtr &req, Addr daddr, uint8_t *data);
+ virtual Fault readBar5(MemReqPtr &req, Addr daddr, uint8_t *data);
public:
/**
* Write to a specific BAR
*/
- virtual Fault * writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data);
- virtual Fault * writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data);
- virtual Fault * writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data);
- virtual Fault * writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data);
- virtual Fault * writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data);
- virtual Fault * writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data);
+ virtual Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data);
+ virtual Fault writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data);
+ virtual Fault writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data);
+ virtual Fault writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data);
+ virtual Fault writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data);
+ virtual Fault writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data);
public:
/**
@@ -257,7 +257,7 @@ class PciDev : public DmaDevice
virtual void unserialize(Checkpoint *cp, const std::string &section);
};
-inline Fault *
+inline Fault
PciDev::readBar(MemReqPtr &req, uint8_t *data)
{
if (isBAR(req->paddr, 0))
@@ -275,7 +275,7 @@ PciDev::readBar(MemReqPtr &req, uint8_t *data)
return MachineCheckFault;
}
-inline Fault *
+inline Fault
PciDev::writeBar(MemReqPtr &req, const uint8_t *data)
{
if (isBAR(req->paddr, 0))
diff --git a/dev/platform.cc b/dev/platform.cc
index 58f94db7b..5b667b12c 100644
--- a/dev/platform.cc
+++ b/dev/platform.cc
@@ -31,6 +31,7 @@
#include "sim/sim_exit.hh"
using namespace std;
+using namespace TheISA;
Platform::Platform(const string &name, IntrControl *intctrl, PciConfigAll *pci)
: SimObject(name), intrctrl(intctrl), pciconfig(pci)
diff --git a/dev/simple_disk.hh b/dev/simple_disk.hh
index 6560e15c2..57f81c5a9 100644
--- a/dev/simple_disk.hh
+++ b/dev/simple_disk.hh
@@ -44,19 +44,19 @@ class PhysicalMemory;
*/
class SimpleDisk : public SimObject
{
-public:
- typedef uint64_t baddr_t;
+ public:
+ typedef uint64_t baddr_t;
-protected:
- PhysicalMemory *physmem;
- DiskImage *image;
+ protected:
+ PhysicalMemory *physmem;
+ DiskImage *image;
-public:
- SimpleDisk(const std::string &name, PhysicalMemory *pmem, DiskImage *img);
- ~SimpleDisk();
+ public:
+ SimpleDisk(const std::string &name, PhysicalMemory *pmem, DiskImage *img);
+ ~SimpleDisk();
- void read(Addr addr, baddr_t block, int count) const;
- void write(Addr addr, baddr_t block, int count);
+ void read(Addr addr, baddr_t block, int count) const;
+ void write(Addr addr, baddr_t block, int count);
};
#endif // __DEV_SIMPLE_DISK_HH__
diff --git a/dev/sinic.cc b/dev/sinic.cc
index e79f80678..c499d2f49 100644
--- a/dev/sinic.cc
+++ b/dev/sinic.cc
@@ -50,6 +50,7 @@
#include "targetarch/vtophys.hh"
using namespace Net;
+using namespace TheISA;
namespace Sinic {
@@ -112,8 +113,6 @@ Device::Device(Params *p)
p->dma_no_allocate);
} else if (p->payload_bus)
panic("must define a header bus if defining a payload bus");
-
- pioDelayWrite = p->pio_delay_write && pioInterface;
}
Device::~Device()
@@ -352,20 +351,17 @@ Device::prepareRead(int cpu, int index)
void
Device::prepareWrite(int cpu, int index)
{
- if (cpu >= writeQueue.size())
- writeQueue.resize(cpu + 1);
-
prepareIO(cpu, index);
}
/**
* I/O read of device register
*/
-Fault *
+Fault
Device::read(MemReqPtr &req, uint8_t *data)
{
assert(config.command & PCI_CMD_MSE);
- Fault * fault = readBar(req, data);
+ Fault fault = readBar(req, data);
if (fault == MachineCheckFault) {
panic("address does not map to a BAR pa=%#x va=%#x size=%d",
@@ -377,7 +373,7 @@ Device::read(MemReqPtr &req, uint8_t *data)
return fault;
}
-Fault *
+Fault
Device::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data)
{
int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff;
@@ -427,7 +423,7 @@ Device::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data)
/**
* IPR read of device register
*/
-Fault *
+Fault
Device::iprRead(Addr daddr, int cpu, uint64_t &result)
{
if (!regValid(daddr))
@@ -457,11 +453,11 @@ Device::iprRead(Addr daddr, int cpu, uint64_t &result)
/**
* I/O write of device register
*/
-Fault *
+Fault
Device::write(MemReqPtr &req, const uint8_t *data)
{
assert(config.command & PCI_CMD_MSE);
- Fault * fault = writeBar(req, data);
+ Fault fault = writeBar(req, data);
if (fault == MachineCheckFault) {
panic("address does not map to a BAR pa=%#x va=%#x size=%d",
@@ -473,7 +469,7 @@ Device::write(MemReqPtr &req, const uint8_t *data)
return fault;
}
-Fault *
+Fault
Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
{
int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff;
@@ -493,20 +489,16 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data)
panic("invalid size for %s: cpu=%d da=%#x pa=%#x va=%#x size=%d",
info.name, cpu, daddr, req->paddr, req->vaddr, req->size);
- uint32_t reg32 = *(uint32_t *)data;
+ //uint32_t reg32 = *(uint32_t *)data;
uint64_t reg64 = *(uint64_t *)data;
DPRINTF(EthernetPIO,
"write %s: cpu=%d val=%#x da=%#x pa=%#x va=%#x size=%d\n",
- info.name, cpu, info.size == 4 ? reg32 : reg64, daddr,
+ info.name, cpu, info.size == 4 ? (*(uint32_t *)data) : reg64, daddr,
req->paddr, req->vaddr, req->size);
prepareWrite(cpu, index);
- if (pioDelayWrite)
- writeQueue[cpu].push_back(RegWriteData(daddr, reg64));
-
- if (!pioDelayWrite || !info.delay_write)
- regWrite(daddr, cpu, data);
+ regWrite(daddr, cpu, data);
return NoFault;
}
@@ -1570,27 +1562,6 @@ Device::cacheAccess(MemReqPtr &req)
DPRINTF(EthernetPIO, "timing %s to paddr=%#x bar=%d daddr=%#x\n",
req->cmd.toString(), req->paddr, bar, daddr);
- if (!pioDelayWrite || !req->cmd.isWrite())
- return curTick + pioLatency;
-
- if (bar == 0) {
- int cpu = (req->xc->regs.ipr[TheISA::IPR_PALtemp16] >> 8) & 0xff;
- std::list<RegWriteData> &wq = writeQueue[cpu];
- if (wq.empty())
- panic("WriteQueue for cpu %d empty timing daddr=%#x", cpu, daddr);
-
- const RegWriteData &data = wq.front();
- if (data.daddr != daddr)
- panic("read mismatch on cpu %d, daddr functional=%#x timing=%#x",
- cpu, data.daddr, daddr);
-
- const Regs::Info &info = regInfo(data.daddr);
- if (info.delay_write)
- regWrite(daddr, cpu, (uint8_t *)&data.value);
-
- wq.pop_front();
- }
-
return curTick + pioLatency;
}
@@ -1648,7 +1619,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
Param<Tick> dma_write_factor;
Param<bool> dma_no_allocate;
Param<Tick> pio_latency;
- Param<bool> pio_delay_write;
Param<Tick> intr_delay;
Param<Tick> rx_delay;
@@ -1692,7 +1662,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Device)
INIT_PARAM(dma_write_factor, "multiplier for dma writes"),
INIT_PARAM(dma_no_allocate, "Should we allocat on read in cache"),
INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"),
- INIT_PARAM(pio_delay_write, ""),
INIT_PARAM(intr_delay, "Interrupt Delay"),
INIT_PARAM(rx_delay, "Receive Delay"),
@@ -1740,7 +1709,6 @@ CREATE_SIM_OBJECT(Device)
params->dma_write_factor = dma_write_factor;
params->dma_no_allocate = dma_no_allocate;
params->pio_latency = pio_latency;
- params->pio_delay_write = pio_delay_write;
params->intr_delay = intr_delay;
params->tx_delay = tx_delay;
diff --git a/dev/sinic.hh b/dev/sinic.hh
index 7935a7cdc..97ebf4c30 100644
--- a/dev/sinic.hh
+++ b/dev/sinic.hh
@@ -271,29 +271,18 @@ class Device : public Base
* Memory Interface
*/
public:
- virtual Fault * read(MemReqPtr &req, uint8_t *data);
- virtual Fault * write(MemReqPtr &req, const uint8_t *data);
+ virtual Fault read(MemReqPtr &req, uint8_t *data);
+ virtual Fault write(MemReqPtr &req, const uint8_t *data);
void prepareIO(int cpu, int index);
void prepareRead(int cpu, int index);
void prepareWrite(int cpu, int index);
- Fault * iprRead(Addr daddr, int cpu, uint64_t &result);
- Fault * readBar0(MemReqPtr &req, Addr daddr, uint8_t *data);
- Fault * writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data);
+ Fault iprRead(Addr daddr, int cpu, uint64_t &result);
+ Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data);
+ Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data);
void regWrite(Addr daddr, int cpu, const uint8_t *data);
Tick cacheAccess(MemReqPtr &req);
- protected:
- struct RegWriteData {
- Addr daddr;
- uint64_t value;
- RegWriteData(Addr da, uint64_t val) : daddr(da), value(val) {}
- };
-
- std::vector<std::list<RegWriteData> > writeQueue;
-
- bool pioDelayWrite;
-
/**
* Statistics
*/
@@ -349,7 +338,6 @@ class Device : public Base
Bus *header_bus;
Bus *payload_bus;
Tick pio_latency;
- bool pio_delay_write;
PhysicalMemory *physmem;
IntrControl *intctrl;
bool rx_filter;
diff --git a/dev/sinicreg.hh b/dev/sinicreg.hh
index b7008b4e1..fc1f4c06b 100644
--- a/dev/sinicreg.hh
+++ b/dev/sinicreg.hh
@@ -157,8 +157,6 @@ struct Info
uint8_t size;
bool read;
bool write;
- bool delay_read;
- bool delay_write;
const char *name;
};
@@ -167,33 +165,33 @@ struct Info
inline const Regs::Info&
regInfo(Addr daddr)
{
- static Regs::Info invalid = { 0, false, false, false, false, "invalid" };
+ static Regs::Info invalid = { 0, false, false, "invalid" };
static Regs::Info info [] = {
- { 4, true, true, false, false, "Config" },
- { 4, false, true, false, false, "Command" },
- { 4, true, true, false, false, "IntrStatus" },
- { 4, true, true, false, false, "IntrMask" },
- { 4, true, false, false, false, "RxMaxCopy" },
- { 4, true, false, false, false, "TxMaxCopy" },
- { 4, true, false, false, false, "RxMaxIntr" },
+ { 4, true, true, "Config" },
+ { 4, false, true, "Command" },
+ { 4, true, true, "IntrStatus" },
+ { 4, true, true, "IntrMask" },
+ { 4, true, false, "RxMaxCopy" },
+ { 4, true, false, "TxMaxCopy" },
+ { 4, true, false, "RxMaxIntr" },
invalid,
- { 4, true, false, false, false, "RxFifoSize" },
- { 4, true, false, false, false, "TxFifoSize" },
- { 4, true, false, false, false, "RxFifoMark" },
- { 4, true, false, false, false, "TxFifoMark" },
- { 8, true, true, false, true, "RxData" },
+ { 4, true, false, "RxFifoSize" },
+ { 4, true, false, "TxFifoSize" },
+ { 4, true, false, "RxFifoMark" },
+ { 4, true, false, "TxFifoMark" },
+ { 8, true, true, "RxData" },
invalid,
- { 8, true, false, false, false, "RxDone" },
+ { 8, true, false, "RxDone" },
invalid,
- { 8, true, false, false, false, "RxWait" },
+ { 8, true, false, "RxWait" },
invalid,
- { 8, true, true, false, true, "TxData" },
+ { 8, true, true, "TxData" },
invalid,
- { 8, true, false, false, false, "TxDone" },
+ { 8, true, false, "TxDone" },
invalid,
- { 8, true, false, false, false, "TxWait" },
+ { 8, true, false, "TxWait" },
invalid,
- { 8, true, false, false, false, "HwAddr" },
+ { 8, true, false, "HwAddr" },
invalid,
};
diff --git a/dev/tsunami.cc b/dev/tsunami.cc
index 760848a00..58fc7434e 100644
--- a/dev/tsunami.cc
+++ b/dev/tsunami.cc
@@ -46,6 +46,8 @@
#include "sim/system.hh"
using namespace std;
+//Should this be AlphaISA?
+using namespace TheISA;
Tsunami::Tsunami(const string &name, System *s, IntrControl *ic,
PciConfigAll *pci)
diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc
index 4cda9ec36..4dc4413a1 100644
--- a/dev/tsunami_cchip.cc
+++ b/dev/tsunami_cchip.cc
@@ -47,6 +47,8 @@
#include "sim/system.hh"
using namespace std;
+//Should this be AlphaISA?
+using namespace TheISA;
TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a,
MemoryController *mmu, HierParams *hier,
@@ -76,7 +78,7 @@ TsunamiCChip::TsunamiCChip(const string &name, Tsunami *t, Addr a,
tsunami->cchip = this;
}
-Fault *
+Fault
TsunamiCChip::read(MemReqPtr &req, uint8_t *data)
{
DPRINTF(Tsunami, "read va=%#x size=%d\n", req->vaddr, req->size);
@@ -190,7 +192,7 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data)
return NoFault;
}
-Fault *
+Fault
TsunamiCChip::write(MemReqPtr &req, const uint8_t *data)
{
DPRINTF(Tsunami, "write - va=%#x value=%#x size=%d \n",
diff --git a/dev/tsunami_cchip.hh b/dev/tsunami_cchip.hh
index dadbdb0e3..d88ad375f 100644
--- a/dev/tsunami_cchip.hh
+++ b/dev/tsunami_cchip.hh
@@ -105,7 +105,7 @@ class TsunamiCChip : public PioDevice
* @param data A pointer to write the read data to.
* @return The fault condition of the access.
*/
- virtual Fault * read(MemReqPtr &req, uint8_t *data);
+ virtual Fault read(MemReqPtr &req, uint8_t *data);
/**
@@ -114,7 +114,7 @@ class TsunamiCChip : public PioDevice
* @param data The data to write.
* @return The fault condition of the access.
*/
- virtual Fault * write(MemReqPtr &req, const uint8_t *data);
+ virtual Fault write(MemReqPtr &req, const uint8_t *data);
/**
* post an RTC interrupt to the CPU
diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc
index 0d0d27570..e66d6653b 100644
--- a/dev/tsunami_io.cc
+++ b/dev/tsunami_io.cc
@@ -50,6 +50,8 @@
#include "mem/functional/memory_control.hh"
using namespace std;
+//Should this be AlphaISA?
+using namespace TheISA;
TsunamiIO::RTC::RTC(const string &name, Tsunami* t, Tick i)
: _name(name), event(t, i), addr(0)
@@ -444,7 +446,7 @@ TsunamiIO::frequency() const
return Clock::Frequency / clockInterval;
}
-Fault *
+Fault
TsunamiIO::read(MemReqPtr &req, uint8_t *data)
{
DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n",
@@ -521,7 +523,7 @@ TsunamiIO::read(MemReqPtr &req, uint8_t *data)
return NoFault;
}
-Fault *
+Fault
TsunamiIO::write(MemReqPtr &req, const uint8_t *data)
{
diff --git a/dev/tsunami_io.hh b/dev/tsunami_io.hh
index 3b26ebfaa..b024ecd14 100644
--- a/dev/tsunami_io.hh
+++ b/dev/tsunami_io.hh
@@ -330,7 +330,7 @@ class TsunamiIO : public PioDevice
* @param data A pointer to write the read data to.
* @return The fault condition of the access.
*/
- virtual Fault * read(MemReqPtr &req, uint8_t *data);
+ virtual Fault read(MemReqPtr &req, uint8_t *data);
/**
* Process a write to one of the devices we emulate.
@@ -338,7 +338,7 @@ class TsunamiIO : public PioDevice
* @param data The data to write.
* @return The fault condition of the access.
*/
- virtual Fault * write(MemReqPtr &req, const uint8_t *data);
+ virtual Fault write(MemReqPtr &req, const uint8_t *data);
/**
* Post an PIC interrupt to the CPU via the CChip
diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc
index a4c04a79f..46efc3dfe 100644
--- a/dev/tsunami_pchip.cc
+++ b/dev/tsunami_pchip.cc
@@ -47,6 +47,8 @@
#include "sim/system.hh"
using namespace std;
+//Should this be AlphaISA?
+using namespace TheISA;
TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a,
MemoryController *mmu, HierParams *hier,
@@ -76,7 +78,7 @@ TsunamiPChip::TsunamiPChip(const string &name, Tsunami *t, Addr a,
tsunami->pchip = this;
}
-Fault *
+Fault
TsunamiPChip::read(MemReqPtr &req, uint8_t *data)
{
DPRINTF(Tsunami, "read va=%#x size=%d\n",
@@ -165,7 +167,7 @@ TsunamiPChip::read(MemReqPtr &req, uint8_t *data)
return NoFault;
}
-Fault *
+Fault
TsunamiPChip::write(MemReqPtr &req, const uint8_t *data)
{
DPRINTF(Tsunami, "write - va=%#x size=%d \n",
diff --git a/dev/tsunami_pchip.hh b/dev/tsunami_pchip.hh
index ff888bea1..c1d95431b 100644
--- a/dev/tsunami_pchip.hh
+++ b/dev/tsunami_pchip.hh
@@ -99,7 +99,7 @@ class TsunamiPChip : public PioDevice
* @param data A pointer to write the read data to.
* @return The fault condition of the access.
*/
- virtual Fault * read(MemReqPtr &req, uint8_t *data);
+ virtual Fault read(MemReqPtr &req, uint8_t *data);
/**
* Process a write to the PChip.
@@ -107,7 +107,7 @@ class TsunamiPChip : public PioDevice
* @param data The data to write.
* @return The fault condition of the access.
*/
- virtual Fault * write(MemReqPtr &req, const uint8_t *data);
+ virtual Fault write(MemReqPtr &req, const uint8_t *data);
/**
* Serialize this object to the given output stream.
diff --git a/dev/uart.hh b/dev/uart.hh
index 96c22025c..145b9ca9e 100644
--- a/dev/uart.hh
+++ b/dev/uart.hh
@@ -57,8 +57,8 @@ class Uart : public PioDevice
Addr a, Addr s, HierParams *hier, Bus *bus, Tick pio_latency,
Platform *p);
- virtual Fault * read(MemReqPtr &req, uint8_t *data) = 0;
- virtual Fault * write(MemReqPtr &req, const uint8_t *data) = 0;
+ virtual Fault read(MemReqPtr &req, uint8_t *data) = 0;
+ virtual Fault write(MemReqPtr &req, const uint8_t *data) = 0;
/**
diff --git a/dev/uart8250.cc b/dev/uart8250.cc
index a2e782189..65bccee86 100644
--- a/dev/uart8250.cc
+++ b/dev/uart8250.cc
@@ -46,6 +46,7 @@
#include "sim/builder.hh"
using namespace std;
+using namespace TheISA;
Uart8250::IntrEvent::IntrEvent(Uart8250 *u, int bit)
: Event(&mainEventQueue), uart(u)
@@ -111,7 +112,7 @@ Uart8250::Uart8250(const string &name, SimConsole *c, MemoryController *mmu,
}
-Fault *
+Fault
Uart8250::read(MemReqPtr &req, uint8_t *data)
{
Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
@@ -187,7 +188,7 @@ Uart8250::read(MemReqPtr &req, uint8_t *data)
}
-Fault *
+Fault
Uart8250::write(MemReqPtr &req, const uint8_t *data)
{
Addr daddr = req->paddr - (addr & EV5::PAddrImplMask);
diff --git a/dev/uart8250.hh b/dev/uart8250.hh
index a0e2d344a..88abf8e24 100644
--- a/dev/uart8250.hh
+++ b/dev/uart8250.hh
@@ -82,8 +82,8 @@ class Uart8250 : public Uart
Addr a, Addr s, HierParams *hier, Bus *pio_bus, Tick pio_latency,
Platform *p);
- virtual Fault * read(MemReqPtr &req, uint8_t *data);
- virtual Fault * write(MemReqPtr &req, const uint8_t *data);
+ virtual Fault read(MemReqPtr &req, uint8_t *data);
+ virtual Fault write(MemReqPtr &req, const uint8_t *data);
/**
diff --git a/kern/freebsd/freebsd_system.cc b/kern/freebsd/freebsd_system.cc
index dbf60a3fc..cead8caaf 100644
--- a/kern/freebsd/freebsd_system.cc
+++ b/kern/freebsd/freebsd_system.cc
@@ -46,6 +46,7 @@
#define TIMER_FREQUENCY 1193180
using namespace std;
+using namespace TheISA;
FreebsdSystem::FreebsdSystem(Params *p)
: System(p)
diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh
index a36c73fb4..02d78e4d9 100644
--- a/kern/kernel_stats.hh
+++ b/kern/kernel_stats.hh
@@ -41,7 +41,6 @@ class ExecContext;
class FnEvent;
// What does kernel stats expect is included?
class System;
-class Fault;
namespace Kernel {
@@ -106,7 +105,7 @@ class Binning
cpu_mode themode;
void palSwapContext(ExecContext *xc);
- void execute(ExecContext *xc, StaticInstPtr<TheISA> inst);
+ void execute(ExecContext *xc, StaticInstPtr inst);
void call(ExecContext *xc, Stats::MainBin *myBin);
void changeMode(cpu_mode mode);
@@ -124,6 +123,7 @@ class Binning
class Statistics : public Serializable
{
+ private:
friend class Binning;
private:
@@ -176,7 +176,7 @@ class Statistics : public Serializable
void ivlb() { _ivlb++; }
void ivle() { _ivle++; }
void hwrei() { _hwrei++; }
- void fault(Fault * fault)
+ void fault(Fault fault)
{
if(fault == NoFault) _faults[0]++;
else if(fault == MachineCheckFault) _faults[2]++;
diff --git a/kern/linux/linux.hh b/kern/linux/linux.hh
index b083b5a31..0dbccf546 100644
--- a/kern/linux/linux.hh
+++ b/kern/linux/linux.hh
@@ -28,7 +28,314 @@
#ifndef __LINUX_HH__
#define __LINUX_HH__
+#include "config/full_system.hh"
+
+#if FULL_SYSTEM
class Linux {};
+#else //!FULL_SYSTEM
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h> // for host open() flags
+#include <string.h> // for memset()
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "sim/syscall_emul.hh"
+
+///
+/// This class encapsulates the types, structures, constants,
+/// functions, and syscall-number mappings specific to the Alpha Linux
+/// syscall interface.
+///
+class Linux {
+
+ public:
+
+ //@{
+ /// Basic Linux types.
+ typedef uint64_t size_t;
+ typedef uint64_t off_t;
+ typedef int64_t time_t;
+ typedef uint32_t uid_t;
+ typedef uint32_t gid_t;
+ //@}
+
+#if BSD_HOST
+ typedef struct stat hst_stat;
+ typedef struct stat hst_stat64;
+#else
+ typedef struct stat hst_stat ;
+ typedef struct stat64 hst_stat64;
+#endif
+
+
+ //@{
+ /// open(2) flag values.
+ static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY
+ static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY
+ static const int TGT_O_RDWR = 00000002; //!< O_RDWR
+ static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK
+ static const int TGT_O_APPEND = 00000010; //!< O_APPEND
+ static const int TGT_O_CREAT = 00001000; //!< O_CREAT
+ static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC
+ static const int TGT_O_EXCL = 00004000; //!< O_EXCL
+ static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY
+ static const int TGT_O_SYNC = 00040000; //!< O_SYNC
+ static const int TGT_O_DRD = 00100000; //!< O_DRD
+ static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO
+ static const int TGT_O_CACHE = 00400000; //!< O_CACHE
+ static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC
+ static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC
+ //@}
+
+ /// This table maps the target open() flags to the corresponding
+ /// host open() flags.
+ static OpenFlagTransTable openFlagTable[];
+
+ /// Number of entries in openFlagTable[].
+ static const int NUM_OPEN_FLAGS;
+
+ /// Stat buffer. Note that we can't call it 'stat' since that
+ /// gets #defined to something else on some systems.
+ struct tgt_stat {
+ uint32_t st_dev; //!< device
+ uint32_t st_ino; //!< inode
+ uint32_t st_mode; //!< mode
+ uint32_t st_nlink; //!< link count
+ uint32_t st_uid; //!< owner's user ID
+ uint32_t st_gid; //!< owner's group ID
+ uint32_t st_rdev; //!< device number
+ int32_t _pad1; //!< for alignment
+ int64_t st_size; //!< file size in bytes
+ uint64_t st_atimeX; //!< time of last access
+ uint64_t st_mtimeX; //!< time of last modification
+ uint64_t st_ctimeX; //!< time of last status change
+ uint32_t st_blksize; //!< optimal I/O block size
+ int32_t st_blocks; //!< number of blocks allocated
+ uint32_t st_flags; //!< flags
+ uint32_t st_gen; //!< unknown
+ };
+
+ // same for stat64
+ struct tgt_stat64 {
+ uint64_t st_dev;
+ uint64_t st_ino;
+ uint64_t st_rdev;
+ int64_t st_size;
+ uint64_t st_blocks;
+
+ uint32_t st_mode;
+ uint32_t st_uid;
+ uint32_t st_gid;
+ uint32_t st_blksize;
+ uint32_t st_nlink;
+ uint32_t __pad0;
+
+ uint64_t tgt_st_atime;
+ uint64_t st_atime_nsec;
+ uint64_t tgt_st_mtime;
+ uint64_t st_mtime_nsec;
+ uint64_t tgt_st_ctime;
+ uint64_t st_ctime_nsec;
+ int64_t ___unused[3];
+ };
+
+ /// Length of strings in struct utsname (plus 1 for null char).
+ static const int _SYS_NMLN = 65;
+
+ /// Interface struct for uname().
+ struct utsname {
+ char sysname[_SYS_NMLN]; //!< System name.
+ char nodename[_SYS_NMLN]; //!< Node name.
+ char release[_SYS_NMLN]; //!< OS release.
+ char version[_SYS_NMLN]; //!< OS version.
+ char machine[_SYS_NMLN]; //!< Machine type.
+ };
+
+
+ //@{
+ /// ioctl() command codes.
+ static const unsigned TIOCGETP = 0x40067408;
+ static const unsigned TIOCSETP = 0x80067409;
+ static const unsigned TIOCSETN = 0x8006740a;
+ static const unsigned TIOCSETC = 0x80067411;
+ static const unsigned TIOCGETC = 0x40067412;
+ static const unsigned FIONREAD = 0x4004667f;
+ static const unsigned TIOCISATTY = 0x2000745e;
+ static const unsigned TIOCGETS = 0x402c7413;
+ static const unsigned TIOCGETA = 0x40127417;
+ //@}
+
+ /// Resource enumeration for getrlimit().
+ enum rlimit_resources {
+ TGT_RLIMIT_CPU = 0,
+ TGT_RLIMIT_FSIZE = 1,
+ TGT_RLIMIT_DATA = 2,
+ TGT_RLIMIT_STACK = 3,
+ TGT_RLIMIT_CORE = 4,
+ TGT_RLIMIT_RSS = 5,
+ TGT_RLIMIT_NOFILE = 6,
+ TGT_RLIMIT_AS = 7,
+ TGT_RLIMIT_VMEM = 7,
+ TGT_RLIMIT_NPROC = 8,
+ TGT_RLIMIT_MEMLOCK = 9,
+ TGT_RLIMIT_LOCKS = 10
+ };
+
+ /// Limit struct for getrlimit/setrlimit.
+ struct rlimit {
+ uint64_t rlim_cur; //!< soft limit
+ uint64_t rlim_max; //!< hard limit
+ };
+
+
+ /// For mmap().
+ static const unsigned TGT_MAP_ANONYMOUS = 0x10;
+
+ /// For gettimeofday().
+ struct timeval {
+ int64_t tv_sec; //!< seconds
+ int64_t tv_usec; //!< microseconds
+ };
+
+ // For writev/readv
+ struct tgt_iovec {
+ uint64_t iov_base; // void *
+ uint64_t iov_len;
+ };
+
+ //@{
+ /// For getrusage().
+ static const int TGT_RUSAGE_SELF = 0;
+ static const int TGT_RUSAGE_CHILDREN = -1;
+ static const int TGT_RUSAGE_BOTH = -2;
+ //@}
+
+ /// For getrusage().
+ struct rusage {
+ struct timeval ru_utime; //!< user time used
+ struct timeval ru_stime; //!< system time used
+ int64_t ru_maxrss; //!< max rss
+ int64_t ru_ixrss; //!< integral shared memory size
+ int64_t ru_idrss; //!< integral unshared data "
+ int64_t ru_isrss; //!< integral unshared stack "
+ int64_t ru_minflt; //!< page reclaims - total vmfaults
+ int64_t ru_majflt; //!< page faults
+ int64_t ru_nswap; //!< swaps
+ int64_t ru_inblock; //!< block input operations
+ int64_t ru_oublock; //!< block output operations
+ int64_t ru_msgsnd; //!< messages sent
+ int64_t ru_msgrcv; //!< messages received
+ int64_t ru_nsignals; //!< signals received
+ int64_t ru_nvcsw; //!< voluntary context switches
+ int64_t ru_nivcsw; //!< involuntary "
+ };
+
+ /// Helper function to convert a host stat buffer to a target stat
+ /// buffer. Also copies the target buffer out to the simulated
+ /// memory space. Used by stat(), fstat(), and lstat().
+#if !BSD_HOST
+ static void
+ copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat *host)
+ {
+ TypedBufferArg<Linux::tgt_stat> tgt(addr);
+
+ tgt->st_dev = htog(host->st_dev);
+ tgt->st_ino = htog(host->st_ino);
+ tgt->st_mode = htog(host->st_mode);
+ tgt->st_nlink = htog(host->st_nlink);
+ tgt->st_uid = htog(host->st_uid);
+ tgt->st_gid = htog(host->st_gid);
+ tgt->st_rdev = htog(host->st_rdev);
+ tgt->st_size = htog(host->st_size);
+ tgt->st_atimeX = htog(host->st_atime);
+ tgt->st_mtimeX = htog(host->st_mtime);
+ tgt->st_ctimeX = htog(host->st_ctime);
+ tgt->st_blksize = htog(host->st_blksize);
+ tgt->st_blocks = htog(host->st_blocks);
+
+ tgt.copyOut(mem);
+ }
+#else
+ // Third version for bsd systems which no longer have any support for
+ // the old stat() call and stat() is actually a stat64()
+ static void
+ copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat64 *host)
+ {
+ TypedBufferArg<Linux::tgt_stat> tgt(addr);
+
+ tgt->st_dev = htog(host->st_dev);
+ tgt->st_ino = htog(host->st_ino);
+ tgt->st_mode = htog(host->st_mode);
+ tgt->st_nlink = htog(host->st_nlink);
+ tgt->st_uid = htog(host->st_uid);
+ tgt->st_gid = htog(host->st_gid);
+ tgt->st_rdev = htog(host->st_rdev);
+ tgt->st_size = htog(host->st_size);
+ tgt->st_atimeX = htog(host->st_atime);
+ tgt->st_mtimeX = htog(host->st_mtime);
+ tgt->st_ctimeX = htog(host->st_ctime);
+ tgt->st_blksize = htog(host->st_blksize);
+ tgt->st_blocks = htog(host->st_blocks);
+
+ tgt.copyOut(mem);
+ }
+#endif
+
+
+ // Same for stat64
+ static void
+ copyOutStat64Buf(FunctionalMemory *mem, int fd, Addr addr, hst_stat64 *host)
+ {
+ TypedBufferArg<Linux::tgt_stat64> tgt(addr);
+
+ // fd == 1 checks are because libc does some checks
+ // that the stdout is interactive vs. a file
+ // this makes it work on non-linux systems
+ if (fd == 1)
+ tgt->st_dev = htog((uint64_t)0xA);
+ else
+ tgt->st_dev = htog((uint64_t)host->st_dev);
+ // XXX What about STAT64_HAS_BROKEN_ST_INO ???
+ tgt->st_ino = htog((uint64_t)host->st_ino);
+ if (fd == 1)
+ tgt->st_rdev = htog((uint64_t)0x880d);
+ else
+ tgt->st_rdev = htog((uint64_t)host->st_rdev);
+ tgt->st_size = htog((int64_t)host->st_size);
+ tgt->st_blocks = htog((uint64_t)host->st_blocks);
+
+ if (fd == 1)
+ tgt->st_mode = htog((uint32_t)0x2190);
+ else
+ tgt->st_mode = htog((uint32_t)host->st_mode);
+ tgt->st_uid = htog((uint32_t)host->st_uid);
+ tgt->st_gid = htog((uint32_t)host->st_gid);
+ tgt->st_blksize = htog((uint32_t)host->st_blksize);
+ tgt->st_nlink = htog((uint32_t)host->st_nlink);
+ tgt->tgt_st_atime = htog((uint64_t)host->st_atime);
+ tgt->tgt_st_mtime = htog((uint64_t)host->st_mtime);
+ tgt->tgt_st_ctime = htog((uint64_t)host->st_ctime);
+#if defined(STAT_HAVE_NSEC)
+ tgt->st_atime_nsec = htog(host->st_atime_nsec);
+ tgt->st_mtime_nsec = htog(host->st_mtime_nsec);
+ tgt->st_ctime_nsec = htog(host->st_ctime_nsec);
+#else
+ tgt->st_atime_nsec = 0;
+ tgt->st_mtime_nsec = 0;
+ tgt->st_ctime_nsec = 0;
+#endif
+
+ tgt.copyOut(mem);
+ }
+
+}; // class Linux
+
+
+#endif // FULL_SYSTEM
+
#endif // __LINUX_HH__
diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc
index 26a4c0d3e..c5a9e184a 100644
--- a/kern/linux/linux_system.cc
+++ b/kern/linux/linux_system.cc
@@ -50,6 +50,7 @@
#include "targetarch/vtophys.hh"
using namespace std;
+using namespace TheISA;
LinuxSystem::LinuxSystem(Params *p)
: System(p)
diff --git a/kern/linux/linux_threadinfo.hh b/kern/linux/linux_threadinfo.hh
index 9bab1dc49..a1c378d6a 100644
--- a/kern/linux/linux_threadinfo.hh
+++ b/kern/linux/linux_threadinfo.hh
@@ -53,7 +53,7 @@ class ThreadInfo
* thread_info struct. So we can get the address by masking off
* the lower 14 bits.
*/
- current = xc->regs.intRegFile[StackPointerReg] & ~0x3fff;
+ current = xc->regs.intRegFile[TheISA::StackPointerReg] & ~0x3fff;
return VPtr<thread_info>(xc, current);
}
diff --git a/kern/system_events.cc b/kern/system_events.cc
index ba3c9274a..55595b9b6 100644
--- a/kern/system_events.cc
+++ b/kern/system_events.cc
@@ -29,6 +29,8 @@
#include "encumbered/cpu/full/cpu.hh"
#include "kern/kernel_stats.hh"
+using namespace TheISA;
+
void
SkipFuncEvent::process(ExecContext *xc)
{
diff --git a/kern/tru64/dump_mbuf.cc b/kern/tru64/dump_mbuf.cc
index 85cb4de96..efdaed62d 100644
--- a/kern/tru64/dump_mbuf.cc
+++ b/kern/tru64/dump_mbuf.cc
@@ -38,6 +38,8 @@
#include "arch/isa_traits.hh"
#include "targetarch/vtophys.hh"
+using namespace TheISA;
+
namespace tru64 {
void
diff --git a/kern/tru64/tru64.hh b/kern/tru64/tru64.hh
index 07c0d21a7..1579a54d8 100644
--- a/kern/tru64/tru64.hh
+++ b/kern/tru64/tru64.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,1297 @@
#ifndef __TRU64_HH__
#define __TRU64_HH__
+#include "config/full_system.hh"
+
+#if FULL_SYSTEM
class Tru64 {};
+#else //!FULL_SYSTEM
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__)
+#include <sys/param.h>
+#include <sys/mount.h>
+#else
+#include <sys/statfs.h>
+#endif
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h> // for memset()
+#include <unistd.h>
+
+#include "cpu/base.hh"
+#include "sim/root.hh"
+#include "sim/syscall_emul.hh"
+
+using namespace std;
+
+typedef struct stat global_stat;
+typedef struct statfs global_statfs;
+typedef struct dirent global_dirent;
+
+///
+/// This class encapsulates the types, structures, constants,
+/// functions, and syscall-number mappings specific to the Alpha Tru64
+/// syscall interface.
+///
+class Tru64 {
+
+ public:
+
+ //@{
+ /// Basic Tru64 types.
+ typedef uint64_t size_t;
+ typedef uint64_t off_t;
+ typedef uint16_t nlink_t;
+ typedef int32_t dev_t;
+ typedef uint32_t uid_t;
+ typedef uint32_t gid_t;
+ typedef uint32_t time_t;
+ typedef uint32_t mode_t;
+ typedef uint32_t ino_t;
+ typedef struct { int val[2]; } quad;
+ typedef quad fsid_t;
+ //@}
+
+ //@{
+ /// open(2) flag values.
+ static const int TGT_O_RDONLY = 00000000;
+ static const int TGT_O_WRONLY = 00000001;
+ static const int TGT_O_RDWR = 00000002;
+ static const int TGT_O_NONBLOCK = 00000004;
+ static const int TGT_O_APPEND = 00000010;
+ static const int TGT_O_CREAT = 00001000;
+ static const int TGT_O_TRUNC = 00002000;
+ static const int TGT_O_EXCL = 00004000;
+ static const int TGT_O_NOCTTY = 00010000;
+ static const int TGT_O_SYNC = 00040000;
+ static const int TGT_O_DRD = 00100000;
+ static const int TGT_O_DIRECTIO = 00200000;
+ static const int TGT_O_CACHE = 00400000;
+ static const int TGT_O_DSYNC = 02000000;
+ static const int TGT_O_RSYNC = 04000000;
+ //@}
+
+ /// This table maps the target open() flags to the corresponding
+ /// host open() flags.
+ static OpenFlagTransTable openFlagTable[];
+
+ /// Number of entries in openFlagTable[].
+ static const int NUM_OPEN_FLAGS;
+
+ /// Stat buffer. Note that Tru64 v5.0+ use a new "F64" stat
+ /// structure, and a new set of syscall numbers for stat calls.
+ /// On some hosts (notably Linux) define st_atime, st_mtime, and
+ /// st_ctime as macros, so we append an X to get around this.
+ struct F64_stat {
+ dev_t st_dev; //!< st_dev
+ int32_t st_retired1; //!< st_retired1
+ mode_t st_mode; //!< st_mode
+ nlink_t st_nlink; //!< st_nlink
+ uint16_t st_nlink_reserved; //!< st_nlink_reserved
+ uid_t st_uid; //!< st_uid
+ gid_t st_gid; //!< st_gid
+ dev_t st_rdev; //!< st_rdev
+ dev_t st_ldev; //!< st_ldev
+ off_t st_size; //!< st_size
+ time_t st_retired2; //!< st_retired2
+ int32_t st_uatime; //!< st_uatime
+ time_t st_retired3; //!< st_retired3
+ int32_t st_umtime; //!< st_umtime
+ time_t st_retired4; //!< st_retired4
+ int32_t st_uctime; //!< st_uctime
+ int32_t st_retired5; //!< st_retired5
+ int32_t st_retired6; //!< st_retired6
+ uint32_t st_flags; //!< st_flags
+ uint32_t st_gen; //!< st_gen
+ uint64_t st_spare[4]; //!< st_spare[4]
+ ino_t st_ino; //!< st_ino
+ int32_t st_ino_reserved; //!< st_ino_reserved
+ time_t st_atimeX; //!< st_atime
+ int32_t st_atime_reserved; //!< st_atime_reserved
+ time_t st_mtimeX; //!< st_mtime
+ int32_t st_mtime_reserved; //!< st_mtime_reserved
+ time_t st_ctimeX; //!< st_ctime
+ int32_t st_ctime_reserved; //!< st_ctime_reserved
+ uint64_t st_blksize; //!< st_blksize
+ uint64_t st_blocks; //!< st_blocks
+ };
+
+
+ /// Old Tru64 v4.x stat struct.
+ /// Tru64 maintains backwards compatibility with v4.x by
+ /// implementing another set of stat functions using the old
+ /// structure definition and binding them to the old syscall
+ /// numbers.
+ struct pre_F64_stat {
+ dev_t st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ nlink_t st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+ dev_t st_rdev;
+ off_t st_size;
+ time_t st_atimeX;
+ int32_t st_uatime;
+ time_t st_mtimeX;
+ int32_t st_umtime;
+ time_t st_ctimeX;
+ int32_t st_uctime;
+ uint32_t st_blksize;
+ int32_t st_blocks;
+ uint32_t st_flags;
+ uint32_t st_gen;
+ };
+
+ /// For statfs().
+ struct F64_statfs {
+ int16_t f_type;
+ int16_t f_flags;
+ int32_t f_retired1;
+ int32_t f_retired2;
+ int32_t f_retired3;
+ int32_t f_retired4;
+ int32_t f_retired5;
+ int32_t f_retired6;
+ int32_t f_retired7;
+ fsid_t f_fsid;
+ int32_t f_spare[9];
+ char f_retired8[90];
+ char f_retired9[90];
+ uint64_t dummy[10]; // was union mount_info mount_info;
+ uint64_t f_flags2;
+ int64_t f_spare2[14];
+ int64_t f_fsize;
+ int64_t f_bsize;
+ int64_t f_blocks;
+ int64_t f_bfree;
+ int64_t f_bavail;
+ int64_t f_files;
+ int64_t f_ffree;
+ char f_mntonname[1024];
+ char f_mntfromname[1024];
+ };
+
+ /// For old Tru64 v4.x statfs()
+ struct pre_F64_statfs {
+ int16_t f_type;
+ int16_t f_flags;
+ int32_t f_fsize;
+ int32_t f_bsize;
+ int32_t f_blocks;
+ int32_t f_bfree;
+ int32_t f_bavail;
+ int32_t f_files;
+ int32_t f_ffree;
+ fsid_t f_fsid;
+ int32_t f_spare[9];
+ char f_mntonname[90];
+ char f_mntfromname[90];
+ uint64_t dummy[10]; // was union mount_info mount_info;
+ };
+
+ /// For getdirentries().
+ struct dirent
+ {
+ ino_t d_ino; //!< file number of entry
+ uint16_t d_reclen; //!< length of this record
+ uint16_t d_namlen; //!< length of string in d_name
+ char d_name[256]; //!< dummy name length
+ };
+
+
+ /// Length of strings in struct utsname (plus 1 for null char).
+ static const int _SYS_NMLN = 32;
+
+ /// Interface struct for uname().
+ struct utsname {
+ char sysname[_SYS_NMLN]; //!< System name.
+ char nodename[_SYS_NMLN]; //!< Node name.
+ char release[_SYS_NMLN]; //!< OS release.
+ char version[_SYS_NMLN]; //!< OS version.
+ char machine[_SYS_NMLN]; //!< Machine type.
+ };
+
+ //@{
+ /// ioctl() command codes.
+ static const unsigned TIOCGETP = 0x40067408;
+ static const unsigned TIOCSETP = 0x80067409;
+ static const unsigned TIOCSETN = 0x8006740a;
+ static const unsigned TIOCSETC = 0x80067411;
+ static const unsigned TIOCGETC = 0x40067412;
+ static const unsigned FIONREAD = 0x4004667f;
+ static const unsigned TIOCISATTY = 0x2000745e;
+ // TIOCGETS not defined in tru64, so I made up a number
+ static const unsigned TIOCGETS = 0x40000000;
+ static const unsigned TIOCGETA = 0x402c7413;
+ //@}
+
+ /// Resource enumeration for getrlimit().
+ enum rlimit_resources {
+ TGT_RLIMIT_CPU = 0,
+ TGT_RLIMIT_FSIZE = 1,
+ TGT_RLIMIT_DATA = 2,
+ TGT_RLIMIT_STACK = 3,
+ TGT_RLIMIT_CORE = 4,
+ TGT_RLIMIT_RSS = 5,
+ TGT_RLIMIT_NOFILE = 6,
+ TGT_RLIMIT_AS = 7,
+ TGT_RLIMIT_VMEM = 7
+ };
+
+ /// Limit struct for getrlimit/setrlimit.
+ struct rlimit {
+ uint64_t rlim_cur; //!< soft limit
+ uint64_t rlim_max; //!< hard limit
+ };
+
+
+ /// For mmap().
+ static const unsigned TGT_MAP_ANONYMOUS = 0x10;
+
+
+ //@{
+ /// For getsysinfo().
+ static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
+ static const unsigned GSI_CPU_INFO = 59; //!< CPU information
+ static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
+ static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine
+ static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
+ static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
+ static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
+ //@}
+
+ /// For getsysinfo() GSI_CPU_INFO option.
+ struct cpu_info {
+ uint32_t current_cpu; //!< current_cpu
+ uint32_t cpus_in_box; //!< cpus_in_box
+ uint32_t cpu_type; //!< cpu_type
+ uint32_t ncpus; //!< ncpus
+ uint64_t cpus_present; //!< cpus_present
+ uint64_t cpus_running; //!< cpus_running
+ uint64_t cpu_binding; //!< cpu_binding
+ uint64_t cpu_ex_binding; //!< cpu_ex_binding
+ uint32_t mhz; //!< mhz
+ uint32_t unused[3]; //!< future expansion
+ };
+
+ //@{
+ /// For setsysinfo().
+ static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
+ //@}
+
+ /// For gettimeofday.
+ struct timeval {
+ uint32_t tv_sec; //!< seconds
+ uint32_t tv_usec; //!< microseconds
+ };
+
+ //@{
+ /// For getrusage().
+ static const int TGT_RUSAGE_THREAD = 1;
+ static const int TGT_RUSAGE_SELF = 0;
+ static const int TGT_RUSAGE_CHILDREN = -1;
+ //@}
+
+ /// For getrusage().
+ struct rusage {
+ struct timeval ru_utime; //!< user time used
+ struct timeval ru_stime; //!< system time used
+ uint64_t ru_maxrss; //!< ru_maxrss
+ uint64_t ru_ixrss; //!< integral shared memory size
+ uint64_t ru_idrss; //!< integral unshared data "
+ uint64_t ru_isrss; //!< integral unshared stack "
+ uint64_t ru_minflt; //!< page reclaims - total vmfaults
+ uint64_t ru_majflt; //!< page faults
+ uint64_t ru_nswap; //!< swaps
+ uint64_t ru_inblock; //!< block input operations
+ uint64_t ru_oublock; //!< block output operations
+ uint64_t ru_msgsnd; //!< messages sent
+ uint64_t ru_msgrcv; //!< messages received
+ uint64_t ru_nsignals; //!< signals received
+ uint64_t ru_nvcsw; //!< voluntary context switches
+ uint64_t ru_nivcsw; //!< involuntary "
+ };
+
+ /// For sigreturn().
+ struct sigcontext {
+ int64_t sc_onstack; //!< sigstack state to restore
+ int64_t sc_mask; //!< signal mask to restore
+ int64_t sc_pc; //!< pc at time of signal
+ int64_t sc_ps; //!< psl to retore
+ int64_t sc_regs[32]; //!< processor regs 0 to 31
+ int64_t sc_ownedfp; //!< fp has been used
+ int64_t sc_fpregs[32]; //!< fp regs 0 to 31
+ uint64_t sc_fpcr; //!< floating point control reg
+ uint64_t sc_fp_control; //!< software fpcr
+ int64_t sc_reserved1; //!< reserved for kernel
+ uint32_t sc_kreserved1; //!< reserved for kernel
+ uint32_t sc_kreserved2; //!< reserved for kernel
+ size_t sc_ssize; //!< stack size
+ caddr_t sc_sbase; //!< stack start
+ uint64_t sc_traparg_a0; //!< a0 argument to trap on exc
+ uint64_t sc_traparg_a1; //!< a1 argument to trap on exc
+ uint64_t sc_traparg_a2; //!< a2 argument to trap on exc
+ uint64_t sc_fp_trap_pc; //!< imprecise pc
+ uint64_t sc_fp_trigger_sum; //!< Exception summary at trigg
+ uint64_t sc_fp_trigger_inst; //!< Instruction at trigger pc
+ };
+
+
+ /// For table().
+ static const int TBL_SYSINFO = 12;
+
+ /// For table().
+ struct tbl_sysinfo {
+ uint64_t si_user; //!< User time
+ uint64_t si_nice; //!< Nice time
+ uint64_t si_sys; //!< System time
+ uint64_t si_idle; //!< Idle time
+ uint64_t si_hz; //!< hz
+ uint64_t si_phz; //!< phz
+ uint64_t si_boottime; //!< Boot time in seconds
+ uint64_t wait; //!< Wait time
+ uint32_t si_max_procs; //!< rpb->rpb_numprocs
+ uint32_t pad; //!< padding
+ };
+
+
+ /// For stack_create.
+ struct vm_stack {
+ // was void *
+ Addr address; //!< address hint
+ size_t rsize; //!< red zone size
+ size_t ysize; //!< yellow zone size
+ size_t gsize; //!< green zone size
+ size_t swap; //!< amount of swap to reserve
+ size_t incr; //!< growth increment
+ uint64_t align; //!< address alignment
+ uint64_t flags; //!< MAP_FIXED etc.
+ // was struct memalloc_attr *
+ Addr attr; //!< allocation policy
+ uint64_t reserved; //!< reserved
+ };
+
+ /// Return values for nxm calls.
+ enum {
+ KERN_NOT_RECEIVER = 7,
+ KERN_NOT_IN_SET = 12
+ };
+
+ /// For nxm_task_init.
+ static const int NXM_TASK_INIT_VP = 2; //!< initial thread is VP
+
+ /// Task attribute structure.
+ struct nxm_task_attr {
+ int64_t nxm_callback; //!< nxm_callback
+ unsigned int nxm_version; //!< nxm_version
+ unsigned short nxm_uniq_offset; //!< nxm_uniq_offset
+ unsigned short flags; //!< flags
+ int nxm_quantum; //!< nxm_quantum
+ int pad1; //!< pad1
+ int64_t pad2; //!< pad2
+ };
+
+ /// Signal set.
+ typedef uint64_t sigset_t;
+
+ /// Thread state shared between user & kernel.
+ struct ushared_state {
+ sigset_t sigmask; //!< thread signal mask
+ sigset_t sig; //!< thread pending mask
+ // struct nxm_pth_state *
+ Addr pth_id; //!< out-of-line state
+ int flags; //!< shared flags
+#define US_SIGSTACK 0x1 // thread called sigaltstack
+#define US_ONSTACK 0x2 // thread is running on altstack
+#define US_PROFILE 0x4 // thread called profil
+#define US_SYSCALL 0x8 // thread in syscall
+#define US_TRAP 0x10 // thread has trapped
+#define US_YELLOW 0x20 // thread has mellowed yellow
+#define US_YZONE 0x40 // thread has zoned out
+#define US_FP_OWNED 0x80 // thread used floating point
+
+ int cancel_state; //!< thread's cancelation state
+#define US_CANCEL 0x1 // cancel pending
+#define US_NOCANCEL 0X2 // synch cancel disabled
+#define US_SYS_NOCANCEL 0x4 // syscall cancel disabled
+#define US_ASYNC_NOCANCEL 0x8 // asynch cancel disabled
+#define US_CANCEL_BITS (US_NOCANCEL|US_SYS_NOCANCEL|US_ASYNC_NOCANCEL)
+#define US_CANCEL_MASK (US_CANCEL|US_NOCANCEL|US_SYS_NOCANCEL| \
+ US_ASYNC_NOCANCEL)
+
+ // These are semi-shared. They are always visible to
+ // the kernel but are never context-switched by the library.
+
+ int nxm_ssig; //!< scheduler's synchronous signals
+ int reserved1; //!< reserved1
+ int64_t nxm_active; //!< scheduler active
+ int64_t reserved2; //!< reserved2
+ };
+
+ struct nxm_sched_state {
+ struct ushared_state nxm_u; //!< state own by user thread
+ unsigned int nxm_bits; //!< scheduler state / slot
+ int nxm_quantum; //!< quantum count-down value
+ int nxm_set_quantum; //!< quantum reset value
+ int nxm_sysevent; //!< syscall state
+ // struct nxm_upcall *
+ Addr nxm_uc_ret; //!< stack ptr of null thread
+ // void *
+ Addr nxm_tid; //!< scheduler's thread id
+ int64_t nxm_va; //!< page fault address
+ // struct nxm_pth_state *
+ Addr nxm_pthid; //!< id of null thread
+ uint64_t nxm_bound_pcs_count; //!< bound PCS thread count
+ int64_t pad[2]; //!< pad
+ };
+
+ /// nxm_shared.
+ struct nxm_shared {
+ int64_t nxm_callback; //!< address of upcall routine
+ unsigned int nxm_version; //!< version number
+ unsigned short nxm_uniq_offset; //!< correction factor for TEB
+ unsigned short pad1; //!< pad1
+ int64_t space[2]; //!< future growth
+ struct nxm_sched_state nxm_ss[1]; //!< array of shared areas
+ };
+
+ /// nxm_slot_state_t.
+ enum nxm_slot_state_t {
+ NXM_SLOT_AVAIL,
+ NXM_SLOT_BOUND,
+ NXM_SLOT_UNBOUND,
+ NXM_SLOT_EMPTY
+ };
+
+ /// nxm_config_info
+ struct nxm_config_info {
+ int nxm_nslots_per_rad; //!< max number of VP slots per RAD
+ int nxm_nrads; //!< max number of RADs
+ // nxm_slot_state_t *
+ Addr nxm_slot_state; //!< per-VP slot state
+ // struct nxm_shared *
+ Addr nxm_rad[1]; //!< per-RAD shared areas
+ };
+
+ /// For nxm_thread_create.
+ enum nxm_thread_type {
+ NXM_TYPE_SCS = 0,
+ NXM_TYPE_VP = 1,
+ NXM_TYPE_MANAGER = 2
+ };
+
+ /// Thread attributes.
+ struct nxm_thread_attr {
+ int version; //!< version
+ int type; //!< type
+ int cancel_flags; //!< cancel_flags
+ int priority; //!< priority
+ int policy; //!< policy
+ int signal_type; //!< signal_type
+ // void *
+ Addr pthid; //!< pthid
+ sigset_t sigmask; //!< sigmask
+ /// Initial register values.
+ struct {
+ uint64_t pc; //!< pc
+ uint64_t sp; //!< sp
+ uint64_t a0; //!< a0
+ } registers;
+ uint64_t pad2[2]; //!< pad2
+ };
+
+ /// Helper function to convert a host stat buffer to a target stat
+ /// buffer. Also copies the target buffer out to the simulated
+ /// memory space. Used by stat(), fstat(), and lstat().
+ template <class T>
+ static void
+ copyOutStatBuf(FunctionalMemory *mem, Addr addr, global_stat *host)
+ {
+ TypedBufferArg<T> tgt(addr);
+
+ tgt->st_dev = htog(host->st_dev);
+ tgt->st_ino = htog(host->st_ino);
+ tgt->st_mode = htog(host->st_mode);
+ tgt->st_nlink = htog(host->st_nlink);
+ tgt->st_uid = htog(host->st_uid);
+ tgt->st_gid = htog(host->st_gid);
+ tgt->st_rdev = htog(host->st_rdev);
+ tgt->st_size = htog(host->st_size);
+ tgt->st_atimeX = htog(host->st_atime);
+ tgt->st_mtimeX = htog(host->st_mtime);
+ tgt->st_ctimeX = htog(host->st_ctime);
+ tgt->st_blksize = htog(host->st_blksize);
+ tgt->st_blocks = htog(host->st_blocks);
+
+ tgt.copyOut(mem);
+ }
+
+ /// Helper function to convert a host statfs buffer to a target statfs
+ /// buffer. Also copies the target buffer out to the simulated
+ /// memory space. Used by statfs() and fstatfs().
+ template <class T>
+ static void
+ copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, global_statfs *host)
+ {
+ TypedBufferArg<T> tgt(addr);
+
+#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__)
+ tgt->f_type = 0;
+#else
+ tgt->f_type = htog(host->f_type);
+#endif
+ tgt->f_bsize = htog(host->f_bsize);
+ tgt->f_blocks = htog(host->f_blocks);
+ tgt->f_bfree = htog(host->f_bfree);
+ tgt->f_bavail = htog(host->f_bavail);
+ tgt->f_files = htog(host->f_files);
+ tgt->f_ffree = htog(host->f_ffree);
+
+ // Is this as string normally?
+ memcpy(&tgt->f_fsid, &host->f_fsid, sizeof(host->f_fsid));
+
+ tgt.copyOut(mem);
+ }
+
+ class F64 {
+ public:
+ static void copyOutStatBuf(FunctionalMemory *mem, Addr addr,
+ global_stat *host)
+ {
+ Tru64::copyOutStatBuf<Tru64::F64_stat>(mem, addr, host);
+ }
+
+ static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr,
+ global_statfs *host)
+ {
+ Tru64::copyOutStatfsBuf<Tru64::F64_statfs>(mem, addr, host);
+ }
+ };
+
+ class PreF64 {
+ public:
+ static void copyOutStatBuf(FunctionalMemory *mem, Addr addr,
+ global_stat *host)
+ {
+ Tru64::copyOutStatBuf<Tru64::pre_F64_stat>(mem, addr, host);
+ }
+
+ static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr,
+ global_statfs *host)
+ {
+ Tru64::copyOutStatfsBuf<Tru64::pre_F64_statfs>(mem, addr, host);
+ }
+ };
+
+ /// Helper function to convert a host stat buffer to an old pre-F64
+ /// (4.x) target stat buffer. Also copies the target buffer out to
+ /// the simulated memory space. Used by pre_F64_stat(),
+ /// pre_F64_fstat(), and pre_F64_lstat().
+ static void
+ copyOutPreF64StatBuf(FunctionalMemory *mem, Addr addr, struct stat *host)
+ {
+ TypedBufferArg<Tru64::pre_F64_stat> tgt(addr);
+
+ tgt->st_dev = htog(host->st_dev);
+ tgt->st_ino = htog(host->st_ino);
+ tgt->st_mode = htog(host->st_mode);
+ tgt->st_nlink = htog(host->st_nlink);
+ tgt->st_uid = htog(host->st_uid);
+ tgt->st_gid = htog(host->st_gid);
+ tgt->st_rdev = htog(host->st_rdev);
+ tgt->st_size = htog(host->st_size);
+ tgt->st_atimeX = htog(host->st_atime);
+ tgt->st_mtimeX = htog(host->st_mtime);
+ tgt->st_ctimeX = htog(host->st_ctime);
+ tgt->st_blksize = htog(host->st_blksize);
+ tgt->st_blocks = htog(host->st_blocks);
+
+ tgt.copyOut(mem);
+ }
+
+
+ /// The target system's hostname.
+ static const char *hostname;
+
+
+ /// Target getdirentries() handler.
+ static SyscallReturn
+ getdirentriesFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+#ifdef __CYGWIN__
+ panic("getdirent not implemented on cygwin!");
+#else
+ int fd = process->sim_fd(xc->getSyscallArg(0));
+ Addr tgt_buf = xc->getSyscallArg(1);
+ int tgt_nbytes = xc->getSyscallArg(2);
+ Addr tgt_basep = xc->getSyscallArg(3);
+
+ char * const host_buf = new char[tgt_nbytes];
+
+ // just pass basep through uninterpreted.
+ TypedBufferArg<int64_t> basep(tgt_basep);
+ basep.copyIn(xc->mem);
+ long host_basep = (off_t)htog((int64_t)*basep);
+ int host_result = getdirentries(fd, host_buf, tgt_nbytes, &host_basep);
+
+ // check for error
+ if (host_result < 0) {
+ delete [] host_buf;
+ return -errno;
+ }
+
+ // no error: copy results back to target space
+ Addr tgt_buf_ptr = tgt_buf;
+ char *host_buf_ptr = host_buf;
+ char *host_buf_end = host_buf + host_result;
+ while (host_buf_ptr < host_buf_end) {
+ global_dirent *host_dp = (global_dirent *)host_buf_ptr;
+ int namelen = strlen(host_dp->d_name);
+
+ // Actual size includes padded string rounded up for alignment.
+ // Subtract 256 for dummy char array in Tru64::dirent definition.
+ // Add 1 to namelen for terminating null char.
+ int tgt_bufsize = sizeof(Tru64::dirent) - 256 + roundUp(namelen+1, 8);
+ TypedBufferArg<Tru64::dirent> tgt_dp(tgt_buf_ptr, tgt_bufsize);
+ tgt_dp->d_ino = host_dp->d_ino;
+ tgt_dp->d_reclen = tgt_bufsize;
+ tgt_dp->d_namlen = namelen;
+ strcpy(tgt_dp->d_name, host_dp->d_name);
+ tgt_dp.copyOut(xc->mem);
+
+ tgt_buf_ptr += tgt_bufsize;
+ host_buf_ptr += host_dp->d_reclen;
+ }
+
+ delete [] host_buf;
+
+ *basep = htog((int64_t)host_basep);
+ basep.copyOut(xc->mem);
+
+ return tgt_buf_ptr - tgt_buf;
+#endif
+ }
+
+ /// Target sigreturn() handler.
+ static SyscallReturn
+ sigreturnFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ using TheISA::RegFile;
+ RegFile *regs = &xc->regs;
+ TypedBufferArg<Tru64::sigcontext> sc(xc->getSyscallArg(0));
+
+ sc.copyIn(xc->mem);
+
+ // Restore state from sigcontext structure.
+ // Note that we'll advance PC <- NPC before the end of the cycle,
+ // so we need to restore the desired PC into NPC.
+ // The current regs->pc will get clobbered.
+ regs->npc = htog(sc->sc_pc);
+
+ for (int i = 0; i < 31; ++i) {
+ regs->intRegFile[i] = htog(sc->sc_regs[i]);
+ regs->floatRegFile.q[i] = htog(sc->sc_fpregs[i]);
+ }
+
+ regs->miscRegs.fpcr = htog(sc->sc_fpcr);
+
+ return 0;
+ }
+
+ /// Target table() handler.
+ static SyscallReturn
+ tableFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ int id = xc->getSyscallArg(0); // table ID
+ int index = xc->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
+
+ switch (id) {
+ case Tru64::TBL_SYSINFO: {
+ if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
+ return -EINVAL;
+ TypedBufferArg<Tru64::tbl_sysinfo> elp(xc->getSyscallArg(2));
+
+ const int clk_hz = one_million;
+ elp->si_user = htog(curTick / (Clock::Frequency / clk_hz));
+ elp->si_nice = htog(0);
+ elp->si_sys = htog(0);
+ elp->si_idle = htog(0);
+ elp->wait = htog(0);
+ elp->si_hz = htog(clk_hz);
+ 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->mem);
+ return 0;
+ }
+
+ default:
+ cerr << "table(): id " << id << " unknown." << endl;
+ return -EINVAL;
+ }
+ }
+
+ //
+ // Mach syscalls -- identified by negated syscall numbers
+ //
+
+ /// Create a stack region for a thread.
+ static SyscallReturn
+ stack_createFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ TypedBufferArg<Tru64::vm_stack> argp(xc->getSyscallArg(0));
+
+ argp.copyIn(xc->mem);
+
+ // if the user chose an address, just let them have it. Otherwise
+ // pick one for them.
+ if (htog(argp->address) == 0) {
+ argp->address = htog(process->next_thread_stack_base);
+ int stack_size = (htog(argp->rsize) + htog(argp->ysize) +
+ htog(argp->gsize));
+ process->next_thread_stack_base -= stack_size;
+ argp.copyOut(xc->mem);
+ }
+
+ return 0;
+ }
+
+ /// NXM library version stamp.
+ static
+ const int NXM_LIB_VERSION = 301003;
+
+ /// This call sets up the interface between the user and kernel
+ /// schedulers by creating a shared-memory region. The shared memory
+ /// region has several structs, some global, some per-RAD, some per-VP.
+ static SyscallReturn
+ nxm_task_initFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ TypedBufferArg<Tru64::nxm_task_attr> attrp(xc->getSyscallArg(0));
+ TypedBufferArg<Addr> configptr_ptr(xc->getSyscallArg(1));
+
+ attrp.copyIn(xc->mem);
+
+ if (gtoh(attrp->nxm_version) != NXM_LIB_VERSION) {
+ cerr << "nxm_task_init: thread library version mismatch! "
+ << "got " << attrp->nxm_version
+ << ", expected " << NXM_LIB_VERSION << endl;
+ abort();
+ }
+
+ if (gtoh(attrp->flags) != Tru64::NXM_TASK_INIT_VP) {
+ cerr << "nxm_task_init: bad flag value " << attrp->flags
+ << " (expected " << Tru64::NXM_TASK_INIT_VP << ")" << endl;
+ abort();
+ }
+
+ const Addr base_addr = 0x12000; // was 0x3f0000000LL;
+ Addr cur_addr = base_addr; // next addresses to use
+ // first comes the config_info struct
+ Addr config_addr = cur_addr;
+ cur_addr += sizeof(Tru64::nxm_config_info);
+ // next comes the per-cpu state vector
+ Addr slot_state_addr = cur_addr;
+ int slot_state_size =
+ process->numCpus() * sizeof(Tru64::nxm_slot_state_t);
+ cur_addr += slot_state_size;
+ // now the per-RAD state struct (we only support one RAD)
+ cur_addr = 0x14000; // bump up addr for alignment
+ Addr rad_state_addr = cur_addr;
+ int rad_state_size =
+ (sizeof(Tru64::nxm_shared)
+ + (process->numCpus()-1) * sizeof(Tru64::nxm_sched_state));
+ cur_addr += rad_state_size;
+
+ // now initialize a config_info struct and copy it out to user space
+ TypedBufferArg<Tru64::nxm_config_info> config(config_addr);
+
+ config->nxm_nslots_per_rad = htog(process->numCpus());
+ config->nxm_nrads = htog(1); // only one RAD in our system!
+ config->nxm_slot_state = htog(slot_state_addr);
+ config->nxm_rad[0] = htog(rad_state_addr);
+
+ config.copyOut(xc->mem);
+
+ // initialize the slot_state array and copy it out
+ TypedBufferArg<Tru64::nxm_slot_state_t> slot_state(slot_state_addr,
+ slot_state_size);
+ for (int i = 0; i < process->numCpus(); ++i) {
+ // CPU 0 is bound to the calling process; all others are available
+ // XXX this code should have an endian conversion, but I don't think
+ // it works anyway
+ slot_state[i] =
+ (i == 0) ? Tru64::NXM_SLOT_BOUND : Tru64::NXM_SLOT_AVAIL;
+ }
+
+ slot_state.copyOut(xc->mem);
+
+ // same for the per-RAD "shared" struct. Note that we need to
+ // allocate extra bytes for the per-VP array which is embedded at
+ // the end.
+ TypedBufferArg<Tru64::nxm_shared> rad_state(rad_state_addr,
+ rad_state_size);
+
+ rad_state->nxm_callback = attrp->nxm_callback;
+ rad_state->nxm_version = attrp->nxm_version;
+ rad_state->nxm_uniq_offset = attrp->nxm_uniq_offset;
+ for (int i = 0; i < process->numCpus(); ++i) {
+ Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[i];
+ ssp->nxm_u.sigmask = htog(0);
+ ssp->nxm_u.sig = htog(0);
+ ssp->nxm_u.flags = htog(0);
+ ssp->nxm_u.cancel_state = htog(0);
+ ssp->nxm_u.nxm_ssig = 0;
+ ssp->nxm_bits = htog(0);
+ ssp->nxm_quantum = attrp->nxm_quantum;
+ ssp->nxm_set_quantum = attrp->nxm_quantum;
+ ssp->nxm_sysevent = htog(0);
+
+ if (i == 0) {
+ uint64_t uniq = xc->regs.miscRegs.uniq;
+ ssp->nxm_u.pth_id = htog(uniq + gtoh(attrp->nxm_uniq_offset));
+ ssp->nxm_u.nxm_active = htog(uniq | 1);
+ }
+ else {
+ ssp->nxm_u.pth_id = htog(0);
+ ssp->nxm_u.nxm_active = htog(0);
+ }
+ }
+
+ rad_state.copyOut(xc->mem);
+
+ //
+ // copy pointer to shared config area out to user
+ //
+ *configptr_ptr = htog(config_addr);
+ configptr_ptr.copyOut(xc->mem);
+
+ // Register this as a valid address range with the process
+ process->nxm_start = base_addr;
+ process->nxm_end = cur_addr;
+
+ return 0;
+ }
+
+ /// Initialize execution context.
+ static void
+ init_exec_context(ExecContext *ec,
+ Tru64::nxm_thread_attr *attrp, uint64_t uniq_val)
+ {
+ memset(&ec->regs, 0, sizeof(ec->regs));
+
+ ec->regs.intRegFile[TheISA::ArgumentReg0] = gtoh(attrp->registers.a0);
+ ec->regs.intRegFile[27/*t12*/] = gtoh(attrp->registers.pc);
+ ec->regs.intRegFile[TheISA::StackPointerReg] = gtoh(attrp->registers.sp);
+ ec->regs.miscRegs.uniq = uniq_val;
+
+ ec->regs.pc = gtoh(attrp->registers.pc);
+ ec->regs.npc = gtoh(attrp->registers.pc) + sizeof(TheISA::MachInst);
+
+ ec->activate();
+ }
+
+ /// Create thread.
+ static SyscallReturn
+ nxm_thread_createFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ TypedBufferArg<Tru64::nxm_thread_attr> attrp(xc->getSyscallArg(0));
+ TypedBufferArg<uint64_t> kidp(xc->getSyscallArg(1));
+ int thread_index = xc->getSyscallArg(2);
+
+ // get attribute args
+ attrp.copyIn(xc->mem);
+
+ if (gtoh(attrp->version) != NXM_LIB_VERSION) {
+ cerr << "nxm_thread_create: thread library version mismatch! "
+ << "got " << attrp->version
+ << ", expected " << NXM_LIB_VERSION << endl;
+ abort();
+ }
+
+ if (thread_index < 0 | thread_index > process->numCpus()) {
+ cerr << "nxm_thread_create: bad thread index " << thread_index
+ << endl;
+ abort();
+ }
+
+ // On a real machine, the per-RAD shared structure is in
+ // shared memory, so both the user and kernel can get at it.
+ // We don't have that luxury, so we just copy it in and then
+ // back out again.
+ int rad_state_size =
+ (sizeof(Tru64::nxm_shared) +
+ (process->numCpus()-1) * sizeof(Tru64::nxm_sched_state));
+
+ TypedBufferArg<Tru64::nxm_shared> rad_state(0x14000,
+ rad_state_size);
+ rad_state.copyIn(xc->mem);
+
+ uint64_t uniq_val = gtoh(attrp->pthid) - gtoh(rad_state->nxm_uniq_offset);
+
+ if (gtoh(attrp->type) == Tru64::NXM_TYPE_MANAGER) {
+ // DEC pthreads seems to always create one of these (in
+ // addition to N application threads), but we don't use it,
+ // so don't bother creating it.
+
+ // This is supposed to be a port number. Make something up.
+ *kidp = htog(99);
+ kidp.copyOut(xc->mem);
+
+ return 0;
+ } else if (gtoh(attrp->type) == Tru64::NXM_TYPE_VP) {
+ // A real "virtual processor" kernel thread. Need to fork
+ // this thread on another CPU.
+ Tru64::nxm_sched_state *ssp = &rad_state->nxm_ss[thread_index];
+
+ if (gtoh(ssp->nxm_u.nxm_active) != 0)
+ return (int) Tru64::KERN_NOT_RECEIVER;
+
+ ssp->nxm_u.pth_id = attrp->pthid;
+ ssp->nxm_u.nxm_active = htog(uniq_val | 1);
+
+ rad_state.copyOut(xc->mem);
+
+ Addr slot_state_addr = 0x12000 + sizeof(Tru64::nxm_config_info);
+ int slot_state_size =
+ process->numCpus() * sizeof(Tru64::nxm_slot_state_t);
+
+ TypedBufferArg<Tru64::nxm_slot_state_t>
+ slot_state(slot_state_addr,
+ slot_state_size);
+
+ slot_state.copyIn(xc->mem);
+
+ if (slot_state[thread_index] != Tru64::NXM_SLOT_AVAIL) {
+ cerr << "nxm_thread_createFunc: requested VP slot "
+ << thread_index << " not available!" << endl;
+ fatal("");
+ }
+
+ // XXX This should have an endian conversion but I think this code
+ // doesn't work anyway
+ slot_state[thread_index] = Tru64::NXM_SLOT_BOUND;
+
+ slot_state.copyOut(xc->mem);
+
+ // Find a free simulator execution context.
+ for (int i = 0; i < process->numCpus(); ++i) {
+ ExecContext *xc = process->execContexts[i];
+
+ if (xc->status() == ExecContext::Unallocated) {
+ // inactive context... grab it
+ init_exec_context(xc, attrp, uniq_val);
+
+ // This is supposed to be a port number, but we'll try
+ // and get away with just sticking the thread index
+ // here.
+ *kidp = htog(thread_index);
+ kidp.copyOut(xc->mem);
+
+ return 0;
+ }
+ }
+
+ // fell out of loop... no available inactive context
+ cerr << "nxm_thread_create: no idle contexts available." << endl;
+ abort();
+ } else {
+ cerr << "nxm_thread_create: can't handle thread type "
+ << attrp->type << endl;
+ abort();
+ }
+
+ return 0;
+ }
+
+ /// Thread idle call (like yield()).
+ static SyscallReturn
+ nxm_idleFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ return 0;
+ }
+
+ /// Block thread.
+ static SyscallReturn
+ nxm_thread_blockFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ uint64_t tid = xc->getSyscallArg(0);
+ uint64_t secs = xc->getSyscallArg(1);
+ uint64_t flags = xc->getSyscallArg(2);
+ uint64_t action = xc->getSyscallArg(3);
+ uint64_t usecs = xc->getSyscallArg(4);
+
+ cout << xc->cpu->name() << ": nxm_thread_block " << tid << " " << secs
+ << " " << flags << " " << action << " " << usecs << endl;
+
+ return 0;
+ }
+
+ /// block.
+ static SyscallReturn
+ nxm_blockFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr uaddr = xc->getSyscallArg(0);
+ uint64_t val = xc->getSyscallArg(1);
+ uint64_t secs = xc->getSyscallArg(2);
+ uint64_t usecs = xc->getSyscallArg(3);
+ uint64_t flags = xc->getSyscallArg(4);
+
+ BaseCPU *cpu = xc->cpu;
+
+ cout << cpu->name() << ": nxm_block "
+ << hex << uaddr << dec << " " << val
+ << " " << secs << " " << usecs
+ << " " << flags << endl;
+
+ return 0;
+ }
+
+ /// Unblock thread.
+ static SyscallReturn
+ nxm_unblockFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr uaddr = xc->getSyscallArg(0);
+
+ cout << xc->cpu->name() << ": nxm_unblock "
+ << hex << uaddr << dec << endl;
+
+ return 0;
+ }
+
+ /// Switch thread priority.
+ static SyscallReturn
+ swtch_priFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ // Attempts to switch to another runnable thread (if there is
+ // one). Returns false if there are no other threads to run
+ // (i.e., the thread can reasonably spin-wait) or true if there
+ // are other threads.
+ //
+ // Since we assume at most one "kernel" thread per CPU, it's
+ // always safe to return false here.
+ return 0; //false;
+ }
+
+
+ /// Activate exec context waiting on a channel. Just activate one
+ /// by default.
+ static int
+ activate_waiting_context(Addr uaddr, Process *process,
+ bool activate_all = false)
+ {
+ int num_activated = 0;
+
+ list<Process::WaitRec>::iterator i = process->waitList.begin();
+ list<Process::WaitRec>::iterator end = process->waitList.end();
+
+ while (i != end && (num_activated == 0 || activate_all)) {
+ if (i->waitChan == uaddr) {
+ // found waiting process: make it active
+ ExecContext *newCtx = i->waitingContext;
+ assert(newCtx->status() == ExecContext::Suspended);
+ newCtx->activate();
+
+ // get rid of this record
+ i = process->waitList.erase(i);
+
+ ++num_activated;
+ } else {
+ ++i;
+ }
+ }
+
+ return num_activated;
+ }
+
+ /// M5 hacked-up lock acquire.
+ static void
+ m5_lock_mutex(Addr uaddr, Process *process, ExecContext *xc)
+ {
+ TypedBufferArg<uint64_t> lockp(uaddr);
+
+ lockp.copyIn(xc->mem);
+
+ if (gtoh(*lockp) == 0) {
+ // lock is free: grab it
+ *lockp = htog(1);
+ lockp.copyOut(xc->mem);
+ } else {
+ // lock is busy: disable until free
+ process->waitList.push_back(Process::WaitRec(uaddr, xc));
+ xc->suspend();
+ }
+ }
+
+ /// M5 unlock call.
+ static void
+ m5_unlock_mutex(Addr uaddr, Process *process, ExecContext *xc)
+ {
+ TypedBufferArg<uint64_t> lockp(uaddr);
+
+ lockp.copyIn(xc->mem);
+ assert(*lockp != 0);
+
+ // Check for a process waiting on the lock.
+ int num_waiting = activate_waiting_context(uaddr, process);
+
+ // clear lock field if no waiting context is taking over the lock
+ if (num_waiting == 0) {
+ *lockp = 0;
+ lockp.copyOut(xc->mem);
+ }
+ }
+
+ /// Lock acquire syscall handler.
+ static SyscallReturn
+ m5_mutex_lockFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr uaddr = xc->getSyscallArg(0);
+
+ m5_lock_mutex(uaddr, process, xc);
+
+ // Return 0 since we will always return to the user with the lock
+ // acquired. We will just keep the context inactive until that is
+ // true.
+ return 0;
+ }
+
+ /// Try lock (non-blocking).
+ static SyscallReturn
+ m5_mutex_trylockFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr uaddr = xc->getSyscallArg(0);
+ TypedBufferArg<uint64_t> lockp(uaddr);
+
+ lockp.copyIn(xc->mem);
+
+ if (gtoh(*lockp) == 0) {
+ // lock is free: grab it
+ *lockp = htog(1);
+ lockp.copyOut(xc->mem);
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+
+ /// Unlock syscall handler.
+ static SyscallReturn
+ m5_mutex_unlockFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr uaddr = xc->getSyscallArg(0);
+
+ m5_unlock_mutex(uaddr, process, xc);
+
+ return 0;
+ }
+
+ /// Signal ocndition.
+ static SyscallReturn
+ m5_cond_signalFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr cond_addr = xc->getSyscallArg(0);
+
+ // Wake up one process waiting on the condition variable.
+ activate_waiting_context(cond_addr, process);
+
+ return 0;
+ }
+
+ /// Wake up all processes waiting on the condition variable.
+ static SyscallReturn
+ m5_cond_broadcastFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr cond_addr = xc->getSyscallArg(0);
+
+ activate_waiting_context(cond_addr, process, true);
+
+ return 0;
+ }
+
+ /// Wait on a condition.
+ static SyscallReturn
+ m5_cond_waitFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr cond_addr = xc->getSyscallArg(0);
+ Addr lock_addr = xc->getSyscallArg(1);
+ TypedBufferArg<uint64_t> condp(cond_addr);
+ TypedBufferArg<uint64_t> lockp(lock_addr);
+
+ // user is supposed to acquire lock before entering
+ lockp.copyIn(xc->mem);
+ assert(gtoh(*lockp) != 0);
+
+ m5_unlock_mutex(lock_addr, process, xc);
+
+ process->waitList.push_back(Process::WaitRec(cond_addr, xc));
+ xc->suspend();
+
+ return 0;
+ }
+
+ /// Thread exit.
+ static SyscallReturn
+ m5_thread_exitFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ assert(xc->status() == ExecContext::Active);
+ xc->deallocate();
+
+ return 0;
+ }
+
+ /// Indirect syscall invocation (call #0).
+ static SyscallReturn
+ indirectSyscallFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ int new_callnum = xc->getSyscallArg(0);
+ LiveProcess *lp = dynamic_cast<LiveProcess*>(process);
+ assert(lp);
+
+ for (int i = 0; i < 5; ++i)
+ xc->setSyscallArg(i, xc->getSyscallArg(i+1));
+
+
+ SyscallDesc *new_desc = lp->getDesc(new_callnum);
+ if (desc == NULL)
+ fatal("Syscall %d out of range", callnum);
+
+ new_desc->doSyscall(new_callnum, process, xc);
+
+ return 0;
+ }
+
+}; // class Tru64
+
+
+#endif // FULL_SYSTEM
+
#endif // __TRU64_HH__
diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc
index d769aab0f..2fe6a2dc4 100644
--- a/kern/tru64/tru64_events.cc
+++ b/kern/tru64/tru64_events.cc
@@ -36,6 +36,8 @@
#include "targetarch/arguments.hh"
#include "arch/isa_traits.hh"
+using namespace TheISA;
+
//void SkipFuncEvent::process(ExecContext *xc);
void
diff --git a/python/m5/objects/Ethernet.py b/python/m5/objects/Ethernet.py
index f58ece0be..3a7f88d04 100644
--- a/python/m5/objects/Ethernet.py
+++ b/python/m5/objects/Ethernet.py
@@ -76,7 +76,6 @@ class EtherDevBase(PciDevice):
dma_write_delay = Param.Latency('0us', "fixed delay for dma writes")
dma_write_factor = Param.Latency('0us', "multiplier for dma writes")
dma_no_allocate = Param.Bool(True, "Should we allocate cache on read")
- pio_delay_write = Param.Bool(False, "Delay pio writes until timing occurs")
rx_delay = Param.Latency('1us', "Receive Delay")
tx_delay = Param.Latency('1us', "Transmit Delay")
diff --git a/sim/faults.hh b/sim/faults.hh
index d9c742b90..dbec399af 100644
--- a/sim/faults.hh
+++ b/sim/faults.hh
@@ -29,30 +29,33 @@
#ifndef __FAULTS_HH__
#define __FAULTS_HH__
-class Fault
+class FaultBase;
+typedef FaultBase * Fault;
+
+class FaultBase
{
public:
- Fault(char * newName, int newId = 0) : name(newName), id(newId) {;}
+ FaultBase(char * newName, int newId = 0) : name(newName), id(newId) {;}
const char * name;
int id;
};
-extern class NoFaultType : public Fault
+extern class NoFaultType : public FaultBase
{
public:
- NoFaultType(char * newName) : Fault(newName) {;}
+ NoFaultType(char * newName) : FaultBase(newName) {;}
} * const NoFault;
-extern class MachineCheckFaultType : public Fault
+extern class MachineCheckFaultType : public FaultBase
{
public:
- MachineCheckFaultType(char * newName) : Fault(newName) {;}
+ MachineCheckFaultType(char * newName) : FaultBase(newName) {;}
} * const MachineCheckFault;
-extern class AlignmentFaultType : public Fault
+extern class AlignmentFaultType : public FaultBase
{
public:
- AlignmentFaultType(char * newName) : Fault(newName) {;}
+ AlignmentFaultType(char * newName) : FaultBase(newName) {;}
} * const AlignmentFault;
diff --git a/sim/host.hh b/sim/host.hh
index ef7008042..f7e64f23c 100644
--- a/sim/host.hh
+++ b/sim/host.hh
@@ -54,4 +54,12 @@ typedef int64_t Counter;
*/
typedef int64_t Tick;
+/**
+ * Address type
+ * This will probably be moved somewhere else in the near future.
+ * This should be at least as big as the biggest address width in use
+ * in the system, which will probably be 64 bits.
+ */
+typedef uint64_t Addr;
+
#endif // __HOST_H__
diff --git a/sim/process.cc b/sim/process.cc
index 59d122b48..0a7e46082 100644
--- a/sim/process.cc
+++ b/sim/process.cc
@@ -46,6 +46,7 @@
#include "sim/fake_syscall.hh"
#include "sim/process.hh"
#include "sim/stats.hh"
+#include "sim/syscall_emul.hh"
#ifdef TARGET_ALPHA
#include "arch/alpha/alpha_tru64_process.hh"
@@ -53,6 +54,7 @@
#endif
using namespace std;
+using namespace TheISA;
//
// The purpose of this code is to fake the loader & syscall mechanism
@@ -350,6 +352,19 @@ LiveProcess::LiveProcess(const string &nm, ObjectFile *objFile,
init_regs->npc = prog_entry + sizeof(MachInst);
}
+void
+LiveProcess::syscall(ExecContext *xc)
+{
+ num_syscalls++;
+
+ int64_t callnum = xc->regs.intRegFile[ReturnValueReg];
+
+ SyscallDesc *desc = getDesc(callnum);
+ if (desc == NULL)
+ fatal("Syscall %d out of range", callnum);
+
+ desc->doSyscall(callnum, this, xc);
+}
LiveProcess *
LiveProcess::create(const string &nm,
@@ -394,6 +409,7 @@ LiveProcess::create(const string &nm,
}
+
BEGIN_DECLARE_SIM_OBJECT_PARAMS(LiveProcess)
VectorParam<string> cmd;
diff --git a/sim/process.hh b/sim/process.hh
index 43fafd9d7..71b7d02b3 100644
--- a/sim/process.hh
+++ b/sim/process.hh
@@ -48,8 +48,12 @@
class ExecContext;
class FunctionalMemory;
+class SyscallDesc;
class Process : public SimObject
{
+ protected:
+ typedef TheISA::RegFile RegFile;
+ typedef TheISA::MachInst MachInst;
public:
// have we initialized an execution context from this process? If
@@ -200,6 +204,11 @@ class LiveProcess : public Process
std::string executable,
std::vector<std::string> &argv,
std::vector<std::string> &envp);
+
+ virtual void syscall(ExecContext *xc);
+
+ virtual SyscallDesc* getDesc(int callnum) { panic("Must be implemented."); }
+
};
diff --git a/sim/pseudo_inst.cc b/sim/pseudo_inst.cc
index 11ab55f53..58ea8266f 100644
--- a/sim/pseudo_inst.cc
+++ b/sim/pseudo_inst.cc
@@ -53,6 +53,7 @@ using namespace std;
extern Sampler *SampCPU;
using namespace Stats;
+using namespace TheISA;
namespace AlphaPseudo
{
diff --git a/sim/syscall_emul.cc b/sim/syscall_emul.cc
index 0fac43fc5..d22dde3b8 100644
--- a/sim/syscall_emul.cc
+++ b/sim/syscall_emul.cc
@@ -26,6 +26,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <fcntl.h>
#include <unistd.h>
#include <string>
@@ -40,6 +41,7 @@
#include "sim/sim_events.hh"
using namespace std;
+using namespace TheISA;
void
SyscallDesc::doSyscall(int callnum, Process *process, ExecContext *xc)
@@ -89,7 +91,7 @@ exitFunc(SyscallDesc *desc, int callnum, Process *process,
SyscallReturn
getpagesizeFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
{
- return VMPageSize;
+ return (int)VMPageSize;
}
@@ -278,3 +280,48 @@ fchownFunc(SyscallDesc *desc, int num, Process *process, ExecContext *xc)
int result = fchown(fd, hostOwner, hostGroup);
return (result == -1) ? -errno : result;
}
+
+
+SyscallReturn
+fcntlFunc(SyscallDesc *desc, int num, Process *process,
+ ExecContext *xc)
+{
+ int fd = xc->getSyscallArg(0);
+
+ if (fd < 0 || process->sim_fd(fd) < 0)
+ return -EBADF;
+
+ int cmd = xc->getSyscallArg(1);
+ switch (cmd) {
+ case 0: // F_DUPFD
+ // if we really wanted to support this, we'd need to do it
+ // in the target fd space.
+ warn("fcntl(%d, F_DUPFD) not supported, error returned\n", fd);
+ return -EMFILE;
+
+ case 1: // F_GETFD (get close-on-exec flag)
+ case 2: // F_SETFD (set close-on-exec flag)
+ return 0;
+
+ case 3: // F_GETFL (get file flags)
+ case 4: // F_SETFL (set file flags)
+ // not sure if this is totally valid, but we'll pass it through
+ // to the underlying OS
+ warn("fcntl(%d, %d) passed through to host\n", fd, cmd);
+ return fcntl(process->sim_fd(fd), cmd);
+ // return 0;
+
+ case 7: // F_GETLK (get lock)
+ case 8: // F_SETLK (set lock)
+ case 9: // F_SETLKW (set lock and wait)
+ // don't mess with file locking... just act like it's OK
+ warn("File lock call (fcntl(%d, %d)) ignored.\n", fd, cmd);
+ return 0;
+
+ default:
+ warn("Unknown fcntl command %d\n", cmd);
+ return 0;
+ }
+}
+
+
diff --git a/sim/syscall_emul.hh b/sim/syscall_emul.hh
index 739cd20e5..f49248dea 100644
--- a/sim/syscall_emul.hh
+++ b/sim/syscall_emul.hh
@@ -239,6 +239,10 @@ SyscallReturn chownFunc(SyscallDesc *desc, int num,
SyscallReturn fchownFunc(SyscallDesc *desc, int num,
Process *p, ExecContext *xc);
+/// Target fnctl() handler.
+SyscallReturn fcntlFunc(SyscallDesc *desc, int num,
+ Process *process, ExecContext *xc);
+
/// This struct is used to build an target-OS-dependent table that
/// maps the target's open() flags to the host open() flags.
struct OpenFlagTransTable {
@@ -646,7 +650,7 @@ mmapFunc(SyscallDesc *desc, int num, Process *p, ExecContext *xc)
if (start == 0) {
// user didn't give an address... pick one from our "mmap region"
start = p->mmap_end;
- p->mmap_end += roundUp(length, VMPageSize);
+ p->mmap_end += roundUp(length, TheISA::VMPageSize);
if (p->nxm_start != 0) {
//If we have an nxm space, make sure we haven't colided
assert(p->mmap_end < p->nxm_start);
diff --git a/sim/system.cc b/sim/system.cc
index 990145826..41de8cee4 100644
--- a/sim/system.cc
+++ b/sim/system.cc
@@ -41,6 +41,7 @@
#include "base/trace.hh"
using namespace std;
+using namespace TheISA;
vector<System *> System::systemList;
@@ -306,11 +307,9 @@ System::registerExecContext(ExecContext *xc, int id)
void
System::startup()
{
- if (!execContexts.empty()) {
- // activate with zero delay so that we start ticking right
- // away on cycle 0
- execContexts[0]->activate(0);
- }
+ int i;
+ for (i = 0; i < execContexts.size(); i++)
+ execContexts[i]->activate(0);
}
void
diff --git a/util/pbs/jobfile.py b/util/pbs/jobfile.py
index d36b5ee6d..fd19b3bf5 100644
--- a/util/pbs/jobfile.py
+++ b/util/pbs/jobfile.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2005 The Regents of The University of Michigan
+# Copyright (c) 2005-2006 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -277,10 +277,11 @@ class Option(Data):
return name
if attr == 'desc':
- desc = self.__dict__[attr]
- if self._suboption is not None:
- desc = '%s, %s' % (desc, self._suboption.desc)
- return desc
+ desc = [ self.__dict__[attr] ]
+ if self._suboption is not None and self._suboption.desc:
+ desc.append(self._suboption.desc)
+ return ', '.join(desc)
+
return super(Option, self).__getattribute__(attr)
@@ -356,6 +357,8 @@ class Configuration(Data):
def __init__(self, name, desc, **kwargs):
super(Configuration, self).__init__(name, desc, **kwargs)
self._groups = []
+ self._posfilters = []
+ self._negfilters = []
def group(self, name, desc, **kwargs):
grp = Group(name, desc, **kwargs)
@@ -402,13 +405,39 @@ class Configuration(Data):
if checkpoint:
yield options
+ def addfilter(self, filt, pos=True):
+ import re
+ filt = re.compile(filt)
+ if pos:
+ self._posfilters.append(filt)
+ else:
+ self._negfilters.append(filt)
+
+ def jobfilter(self, job):
+ for filt in self._negfilters:
+ if filt.match(job.name):
+ return False
+
+ if not self._posfilters:
+ return True
+
+ for filt in self._posfilters:
+ if filt.match(job.name):
+ return True
+
+ return False
+
def checkpoints(self, groups = None):
for options in self.options(groups, True):
- yield Job(options)
+ job = Job(options)
+ if self.jobfilter(job):
+ yield job
def jobs(self, groups = None):
for options in self.options(groups, False):
- yield Job(options)
+ job = Job(options)
+ if self.jobfilter(job):
+ yield job
def alljobs(self, groups = None):
for options in self.options(groups, True):