diff options
Diffstat (limited to 'src/kern')
-rw-r--r-- | src/kern/kernel_stats.cc | 299 | ||||
-rw-r--r-- | src/kern/kernel_stats.hh | 192 | ||||
-rw-r--r-- | src/kern/linux/events.cc | 55 | ||||
-rw-r--r-- | src/kern/linux/events.hh | 50 | ||||
-rw-r--r-- | src/kern/linux/linux.hh | 283 | ||||
-rw-r--r-- | src/kern/linux/linux_syscalls.cc | 374 | ||||
-rw-r--r-- | src/kern/linux/linux_syscalls.hh | 326 | ||||
-rw-r--r-- | src/kern/linux/printk.cc | 261 | ||||
-rw-r--r-- | src/kern/linux/printk.hh | 36 | ||||
-rw-r--r-- | src/kern/linux/sched.hh | 45 | ||||
-rw-r--r-- | src/kern/solaris/solaris.hh | 304 | ||||
-rw-r--r-- | src/kern/system_events.cc | 91 | ||||
-rw-r--r-- | src/kern/system_events.hh | 86 | ||||
-rw-r--r-- | src/kern/tru64/dump_mbuf.cc | 78 | ||||
-rw-r--r-- | src/kern/tru64/dump_mbuf.hh | 38 | ||||
-rw-r--r-- | src/kern/tru64/mbuf.hh | 98 | ||||
-rw-r--r-- | src/kern/tru64/printf.cc | 266 | ||||
-rw-r--r-- | src/kern/tru64/printf.hh | 38 | ||||
-rw-r--r-- | src/kern/tru64/tru64.hh | 1240 | ||||
-rw-r--r-- | src/kern/tru64/tru64_events.cc | 105 | ||||
-rw-r--r-- | src/kern/tru64/tru64_events.hh | 83 | ||||
-rw-r--r-- | src/kern/tru64/tru64_syscalls.cc | 438 | ||||
-rw-r--r-- | src/kern/tru64/tru64_syscalls.hh | 359 |
23 files changed, 5145 insertions, 0 deletions
diff --git a/src/kern/kernel_stats.cc b/src/kern/kernel_stats.cc new file mode 100644 index 000000000..b85d88145 --- /dev/null +++ b/src/kern/kernel_stats.cc @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <map> +#include <stack> +#include <string> + +#include "arch/alpha/osfpal.hh" +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "kern/kernel_stats.hh" +#include "kern/tru64/tru64_syscalls.hh" +#include "sim/system.hh" + +using namespace std; +using namespace Stats; + +namespace Kernel { + +const char *modestr[] = { "kernel", "user", "idle", "interrupt" }; + +Statistics::Statistics(System *system) + : idleProcess((Addr)-1), themode(kernel), lastModeTick(0), + iplLast(0), iplLastTick(0) +{ + bin_int = system->params()->bin_int; +} + +void +Statistics::regStats(const string &_name) +{ + myname = _name; + + _arm + .name(name() + ".inst.arm") + .desc("number of arm instructions executed") + ; + + _quiesce + .name(name() + ".inst.quiesce") + .desc("number of quiesce instructions executed") + ; + + _ivlb + .name(name() + ".inst.ivlb") + .desc("number of ivlb instructions executed") + ; + + _ivle + .name(name() + ".inst.ivle") + .desc("number of ivle instructions executed") + ; + + _hwrei + .name(name() + ".inst.hwrei") + .desc("number of hwrei instructions executed") + ; + + _iplCount + .init(32) + .name(name() + ".ipl_count") + .desc("number of times we switched to this ipl") + .flags(total | pdf | nozero | nonan) + ; + + _iplGood + .init(32) + .name(name() + ".ipl_good") + .desc("number of times we switched to this ipl from a different ipl") + .flags(total | pdf | nozero | nonan) + ; + + _iplTicks + .init(32) + .name(name() + ".ipl_ticks") + .desc("number of cycles we spent at this ipl") + .flags(total | pdf | nozero | nonan) + ; + + _iplUsed + .name(name() + ".ipl_used") + .desc("fraction of swpipl calls that actually changed the ipl") + .flags(total | nozero | nonan) + ; + + _iplUsed = _iplGood / _iplCount; + + _callpal + .init(256) + .name(name() + ".callpal") + .desc("number of callpals executed") + .flags(total | pdf | nozero | nonan) + ; + + for (int i = 0; i < PAL::NumCodes; ++i) { + const char *str = PAL::name(i); + if (str) + _callpal.subname(i, str); + } + + _syscall + .init(SystemCalls<Tru64>::Number) + .name(name() + ".syscall") + .desc("number of syscalls executed") + .flags(total | pdf | nozero | nonan) + ; + + for (int i = 0; i < SystemCalls<Tru64>::Number; ++i) { + const char *str = SystemCalls<Tru64>::name(i); + if (str) { + _syscall.subname(i, str); + } + } + + _mode + .init(cpu_mode_num) + .name(name() + ".mode_switch") + .desc("number of protection mode switches") + ; + + for (int i = 0; i < cpu_mode_num; ++i) + _mode.subname(i, modestr[i]); + + _modeGood + .init(cpu_mode_num) + .name(name() + ".mode_good") + ; + + for (int i = 0; i < cpu_mode_num; ++i) + _modeGood.subname(i, modestr[i]); + + _modeFraction + .name(name() + ".mode_switch_good") + .desc("fraction of useful protection mode switches") + .flags(total) + ; + + for (int i = 0; i < cpu_mode_num; ++i) + _modeFraction.subname(i, modestr[i]); + + _modeFraction = _modeGood / _mode; + + _modeTicks + .init(cpu_mode_num) + .name(name() + ".mode_ticks") + .desc("number of ticks spent at the given mode") + .flags(pdf) + ; + for (int i = 0; i < cpu_mode_num; ++i) + _modeTicks.subname(i, modestr[i]); + + _swap_context + .name(name() + ".swap_context") + .desc("number of times the context was actually changed") + ; +} + +void +Statistics::setIdleProcess(Addr idlepcbb, ExecContext *xc) +{ + assert(themode == kernel || themode == interrupt); + idleProcess = idlepcbb; + themode = idle; + changeMode(themode, xc); +} + +void +Statistics::changeMode(cpu_mode newmode, ExecContext *xc) +{ + _mode[newmode]++; + + if (newmode == themode) + return; + + DPRINTF(Context, "old mode=%-8s new mode=%-8s\n", + modestr[themode], modestr[newmode]); + + _modeGood[newmode]++; + _modeTicks[themode] += curTick - lastModeTick; + + xc->getSystemPtr()->kernelBinning->changeMode(newmode); + + lastModeTick = curTick; + themode = newmode; +} + +void +Statistics::swpipl(int ipl) +{ + assert(ipl >= 0 && ipl <= 0x1f && "invalid IPL\n"); + + _iplCount[ipl]++; + + if (ipl == iplLast) + return; + + _iplGood[ipl]++; + _iplTicks[iplLast] += curTick - iplLastTick; + iplLastTick = curTick; + iplLast = ipl; +} + +void +Statistics::mode(cpu_mode newmode, ExecContext *xc) +{ + Addr pcbb = xc->readMiscReg(AlphaISA::IPR_PALtemp23); + + if ((newmode == kernel || newmode == interrupt) && + pcbb == idleProcess) + newmode = idle; + + if (bin_int == false && newmode == interrupt) + newmode = kernel; + + changeMode(newmode, xc); +} + +void +Statistics::context(Addr oldpcbb, Addr newpcbb, ExecContext *xc) +{ + assert(themode != user); + + _swap_context++; + changeMode(newpcbb == idleProcess ? idle : kernel, xc); +} + +void +Statistics::callpal(int code, ExecContext *xc) +{ + if (!PAL::name(code)) + return; + + _callpal[code]++; + + switch (code) { + case PAL::callsys: { + int number = xc->readIntReg(0); + if (SystemCalls<Tru64>::validSyscallNumber(number)) { + int cvtnum = SystemCalls<Tru64>::convert(number); + _syscall[cvtnum]++; + } + } break; + + case PAL::swpctx: + if (xc->getSystemPtr()->kernelBinning) + xc->getSystemPtr()->kernelBinning->palSwapContext(xc); + break; + } +} + +void +Statistics::serialize(ostream &os) +{ + int exemode = themode; + SERIALIZE_SCALAR(exemode); + SERIALIZE_SCALAR(idleProcess); + SERIALIZE_SCALAR(iplLast); + SERIALIZE_SCALAR(iplLastTick); + SERIALIZE_SCALAR(lastModeTick); +} + +void +Statistics::unserialize(Checkpoint *cp, const string §ion) +{ + int exemode; + UNSERIALIZE_SCALAR(exemode); + UNSERIALIZE_SCALAR(idleProcess); + UNSERIALIZE_SCALAR(iplLast); + UNSERIALIZE_SCALAR(iplLastTick); + UNSERIALIZE_SCALAR(lastModeTick); + themode = (cpu_mode)exemode; +} + +/* end namespace Kernel */ } diff --git a/src/kern/kernel_stats.hh b/src/kern/kernel_stats.hh new file mode 100644 index 000000000..16ec721d0 --- /dev/null +++ b/src/kern/kernel_stats.hh @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __KERNEL_STATS_HH__ +#define __KERNEL_STATS_HH__ + +#include <map> +#include <stack> +#include <string> +#include <vector> + +#include "cpu/static_inst.hh" + +class BaseCPU; +class ExecContext; +class FnEvent; +// What does kernel stats expect is included? +class System; + +namespace Kernel { + +enum cpu_mode { kernel, user, idle, interrupt, cpu_mode_num }; +extern const char *modestr[]; + +class Binning +{ + private: + std::string myname; + System *system; + + private: + // lisa's binning stuff + struct fnCall + { + Stats::MainBin *myBin; + std::string name; + }; + + struct SWContext + { + Counter calls; + std::stack<fnCall *> callStack; + }; + + std::map<const std::string, Stats::MainBin *> fnBins; + std::map<const Addr, SWContext *> swCtxMap; + + std::multimap<const std::string, std::string> callerMap; + void populateMap(std::string caller, std::string callee); + + std::vector<FnEvent *> fnEvents; + + Stats::Scalar<> fnCalls; + + Stats::MainBin *getBin(const std::string &name); + bool findCaller(std::string, std::string) const; + + SWContext *findContext(Addr pcb); + bool addContext(Addr pcb, SWContext *ctx) + { + return (swCtxMap.insert(std::make_pair(pcb, ctx))).second; + } + + void remContext(Addr pcb) + { + swCtxMap.erase(pcb); + } + + void dumpState() const; + + SWContext *swctx; + std::vector<std::string> binned_fns; + + private: + Stats::MainBin *modeBin[cpu_mode_num]; + + public: + const bool bin; + const bool fnbin; + + cpu_mode themode; + void palSwapContext(ExecContext *xc); + void execute(ExecContext *xc, StaticInstPtr inst); + void call(ExecContext *xc, Stats::MainBin *myBin); + void changeMode(cpu_mode mode); + + public: + Binning(System *sys); + virtual ~Binning(); + + const std::string name() const { return myname; } + void regStats(const std::string &name); + + public: + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +class Statistics : public Serializable +{ + private: + friend class Binning; + + private: + std::string myname; + + Addr idleProcess; + cpu_mode themode; + Tick lastModeTick; + bool bin_int; + + void changeMode(cpu_mode newmode, ExecContext *xc); + + private: + Stats::Scalar<> _arm; + Stats::Scalar<> _quiesce; + Stats::Scalar<> _ivlb; + Stats::Scalar<> _ivle; + Stats::Scalar<> _hwrei; + + Stats::Vector<> _iplCount; + Stats::Vector<> _iplGood; + Stats::Vector<> _iplTicks; + Stats::Formula _iplUsed; + + Stats::Vector<> _callpal; + Stats::Vector<> _syscall; +// Stats::Vector<> _faults; + + Stats::Vector<> _mode; + Stats::Vector<> _modeGood; + Stats::Formula _modeFraction; + Stats::Vector<> _modeTicks; + + Stats::Scalar<> _swap_context; + + private: + int iplLast; + Tick iplLastTick; + + public: + Statistics(System *system); + + const std::string name() const { return myname; } + void regStats(const std::string &name); + + public: + void arm() { _arm++; } + void quiesce() { _quiesce++; } + void ivlb() { _ivlb++; } + void ivle() { _ivle++; } + void hwrei() { _hwrei++; } + void swpipl(int ipl); + void mode(cpu_mode newmode, ExecContext *xc); + void context(Addr oldpcbb, Addr newpcbb, ExecContext *xc); + void callpal(int code, ExecContext *xc); + + void setIdleProcess(Addr idle, ExecContext *xc); + + public: + virtual void serialize(std::ostream &os); + virtual void unserialize(Checkpoint *cp, const std::string §ion); +}; + +/* end namespace Kernel */ } + +#endif // __KERNEL_STATS_HH__ diff --git a/src/kern/linux/events.cc b/src/kern/linux/events.cc new file mode 100644 index 000000000..b688e9dd0 --- /dev/null +++ b/src/kern/linux/events.cc @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2004-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "arch/arguments.hh" +#include "base/trace.hh" +#include "cpu/exec_context.hh" +#include "kern/linux/events.hh" +#include "kern/linux/printk.hh" +#include "kern/system_events.hh" +#include "sim/system.hh" + + +namespace Linux { + +void +DebugPrintkEvent::process(ExecContext *xc) +{ + if (DTRACE(DebugPrintf)) { + if (!raw) { + StringWrap name(xc->getSystemPtr()->name() + ".dprintk"); + DPRINTFN(""); + } + + AlphaISA::AlphaArguments args(xc); + Printk(args); + SkipFuncEvent::process(xc); + } +} + +} // namespace linux diff --git a/src/kern/linux/events.hh b/src/kern/linux/events.hh new file mode 100644 index 000000000..95c268976 --- /dev/null +++ b/src/kern/linux/events.hh @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2004-2006 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __KERN_LINUX_EVENTS_HH__ +#define __KERN_LINUX_EVENTS_HH__ + +#include "kern/system_events.hh" + +namespace Linux { + +class DebugPrintkEvent : public SkipFuncEvent +{ + private: + bool raw; + + public: + DebugPrintkEvent(PCEventQueue *q, const std::string &desc, Addr addr, + bool r = false) + : SkipFuncEvent(q, desc, addr), raw(r) {} + virtual void process(ExecContext *xc); +}; + +} + +#endif diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh new file mode 100644 index 000000000..63e0dd5ca --- /dev/null +++ b/src/kern/linux/linux.hh @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LINUX_HH__ +#define __LINUX_HH__ +#include "config/full_system.hh" + +#if FULL_SYSTEM + +class Linux {}; + +#else //!FULL_SYSTEM + +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> // for host open() flags +#include <string.h> // for memset() +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include "arch/isa_traits.hh" +#include "sim/syscall_emul.hh" + +class TranslatingPort; + +/// +/// 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 + + /// 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. + }; + + /// Limit struct for getrlimit/setrlimit. + struct rlimit { + uint64_t rlim_cur; //!< soft limit + uint64_t rlim_max; //!< hard limit + }; + + /// 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(). + 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(TranslatingPort *mem, Addr addr, hst_stat *host) + { + using namespace TheISA; + + 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(TranslatingPort *mem, Addr addr, hst_stat64 *host) + { + using namespace TheISA; + + 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(TranslatingPort *mem, int fd, Addr addr, hst_stat64 *host) + { + using namespace TheISA; + + TypedBufferArg<Linux::tgt_stat64> tgt(addr); + + // fd == 1 checks are because libc does some checks + // that the stdout is interactive vs. a file + // this makes it work on non-linux systems + if (fd == 1) + tgt->st_dev = htog((uint64_t)0xA); + else + tgt->st_dev = htog((uint64_t)host->st_dev); + // XXX What about STAT64_HAS_BROKEN_ST_INO ??? + tgt->st_ino = htog((uint64_t)host->st_ino); + if (fd == 1) + tgt->st_rdev = htog((uint64_t)0x880d); + else + tgt->st_rdev = htog((uint64_t)host->st_rdev); + tgt->st_size = htog((int64_t)host->st_size); + tgt->st_blocks = htog((uint64_t)host->st_blocks); + + if (fd == 1) + tgt->st_mode = htog((uint32_t)0x2190); + else + tgt->st_mode = htog((uint32_t)host->st_mode); + tgt->st_uid = htog((uint32_t)host->st_uid); + tgt->st_gid = htog((uint32_t)host->st_gid); + tgt->st_blksize = htog((uint32_t)host->st_blksize); + tgt->st_nlink = htog((uint32_t)host->st_nlink); + tgt->tgt_st_atime = htog((uint64_t)host->st_atime); + tgt->tgt_st_mtime = htog((uint64_t)host->st_mtime); + tgt->tgt_st_ctime = htog((uint64_t)host->st_ctime); +#if defined(STAT_HAVE_NSEC) + tgt->st_atime_nsec = htog(host->st_atime_nsec); + tgt->st_mtime_nsec = htog(host->st_mtime_nsec); + tgt->st_ctime_nsec = htog(host->st_ctime_nsec); +#else + tgt->st_atime_nsec = 0; + tgt->st_mtime_nsec = 0; + tgt->st_ctime_nsec = 0; +#endif + + tgt.copyOut(mem); + } + +}; // class Linux + + +#endif // FULL_SYSTEM + +#endif // __LINUX_HH__ diff --git a/src/kern/linux/linux_syscalls.cc b/src/kern/linux/linux_syscalls.cc new file mode 100644 index 000000000..c85b6d28f --- /dev/null +++ b/src/kern/linux/linux_syscalls.cc @@ -0,0 +1,374 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "kern/linux/linux_syscalls.hh" + +namespace { + const char * + standard_strings[SystemCalls<Linux>::Number] = { + + + "llseek", //0 + "newselect", //1 + "sysctl", //2 + "access", //3 + "acct", //4 + "adjtimex", //5 + "afs_syscall", //6 + "alarm", //7 + "bdflush", //8 + "break", //9 + + + "brk", //10 + "capget", //11 + "capset", //12 + "chdir", //13 + "chmod", //14 + "chown", //15 + "chown32", //16 + "chroot", //17 + "clock_getres", //18 + "clock_gettime", //19 + + + "clock_nanosleep", //20 + "clock_settime", //21 + "clone", //22 + "close", //23 + "creat", //24 + "create_module", //25 + "delete_module", //26 + "dup", //27 + "dup2", //28 + "epoll_create", //29 + + + "epoll_ctl", //30 + "epoll_wait", //31 + "execve", //32 + "exit", //33 + "exit_group", //34 + "fadvise64", //35 + "fadvise64_64", //36 + "fchdir", //37 + "fchmod", //38 + "fchown", //39 + + + "fchown32", //40 + "fcntl", //41 + "fcntl64", //42 + "fdatasync", //43 + "fgetxattr", //44 + "flistxattr", //45 + "flock", //46 + "fork", //47 + "fremovexattr", //48 + "fsetxattr", //49 + + + "fstat", //50 + "fstat64", //51 + "fstatfs", //52 + "fstatfs64", //53 + "fsync", //54 + "ftime", //55 + "ftruncate", //56 + "ftruncate64", //57 + "futex", //58 + "get_kernel_syms", //59 + + + "get_thread_area", //60 + "getcwd", //61 + "getdents", //62 + "getdents64", //63 + "getegid", //64 + "getegid32", //65 + "geteuid", //66 + "geteuid32", //67 + "getgid", //68 + "getgid32", //69 + + + "getgroups", //70 + "getgroups32", //71 + "getitimer", //72 + "getpgid", //73 + "getpgrp", //74 + "getpid", //75 + "getpmsg", //76 + "getppid", //77 + "getpriority", //78 + "getresgid", //79 + + + "getresgid32", //80 + "getresuid", //81 + "getresuid32", //82 + "getrlimit", //83 + "getrusage", //84 + "getsid", //85 + "gettid", //86 + "gettimeofday", //87 + "getuid", //88 + "getuid32", //89 + + + "getxattr", //90 + "gtty", //91 + "idle", //92 + "init_module", //93 + "io_cancel", //94 + "io_destroy", //95 + "io_getevents", //96 + "io_setup", //97 + "io_submit", //98 + "ioctl", //99 + + + "ioperm", //100 + "iopl", //101 + "ipc", //102 + "kill", //103 + "lchown", //104 + "lchown32", //105 + "lgetxattr", //106 + "link", //107 + "listxattr", //108 + "llistxattr", //109 + + + "lock", //110 + "lookup_dcookie", //111 + "lremovexattr", //112 + "lseek", //113 + "lsetxattr", //114 + "lstat", //115 + "lstat64", //116 + "madvise", //117 + "madvise1", //118 + "mincore", //119 + + + "mkdir", //120 + "mknod", //121 + "mlock", //122 + "mlockall", //123 + "mmap", //124 + "mmap2", //125 + "modify_ldt", //126 + "mount", //127 + "mprotect", //128 + "mpx", //129 + + + "mremap", //130 + "msync", //131 + "munlock", //132 + "munlockall", //133 + "munmap", //134 + "nanosleep", //135 + "nfsservctl", //136 + "nice", //137 + "oldfstat", //138 + "oldlstat", //139 + + + "oldolduname", //140 + "oldstat", //141 + "olduname", //142 + "open", //143 + "pause", //144 + "personality", //145 + "pipe", //146 + "pivot_root", //147 + "poll", //148 + "prctl", //149 + + + "pread64", //150 + "prof", //151 + "profil", //152 + "ptrace", //153 + "putpmsg", //154 + "pwrite64", //155 + "query_module", //156 + "quotactl", //157 + "read", //158 + "readahead", //159 + + + "readdir", //160 + "readlink", //161 + "readv", //162 + "reboot", //163 + "remap_file_pages", //164 + "removexattr", //165 + "rename", //166 + "restart_syscall", //167 + "rmdir", //168 + "rt_sigaction", //169 + + + "rt_sigpending", //170 + "rt_sigprocmask", //171 + "rt_sigqueueinfo", //172 + "rt_sigreturn", //173 + "rt_sigsuspend", //174 + "rt_sigtimedwait", //175 + "sched_get_priority_max", //176 + "sched_get_priority_min", //177 + "sched_getaffinity", //178 + "sched_getparam", //179 + + + "sched_getscheduler", //180 + "sched_rr_get_interval", //181 + "sched_setaffinity", //182 + "sched_setparam", //183 + "sched_setscheduler", //184 + "sched_yield", //185 + "select", //186 + "sendfile", //187 + "sendfile64", //188 + "set_thread_area", //189 + + + "set_tid_address", //190 + "setdomainname", //191 + "setfsgid", //192 + "setfsgid32", //193 + "setfsuid", //194 + "setfsuid32", //195 + "setgid", //196 + "setgid32", //197 + "setgroups", //198 + "setgroups32", //199 + + + "sethostname", //200 + "setitimer", //201 + "setpgid", //202 + "setpriority", //203 + "setregid", //204 + "setregid32", //205 + "setresgid", //206 + "setresgid32", //207 + "setresuid", //208 + "setresuid32", //209 + + + "setreuid", //210 + "setreuid32", //211 + "setrlimit", //212 + "setsid", //213 + "settimeofday", //214 + "setuid", //215 + "setuid32", //216 + "setxattr", //217 + "sgetmask", //218 + "sigaction", //219 + + + "sigaltstack", //220 + "signal", //221 + "sigpending", //222 + "sigprocmask", //223 + "sigreturn", //224 + "sigsuspend", //225 + "socketcall", //226 + "ssetmask", //227 + "stat", //228 + "stat64", //229 + + + "statfs", //230 + "statfs64", //231 + "stime", //232 + "stty", //233 + "swapoff", //234 + "swapon", //235 + "symlink", //236 + "sync", //237 + "sysfs", //238 + "sysinfo", //239 + + + "syslog", //240 + "tgkill", //241 + "time", //242 + "timer_create", //243 + "timer_delete", //244 + "timer_getoverrun", //245 + "timer_gettime", //246 + "timer_settime", //247 + "times", //248 + "tkill", //249 + + + "truncate", //250 + "truncate64", //251 + "ugetrlimit", //252 + "ulimit", //253 + "umask", //254 + "umount", //255 + "umount2", //256 + "uname", //257 + "unlink", //258 + "uselib", //259 + + + "ustat", //260 + "utime", //261 + "utimes", //262 + "vfork", //263 + "vhangup", //264 + "vm86", //265 + "vm86old", //266 + "vserver", //267 + "wait4", //268 + "waitpid", //269 + + + "write", //270 + "writev", //271 + }; + + +} + +const char * +SystemCalls<Linux>::name(int num) +{ + if ((num >= 0) && (num < Number)) + return standard_strings[num]; + else + return 0; +} diff --git a/src/kern/linux/linux_syscalls.hh b/src/kern/linux/linux_syscalls.hh new file mode 100644 index 000000000..7f2a08ea9 --- /dev/null +++ b/src/kern/linux/linux_syscalls.hh @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __KERN_LINUX_LINUX_SYSCALLS_HH__ +#define __KERN_LINUX_LINUX_SYSCALLS_HH__ + +#include "kern/linux/linux.hh" + +template <class OS> +class SystemCalls; + +template <> +class SystemCalls<Linux> +{ + public: + enum { + syscall = 0, + llseek = 1, + newselect = 2, + sysctl = 3, + access = 4, + acct = 5, + adjtimex = 6, + afs_syscall = 7, + alarm = 8, + bdflush = 9, + _break = 10, /*renamed from break*/ + brk = 11, + capget = 12, + capset = 13, + chdir = 14, + chmod = 15, + chown = 16, + chown32 = 17, + chroot = 18, + clock_getres = 19, + clock_gettime = 20, + clock_nanosleep = 21, + clock_settime = 22, + clone = 23, + close = 24, + creat = 25, + create_module = 26, + delete_module = 27, + dup = 28, + dup2 = 29, + epoll_create = 30, + epoll_ctl = 31, + epoll_wait = 32, + execve = 33, + exit = 34, + exit_group = 35, + fadvise64 = 36, + fadvise64_64 = 37, + fchdir = 38, + fchmod = 39, + fchown = 40, + fchown32 = 41, + fcntl = 42, + fcntl64 = 43, + fdatasync = 44, + fgetxattr = 45, + flistxattr = 46, + flock = 47, + fork = 48, + fremovexattr = 49, + fsetxattr = 50, + fstat = 51, + fstat64 = 52, + fstatfs = 53, + fstatfs64 = 54, + fsync = 55, + ftime = 56, + ftruncate = 57, + ftruncate64 = 58, + futex = 59, + get_kernel_syms = 60, + get_thread_area = 61, + getcwd = 62, + getdents = 63, + getdents64 = 64, + getegid = 65, + getegid32 = 66, + geteuid = 67, + geteuid32 = 68, + getgid = 69, + getgid32 = 70, + getgroups = 71, + getgroups32 = 72, + getitimer = 73, + getpgid = 74, + getpgrp = 75, + getpid = 76, + getpmsg = 77, + getppid = 78, + getpriority = 79, + getresgid = 80, + getresgid32 = 81, + getresuid = 82, + getresuid32 = 83, + getrlimit = 84, + getrusage = 85, + getsid = 86, + gettid = 87, + gettimeofday = 88, + getuid = 89, + getuid32 = 90, + getxattr = 91, + gtty = 92, + idle = 93, + init_module = 94, + io_cancel = 95, + io_destroy = 96, + io_getevents = 97, + io_setup = 98, + io_submit = 99, + ioctl = 100, + ioperm = 101, + iopl = 102, + ipc = 103, + kill = 104, + lchown = 105, + lchown32 = 106, + lgetxattr = 107, + link = 108, + listxattr = 109, + llistxattr = 110, + lock = 111, + lookup_dcookie = 112, + lremovexattr = 113, + lseek = 114, + lsetxattr = 115, + lstat = 116, + lstat64 = 117, + madvise = 118, + madvise1 = 119, + mincore = 120, + mkdir = 121, + mknod = 122, + mlock = 123, + mlockall = 124, + mmap = 125, + mmap2 = 126, + modify_ldt = 127, + mount = 128, + mprotect = 129, + mpx = 130, + mremap = 131, + msync = 132, + munlock = 133, + munlockall = 134, + munmap = 135, + nanosleep = 136, + nfsservctl = 137, + nice = 138, + oldfstat = 139, + oldlstat = 140, + oldolduname = 141, + oldstat = 142, + olduname = 143, + open = 144, + pause = 145, + personality = 146, + pipe = 147, + pivot_root = 148, + poll = 149, + prctl = 150, + pread64 = 151, + prof = 152, + profil = 153, + ptrace = 154, + putpmsg = 155, + pwrite64 = 156, + query_module = 157, + quotactl = 158, + read = 159, + readahead = 160, + readdir = 161, + readlink = 162, + readv = 163, + reboot = 164, + remap_file_pages = 165, + removexattr = 166, + rename = 167, + restart_syscall = 168, + rmdir = 169, + rt_sigaction = 170, + rt_sigpending = 171, + rt_sigprocmask = 172, + rt_sigqueueinfo = 173, + rt_sigreturn = 174, + rt_sigsuspend = 175, + rt_sigtimedwait = 176, + sched_get_priority_max = 177, + sched_get_priority_min = 178, + sched_getaffinity = 179, + sched_getparam = 180, + sched_getscheduler = 181, + sched_rr_get_interval = 182, + sched_setaffinity = 183, + sched_setparam = 184, + sched_setscheduler = 185, + sched_yield = 186, + select = 187, + sendfile = 188, + sendfile64 = 189, + set_thread_area = 190, + set_tid_address = 191, + setdomainname = 192, + setfsgid = 193, + setfsgid32 = 194, + setfsuid = 195, + setfsuid32 = 196, + setgid = 197, + setgid32 = 198, + setgroups = 199, + setgroups32 = 200, + sethostname = 201, + setitimer = 202, + setpgid = 203, + setpriority = 204, + setregid = 205, + setregid32 = 206, + setresgid = 207, + setresgid32 = 208, + setresuid = 209, + setresuid32 = 210, + setreuid = 211, + setreuid32 = 212, + setrlimit = 213, + setsid = 214, + settimeofday = 215, + setuid = 216, + setuid32 = 217, + setxattr = 218, + sgetmask = 219, + sigaction = 220, + sigaltstack = 221, + signal = 222, + sigpending = 223, + sigprocmask = 224, + sigreturn = 225, + sigsuspend = 226, + socketcall = 227, + ssetmask = 228, + stat = 229, + stat64 = 230, + statfs = 231, + statfs64 = 232, + stime = 233, + stty = 234, + swapoff = 235, + swapon = 236, + symlink = 237, + sync = 238, + sysfs = 239, + sysinfo = 240, + syslog = 241, + tgkill = 242, + time = 243, + timer_create = 244, + timer_delete = 245, + timer_getoverrun = 246, + timer_gettime = 247, + timer_settime = 248, + times = 249, + tkill = 250, + truncate = 251, + truncate64 = 252, + ugetrlimit = 253, + ulimit = 254, + umask = 255, + umount = 256, + umount2 = 257, + uname = 258, + unlink = 259, + uselib = 260, + ustat = 261, + utime = 262, + utimes = 263, + vfork = 264, + vhangup = 265, + vm86 = 266, + vm86old = 267, + vserver = 268, + wait4 = 269, + waitpid = 270, + write = 271, + writev = 272, + Number + }; + + static const char *name(int num); + + static bool validSyscallNumber(int num) { + return num < Number; + } + +}; + +#endif // __KERN_LINUX_LINUX_SYSCALLS_HH__ diff --git a/src/kern/linux/printk.cc b/src/kern/linux/printk.cc new file mode 100644 index 000000000..918b8dabe --- /dev/null +++ b/src/kern/linux/printk.cc @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <algorithm> + +#include "base/trace.hh" +#include "arch/arguments.hh" + +using namespace std; + + +void +Printk(AlphaISA::AlphaArguments args) +{ + char *p = (char *)args++; + + ios::fmtflags saved_flags = DebugOut().flags(); + char old_fill = DebugOut().fill(); + int old_precision = DebugOut().precision(); + + while (*p) { + switch (*p) { + case '%': { + bool more = true; + bool islong = false; + bool leftjustify = false; + bool format = false; + bool zero = false; + int width = 0; + while (more && *++p) { + switch (*p) { + case 'l': + case 'L': + islong = true; + break; + case '-': + leftjustify = true; + break; + case '#': + format = true; + break; + case '0': + if (width) + width *= 10; + else + zero = true; + break; + default: + if (*p >= '1' && *p <= '9') + width = 10 * width + *p - '0'; + else + more = false; + break; + } + } + + bool hexnum = false; + bool octal = false; + bool sign = false; + switch (*p) { + case 'X': + case 'x': + hexnum = true; + break; + case 'O': + case 'o': + octal = true; + break; + case 'D': + case 'd': + sign = true; + break; + case 'P': + format = true; + case 'p': + hexnum = true; + break; + } + + switch (*p) { + case 'D': + case 'd': + case 'U': + case 'u': + case 'X': + case 'x': + case 'O': + case 'o': + case 'P': + case 'p': { + if (hexnum) + DebugOut() << hex; + + if (octal) + DebugOut() << oct; + + if (format) { + if (!zero) + DebugOut().setf(ios::showbase); + else { + if (hexnum) { + DebugOut() << "0x"; + width -= 2; + } else if (octal) { + DebugOut() << "0"; + width -= 1; + } + } + } + + if (zero) + DebugOut().fill('0'); + + if (width > 0) + DebugOut().width(width); + + if (leftjustify && !zero) + DebugOut().setf(ios::left); + + if (sign) { + if (islong) + DebugOut() << (int64_t)args; + else + DebugOut() << (int32_t)args; + } else { + if (islong) + DebugOut() << (uint64_t)args; + else + DebugOut() << (uint32_t)args; + } + + if (zero) + DebugOut().fill(' '); + + if (width > 0) + DebugOut().width(0); + + DebugOut() << dec; + + ++args; + } + break; + + case 's': { + char *s = (char *)args; + if (!s) + s = "<NULL>"; + + if (width > 0) + DebugOut().width(width); + if (leftjustify) + DebugOut().setf(ios::left); + + DebugOut() << s; + ++args; + } + break; + case 'C': + case 'c': { + uint64_t mask = (*p == 'C') ? 0xffL : 0x7fL; + uint64_t num; + int width; + + if (islong) { + num = (uint64_t)args; + width = sizeof(uint64_t); + } else { + num = (uint32_t)args; + width = sizeof(uint32_t); + } + + while (width-- > 0) { + char c = (char)(num & mask); + if (c) + DebugOut() << c; + num >>= 8; + } + + ++args; + } + break; + case 'b': { + uint64_t n = (uint64_t)args++; + char *s = (char *)args++; + DebugOut() << s << ": " << n; + } + break; + case 'n': + case 'N': { + args += 2; +#if 0 + uint64_t n = (uint64_t)args++; + struct reg_values *rv = (struct reg_values *)args++; +#endif + } + break; + case 'r': + case 'R': { + args += 2; +#if 0 + uint64_t n = (uint64_t)args++; + struct reg_desc *rd = (struct reg_desc *)args++; +#endif + } + break; + case '%': + DebugOut() << '%'; + break; + } + ++p; + } + break; + case '\n': + DebugOut() << endl; + ++p; + break; + case '\r': + ++p; + if (*p != '\n') + DebugOut() << endl; + break; + + default: { + size_t len = strcspn(p, "%\n\r\0"); + DebugOut().write(p, len); + p += len; + } + } + } + + DebugOut().flags(saved_flags); + DebugOut().fill(old_fill); + DebugOut().precision(old_precision); +} + diff --git a/src/kern/linux/printk.hh b/src/kern/linux/printk.hh new file mode 100644 index 000000000..b88c40f5e --- /dev/null +++ b/src/kern/linux/printk.hh @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PRINTK_HH__ +#define __PRINTK_HH__ + +class AlphaISA::AlphaArguments; + +void Printk(AlphaISA::AlphaArguments args); + +#endif // __PRINTK_HH__ diff --git a/src/kern/linux/sched.hh b/src/kern/linux/sched.hh new file mode 100644 index 000000000..a11fa590d --- /dev/null +++ b/src/kern/linux/sched.hh @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __KERN_LINUX_SCHED_HH__ +#define __KERN_LINUX_SCHED_HH__ + +namespace Linux { + struct task_struct { + uint8_t junk1[0xf4]; + int32_t pid; + uint8_t junk2[0x190]; + uint64_ta start; + uint8_t junk3[0x5c]; + char name[16]; + }; + + +} + +#endif // __KERN_LINUX_SCHED_HH__ diff --git a/src/kern/solaris/solaris.hh b/src/kern/solaris/solaris.hh new file mode 100644 index 000000000..e2b61d613 --- /dev/null +++ b/src/kern/solaris/solaris.hh @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SOLARIS_HH__ +#define __SOLARIS_HH__ +#include "config/full_system.hh" + +#if FULL_SYSTEM + +class Solaris {}; + +#else //!FULL_SYSTEM + +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> // for host open() flags +#include <string.h> // for memset() +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#include "arch/isa_traits.hh" +#include "sim/syscall_emul.hh" + +class TranslatingPort; + +/// +/// This class encapsulates the types, structures, constants, +/// functions, and syscall-number mappings specific to the Solaris +/// syscall interface. +/// +class Solaris { + + public: + + //@{ + /// Basic Solaris types. + typedef uint64_t size_t; + typedef uint64_t off_t; + typedef int64_t time_t; + typedef int32_t uid_t; + typedef int32_t gid_t; + typedef uint64_t rlim_t; + typedef uint64_t ino_t; + typedef uint64_t dev_t; + typedef uint32_t mode_t; + typedef uint32_t nlink_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 + struct tgt_timespec { + int64_t tv_sec; + int64_t tv_nsec; + }; + + /// Stat buffer. Note that we can't call it 'stat' since that + /// gets #defined to something else on some systems. + struct tgt_stat { + uint64_t st_dev; //!< device + uint64_t st_ino; //!< inode + uint32_t st_mode; //!< mode + uint32_t st_nlink; //!< link count + int32_t st_uid; //!< owner's user ID + int32_t st_gid; //!< owner's group ID + uint64_t st_rdev; //!< device number + int64_t st_size; //!< file size in bytes + struct tgt_timespec st_atimeX; //!< time of last access + struct tgt_timespec st_mtimeX; //!< time of last modification + struct tgt_timespec st_ctimeX; //!< time of last status change + int32_t st_blksize; //!< optimal I/O block size + int64_t st_blocks; //!< number of blocks allocated + char st_fstype[16]; + }; + + // same for stat64 + struct tgt_stat64 { + uint64_t st_dev; //!< device + uint64_t st_ino; //!< inode + uint32_t st_mode; //!< mode + uint32_t st_nlink; //!< link count + int32_t st_uid; //!< owner's user ID + int32_t st_gid; //!< owner's group ID + uint64_t st_rdev; //!< device number + int64_t st_size; //!< file size in bytes + struct tgt_timespec st_atimeX; //!< time of last access + struct tgt_timespec st_mtimeX; //!< time of last modification + struct tgt_timespec st_ctimeX; //!< time of last status change + int32_t st_blksize; //!< optimal I/O block size + int64_t st_blocks; //!< number of blocks allocated + char st_fstype[16]; + }; + + /// Length of strings in struct utsname (plus 1 for null char). + static const int _SYS_NMLN = 257; + + /// 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. + }; + + /// Limit struct for getrlimit/setrlimit. + struct rlimit { + uint64_t rlim_cur; //!< soft limit + uint64_t rlim_max; //!< hard limit + }; + + /// 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(). + 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(TranslatingPort *mem, Addr addr, hst_stat *host) + { + using namespace TheISA; + + TypedBufferArg<Solaris::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.tv_sec = htog((uint64_t)host->st_atime); + tgt->st_mtimeX.tv_sec = htog((uint64_t)host->st_mtime); + tgt->st_ctimeX.tv_sec = htog((uint64_t)host->st_ctime); +#if defined(STAT_HAVE_NSEC) + tgt->st_atimeX.tv_nsec = htog(host->st_atime_nsec); + tgt->st_mtimeX.tv_nsec = htog(host->st_mtime_nsec); + tgt->st_ctimeX.tv_nsec = htog(host->st_ctime_nsec); +#else + tgt->st_atimeX.tv_nsec = 0; + tgt->st_mtimeX.tv_nsec = 0; + tgt->st_ctimeX.tv_nsec = 0; +#endif + tgt->st_blksize = htog(host->st_blksize); + tgt->st_blocks = htog(host->st_blocks); + strncpy(tgt->st_fstype, "????", 16); + + 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(TranslatingPort *mem, Addr addr, hst_stat64 *host) + { + using namespace TheISA; + + TypedBufferArg<Solaris::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.tv_sec = htog((uint64_t)host->st_atime); + tgt->st_mtimeX.tv_sec = htog((uint64_t)host->st_mtime); + tgt->st_ctimeX.tv_sec = htog((uint64_t)host->st_ctime); +#if defined(STAT_HAVE_NSEC) + tgt->st_atimeX.tv_nsec = htog(host->st_atime_nsec); + tgt->st_mtimeX.tv_nsec = htog(host->st_mtime_nsec); + tgt->st_ctimeX.tv_nsec = htog(host->st_ctime_nsec); +#else + tgt->st_atimeX.tv_nsec = 0; + tgt->st_mtimeX.tv_nsec = 0; + tgt->st_ctimeX.tv_nsec = 0; +#endif + tgt->st_blksize = htog(host->st_blksize); + tgt->st_blocks = htog(host->st_blocks); + strncpy(tgt->st_fstype, "????", 16); + + tgt.copyOut(mem); + } +#endif + + + // Same for stat64 + static void + copyOutStat64Buf(TranslatingPort *mem, int fd, Addr addr, hst_stat64 *host) + { + using namespace TheISA; + + TypedBufferArg<Solaris::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-solaris 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->st_atimeX.tv_sec = htog((uint64_t)host->st_atime); + tgt->st_mtimeX.tv_sec = htog((uint64_t)host->st_mtime); + tgt->st_ctimeX.tv_sec = htog((uint64_t)host->st_ctime); +#if defined(STAT_HAVE_NSEC) + tgt->st_atimeX.tv_nsec = htog(host->st_atime_nsec); + tgt->st_mtimeX.tv_nsec = htog(host->st_mtime_nsec); + tgt->st_ctimeX.tv_nsec = htog(host->st_ctime_nsec); +#else + tgt->st_atimeX.tv_nsec = 0; + tgt->st_mtimeX.tv_nsec = 0; + tgt->st_ctimeX.tv_nsec = 0; +#endif + + tgt.copyOut(mem); + } + +}; // class Solaris + + +#endif // FULL_SYSTEM + +#endif // __SOLARIS_HH__ diff --git a/src/kern/system_events.cc b/src/kern/system_events.cc new file mode 100644 index 000000000..fd5c12e44 --- /dev/null +++ b/src/kern/system_events.cc @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cpu/base.hh" +#include "cpu/cpu_exec_context.hh" +#include "kern/kernel_stats.hh" +#include "kern/system_events.hh" +#include "sim/system.hh" + +using namespace TheISA; + +void +SkipFuncEvent::process(ExecContext *xc) +{ + Addr newpc = xc->readIntReg(ReturnAddressReg); + + DPRINTF(PCEvent, "skipping %s: pc=%x, newpc=%x\n", description, + xc->readPC(), newpc); + + xc->setPC(newpc); + xc->setNextPC(xc->readPC() + sizeof(TheISA::MachInst)); +/* + BranchPred *bp = xc->getCpuPtr()->getBranchPred(); + if (bp != NULL) { + bp->popRAS(xc->getThreadNum()); + } +*/ +} + + +FnEvent::FnEvent(PCEventQueue *q, const std::string &desc, Addr addr, + Stats::MainBin *bin) + : PCEvent(q, desc, addr), _name(desc), mybin(bin) +{ +} + +void +FnEvent::process(ExecContext *xc) +{ + if (xc->misspeculating()) + return; + + xc->getSystemPtr()->kernelBinning->call(xc, mybin); +} + +void +IdleStartEvent::process(ExecContext *xc) +{ + xc->getCpuPtr()->kernelStats->setIdleProcess( + xc->readMiscReg(AlphaISA::IPR_PALtemp23), xc); + remove(); +} + +void +InterruptStartEvent::process(ExecContext *xc) +{ + xc->getCpuPtr()->kernelStats->mode(Kernel::interrupt, xc); +} + +void +InterruptEndEvent::process(ExecContext *xc) +{ + // We go back to kernel, if we are user, inside the rti + // pal code we will get switched to user because of the ICM write + xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc); +} diff --git a/src/kern/system_events.hh b/src/kern/system_events.hh new file mode 100644 index 000000000..246140a09 --- /dev/null +++ b/src/kern/system_events.hh @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2004-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SYSTEM_EVENTS_HH__ +#define __SYSTEM_EVENTS_HH__ + +#include "cpu/pc_event.hh" + +class System; + +class SkipFuncEvent : public PCEvent +{ + public: + SkipFuncEvent(PCEventQueue *q, const std::string &desc, Addr addr) + : PCEvent(q, desc, addr) + {} + virtual void process(ExecContext *xc); +}; + +class FnEvent : public PCEvent +{ + public: + FnEvent(PCEventQueue *q, const std::string &desc, Addr addr, + Stats::MainBin *bin); + virtual void process(ExecContext *xc); + std::string myname() const { return _name; } + + private: + std::string _name; + Stats::MainBin *mybin; +}; + +class IdleStartEvent : public PCEvent +{ + public: + IdleStartEvent(PCEventQueue *q, const std::string &desc, Addr addr) + : PCEvent(q, desc, addr) + {} + virtual void process(ExecContext *xc); +}; + +class InterruptStartEvent : public PCEvent +{ + public: + InterruptStartEvent(PCEventQueue *q, const std::string &desc, Addr addr) + : PCEvent(q, desc, addr) + {} + virtual void process(ExecContext *xc); +}; + +class InterruptEndEvent : public PCEvent +{ + public: + InterruptEndEvent(PCEventQueue *q, const std::string &desc, Addr addr) + : PCEvent(q, desc, addr) + {} + virtual void process(ExecContext *xc); +}; + + +#endif // __SYSTEM_EVENTS_HH__ diff --git a/src/kern/tru64/dump_mbuf.cc b/src/kern/tru64/dump_mbuf.cc new file mode 100644 index 000000000..c3c37531a --- /dev/null +++ b/src/kern/tru64/dump_mbuf.cc @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <algorithm> + +#include "base/cprintf.hh" +#include "base/trace.hh" +#include "base/loader/symtab.hh" +#include "cpu/exec_context.hh" +#include "kern/tru64/mbuf.hh" +#include "sim/host.hh" +#include "sim/system.hh" +#include "arch/arguments.hh" +#include "arch/isa_traits.hh" +#include "arch/vtophys.hh" + +using namespace TheISA; + +namespace tru64 { + +void +DumpMbuf(AlphaArguments args) +{ + ExecContext *xc = args.getExecContext(); + Addr addr = (Addr)args; + struct mbuf m; + + CopyOut(xc, &m, addr, sizeof(m)); + + int count = m.m_pkthdr.len; + + ccprintf(DebugOut(), "m=%#lx, m->m_pkthdr.len=%#d\n", addr, + m.m_pkthdr.len); + + while (count > 0) { + ccprintf(DebugOut(), "m=%#lx, m->m_data=%#lx, m->m_len=%d\n", + addr, m.m_data, m.m_len); + char *buffer = new char[m.m_len]; + CopyOut(xc, buffer, m.m_data, m.m_len); + Trace::dataDump(curTick, xc->getSystemPtr()->name(), (uint8_t *)buffer, + m.m_len); + delete [] buffer; + + count -= m.m_len; + if (!m.m_next) + break; + + CopyOut(xc, &m, m.m_next, sizeof(m)); + } +} + +} // namespace Tru64 diff --git a/src/kern/tru64/dump_mbuf.hh b/src/kern/tru64/dump_mbuf.hh new file mode 100644 index 000000000..9e1698ff1 --- /dev/null +++ b/src/kern/tru64/dump_mbuf.hh @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DUMP_MBUF_HH__ +#define __DUMP_MBUF_HH__ + +#include "arch/arguments.hh" + +namespace tru64 { + void DumpMbuf(AlphaISA::AlphaArguments args); +} + +#endif // __DUMP_MBUF_HH__ diff --git a/src/kern/tru64/mbuf.hh b/src/kern/tru64/mbuf.hh new file mode 100644 index 000000000..93424858f --- /dev/null +++ b/src/kern/tru64/mbuf.hh @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __MBUF_HH__ +#define __MBUF_HH__ + +#include "sim/host.hh" +#include "arch/isa_traits.hh" + +namespace tru64 { + +struct m_hdr { + Addr mh_next; // 0x00 + Addr mh_nextpkt; // 0x08 + Addr mh_data; // 0x10 + int32_t mh_len; // 0x18 + int32_t mh_type; // 0x1C + int32_t mh_flags; // 0x20 + int32_t mh_pad0; // 0x24 + Addr mh_foo[4]; // 0x28, 0x30, 0x38, 0x40 +}; + +struct pkthdr { + int32_t len; + int32_t protocolSum; + Addr rcvif; +}; + +struct m_ext { + Addr ext_buf; // 0x00 + Addr ext_free; // 0x08 + uint32_t ext_size; // 0x10 + uint32_t ext_pad0; // 0x14 + Addr ext_arg; // 0x18 + struct ext_refq { + Addr forw, back; // 0x20, 0x28 + } ext_ref; + Addr uiomove_f; // 0x30 + int32_t protocolSum; // 0x38 + int32_t bytesSummed; // 0x3C + Addr checksum; // 0x40 +}; + +struct mbuf { + struct m_hdr m_hdr; + union { + struct { + struct pkthdr MH_pkthdr; + union { + struct m_ext MH_ext; + char MH_databuf[1]; + } MH_dat; + } MH; + char M_databuf[1]; + } M_dat; +}; + +#define m_attr m_hdr.mh_attr +#define m_next m_hdr.mh_next +#define m_len m_hdr.mh_len +#define m_data m_hdr.mh_data +#define m_type m_hdr.mh_type +#define m_flags m_hdr.mh_flags +#define m_nextpkt m_hdr.mh_nextpkt +#define m_act m_nextpkt +#define m_pkthdr M_dat.MH.MH_pkthdr +#define m_ext M_dat.MH.MH_dat.MH_ext +#define m_pktdat M_dat.MH.MH_dat.MH_databuf +#define m_dat M_dat.M_databuf + +} + +#endif // __MBUF_HH__ diff --git a/src/kern/tru64/printf.cc b/src/kern/tru64/printf.cc new file mode 100644 index 000000000..319d36673 --- /dev/null +++ b/src/kern/tru64/printf.cc @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <algorithm> + +#include "base/cprintf.hh" +#include "base/trace.hh" +#include "sim/host.hh" +#include "arch/arguments.hh" +#include "arch/vtophys.hh" + +using namespace std; + +namespace tru64 { + +void +Printf(AlphaISA::AlphaArguments args) +{ + char *p = (char *)args++; + + ios::fmtflags saved_flags = DebugOut().flags(); + char old_fill = DebugOut().fill(); + int old_precision = DebugOut().precision(); + + while (*p) { + switch (*p) { + case '%': { + bool more = true; + bool islong = false; + bool leftjustify = false; + bool format = false; + bool zero = false; + int width = 0; + while (more && *++p) { + switch (*p) { + case 'l': + case 'L': + islong = true; + break; + case '-': + leftjustify = true; + break; + case '#': + format = true; + break; + case '0': + if (width) + width *= 10; + else + zero = true; + break; + default: + if (*p >= '1' && *p <= '9') + width = 10 * width + *p - '0'; + else + more = false; + break; + } + } + + bool hexnum = false; + bool octal = false; + bool sign = false; + switch (*p) { + case 'X': + case 'x': + hexnum = true; + break; + case 'O': + case 'o': + octal = true; + break; + case 'D': + case 'd': + sign = true; + break; + case 'P': + format = true; + case 'p': + hexnum = true; + break; + } + + switch (*p) { + case 'D': + case 'd': + case 'U': + case 'u': + case 'X': + case 'x': + case 'O': + case 'o': + case 'P': + case 'p': { + if (hexnum) + DebugOut() << hex; + + if (octal) + DebugOut() << oct; + + if (format) { + if (!zero) + DebugOut().setf(ios::showbase); + else { + if (hexnum) { + DebugOut() << "0x"; + width -= 2; + } else if (octal) { + DebugOut() << "0"; + width -= 1; + } + } + } + + if (zero) + DebugOut().fill('0'); + + if (width > 0) + DebugOut().width(width); + + if (leftjustify && !zero) + DebugOut().setf(ios::left); + + if (sign) { + if (islong) + DebugOut() << (int64_t)args; + else + DebugOut() << (int32_t)args; + } else { + if (islong) + DebugOut() << (uint64_t)args; + else + DebugOut() << (uint32_t)args; + } + + if (zero) + DebugOut().fill(' '); + + if (width > 0) + DebugOut().width(0); + + DebugOut() << dec; + + ++args; + } + break; + + case 's': { + char *s = (char *)args; + if (!s) + s = "<NULL>"; + + if (width > 0) + DebugOut().width(width); + if (leftjustify) + DebugOut().setf(ios::left); + + DebugOut() << s; + ++args; + } + break; + case 'C': + case 'c': { + uint64_t mask = (*p == 'C') ? 0xffL : 0x7fL; + uint64_t num; + int width; + + if (islong) { + num = (uint64_t)args; + width = sizeof(uint64_t); + } else { + num = (uint32_t)args; + width = sizeof(uint32_t); + } + + while (width-- > 0) { + char c = (char)(num & mask); + if (c) + DebugOut() << c; + num >>= 8; + } + + ++args; + } + break; + case 'b': { + uint64_t n = (uint64_t)args++; + char *s = (char *)args++; + DebugOut() << s << ": " << n; + } + break; + case 'n': + case 'N': { + args += 2; +#if 0 + uint64_t n = (uint64_t)args++; + struct reg_values *rv = (struct reg_values *)args++; +#endif + } + break; + case 'r': + case 'R': { + args += 2; +#if 0 + uint64_t n = (uint64_t)args++; + struct reg_desc *rd = (struct reg_desc *)args++; +#endif + } + break; + case '%': + DebugOut() << '%'; + break; + } + ++p; + } + break; + case '\n': + DebugOut() << endl; + ++p; + break; + case '\r': + ++p; + if (*p != '\n') + DebugOut() << endl; + break; + + default: { + size_t len = strcspn(p, "%\n\r\0"); + DebugOut().write(p, len); + p += len; + } + } + } + + DebugOut().flags(saved_flags); + DebugOut().fill(old_fill); + DebugOut().precision(old_precision); +} + +} // namespace Tru64 diff --git a/src/kern/tru64/printf.hh b/src/kern/tru64/printf.hh new file mode 100644 index 000000000..61236e83a --- /dev/null +++ b/src/kern/tru64/printf.hh @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PRINTF_HH__ +#define __PRINTF_HH__ + +#include "arch/arguments.hh" + +namespace tru64 { + void Printf(AlphaISA::AlphaArguments args); +} + +#endif // __PRINTF_HH__ diff --git a/src/kern/tru64/tru64.hh b/src/kern/tru64/tru64.hh new file mode 100644 index 000000000..91db5bb84 --- /dev/null +++ b/src/kern/tru64/tru64.hh @@ -0,0 +1,1240 @@ +/* + * Copyright (c) 2001-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __TRU64_HH__ +#define __TRU64_HH__ +#include "config/full_system.hh" + +#if FULL_SYSTEM + +class Tru64 {}; + +#else //!FULL_SYSTEM + +#include <sys/types.h> +#include <sys/stat.h> +#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__) +#include <sys/param.h> +#include <sys/mount.h> +#else +#include <sys/statfs.h> +#endif + +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <string.h> // for memset() +#include <unistd.h> + +#include "cpu/base.hh" +#include "sim/root.hh" +#include "sim/syscall_emul.hh" + +typedef struct stat global_stat; +typedef struct statfs global_statfs; +typedef struct dirent global_dirent; + +class TranslatingPort; + +/// +/// 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; + //@} + + /// 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 __attribute__ ((aligned(sizeof(uid_t)))); + gid_t st_gid; + dev_t st_rdev; + off_t st_size __attribute__ ((aligned(sizeof(off_t)))); + 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. + }; + + /// Limit struct for getrlimit/setrlimit. + struct rlimit { + uint64_t rlim_cur; //!< soft limit + uint64_t rlim_max; //!< hard limit + }; + + + /// 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 gettimeofday. + struct timeval { + uint32_t tv_sec; //!< seconds + uint32_t tv_usec; //!< microseconds + }; + + /// 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(). + 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(TranslatingPort *mem, Addr addr, global_stat *host) + { + using namespace TheISA; + + 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(TranslatingPort *mem, Addr addr, global_statfs *host) + { + using namespace TheISA; + + 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(TranslatingPort *mem, Addr addr, + global_stat *host) + { + Tru64::copyOutStatBuf<Tru64::F64_stat>(mem, addr, host); + } + + static void copyOutStatfsBuf(TranslatingPort *mem, Addr addr, + global_statfs *host) + { + Tru64::copyOutStatfsBuf<Tru64::F64_statfs>(mem, addr, host); + } + }; + + class PreF64 { + public: + static void copyOutStatBuf(TranslatingPort *mem, Addr addr, + global_stat *host) + { + Tru64::copyOutStatBuf<Tru64::pre_F64_stat>(mem, addr, host); + } + + static void copyOutStatfsBuf(TranslatingPort *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(TranslatingPort *mem, Addr addr, struct stat *host) + { + using namespace TheISA; + + TypedBufferArg<Tru64::pre_F64_stat> tgt(addr); + + tgt->st_dev = htog(host->st_dev); + tgt->st_ino = htog(host->st_ino); + tgt->st_mode = htog(host->st_mode); + tgt->st_nlink = htog(host->st_nlink); + tgt->st_uid = htog(host->st_uid); + tgt->st_gid = htog(host->st_gid); + tgt->st_rdev = htog(host->st_rdev); + tgt->st_size = htog(host->st_size); + tgt->st_atimeX = htog(host->st_atime); + tgt->st_mtimeX = htog(host->st_mtime); + tgt->st_ctimeX = htog(host->st_ctime); + tgt->st_blksize = htog(host->st_blksize); + tgt->st_blocks = htog(host->st_blocks); + + tgt.copyOut(mem); + } + + + /// The target system's hostname. + static const char *hostname; + + + /// Target getdirentries() handler. + static SyscallReturn + getdirentriesFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + using namespace TheISA; + +#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->getMemPort()); + 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->getMemPort()); + + tgt_buf_ptr += tgt_bufsize; + host_buf_ptr += host_dp->d_reclen; + } + + delete [] host_buf; + + *basep = htog((int64_t)host_basep); + basep.copyOut(xc->getMemPort()); + + return tgt_buf_ptr - tgt_buf; +#endif + } + + /// Target sigreturn() handler. + static SyscallReturn + sigreturnFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + using namespace TheISA; + + using TheISA::RegFile; + TypedBufferArg<Tru64::sigcontext> sc(xc->getSyscallArg(0)); + + sc.copyIn(xc->getMemPort()); + + // 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. + xc->setNextPC(htog(sc->sc_pc)); + + for (int i = 0; i < 31; ++i) { + xc->setIntReg(i, htog(sc->sc_regs[i])); + xc->setFloatRegBits(i, htog(sc->sc_fpregs[i])); + } + + xc->setMiscReg(TheISA::Fpcr_DepTag, htog(sc->sc_fpcr)); + + return 0; + } + + + // + // 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) + { + using namespace TheISA; + + TypedBufferArg<Tru64::vm_stack> argp(xc->getSyscallArg(0)); + + argp.copyIn(xc->getMemPort()); + + // 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->getMemPort()); + } + + 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) + { + using namespace std; + using namespace TheISA; + + TypedBufferArg<Tru64::nxm_task_attr> attrp(xc->getSyscallArg(0)); + TypedBufferArg<Addr> configptr_ptr(xc->getSyscallArg(1)); + + attrp.copyIn(xc->getMemPort()); + + 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->getMemPort()); + + // 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->getMemPort()); + + // 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->readMiscReg(TheISA::Uniq_DepTag); + 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->getMemPort()); + + // + // copy pointer to shared config area out to user + // + *configptr_ptr = htog(config_addr); + configptr_ptr.copyOut(xc->getMemPort()); + + // 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) + { + using namespace TheISA; + + ec->clearArchRegs(); + + ec->setIntReg(TheISA::ArgumentReg0, gtoh(attrp->registers.a0)); + ec->setIntReg(27/*t12*/, gtoh(attrp->registers.pc)); + ec->setIntReg(TheISA::StackPointerReg, gtoh(attrp->registers.sp)); + ec->setMiscReg(TheISA::Uniq_DepTag, uniq_val); + + ec->setPC(gtoh(attrp->registers.pc)); + ec->setNextPC(gtoh(attrp->registers.pc) + sizeof(TheISA::MachInst)); + + ec->activate(); + } + + /// Create thread. + static SyscallReturn + nxm_thread_createFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + using namespace std; + using namespace TheISA; + + 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->getMemPort()); + + 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->getMemPort()); + + 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->getMemPort()); + + 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->getMemPort()); + + 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->getMemPort()); + + 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->getMemPort()); + + // 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->getMemPort()); + + 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) + { + using namespace std; + + 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->getCpuPtr()->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) + { + using namespace std; + + 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->getCpuPtr(); + + 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) + { + using namespace std; + + Addr uaddr = xc->getSyscallArg(0); + + cout << xc->getCpuPtr()->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) + { + using namespace std; + + 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) + { + using namespace TheISA; + + TypedBufferArg<uint64_t> lockp(uaddr); + + lockp.copyIn(xc->getMemPort()); + + if (gtoh(*lockp) == 0) { + // lock is free: grab it + *lockp = htog(1); + lockp.copyOut(xc->getMemPort()); + } 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->getMemPort()); + 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->getMemPort()); + } + } + + /// 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) + { + using namespace TheISA; + + Addr uaddr = xc->getSyscallArg(0); + TypedBufferArg<uint64_t> lockp(uaddr); + + lockp.copyIn(xc->getMemPort()); + + if (gtoh(*lockp) == 0) { + // lock is free: grab it + *lockp = htog(1); + lockp.copyOut(xc->getMemPort()); + 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) + { + using namespace TheISA; + + 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->getMemPort()); + assert(gtoh(*lockp) != 0); + + m5_unlock_mutex(lock_addr, process, xc); + + process->waitList.push_back(Process::WaitRec(cond_addr, xc)); + xc->suspend(); + + return 0; + } + + /// Thread exit. + static SyscallReturn + m5_thread_exitFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + assert(xc->status() == ExecContext::Active); + xc->deallocate(); + + return 0; + } + + /// Indirect syscall invocation (call #0). + static SyscallReturn + indirectSyscallFunc(SyscallDesc *desc, int callnum, Process *process, + ExecContext *xc) + { + int new_callnum = xc->getSyscallArg(0); + LiveProcess *lp = dynamic_cast<LiveProcess*>(process); + assert(lp); + + for (int i = 0; i < 5; ++i) + xc->setSyscallArg(i, xc->getSyscallArg(i+1)); + + + SyscallDesc *new_desc = lp->getDesc(new_callnum); + if (desc == NULL) + fatal("Syscall %d out of range", callnum); + + new_desc->doSyscall(new_callnum, process, xc); + + return 0; + } + +}; // class Tru64 + + +#endif // FULL_SYSTEM + +#endif // __TRU64_HH__ diff --git a/src/kern/tru64/tru64_events.cc b/src/kern/tru64/tru64_events.cc new file mode 100644 index 000000000..69fc5c55d --- /dev/null +++ b/src/kern/tru64/tru64_events.cc @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "cpu/exec_context.hh" +#include "cpu/base.hh" +#include "kern/system_events.hh" +#include "kern/tru64/tru64_events.hh" +#include "kern/tru64/dump_mbuf.hh" +#include "kern/tru64/printf.hh" +#include "arch/alpha/ev5.hh" +#include "arch/arguments.hh" +#include "arch/isa_traits.hh" +#include "sim/system.hh" + +using namespace TheISA; + +//void SkipFuncEvent::process(ExecContext *xc); + +void +BadAddrEvent::process(ExecContext *xc) +{ + // The following gross hack is the equivalent function to the + // annotation for vmunix::badaddr in: + // simos/simulation/apps/tcl/osf/tlaser.tcl + + uint64_t a0 = xc->readIntReg(ArgumentReg0); + + AddrRangeList resp; + AddrRangeList snoop; + AddrRangeIter iter; + bool found = false; + + xc->getPhysPort()->getPeerAddressRanges(resp, snoop); + for(iter = resp.begin(); iter != resp.end(); iter++) + { + if (*iter == (TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask)) + found = true; + } + + if (!TheISA::IsK0Seg(a0) || found ) { + + DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0); + xc->setIntReg(ReturnValueReg, 0x1); + SkipFuncEvent::process(xc); + } + else + DPRINTF(BADADDR, "badaddr arg=%#x good\n", a0); +} + +void +PrintfEvent::process(ExecContext *xc) +{ + if (DTRACE(Printf)) { + DebugOut() << curTick << ": " << xc->getCpuPtr()->name() << ": "; + + AlphaArguments args(xc); + tru64::Printf(args); + } +} + +void +DebugPrintfEvent::process(ExecContext *xc) +{ + if (DTRACE(DebugPrintf)) { + if (!raw) + DebugOut() << curTick << ": " << xc->getCpuPtr()->name() << ": "; + + AlphaArguments args(xc); + tru64::Printf(args); + } +} + +void +DumpMbufEvent::process(ExecContext *xc) +{ + if (DTRACE(DebugPrintf)) { + AlphaArguments args(xc); + tru64::DumpMbuf(args); + } +} diff --git a/src/kern/tru64/tru64_events.hh b/src/kern/tru64/tru64_events.hh new file mode 100644 index 000000000..9b5bcfea2 --- /dev/null +++ b/src/kern/tru64/tru64_events.hh @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __TRU64_EVENTS_HH__ +#define __TRU64_EVENTS_HH__ + +#include <string> + +#include "cpu/pc_event.hh" +#include "kern/system_events.hh" + +class ExecContext; + +class BadAddrEvent : public SkipFuncEvent +{ + public: + BadAddrEvent(PCEventQueue *q, const std::string &desc, Addr addr) + : SkipFuncEvent(q, desc, addr) {} + virtual void process(ExecContext *xc); +}; + +class PrintfEvent : public PCEvent +{ + public: + PrintfEvent(PCEventQueue *q, const std::string &desc, Addr addr) + : PCEvent(q, desc, addr) {} + virtual void process(ExecContext *xc); +}; + +class DebugPrintfEvent : public PCEvent +{ + private: + bool raw; + + public: + DebugPrintfEvent(PCEventQueue *q, const std::string &desc, Addr addr, + bool r = false) + : PCEvent(q, desc, addr), raw(r) {} + virtual void process(ExecContext *xc); +}; + +class DebugPrintfrEvent : public DebugPrintfEvent +{ + public: + DebugPrintfrEvent(PCEventQueue *q, const std::string &desc, Addr addr) + : DebugPrintfEvent(q, desc, addr, true) + {} +}; + +class DumpMbufEvent : public PCEvent +{ + public: + DumpMbufEvent(PCEventQueue *q, const std::string &desc, Addr addr) + : PCEvent(q, desc, addr) {} + virtual void process(ExecContext *xc); +}; + +#endif // __TRU64_EVENTS_HH__ diff --git a/src/kern/tru64/tru64_syscalls.cc b/src/kern/tru64/tru64_syscalls.cc new file mode 100644 index 000000000..8aa57dbaa --- /dev/null +++ b/src/kern/tru64/tru64_syscalls.cc @@ -0,0 +1,438 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "kern/tru64/tru64_syscalls.hh" + +namespace { + const char * + standard_strings[SystemCalls<Tru64>::StandardNumber] = { + "syscall", // 0 + "exit", // 1 + "fork", // 2 + "read", // 3 + "write", // 4 + "old_open", // 5 + "close", // 6 + "wait4", // 7 + "old_creat", // 8 + "link", // 9 + + "unlink", // 10 + "execv", // 11 + "chdir", // 12 + "fchdir", // 13 + "mknod", // 14 + "chmod", // 15 + "chown", // 16 + "obreak", // 17 + "pre_F64_getfsstat", // 18 + "lseek", // 19 + + "getpid", // 20 + "mount", // 21 + "unmount", // 22 + "setuid", // 23 + "getuid", // 24 + "exec_with_loader", // 25 + "ptrace", // 26 + "recvmsg", // 27 + "sendmsg", // 28 + "recvfrom", // 29 + + "accept", // 30 + "getpeername", // 31 + "getsockname", // 32 + "access", // 33 + "chflags", // 34 + "fchflags", // 35 + "sync", // 36 + "kill", // 37 + "old_stat", // 38 + "setpgid", // 39 + + "old_lstat", // 40 + "dup", // 41 + "pipe", // 42 + "set_program_attributes", // 43 + "profil", // 44 + "open", // 45 + "obsolete_osigaction", // 46 + "getgid", // 47 + "sigprocmask", // 48 + "getlogin", // 49 + + "setlogin", // 50 + "acct", // 51 + "sigpending", // 52 + "classcntl", // 53 + "ioctl", // 54 + "reboot", // 55 + "revoke", // 56 + "symlink", // 57 + "readlink", // 58 + "execve", // 59 + + "umask", // 60 + "chroot", // 61 + "old_fstat", // 62 + "getpgrp", // 63 + "getpagesize", // 64 + "mremap", // 65 + "vfork", // 66 + "pre_F64_stat", // 67 + "pre_F64_lstat", // 68 + "sbrk", // 69 + + "sstk", // 70 + "mmap", // 71 + "ovadvise", // 72 + "munmap", // 73 + "mprotect", // 74 + "madvise", // 75 + "old_vhangup", // 76 + "kmodcall", // 77 + "mincore", // 78 + "getgroups", // 79 + + "setgroups", // 80 + "old_getpgrp", // 81 + "setpgrp", // 82 + "setitimer", // 83 + "old_wait", // 84 + "table", // 85 + "getitimer", // 86 + "gethostname", // 87 + "sethostname", // 88 + "getdtablesize", // 89 + + "dup2", // 90 + "pre_F64_fstat", // 91 + "fcntl", // 92 + "select", // 93 + "poll", // 94 + "fsync", // 95 + "setpriority", // 96 + "socket", // 97 + "connect", // 98 + "old_accept", // 99 + + "getpriority", // 100 + "old_send", // 101 + "old_recv", // 102 + "sigreturn", // 103 + "bind", // 104 + "setsockopt", // 105 + "listen", // 106 + "plock", // 107 + "old_sigvec", // 108 + "old_sigblock", // 109 + + "old_sigsetmask", // 110 + "sigsuspend", // 111 + "sigstack", // 112 + "old_recvmsg", // 113 + "old_sendmsg", // 114 + "obsolete_vtrcae", // 115 + "gettimeofday", // 116 + "getrusage", // 117 + "getsockopt", // 118 + "numa_syscalls", // 119 + + "readv", // 120 + "writev", // 121 + "settimeofday", // 122 + "fchown", // 123 + "fchmod", // 124 + "old_recvfrom", // 125 + "setreuid", // 126 + "setregid", // 127 + "rename", // 128 + "truncate", // 129 + + "ftruncate", // 130 + "flock", // 131 + "setgid", // 132 + "sendto", // 133 + "shutdown", // 134 + "socketpair", // 135 + "mkdir", // 136 + "rmdir", // 137 + "utimes", // 138 + "obsolete_42_sigreturn", // 139 + + "adjtime", // 140 + "old_getpeername", // 141 + "gethostid", // 142 + "sethostid", // 143 + "getrlimit", // 144 + "setrlimit", // 145 + "old_killpg", // 146 + "setsid", // 147 + "quotactl", // 148 + "oldquota", // 149 + + "old_getsockname", // 150 + "pread", // 151 + "pwrite", // 152 + "pid_block", // 153 + "pid_unblock", // 154 + "signal_urti", // 155 + "sigaction", // 156 + "sigwaitprim", // 157 + "nfssvc", // 158 + "getdirentries", // 159 + + "pre_F64_statfs", // 160 + "pre_F64_fstatfs", // 161 + 0, // 162 + "async_daemon", // 163 + "getfh", // 164 + "getdomainname", // 165 + "setdomainname", // 166 + 0, // 167 + 0, // 168 + "exportfs", // 169 + + 0, // 170 + 0, // 171 + 0, // 172 + 0, // 173 + 0, // 174 + 0, // 175 + 0, // 176 + 0, // 177 + 0, // 178 + 0, // 179 + + 0, // 180 + "alt_plock", // 181 + 0, // 182 + 0, // 183 + "getmnt", // 184 + 0, // 185 + 0, // 186 + "alt_sigpending", // 187 + "alt_setsid", // 188 + 0, // 189 + + 0, // 190 + 0, // 191 + 0, // 192 + 0, // 193 + 0, // 194 + 0, // 195 + 0, // 196 + 0, // 197 + 0, // 198 + "swapon", // 199 + + "msgctl", // 200 + "msgget", // 201 + "msgrcv", // 202 + "msgsnd", // 203 + "semctl", // 204 + "semget", // 205 + "semop", // 206 + "uname", // 207 + "lchown", // 208 + "shmat", // 209 + + "shmctl", // 210 + "shmdt", // 211 + "shmget", // 212 + "mvalid", // 213 + "getaddressconf", // 214 + "msleep", // 215 + "mwakeup", // 216 + "msync", // 217 + "signal", // 218 + "utc_gettime", // 219 + + "utc_adjtime", // 220 + 0, // 221 + "security", // 222 + "kloadcall", // 223 + "stat", // 224 + "lstat", // 225 + "fstat", // 226 + "statfs", // 227 + "fstatfs", // 228 + "getfsstat", // 229 + + "gettimeofday64", // 230 + "settimeofday64", // 231 + 0, // 232 + "getpgid", // 233 + "getsid", // 234 + "sigaltstack", // 235 + "waitid", // 236 + "priocntlset", // 237 + "sigsendset", // 238 + "set_speculative", // 239 + + "msfs_syscall", // 240 + "sysinfo", // 241 + "uadmin", // 242 + "fuser", // 243 + "proplist_syscall", // 244 + "ntp_adjtime", // 245 + "ntp_gettime", // 246 + "pathconf", // 247 + "fpathconf", // 248 + "sync2", // 249 + + "uswitch", // 250 + "usleep_thread", // 251 + "audcntl", // 252 + "audgen", // 253 + "sysfs", // 254 + "subsys_info", // 255 + "getsysinfo", // 256 + "setsysinfo", // 257 + "afs_syscall", // 258 + "swapctl", // 259 + + "memcntl", // 260 + "fdatasync", // 261 + "oflock", // 262 + "_F64_readv", // 263 + "_F64_writev", // 264 + "cdslxlate", // 265 + "sendfile", // 266 + }; + + const char * + mach_strings[SystemCalls<Tru64>::MachNumber] = { + 0, // 0 + 0, // 1 + 0, // 2 + 0, // 3 + 0, // 4 + 0, // 5 + 0, // 6 + 0, // 7 + 0, // 8 + 0, // 9 + + "task_self", // 10 + "thread_reply", // 11 + "task_notify", // 12 + "thread_self", // 13 + 0, // 14 + 0, // 15 + 0, // 16 + 0, // 17 + 0, // 18 + 0, // 19 + + "msg_send_trap", // 20 + "msg_receive_trap", // 21 + "msg_rpc_trap", // 22 + 0, // 23 + "nxm_block", // 24 + "nxm_unblock", // 25 + 0, // 26 + 0, // 27 + 0, // 28 + "nxm_thread_destroy", // 29 + + "lw_wire", // 30 + "lw_unwire", // 31 + "nxm_thread_create", // 32 + "nxm_task_init", // 33 + 0, // 34 + "nxm_idle", // 35 + "nxm_wakeup_idle", // 36 + "nxm_set_pthid", // 37 + "nxm_thread_kill", // 38 + "nxm_thread_block", // 39 + + "nxm_thread_wakeup", // 40 + "init_process", // 41 + "nxm_get_binding", // 42 + "map_fd", // 43 + "nxm_resched", // 44 + "nxm_set_cancel", // 45 + "nxm_set_binding", // 46 + "stack_create", // 47 + "nxm_get_state", // 48 + "nxm_thread_suspend", // 49 + + "nxm_thread_resume", // 50 + "nxm_signal_check", // 51 + "htg_unix_syscall", // 52 + 0, // 53 + 0, // 54 + "host_self", // 55 + "host_priv_self", // 56 + 0, // 57 + 0, // 58 + "swtch_pri", // 59 + + "swtch", // 60 + "thread_switch", // 61 + "semop_fast", // 62 + "nxm_pshared_init", // 63 + "nxm_pshared_block", // 64 + "nxm_pshared_unblock", // 65 + "nxm_pshared_destroy", // 66 + "nxm_swtch_pri", // 67 + "lw_syscall", // 68 + 0, // 69 + + "mach_sctimes_0", // 70 + "mach_sctimes_1", // 71 + "mach_sctimes_2", // 72 + "mach_sctimes_3", // 73 + "mach_sctimes_4", // 74 + "mach_sctimes_5", // 75 + "mach_sctimes_6", // 76 + "mach_sctimes_7", // 77 + "mach_sctimes_8", // 78 + "mach_sctimes_9", // 79 + + "mach_sctimes_10", // 80 + "mach_sctimes_11", // 81 + "mach_sctimes_port_alloc_dealloc", // 82 + }; +} + +const char * +SystemCalls<Tru64>::name(int num) +{ + if (num >= Number) + return 0; + else if (num >= StandardNumber) + return mach_strings[num - StandardNumber]; + else if (num >= 0) + return standard_strings[num]; + else if (num > -MachNumber) + return mach_strings[-num]; + else + return 0; +} diff --git a/src/kern/tru64/tru64_syscalls.hh b/src/kern/tru64/tru64_syscalls.hh new file mode 100644 index 000000000..69fa9101c --- /dev/null +++ b/src/kern/tru64/tru64_syscalls.hh @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2003-2005 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __KERN_TRU64_TRU64_SYSCALLS_HH__ +#define __KERN_TRU64_TRU64_SYSCALLS_HH__ + +#include "kern/tru64/tru64.hh" + +template <class OS> +class SystemCalls; + +template <> +class SystemCalls<Tru64> +{ + public: + enum { + syscall = 0, + exit = 1, + fork = 2, + read = 3, + write = 4, + old_open = 5, + close = 6, + wait4 = 7, + old_creat = 8, + link = 9, + unlink = 10, + execv = 11, + chdir = 12, + fchdir = 13, + mknod = 14, + chmod = 15, + chown = 16, + obreak = 17, + pre_F64_getfsstat = 18, + lseek = 19, + getpid = 20, + mount = 21, + unmount = 22, + setuid = 23, + getuid = 24, + exec_with_loader = 25, + ptrace = 26, + recvmsg = 27, + sendmsg = 28, + recvfrom = 29, + accept = 30, + getpeername = 31, + getsockname = 32, + access = 33, + chflags = 34, + fchflags = 35, + sync = 36, + kill = 37, + old_stat = 38, + setpgid = 39, + old_lstat = 40, + dup = 41, + pipe = 42, + set_program_attributes = 43, + profil = 44, + open = 45, + obsolete_osigaction = 46, + getgid = 47, + sigprocmask = 48, + getlogin = 49, + setlogin = 50, + acct = 51, + sigpending = 52, + classcntl = 53, + ioctl = 54, + reboot = 55, + revoke = 56, + symlink = 57, + readlink = 58, + execve = 59, + umask = 60, + chroot = 61, + old_fstat = 62, + getpgrp = 63, + getpagesize = 64, + mremap = 65, + vfork = 66, + pre_F64_stat = 67, + pre_F64_lstat = 68, + sbrk = 69, + sstk = 70, + mmap = 71, + ovadvise = 72, + munmap = 73, + mprotect = 74, + madvise = 75, + old_vhangup = 76, + kmodcall = 77, + mincore = 78, + getgroups = 79, + setgroups = 80, + old_getpgrp = 81, + setpgrp = 82, + setitimer = 83, + old_wait = 84, + table = 85, + getitimer = 86, + gethostname = 87, + sethostname = 88, + getdtablesize = 89, + dup2 = 90, + pre_F64_fstat = 91, + fcntl = 92, + select = 93, + poll = 94, + fsync = 95, + setpriority = 96, + socket = 97, + connect = 98, + old_accept = 99, + getpriority = 100, + old_send = 101, + old_recv = 102, + sigreturn = 103, + bind = 104, + setsockopt = 105, + listen = 106, + plock = 107, + old_sigvec = 108, + old_sigblock = 109, + old_sigsetmask = 110, + sigsuspend = 111, + sigstack = 112, + old_recvmsg = 113, + old_sendmsg = 114, + obsolete_vtrcae = 115, + gettimeofday = 116, + getrusage = 117, + getsockopt = 118, + numa_syscalls = 119, + readv = 120, + writev = 121, + settimeofday = 122, + fchown = 123, + fchmod = 124, + old_recvfrom = 125, + setreuid = 126, + setregid = 127, + rename = 128, + truncate = 129, + ftruncate = 130, + flock = 131, + setgid = 132, + sendto = 133, + shutdown = 134, + socketpair = 135, + mkdir = 136, + rmdir = 137, + utimes = 138, + obsolete_42_sigreturn = 139, + adjtime = 140, + old_getpeername = 141, + gethostid = 142, + sethostid = 143, + getrlimit = 144, + setrlimit = 145, + old_killpg = 146, + setsid = 147, + quotactl = 148, + oldquota = 149, + old_getsockname = 150, + pread = 151, + pwrite = 152, + pid_block = 153, + pid_unblock = 154, + signal_urti = 155, + sigaction = 156, + sigwaitprim = 157, + nfssvc = 158, + getdirentries = 159, + pre_F64_statfs = 160, + pre_F64_fstatfs = 161, + async_daemon = 163, + getfh = 164, + getdomainname = 165, + setdomainname = 166, + exportfs = 169, + alt_plock = 181, + getmnt = 184, + alt_sigpending = 187, + alt_setsid = 188, + swapon = 199, + msgctl = 200, + msgget = 201, + msgrcv = 202, + msgsnd = 203, + semctl = 204, + semget = 205, + semop = 206, + uname = 207, + lchown = 208, + shmat = 209, + shmctl = 210, + shmdt = 211, + shmget = 212, + mvalid = 213, + getaddressconf = 214, + msleep = 215, + mwakeup = 216, + msync = 217, + signal = 218, + utc_gettime = 219, + utc_adjtime = 220, + security = 222, + kloadcall = 223, + stat = 224, + lstat = 225, + fstat = 226, + statfs = 227, + fstatfs = 228, + getfsstat = 229, + gettimeofday64 = 230, + settimeofday64 = 231, + getpgid = 233, + getsid = 234, + sigaltstack = 235, + waitid = 236, + priocntlset = 237, + sigsendset = 238, + set_speculative = 239, + msfs_syscall = 240, + sysinfo = 241, + uadmin = 242, + fuser = 243, + proplist_syscall = 244, + ntp_adjtime = 245, + ntp_gettime = 246, + pathconf = 247, + fpathconf = 248, + sync2 = 249, + uswitch = 250, + usleep_thread = 251, + audcntl = 252, + audgen = 253, + sysfs = 254, + subsys_info = 255, + getsysinfo = 256, + setsysinfo = 257, + afs_syscall = 258, + swapctl = 259, + memcntl = 260, + fdatasync = 261, + oflock = 262, + _F64_readv = 263, + _F64_writev = 264, + cdslxlate = 265, + sendfile = 266, + StandardNumber + }; + + enum { + task_self = 10, + thread_reply = 11, + task_notify = 12, + thread_self = 13, + msg_send_trap = 20, + msg_receive_trap = 21, + msg_rpc_trap = 22, + nxm_block = 24, + nxm_unblock = 25, + nxm_thread_destroy = 29, + lw_wire = 30, + lw_unwire = 31, + nxm_thread_create = 32, + nxm_task_init = 33, + nxm_idle = 35, + nxm_wakeup_idle = 36, + nxm_set_pthid = 37, + nxm_thread_kill = 38, + nxm_thread_block = 39, + nxm_thread_wakeup = 40, + init_process = 41, + nxm_get_binding = 42, + map_fd = 43, + nxm_resched = 44, + nxm_set_cancel = 45, + nxm_set_binding = 46, + stack_create = 47, + nxm_get_state = 48, + nxm_thread_suspend = 49, + nxm_thread_resume = 50, + nxm_signal_check = 51, + htg_unix_syscall = 52, + host_self = 55, + host_priv_self = 56, + swtch_pri = 59, + swtch = 60, + thread_switch = 61, + semop_fast = 62, + nxm_pshared_init = 63, + nxm_pshared_block = 64, + nxm_pshared_unblock = 65, + nxm_pshared_destroy = 66, + nxm_swtch_pri = 67, + lw_syscall = 68, + mach_sctimes_0 = 70, + mach_sctimes_1 = 71, + mach_sctimes_2 = 72, + mach_sctimes_3 = 73, + mach_sctimes_4 = 74, + mach_sctimes_5 = 75, + mach_sctimes_6 = 76, + mach_sctimes_7 = 77, + mach_sctimes_8 = 78, + mach_sctimes_9 = 79, + mach_sctimes_10 = 80, + mach_sctimes_11 = 81, + mach_sctimes_port_alloc_dealloc = 82, + MachNumber + }; + + static const int Number = StandardNumber + MachNumber; + + static const char *name(int num); + + static bool validSyscallNumber(int num) { + return -MachNumber < num && num < StandardNumber; + } + + static int convert(int syscall_num) { + if (!validSyscallNumber(syscall_num)) + return -1; + + return syscall_num < 0 ? StandardNumber - syscall_num : syscall_num; + } +}; + +#endif // __KERN_TRU64_TRU64_SYSCALLS_HH__ |