diff options
Diffstat (limited to 'arch/alpha')
-rw-r--r-- | arch/alpha/SConscript | 450 | ||||
-rw-r--r-- | arch/alpha/alpha_linux_process.cc | 602 | ||||
-rw-r--r-- | arch/alpha/alpha_linux_process.hh | 11 | ||||
-rw-r--r-- | arch/alpha/alpha_memory.cc | 34 | ||||
-rw-r--r-- | arch/alpha/alpha_memory.hh | 1 | ||||
-rw-r--r-- | arch/alpha/alpha_tru64_process.cc | 1680 | ||||
-rw-r--r-- | arch/alpha/alpha_tru64_process.hh | 12 | ||||
-rw-r--r-- | arch/alpha/arguments.cc | 2 | ||||
-rw-r--r-- | arch/alpha/ev5.hh | 4 | ||||
-rw-r--r-- | arch/alpha/faults.cc | 77 | ||||
-rw-r--r-- | arch/alpha/faults.hh | 153 | ||||
-rw-r--r-- | arch/alpha/isa/branch.isa | 4 | ||||
-rw-r--r-- | arch/alpha/isa/decoder.isa | 26 | ||||
-rw-r--r-- | arch/alpha/isa/fp.isa | 18 | ||||
-rw-r--r-- | arch/alpha/isa/main.isa | 37 | ||||
-rw-r--r-- | arch/alpha/isa/mem.isa | 239 | ||||
-rw-r--r-- | arch/alpha/isa/pal.isa | 8 | ||||
-rw-r--r-- | arch/alpha/isa/unimp.isa | 4 | ||||
-rw-r--r-- | arch/alpha/isa/unknown.isa | 2 | ||||
-rw-r--r-- | arch/alpha/isa_traits.hh | 100 | ||||
-rw-r--r-- | arch/alpha/stacktrace.cc | 3 | ||||
-rw-r--r-- | arch/alpha/stacktrace.hh | 8 | ||||
-rw-r--r-- | arch/alpha/vtophys.cc | 1 |
23 files changed, 805 insertions, 2671 deletions
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 8dda4d9c4..d00186d95 100644 --- a/arch/alpha/alpha_memory.cc +++ b/arch/alpha/alpha_memory.cc @@ -312,7 +312,7 @@ AlphaITB::translate(MemReqPtr &req) const // strip off PAL PC marker (lsb is 1) req->paddr = (req->vaddr & ~3) & PAddrImplMask; hits++; - return No_Fault; + return NoFault; } if (req->flags & PHYSICAL) { @@ -322,7 +322,7 @@ AlphaITB::translate(MemReqPtr &req) const if (!validVirtualAddress(req->vaddr)) { fault(req->vaddr, req->xc); acv++; - return ITB_Acv_Fault; + return ItbAcvFault; } @@ -339,7 +339,7 @@ AlphaITB::translate(MemReqPtr &req) const AlphaISA::mode_kernel) { fault(req->vaddr, req->xc); acv++; - return ITB_Acv_Fault; + return ItbAcvFault; } req->paddr = req->vaddr & PAddrImplMask; @@ -360,7 +360,7 @@ AlphaITB::translate(MemReqPtr &req) const if (!pte) { fault(req->vaddr, req->xc); misses++; - return ITB_Fault_Fault; + return ItbPageFault; } req->paddr = (pte->ppn << AlphaISA::PageShift) + @@ -371,7 +371,7 @@ AlphaITB::translate(MemReqPtr &req) const // instruction access fault fault(req->vaddr, req->xc); acv++; - return ITB_Acv_Fault; + return ItbAcvFault; } hits++; @@ -380,11 +380,11 @@ AlphaITB::translate(MemReqPtr &req) const // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) - return Machine_Check_Fault; + return MachineCheckFault; checkCacheability(req); - return No_Fault; + return NoFault; } /////////////////////////////////////////////////////////////////////// @@ -511,7 +511,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, write ? MM_STAT_WR_MASK : 0); DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr, req->size); - return Alignment_Fault; + return AlignmentFault; } if (pc & 0x1) { @@ -530,7 +530,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const MM_STAT_ACV_MASK); if (write) { write_acv++; } else { read_acv++; } - return DTB_Fault_Fault; + return DtbPageFault; } // Check for "superpage" mapping @@ -547,7 +547,7 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const fault(req, ((write ? MM_STAT_WR_MASK : 0) | MM_STAT_ACV_MASK)); if (write) { write_acv++; } else { read_acv++; } - return DTB_Acv_Fault; + return DtbAcvFault; } req->paddr = req->vaddr & PAddrImplMask; @@ -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) ? Pdtb_Miss_Fault : Ndtb_Miss_Fault; + return (req->flags & VPTE) ? (Fault)PDtbMissFault : (Fault)NDtbMissFault; } req->paddr = (pte->ppn << AlphaISA::PageShift) + @@ -588,25 +588,25 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const MM_STAT_ACV_MASK | (pte->fonw ? MM_STAT_FONW_MASK : 0)); write_acv++; - return DTB_Fault_Fault; + return DtbPageFault; } if (pte->fonw) { fault(req, MM_STAT_WR_MASK | MM_STAT_FONW_MASK); write_acv++; - return DTB_Fault_Fault; + return DtbPageFault; } } else { if (!(pte->xre & MODE2MASK(mode))) { fault(req, MM_STAT_ACV_MASK | (pte->fonr ? MM_STAT_FONR_MASK : 0)); read_acv++; - return DTB_Acv_Fault; + return DtbAcvFault; } if (pte->fonr) { fault(req, MM_STAT_FONR_MASK); read_acv++; - return DTB_Fault_Fault; + return DtbPageFault; } } } @@ -619,11 +619,11 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const // check that the physical address is ok (catch bad physical addresses) if (req->paddr & ~PAddrImplMask) - return Machine_Check_Fault; + return MachineCheckFault; checkCacheability(req); - return No_Fault; + return NoFault; } AlphaISA::PTE & diff --git a/arch/alpha/alpha_memory.hh b/arch/alpha/alpha_memory.hh index 788923434..de955fa46 100644 --- a/arch/alpha/alpha_memory.hh +++ b/arch/alpha/alpha_memory.hh @@ -32,6 +32,7 @@ #include <map> #include "arch/alpha/isa_traits.hh" +#include "arch/alpha/faults.hh" #include "base/statistics.hh" #include "mem/mem_req.hh" #include "sim/sim_object.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.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 3aecf029d..fa4950198 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -28,34 +28,53 @@ #include "arch/alpha/faults.hh" -namespace { - const char * - fault_name[Num_Faults] = { - "none", - "reset", - "mchk", - "arith", - "interrupt", - "dtb_miss_single", - "dtb_miss_double", - "unalign", - "dfault", - "dfault", - "itbmiss", - "itbmiss", - "iaccvio", - "opdec", - "fen", - "pal", - }; -} +ResetFaultType * const ResetFault = + new ResetFaultType("reset", 1, 0x0001); +ArithmeticFaultType * const ArithmeticFault = + new ArithmeticFaultType("arith", 3, 0x0501); +InterruptFaultType * const InterruptFault = + new InterruptFaultType("interrupt", 4, 0x0101); +NDtbMissFaultType * const NDtbMissFault = + new NDtbMissFaultType("dtb_miss_single", 5, 0x0201); +PDtbMissFaultType * const PDtbMissFault = + new PDtbMissFaultType("dtb_miss_double", 6, 0x0281); +DtbPageFaultType * const DtbPageFault = + new DtbPageFaultType("dfault", 8, 0x0381); +DtbAcvFaultType * const DtbAcvFault = + new DtbAcvFaultType("dfault", 9, 0x0381); +ItbMissFaultType * const ItbMissFault = + new ItbMissFaultType("itbmiss", 10, 0x0181); +ItbPageFaultType * const ItbPageFault = + new ItbPageFaultType("itbmiss", 11, 0x0181); +ItbAcvFaultType * const ItbAcvFault = + new ItbAcvFaultType("iaccvio", 12, 0x0081); +UnimplementedOpcodeFaultType * const UnimplementedOpcodeFault = + new UnimplementedOpcodeFaultType("opdec", 13, 0x0481); +FloatEnableFaultType * const FloatEnableFault = + new FloatEnableFaultType("fen", 14, 0x0581); +PalFaultType * const PalFault = + new PalFaultType("pal", 15, 0x2001); +IntegerOverflowFaultType * const IntegerOverflowFault = + new IntegerOverflowFaultType("intover", 16, 0x0501); -const char * -FaultName(int index) -{ - if (index < 0 || index >= Num_Faults) - return 0; - - return fault_name[index]; -} +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 *); diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index bbac7cbf2..3e25adc4e 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -26,32 +26,135 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __FAULTS_HH__ -#define __FAULTS_HH__ - -enum Fault { - No_Fault, - Reset_Fault, // processor reset - Machine_Check_Fault, // machine check (also internal S/W fault) - Arithmetic_Fault, // FP exception - Interrupt_Fault, // external interrupt - Ndtb_Miss_Fault, // DTB miss - Pdtb_Miss_Fault, // nested DTB miss - Alignment_Fault, // unaligned access - DTB_Fault_Fault, // DTB page fault - DTB_Acv_Fault, // DTB access violation - ITB_Miss_Fault, // ITB miss - ITB_Fault_Fault, // ITB page fault - ITB_Acv_Fault, // ITB access violation - Unimplemented_Opcode_Fault, // invalid/unimplemented instruction - Fen_Fault, // FP not-enabled fault - Pal_Fault, // call_pal S/W interrupt - Integer_Overflow_Fault, - Fake_Mem_Fault, - Num_Faults // number of faults +#ifndef __ALPHA_FAULTS_HH__ +#define __ALPHA_FAULTS_HH__ + +#include "sim/faults.hh" +#include "arch/isa_traits.hh" //For the Addr type + +class AlphaFault : public FaultBase +{ + public: + AlphaFault(char * newName, int newId, Addr newVect) + : FaultBase(newName, newId), vect(newVect) + {;} + + Addr vect; }; -const char * -FaultName(int index); +extern class ResetFaultType : public AlphaFault +{ + public: + ResetFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ResetFault; + +extern class ArithmeticFaultType : public AlphaFault +{ + public: + ArithmeticFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ArithmeticFault; + +extern class InterruptFaultType : public AlphaFault +{ + public: + InterruptFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const InterruptFault; + +extern class NDtbMissFaultType : public AlphaFault +{ + public: + NDtbMissFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const NDtbMissFault; + +extern class PDtbMissFaultType : public AlphaFault +{ + public: + PDtbMissFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const PDtbMissFault; + +extern class DtbPageFaultType : public AlphaFault +{ + public: + DtbPageFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const DtbPageFault; + +extern class DtbAcvFaultType : public AlphaFault +{ + public: + DtbAcvFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const DtbAcvFault; + +extern class ItbMissFaultType : public AlphaFault +{ + public: + ItbMissFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ItbMissFault; + +extern class ItbPageFaultType : public AlphaFault +{ + public: + ItbPageFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ItbPageFault; + +extern class ItbAcvFaultType : public AlphaFault +{ + public: + ItbAcvFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const ItbAcvFault; + +extern class UnimplementedOpcodeFaultType : public AlphaFault +{ + public: + UnimplementedOpcodeFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const UnimplementedOpcodeFault; + +extern class FloatEnableFaultType : public AlphaFault +{ + public: + FloatEnableFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const FloatEnableFault; + +extern class PalFaultType : public AlphaFault +{ + public: + PalFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const PalFault; + +extern class IntegerOverflowFaultType : public AlphaFault +{ + public: + IntegerOverflowFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const IntegerOverflowFault; + +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/decoder.isa b/arch/alpha/isa/decoder.isa index aff8571e9..37b15416b 100644 --- a/arch/alpha/isa/decoder.isa +++ b/arch/alpha/isa/decoder.isa @@ -98,7 +98,7 @@ decode OPCODE default Unknown::unknown() { // signed overflow occurs when operands have same sign // and sign of result does not match. if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc.sl = tmp; }}); 0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }}); @@ -110,7 +110,7 @@ decode OPCODE default Unknown::unknown() { // signed overflow occurs when operands have same sign // and sign of result does not match. if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc = tmp; }}); 0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }}); @@ -124,7 +124,7 @@ decode OPCODE default Unknown::unknown() { // sign bit of the subtrahend (Rb), i.e., if the initial // signs are the *same* then no overflow can occur if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc.sl = tmp; }}); 0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }}); @@ -138,7 +138,7 @@ decode OPCODE default Unknown::unknown() { // sign bit of the subtrahend (Rb), i.e., if the initial // signs are the *same* then no overflow can occur if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc = tmp; }}); 0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }}); @@ -299,7 +299,7 @@ decode OPCODE default Unknown::unknown() { // checking the upper 33 bits for all 0s or all 1s. uint64_t sign_bits = tmp<63:31>; if (sign_bits != 0 && sign_bits != mask(33)) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc.sl = tmp<31:0>; }}, IntMultOp); 0x60: mulqv({{ @@ -310,7 +310,7 @@ decode OPCODE default Unknown::unknown() { // the lower 64 if (!((hi == 0 && lo<63:> == 0) || (hi == mask(64) && lo<63:> == 1))) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Rc = lo; }}, IntMultOp); } @@ -427,19 +427,19 @@ decode OPCODE default Unknown::unknown() { #if SS_COMPATIBLE_FP 0x0b: sqrts({{ if (Fb < 0.0) - fault = Arithmetic_Fault; + fault = ArithmeticFault; Fc = sqrt(Fb); }}, FloatSqrtOp); #else 0x0b: sqrts({{ if (Fb.sf < 0.0) - fault = Arithmetic_Fault; + fault = ArithmeticFault; Fc.sf = sqrt(Fb.sf); }}, FloatSqrtOp); #endif 0x2b: sqrtt({{ if (Fb < 0.0) - fault = Arithmetic_Fault; + fault = ArithmeticFault; Fc = sqrt(Fb); }}, FloatSqrtOp); } @@ -570,7 +570,7 @@ decode OPCODE default Unknown::unknown() { // checking the upper 33 bits for all 0s or all 1s. uint64_t sign_bits = Fb.uq<63:31>; if (sign_bits != 0 && sign_bits != mask(33)) - fault = Integer_Overflow_Fault; + fault = IntegerOverflowFault; Fc.uq = (Fb.uq<31:30> << 62) | (Fb.uq<29:0> << 29); }}); @@ -673,7 +673,7 @@ decode OPCODE default Unknown::unknown() { && xc->readIpr(AlphaISA::IPR_ICM, fault) != AlphaISA::mode_kernel)) { // invalid pal function code, or attempt to do privileged // PAL call in non-kernel mode - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; } else { // check to see if simulator wants to do something special @@ -729,7 +729,7 @@ decode OPCODE default Unknown::unknown() { 0x19: hw_mfpr({{ // this instruction is only valid in PAL mode if (!xc->inPalMode()) { - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; } else { Ra = xc->readIpr(ipr_index, fault); @@ -738,7 +738,7 @@ decode OPCODE default Unknown::unknown() { 0x1d: hw_mtpr({{ // this instruction is only valid in PAL mode if (!xc->inPalMode()) { - fault = Unimplemented_Opcode_Fault; + fault = UnimplementedOpcodeFault; } else { xc->setIpr(ipr_index, Ra); diff --git a/arch/alpha/isa/fp.isa b/arch/alpha/isa/fp.isa index 0abc814be..7e81fb830 100644 --- a/arch/alpha/isa/fp.isa +++ b/arch/alpha/isa/fp.isa @@ -29,21 +29,21 @@ output exec {{ /// Check "FP enabled" machine status bit. Called when executing any FP /// instruction in full-system mode. - /// @retval Full-system mode: No_Fault if FP is enabled, Fen_Fault - /// if not. Non-full-system mode: always returns No_Fault. + /// @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) { - Fault fault = No_Fault; // 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 = Fen_Fault; + fault = FloatEnableFault; } return fault; } #else inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc) { - return No_Fault; + return NoFault; } #endif }}; @@ -208,7 +208,7 @@ def template FloatingPointExecute {{ warnedOnTrapping = true; } - Fault fault = No_Fault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; @@ -230,7 +230,7 @@ def template FloatingPointExecute {{ %(code)s; #endif - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -251,14 +251,14 @@ def template FPFixedRoundingExecute {{ warnedOnTrapping = true; } - Fault fault = No_Fault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } diff --git a/arch/alpha/isa/main.isa b/arch/alpha/isa/main.isa index ef4d83ce2..b8d03c0be 100644 --- a/arch/alpha/isa/main.isa +++ b/arch/alpha/isa/main.isa @@ -33,6 +33,7 @@ output header {{ #include "config/ss_compatible_fp.hh" #include "cpu/static_inst.hh" +#include "arch/alpha/faults.hh" #include "mem/mem_req.hh" // some constructors use MemReq flags }}; @@ -44,6 +45,8 @@ output decoder {{ #include "cpu/exec_context.hh" // for Jump::branchTarget() #include <math.h> + +using namespace AlphaISA; }}; output exec {{ @@ -57,6 +60,8 @@ output exec {{ #include "cpu/base.hh" #include "cpu/exetrace.hh" #include "sim/sim_exit.hh" + +using namespace AlphaISA; }}; //////////////////////////////////////////////////////////////////// @@ -178,7 +183,7 @@ output header {{ /** * Base class for all Alpha static instructions. */ - class AlphaStaticInst : public StaticInst<AlphaISA> + class AlphaStaticInst : public StaticInst { protected: @@ -195,7 +200,7 @@ output header {{ /// Constructor. AlphaStaticInst(const char *mnem, MachInst _machInst, OpClass __opClass) - : StaticInst<AlphaISA>(mnem, _machInst, __opClass) + : StaticInst(mnem, _machInst, __opClass) { } @@ -285,14 +290,14 @@ def template BasicExecute {{ Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Fault fault = No_Fault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -351,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 {{ @@ -363,24 +379,13 @@ 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 Nop::execute(%(CPU_exec_context)s *, Trace::InstRecord *) const { - return No_Fault; + return NoFault; } }}; diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa index 45afd378c..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) { } @@ -164,9 +164,24 @@ def template LoadStoreDeclare {{ %(class_name)s(MachInst machInst); %(BasicExecDeclare)s + + %(InitiateAccDeclare)s + + %(CompleteAccDeclare)s }; }}; + +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 @@ -198,14 +213,14 @@ def template EACompExecute {{ Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; xc->setEA(EA); } @@ -220,19 +235,19 @@ def template LoadMemAccExecute {{ Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; EA = xc->getEA(); - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); %(code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -246,19 +261,66 @@ def template LoadExecute {{ Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(ea_code)s; - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags); %(memacc_code)s; } - if (fault == No_Fault) { + 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; } @@ -273,7 +335,7 @@ def template StoreMemAccExecute {{ Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -281,21 +343,21 @@ def template StoreMemAccExecute {{ %(op_rd)s; EA = xc->getEA(); - if (fault == No_Fault) { + if (fault == NoFault) { %(code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, memAccessFlags, &write_result); if (traceData) { traceData->setData(Mem); } } - if (fault == No_Fault) { + if (fault == NoFault) { %(postacc_code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { %(op_wb)s; } @@ -309,7 +371,7 @@ def template StoreExecute {{ Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault fault = NoFault; uint64_t write_result = 0; %(fp_enable_check)s; @@ -317,21 +379,75 @@ def template StoreExecute {{ %(op_rd)s; %(ea_code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(memacc_code)s; } - if (fault == No_Fault) { + if (fault == NoFault) { fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA, memAccessFlags, &write_result); if (traceData) { traceData->setData(Mem); } } - if (fault == No_Fault) { + if (fault == NoFault) { %(postacc_code)s; } - if (fault == No_Fault) { + 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; } @@ -345,18 +461,18 @@ def template MiscMemAccExecute {{ Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; EA = xc->getEA(); - if (fault == No_Fault) { + if (fault == NoFault) { %(code)s; } - return No_Fault; + return NoFault; } }}; @@ -365,18 +481,39 @@ def template MiscExecute {{ Trace::InstRecord *traceData) const { Addr EA; - Fault fault = No_Fault; + Fault fault = NoFault; %(fp_enable_check)s; %(op_decl)s; %(op_rd)s; %(ea_code)s; - if (fault == No_Fault) { + if (fault == NoFault) { %(memacc_code)s; } - return No_Fault; + return NoFault; + } +}}; + +def template MiscInitiateAcc {{ + Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("Misc instruction does not support split access method!"); + return NoFault; + } +}}; + + +def template MiscCompleteAcc {{ + Fault %(class_name)s::completeAcc(uint8_t *data, + %(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + panic("Misc instruction does not support split access method!"); + + return NoFault; } }}; @@ -437,6 +574,34 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, # 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) @@ -455,13 +620,17 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, # 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)) + + fullExecTemplate.subst(iop) + + initiateAccTemplate.subst(initiateacc_iop) + + completeAccTemplate.subst(completeacc_iop)) }}; 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 767888157..de4ac3eaf 100644 --- a/arch/alpha/isa/unimp.isa +++ b/arch/alpha/isa/unimp.isa @@ -111,7 +111,7 @@ output exec {{ { panic("attempt to execute unimplemented instruction '%s' " "(inst 0x%08x, opcode 0x%x)", mnemonic, machInst, OPCODE); - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } Fault @@ -123,7 +123,7 @@ output exec {{ warned = true; } - return No_Fault; + return NoFault; } }}; diff --git a/arch/alpha/isa/unknown.isa b/arch/alpha/isa/unknown.isa index 6eba5b4f9..4601b3684 100644 --- a/arch/alpha/isa/unknown.isa +++ b/arch/alpha/isa/unknown.isa @@ -42,7 +42,7 @@ output exec {{ { panic("attempt to execute unknown instruction " "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); - return Unimplemented_Opcode_Fault; + return UnimplementedOpcodeFault; } }}; diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh index a17cde49b..f47e90f86 100644 --- a/arch/alpha/isa_traits.hh +++ b/arch/alpha/isa_traits.hh @@ -32,10 +32,11 @@ namespace LittleEndianGuest {} using namespace LittleEndianGuest; -#include "arch/alpha/faults.hh" +//#include "arch/alpha/faults.hh" #include "base/misc.hh" #include "config/full_system.hh" #include "sim/host.hh" +#include "sim/faults.hh" class FastCPU; class FullCPU; @@ -43,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 { @@ -132,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 @@ -183,10 +183,10 @@ static const Addr PageOffset = PageBytes - 1; void unserialize(Checkpoint *cp, const std::string §ion); }; - 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, @@ -241,10 +241,10 @@ static const Addr PageOffset = PageBytes - 1; // Machine operations - static void saveMachineReg(AnyReg &savereg, const RegFile ®_file, + void saveMachineReg(AnyReg &savereg, const RegFile ®_file, int regnum); - static void restoreMachineReg(RegFile ®s, const AnyReg ®, + void restoreMachineReg(RegFile ®s, const AnyReg ®, int regnum); #if 0 @@ -262,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: @@ -335,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) |