Merge zizzer.eecs.umich.edu:/z/m5/Bitkeeper/m5
authorGabe Black <gblack@eecs.umich.edu>
Sun, 19 Feb 2006 08:20:05 +0000 (03:20 -0500)
committerGabe Black <gblack@eecs.umich.edu>
Sun, 19 Feb 2006 08:20:05 +0000 (03:20 -0500)
into  zizzer.eecs.umich.edu:/z/m5/Bitkeeper/multiarch

arch/alpha/faults.hh:
    ur
    Using cleaned up fault class dei\7ff\7ffinitions

--HG--
extra : convert_revision : a600950d539be2be73358f072aa5426456bf3d2d

1  2 
arch/alpha/alpha_linux_process.cc
arch/alpha/alpha_tru64_process.cc
arch/alpha/isa/mem.isa
arch/isa_parser.py
kern/kernel_stats.hh
sim/process.cc
sim/process.hh
sim/syscall_emul.cc
sim/syscall_emul.hh

index af4df7c30422138fc40cd06336f28bfe39e59e91,6d50756f2b228ddcf385b5e2ca17cec7556e0ded..783b189ccdbca133965ea96227cdf837fae5b38c
   * 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;
  
- ///
- /// 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;
-     }
-     /// 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;
+ /// 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
  
+     return 1;
+ }
  
- // 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]));
- 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),
index 49e672203d426027f34c0fd8c1b936eeae660236,e6624305cf8c59d7b2211d68c97f28411142f73a..8121d34527617fb4de9ac46c65b5dae2952951f4
  #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),
Simple merge
Simple merge
Simple merge
diff --cc sim/process.cc
Simple merge
diff --cc sim/process.hh
index f5b713e3cda5d5435f274583098334d5dc514f37,40143ea046e79ce874a084b1d9cbd66f3a1bfd6b..6e91bb0ab04d99639153c54860d4b40a760d37b7
  
  class ExecContext;
  class FunctionalMemory;
+ class SyscallDesc;
  class Process : public SimObject
  {
 +  protected:
 +    typedef TheISA::Addr Addr;
 +    typedef TheISA::RegFile RegFile;
 +    typedef TheISA::MachInst MachInst;
    public:
  
      // have we initialized an execution context from this process?  If
Simple merge
Simple merge