From 485568efa972db7fc27f34708d9bc3a2f19871de Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 16 Feb 2006 11:55:28 -0500 Subject: Fixes to handle generating the initiateAcc and completeAcc functions a little more cleanly. arch/alpha/isa/mem.isa: Avoid explicitly declaring the Mem variable. Instead break up the code blocks used to generate the initiate and complete functions. The templates reflect which operands need to be declared for each function (src, dest, or both). Loads use both the EA code and mem acc code for the initiate, and memacc code and postacc code for the complete. Stores use both the EA code and mem acc code for the initiate, and only post acc code for the complete. arch/isa_parser.py: Remove hack for mem ops. --HG-- extra : convert_revision : a367797a2cb698762bfc27be1da00bcbe9367150 --- arch/alpha/isa/mem.isa | 51 ++++++++++++++++++++++++++++++++++---------------- arch/isa_parser.py | 4 ---- 2 files changed, 35 insertions(+), 20 deletions(-) (limited to 'arch') diff --git a/arch/alpha/isa/mem.isa b/arch/alpha/isa/mem.isa index 1889daefc..37d0dcf14 100644 --- a/arch/alpha/isa/mem.isa +++ b/arch/alpha/isa/mem.isa @@ -288,7 +288,6 @@ def template LoadInitiateAcc {{ { Addr EA; Fault fault = No_Fault; - %(mem_acc_type)s Mem = 0; %(fp_enable_check)s; %(op_src_decl)s; @@ -310,9 +309,9 @@ def template LoadCompleteAcc {{ Trace::InstRecord *traceData) const { Fault fault = No_Fault; - %(mem_acc_type)s Mem = 0; %(fp_enable_check)s; + %(op_src_decl)s; %(op_dest_decl)s; memcpy(&Mem, data, sizeof(Mem)); @@ -409,10 +408,10 @@ def template StoreInitiateAcc {{ Addr EA; Fault fault = No_Fault; uint64_t write_result = 0; - %(mem_acc_type)s Mem = 0; %(fp_enable_check)s; %(op_src_decl)s; + %(op_dest_decl)s; %(op_rd)s; %(ea_code)s; @@ -501,17 +500,7 @@ def template MiscInitiateAcc {{ Fault %(class_name)s::initiateAcc(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - Addr EA; - Fault fault = No_Fault; - - %(fp_enable_check)s; - %(op_decl)s; - %(op_rd)s; - %(ea_code)s; - - if (fault == No_Fault) { - %(memacc_code)s; - } + panic("Misc instruction does not support split access method!"); return No_Fault; } @@ -523,6 +512,8 @@ def template MiscCompleteAcc {{ %(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { + panic("Misc instruction does not support split access method!"); + return No_Fault; } }}; @@ -584,6 +575,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) @@ -611,8 +630,8 @@ def LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, EACompExecute.subst(ea_iop) + memAccExecTemplate.subst(memacc_iop) + fullExecTemplate.subst(iop) - + initiateAccTemplate.subst(iop) - + completeAccTemplate.subst(iop)) + + initiateAccTemplate.subst(initiateacc_iop) + + completeAccTemplate.subst(completeacc_iop)) }}; diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 96d3e8438..bcef77ddf 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1149,10 +1149,6 @@ class Operand(object): self.constructor = self.makeConstructor() self.op_decl = self.makeDecl() - if self.isMem(): - self.is_src = '' - self.is_dest = '' - if self.is_src: self.op_rd = self.makeRead() self.op_src_decl = self.makeDecl() -- cgit v1.2.3 From d6a330ebb949b6cd63195d44e5a4304e2fd3378e Mon Sep 17 00:00:00 2001 From: Kevin Lim Date: Thu, 16 Feb 2006 14:55:15 -0500 Subject: Remove fake fault. Switch fault pointers to const pointers to prevent them from accidentally being changed. Fix some coding style. arch/alpha/ev5.cc: cpu/o3/commit_impl.hh: kern/kernel_stats.hh: Remove fake fault. arch/alpha/faults.cc: Remove fake fault, fix to have normal m5 line length limit, and change pointers to be const pointers so that the default faults aren't changed accidentally. arch/alpha/faults.hh: Fix to have normal m5 line length limit, change pointers to const pointers. sim/faults.cc: sim/faults.hh: Remove fake fault, change pointers to const pointers. --HG-- extra : convert_revision : 01d4600e0d4bdc1d177b32edebc78f86a1bbfe2e --- arch/alpha/ev5.cc | 1 - arch/alpha/faults.cc | 43 +++++++++++------- arch/alpha/faults.hh | 121 ++++++++++++++++++++++++++++++++------------------- 3 files changed, 104 insertions(+), 61 deletions(-) (limited to 'arch') diff --git a/arch/alpha/ev5.cc b/arch/alpha/ev5.cc index a48609729..72f48bfb2 100644 --- a/arch/alpha/ev5.cc +++ b/arch/alpha/ev5.cc @@ -91,7 +91,6 @@ AlphaISA::fault_addr(Fault * fault) if(fault == NoFault) return 0x0000; else if(fault == MachineCheckFault) return 0x0401; else if(fault == AlignmentFault) return 0x0301; - else if(fault == FakeMemFault) return 0x0000; //Deal with the alpha specific faults return ((AlphaFault*)fault)->vect; }; diff --git a/arch/alpha/faults.cc b/arch/alpha/faults.cc index 2dc3d9cbb..e05b3fe59 100644 --- a/arch/alpha/faults.cc +++ b/arch/alpha/faults.cc @@ -28,20 +28,34 @@ #include "arch/alpha/faults.hh" -ResetFaultType * ResetFault = new ResetFaultType("reset", 1, 0x0001); -ArithmeticFaultType * ArithmeticFault = new ArithmeticFaultType("arith", 3, 0x0501); -InterruptFaultType * InterruptFault = new InterruptFaultType("interrupt", 4, 0x0101); -NDtbMissFaultType * NDtbMissFault = new NDtbMissFaultType("dtb_miss_single", 5, 0x0201); -PDtbMissFaultType * PDtbMissFault = new PDtbMissFaultType("dtb_miss_double", 6, 0x0281); -DtbPageFaultType * DtbPageFault = new DtbPageFaultType("dfault", 8, 0x0381); -DtbAcvFaultType * DtbAcvFault = new DtbAcvFaultType("dfault", 9, 0x0381); -ItbMissFaultType * ItbMissFault = new ItbMissFaultType("itbmiss", 10, 0x0181); -ItbPageFaultType * ItbPageFault = new ItbPageFaultType("itbmiss", 11, 0x0181); -ItbAcvFaultType * ItbAcvFault = new ItbAcvFaultType("iaccvio", 12, 0x0081); -UnimplementedOpcodeFaultType * UnimplementedOpcodeFault = new UnimplementedOpcodeFaultType("opdec", 13, 0x0481); -FloatEnableFaultType * FloatEnableFault = new FloatEnableFaultType("fen", 14, 0x0581); -PalFaultType * PalFault = new PalFaultType("pal", 15, 0x2001); -IntegerOverflowFaultType * IntegerOverflowFault = new IntegerOverflowFaultType("intover", 16, 0x0501); +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); Fault ** ListOfFaults[] = { (Fault **)&NoFault, @@ -61,7 +75,6 @@ Fault ** ListOfFaults[] = { (Fault **)&FloatEnableFault, (Fault **)&PalFault, (Fault **)&IntegerOverflowFault, - (Fault **)&FakeMemFault }; int NumFaults = sizeof(ListOfFaults) / sizeof(Fault **); diff --git a/arch/alpha/faults.hh b/arch/alpha/faults.hh index 2bb929a1e..06605861a 100644 --- a/arch/alpha/faults.hh +++ b/arch/alpha/faults.hh @@ -34,94 +34,125 @@ class AlphaFault : public Fault { -public: - AlphaFault(char * newName, int newId, Addr newVect) : Fault(newName, newId), vect(newVect) {;} - TheISA::Addr vect; + public: + AlphaFault(char * newName, int newId, Addr newVect) + : Fault(newName, newId), vect(newVect) + {;} + + TheISA::Addr vect; }; extern class ResetFaultType : public AlphaFault { -public: - ResetFaultType(char * newName, int newId, Addr newVect) : AlphaFault(newName, newId, newVect) {;} -} * ResetFault; + 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) {;} -} * ArithmeticFault; + 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) {;} -} * InterruptFault; + 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) {;} -} * NDtbMissFault; + 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) {;} -} * PDtbMissFault; + 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) {;} -} * DtbPageFault; + 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) {;} -} * DtbAcvFault; + 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) {;} -} * ItbMissFault; + 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) {;} -} * ItbPageFault; + 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) {;} -} * ItbAcvFault; + 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) {;} -} * UnimplementedOpcodeFault; + 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) {;} -} * FloatEnableFault; + 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) {;} -} * PalFault; + 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) {;} -} * IntegerOverflowFault; + public: + IntegerOverflowFaultType(char * newName, int newId, Addr newVect) + : AlphaFault(newName, newId, newVect) + {;} +} * const IntegerOverflowFault; extern Fault ** ListOfFaults[]; extern int NumFaults; -- cgit v1.2.3 From 53d2c9398e8c1631ae3fd5469b187b006d317f88 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sat, 18 Feb 2006 23:44:22 -0500 Subject: Move Linux/Tru64 architecture independent code into kern/* leaving dependent code making way for solaris linux syscall emu. SConscript: Add two new files for syscall emulation Add getDesc() function arch/alpha/alpha_linux_process.cc: arch/alpha/alpha_tru64_process.cc: move architecture independent code into kern/linux/linux.(hh|cc) arch/alpha/alpha_linux_process.hh: arch/alpha/alpha_tru64_process.hh: Add getDesc function kern/linux/linux.hh: move generi linux syscall emulation code into kern/linux kern/tru64/tru64.hh: move generi tru64 syscall emulation code into kern/tru64 sim/process.cc: sim/process.hh: Push the function determination and calling stuff down to LiveProcess and out of the Linux/Tru64 classes respectively sim/syscall_emul.cc: sim/syscall_emul.hh: fnctl implementation was identical in tru64 and linux so moved to generic --HG-- extra : convert_revision : 103293dbe6fe2f7892de4929d17dc085def77026 --- arch/alpha/alpha_linux_process.cc | 584 ++----------- arch/alpha/alpha_linux_process.hh | 11 +- arch/alpha/alpha_tru64_process.cc | 1679 ++++--------------------------------- arch/alpha/alpha_tru64_process.hh | 12 +- 4 files changed, 243 insertions(+), 2043 deletions(-) (limited to 'arch') diff --git a/arch/alpha/alpha_linux_process.cc b/arch/alpha/alpha_linux_process.cc index fb5e32e63..6d50756f2 100644 --- a/arch/alpha/alpha_linux_process.cc +++ b/arch/alpha/alpha_linux_process.cc @@ -26,506 +26,96 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include // for host open() flags -#include // for memset() -#include -#include -#include +#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; -/// -/// 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 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 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 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 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 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 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 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 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 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), @@ -973,23 +563,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 +570,18 @@ AlphaLinuxProcess::AlphaLinuxProcess(const std::string &name, int stderr_fd, std::vector &argv, std::vector &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 &argv, std::vector &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_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index 5c24adad9..90f01637d 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -26,1532 +26,138 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__) -#include -#include -#else -#include -#endif - -#include -#include -#include // for host open() flags -#include // for memset() -#include - #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; -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 - static void - copyOutStatBuf(FunctionalMemory *mem, Addr addr, global_stat *host) - { - TypedBufferArg 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 - static void - copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, global_statfs *host) - { - TypedBufferArg 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(mem, addr, host); - } - - static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, - global_statfs *host) - { - Tru64::copyOutStatfsBuf(mem, addr, host); - } - }; - - class PreF64 { - public: - static void copyOutStatBuf(FunctionalMemory *mem, Addr addr, - global_stat *host) - { - Tru64::copyOutStatBuf(mem, addr, host); - } - - static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, - global_statfs *host) - { - Tru64::copyOutStatfsBuf(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 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 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 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 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 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 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 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 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 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 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 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 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 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 attrp(xc->getSyscallArg(0)); - TypedBufferArg 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 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 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 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 attrp(xc->getSyscallArg(0)); - TypedBufferArg 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 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 - 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::iterator i = process->waitList.begin(); - list::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 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 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 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 condp(cond_addr); - TypedBufferArg 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 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 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 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 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 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 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 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 +243,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 +261,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 +318,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), /* 161 */ SyscallDesc("pre_F64_fstatfs", fstatfsFunc), /* 162 */ SyscallDesc("unknown #162", unimplementedFunc), @@ -1822,20 +428,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 +455,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 +478,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 +490,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 +498,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 +516,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 +536,8 @@ AlphaTru64Process::AlphaTru64Process(const std::string &name, int stderr_fd, std::vector &argv, std::vector &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 &argv, std::vector &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); }; -- cgit v1.2.3 From 00d58aeb4dc0569bc3d1273d90867148e6500ad9 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Sun, 19 Feb 2006 00:28:53 -0500 Subject: forgot a negative sign --HG-- extra : convert_revision : 9cdb00198979fca831d3e6840f9c534671ccead3 --- arch/alpha/alpha_tru64_process.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/alpha/alpha_tru64_process.cc b/arch/alpha/alpha_tru64_process.cc index 90f01637d..e6624305c 100644 --- a/arch/alpha/alpha_tru64_process.cc +++ b/arch/alpha/alpha_tru64_process.cc @@ -519,7 +519,7 @@ SyscallDesc AlphaTru64Process::machSyscallDescs[] = { SyscallDesc* AlphaTru64Process::getDesc(int callnum) { - if (callnum < Num_Mach_Syscall_Descs || callnum > Num_Syscall_Descs) + if (callnum < -Num_Mach_Syscall_Descs || callnum > Num_Syscall_Descs) return NULL; if (callnum < 0) -- cgit v1.2.3