summaryrefslogtreecommitdiff
path: root/kern
diff options
context:
space:
mode:
Diffstat (limited to 'kern')
-rw-r--r--kern/freebsd/freebsd_system.cc163
-rw-r--r--kern/kernel_stats.cc46
-rw-r--r--kern/kernel_stats.hh20
-rw-r--r--kern/linux/aligned.hh47
-rw-r--r--kern/linux/events.cc (renamed from kern/freebsd/freebsd_system.hh)45
-rw-r--r--kern/linux/events.hh (renamed from kern/linux/thread_info.hh)27
-rw-r--r--kern/linux/hwrpb.hh42
-rw-r--r--kern/linux/linux.hh307
-rw-r--r--kern/linux/linux_system.cc298
-rw-r--r--kern/linux/linux_system.hh151
-rw-r--r--kern/linux/linux_threadinfo.hh88
-rw-r--r--kern/linux/printk.cc2
-rw-r--r--kern/system_events.cc23
-rw-r--r--kern/tru64/dump_mbuf.cc12
-rw-r--r--kern/tru64/mbuf.hh2
-rw-r--r--kern/tru64/printf.cc4
-rw-r--r--kern/tru64/tru64.hh1292
-rw-r--r--kern/tru64/tru64_events.cc18
-rw-r--r--kern/tru64/tru64_system.cc159
-rw-r--r--kern/tru64/tru64_system.hh69
20 files changed, 1700 insertions, 1115 deletions
diff --git a/kern/freebsd/freebsd_system.cc b/kern/freebsd/freebsd_system.cc
deleted file mode 100644
index 283713d40..000000000
--- a/kern/freebsd/freebsd_system.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * @file
- * Modifications for the FreeBSD kernel.
- * Based on kern/linux/linux_system.cc.
- *
- */
-
-#include "base/loader/symtab.hh"
-#include "cpu/exec_context.hh"
-#include "kern/freebsd/freebsd_system.hh"
-#include "mem/functional/memory_control.hh"
-#include "mem/functional/physical.hh"
-#include "sim/builder.hh"
-#include "targetarch/vtophys.hh"
-
-#define TIMER_FREQUENCY 1193180
-
-using namespace std;
-
-FreebsdSystem::FreebsdSystem(Params *p)
- : System(p)
-{
- /**
- * Any time DELAY is called just skip the function.
- * Shouldn't we actually emulate the delay?
- */
- skipDelayEvent = addKernelFuncEvent<SkipFuncEvent>("DELAY");
- skipCalibrateClocks =
- addKernelFuncEvent<SkipCalibrateClocksEvent>("calibrate_clocks");
-}
-
-
-FreebsdSystem::~FreebsdSystem()
-{
- delete skipDelayEvent;
- delete skipCalibrateClocks;
-}
-
-
-void
-FreebsdSystem::doCalibrateClocks(ExecContext *xc)
-{
- Addr ppc_vaddr = 0;
- Addr timer_vaddr = 0;
- Addr ppc_paddr = 0;
- Addr timer_paddr = 0;
-
- ppc_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg1];
- timer_vaddr = (Addr)xc->regs.intRegFile[ArgumentReg2];
-
- ppc_paddr = vtophys(physmem, ppc_vaddr);
- timer_paddr = vtophys(physmem, timer_vaddr);
-
- uint8_t *ppc = physmem->dma_addr(ppc_paddr, sizeof(uint32_t));
- uint8_t *timer = physmem->dma_addr(timer_paddr, sizeof(uint32_t));
-
- *(uint32_t *)ppc = htog((uint32_t)Clock::Frequency);
- *(uint32_t *)timer = htog((uint32_t)TIMER_FREQUENCY);
-}
-
-
-void
-FreebsdSystem::SkipCalibrateClocksEvent::process(ExecContext *xc)
-{
- SkipFuncEvent::process(xc);
- ((FreebsdSystem *)xc->system)->doCalibrateClocks(xc);
-}
-
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(FreebsdSystem)
-
- Param<Tick> boot_cpu_frequency;
- SimObjectParam<MemoryController *> memctrl;
- SimObjectParam<PhysicalMemory *> physmem;
-
- Param<string> kernel;
- Param<string> console;
- Param<string> pal;
-
- Param<string> boot_osflags;
- Param<string> readfile;
- Param<unsigned int> init_param;
-
- Param<uint64_t> system_type;
- Param<uint64_t> system_rev;
-
- Param<bool> bin;
- VectorParam<string> binned_fns;
- Param<bool> bin_int;
-
-END_DECLARE_SIM_OBJECT_PARAMS(FreebsdSystem)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(FreebsdSystem)
-
- INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
- INIT_PARAM(memctrl, "memory controller"),
- INIT_PARAM(physmem, "phsyical memory"),
- INIT_PARAM(kernel, "file that contains the kernel code"),
- INIT_PARAM(console, "file that contains the console code"),
- INIT_PARAM(pal, "file that contains palcode"),
- INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
- "a"),
- INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
- INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
- INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
- INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
- INIT_PARAM_DFLT(bin, "is this system to be binned", false),
- INIT_PARAM(binned_fns, "functions to be broken down and binned"),
- INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
-
-END_INIT_SIM_OBJECT_PARAMS(FreebsdSystem)
-
-CREATE_SIM_OBJECT(FreebsdSystem)
-{
- System::Params *p = new System::Params;
- p->name = getInstanceName();
- p->boot_cpu_frequency = boot_cpu_frequency;
- p->memctrl = memctrl;
- p->physmem = physmem;
- p->kernel_path = kernel;
- p->console_path = console;
- p->palcode = pal;
- p->boot_osflags = boot_osflags;
- p->init_param = init_param;
- p->readfile = readfile;
- p->system_type = system_type;
- p->system_rev = system_rev;
- p->bin = bin;
- p->binned_fns = binned_fns;
- p->bin_int = bin_int;
- return new FreebsdSystem(p);
-}
-
-REGISTER_SIM_OBJECT("FreebsdSystem", FreebsdSystem)
-
diff --git a/kern/kernel_stats.cc b/kern/kernel_stats.cc
index 3a7d12443..b85d88145 100644
--- a/kern/kernel_stats.cc
+++ b/kern/kernel_stats.cc
@@ -35,6 +35,7 @@
#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;
@@ -43,11 +44,11 @@ namespace Kernel {
const char *modestr[] = { "kernel", "user", "idle", "interrupt" };
-Statistics::Statistics(ExecContext *context)
- : xc(context), idleProcess((Addr)-1), themode(kernel), lastModeTick(0),
+Statistics::Statistics(System *system)
+ : idleProcess((Addr)-1), themode(kernel), lastModeTick(0),
iplLast(0), iplLastTick(0)
{
- bin_int = xc->system->params->bin_int;
+ bin_int = system->params()->bin_int;
}
void
@@ -136,19 +137,6 @@ Statistics::regStats(const string &_name)
}
}
- _faults
- .init(Num_Faults)
- .name(name() + ".faults")
- .desc("number of faults")
- .flags(total | pdf | nozero | nonan)
- ;
-
- for (int i = 1; i < Num_Faults; ++i) {
- const char *str = FaultName(i);
- if (str)
- _faults.subname(i, str);
- }
-
_mode
.init(cpu_mode_num)
.name(name() + ".mode_switch")
@@ -193,16 +181,16 @@ Statistics::regStats(const string &_name)
}
void
-Statistics::setIdleProcess(Addr idlepcbb)
+Statistics::setIdleProcess(Addr idlepcbb, ExecContext *xc)
{
assert(themode == kernel || themode == interrupt);
idleProcess = idlepcbb;
themode = idle;
- changeMode(themode);
+ changeMode(themode, xc);
}
void
-Statistics::changeMode(cpu_mode newmode)
+Statistics::changeMode(cpu_mode newmode, ExecContext *xc)
{
_mode[newmode]++;
@@ -215,7 +203,7 @@ Statistics::changeMode(cpu_mode newmode)
_modeGood[newmode]++;
_modeTicks[themode] += curTick - lastModeTick;
- xc->system->kernelBinning->changeMode(newmode);
+ xc->getSystemPtr()->kernelBinning->changeMode(newmode);
lastModeTick = curTick;
themode = newmode;
@@ -238,9 +226,9 @@ Statistics::swpipl(int ipl)
}
void
-Statistics::mode(cpu_mode newmode)
+Statistics::mode(cpu_mode newmode, ExecContext *xc)
{
- Addr pcbb = xc->regs.ipr[AlphaISA::IPR_PALtemp23];
+ Addr pcbb = xc->readMiscReg(AlphaISA::IPR_PALtemp23);
if ((newmode == kernel || newmode == interrupt) &&
pcbb == idleProcess)
@@ -249,20 +237,20 @@ Statistics::mode(cpu_mode newmode)
if (bin_int == false && newmode == interrupt)
newmode = kernel;
- changeMode(newmode);
+ changeMode(newmode, xc);
}
void
-Statistics::context(Addr oldpcbb, Addr newpcbb)
+Statistics::context(Addr oldpcbb, Addr newpcbb, ExecContext *xc)
{
assert(themode != user);
_swap_context++;
- changeMode(newpcbb == idleProcess ? idle : kernel);
+ changeMode(newpcbb == idleProcess ? idle : kernel, xc);
}
void
-Statistics::callpal(int code)
+Statistics::callpal(int code, ExecContext *xc)
{
if (!PAL::name(code))
return;
@@ -271,7 +259,7 @@ Statistics::callpal(int code)
switch (code) {
case PAL::callsys: {
- int number = xc->regs.intRegFile[0];
+ int number = xc->readIntReg(0);
if (SystemCalls<Tru64>::validSyscallNumber(number)) {
int cvtnum = SystemCalls<Tru64>::convert(number);
_syscall[cvtnum]++;
@@ -279,8 +267,8 @@ Statistics::callpal(int code)
} break;
case PAL::swpctx:
- if (xc->system->kernelBinning)
- xc->system->kernelBinning->palSwapContext(xc);
+ if (xc->getSystemPtr()->kernelBinning)
+ xc->getSystemPtr()->kernelBinning->palSwapContext(xc);
break;
}
}
diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh
index 62dd84a28..16ec721d0 100644
--- a/kern/kernel_stats.hh
+++ b/kern/kernel_stats.hh
@@ -41,7 +41,6 @@ class ExecContext;
class FnEvent;
// What does kernel stats expect is included?
class System;
-enum Fault;
namespace Kernel {
@@ -106,7 +105,7 @@ class Binning
cpu_mode themode;
void palSwapContext(ExecContext *xc);
- void execute(ExecContext *xc, StaticInstPtr<TheISA> inst);
+ void execute(ExecContext *xc, StaticInstPtr inst);
void call(ExecContext *xc, Stats::MainBin *myBin);
void changeMode(cpu_mode mode);
@@ -124,18 +123,18 @@ class Binning
class Statistics : public Serializable
{
+ private:
friend class Binning;
private:
std::string myname;
- ExecContext *xc;
Addr idleProcess;
cpu_mode themode;
Tick lastModeTick;
bool bin_int;
- void changeMode(cpu_mode newmode);
+ void changeMode(cpu_mode newmode, ExecContext *xc);
private:
Stats::Scalar<> _arm;
@@ -151,7 +150,7 @@ class Statistics : public Serializable
Stats::Vector<> _callpal;
Stats::Vector<> _syscall;
- Stats::Vector<> _faults;
+// Stats::Vector<> _faults;
Stats::Vector<> _mode;
Stats::Vector<> _modeGood;
@@ -165,7 +164,7 @@ class Statistics : public Serializable
Tick iplLastTick;
public:
- Statistics(ExecContext *context);
+ Statistics(System *system);
const std::string name() const { return myname; }
void regStats(const std::string &name);
@@ -176,13 +175,12 @@ class Statistics : public Serializable
void ivlb() { _ivlb++; }
void ivle() { _ivle++; }
void hwrei() { _hwrei++; }
- void fault(Fault fault) { _faults[fault]++; }
void swpipl(int ipl);
- void mode(cpu_mode newmode);
- void context(Addr oldpcbb, Addr newpcbb);
- void callpal(int code);
+ 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);
+ void setIdleProcess(Addr idle, ExecContext *xc);
public:
virtual void serialize(std::ostream &os);
diff --git a/kern/linux/aligned.hh b/kern/linux/aligned.hh
deleted file mode 100644
index 18d1b43c0..000000000
--- a/kern/linux/aligned.hh
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2004 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_ALIGNED_HH__
-#define __KERN_LINUX_ALIGNED_HH__
-
-
-/* GCC 3.3.X has a bug in which attributes+typedefs don't work. 3.2.X is fine
- * as in 3.4.X, but the bug is marked will not fix in 3.3.X so here is
- * the work around.
- */
-#if __GNUC__ == 3 && __GNUC_MINOR__ != 3
-typedef uint64_t uint64_ta __attribute__ ((aligned (8))) ;
-typedef int64_t int64_ta __attribute__ ((aligned (8))) ;
-typedef Addr Addr_a __attribute__ ((aligned (8))) ;
-#else
-#define uint64_ta uint64_t __attribute__ ((aligned (8)))
-#define int64_ta int64_t __attribute__ ((aligned (8)))
-#define Addr_a Addr __attribute__ ((aligned (8)))
-#endif /* __GNUC__ __GNUC_MINOR__ */
-
-#endif /* __KERN_LINUX_ALIGNED_HH__ */
diff --git a/kern/freebsd/freebsd_system.hh b/kern/linux/events.cc
index ecb842ec6..9f50eef04 100644
--- a/kern/freebsd/freebsd_system.hh
+++ b/kern/linux/events.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * 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
@@ -26,31 +26,30 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __KERN_FREEBSD_FREEBSD_SYSTEM_HH__
-#define __KERN_FREEBSD_FREEBSD_SYSTEM_HH__
-
+#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"
-class FreebsdSystem : public System
-{
- private:
- class SkipCalibrateClocksEvent : public SkipFuncEvent
- {
- public:
- SkipCalibrateClocksEvent(PCEventQueue *q, const std::string &desc,
- Addr addr)
- : SkipFuncEvent(q, desc, addr) {}
- virtual void process(ExecContext *xc);
- };
- SkipFuncEvent *skipDelayEvent;
- SkipCalibrateClocksEvent *skipCalibrateClocks;
+namespace Linux {
- public:
- FreebsdSystem(Params *p);
- ~FreebsdSystem();
- void doCalibrateClocks(ExecContext *xc);
+void
+DebugPrintkEvent::process(ExecContext *xc)
+{
+ if (DTRACE(DebugPrintf)) {
+ if (!raw) {
+ StringWrap name(xc->getSystemPtr()->name() + ".dprintk");
+ DPRINTFN("");
+ }
-};
+ AlphaArguments args(xc);
+ Printk(args);
+ SkipFuncEvent::process(xc);
+ }
+}
-#endif // __KERN_FREEBSD_FREEBSD_SYSTEM_HH__
+} // namespace linux
diff --git a/kern/linux/thread_info.hh b/kern/linux/events.hh
index cf24ef939..95c268976 100644
--- a/kern/linux/thread_info.hh
+++ b/kern/linux/events.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005 The Regents of The University of Michigan
+ * 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
@@ -26,16 +26,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef __KERN_LINUX_THREAD_INFO_H__
-#define __KERN_LINUX_THREAD_INFO_H__
+#ifndef __KERN_LINUX_EVENTS_HH__
+#define __KERN_LINUX_EVENTS_HH__
-#include "kern/linux/hwrpb.hh"
+#include "kern/system_events.hh"
namespace Linux {
- struct thread_info {
- struct pcb_struct pcb;
- Addr_a task;
- };
+
+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 // __KERN_LINUX_THREAD_INFO_H__
+#endif
diff --git a/kern/linux/hwrpb.hh b/kern/linux/hwrpb.hh
deleted file mode 100644
index 4c8ac32e8..000000000
--- a/kern/linux/hwrpb.hh
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 1990 Hewlett-Packard Development Company, L.P.
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use, copy,
- * modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-#ifndef __KERN_LINUX_HWRPB_HH__
-#define __KERN_LINUX_HWRPB_HH__
-
-#include "kern/linux/aligned.hh"
-
-namespace Linux {
- struct pcb_struct {
- uint64_ta rpb_ksp;
- uint64_ta rpb_usp;
- uint64_ta rpb_ptbr;
- uint32_t rpb_cc;
- uint32_t rpb_psn;
- uint64_ta rpb_unique;
- uint64_ta rpb_fen;
- uint64_ta res1, res2;
- };
-}
-#endif // __KERN_LINUX_HWRPB_HH__
diff --git a/kern/linux/linux.hh b/kern/linux/linux.hh
index b083b5a31..0dbccf546 100644
--- a/kern/linux/linux.hh
+++ b/kern/linux/linux.hh
@@ -28,7 +28,314 @@
#ifndef __LINUX_HH__
#define __LINUX_HH__
+#include "config/full_system.hh"
+
+#if FULL_SYSTEM
class Linux {};
+#else //!FULL_SYSTEM
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h> // for host open() flags
+#include <string.h> // for memset()
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "sim/syscall_emul.hh"
+
+///
+/// This class encapsulates the types, structures, constants,
+/// functions, and syscall-number mappings specific to the Alpha Linux
+/// syscall interface.
+///
+class Linux {
+
+ public:
+
+ //@{
+ /// Basic Linux types.
+ typedef uint64_t size_t;
+ typedef uint64_t off_t;
+ typedef int64_t time_t;
+ typedef uint32_t uid_t;
+ typedef uint32_t gid_t;
+ //@}
+
+#if BSD_HOST
+ typedef struct stat hst_stat;
+ typedef struct stat hst_stat64;
+#else
+ typedef struct stat hst_stat ;
+ typedef struct stat64 hst_stat64;
+#endif
+
+
+ //@{
+ /// open(2) flag values.
+ static const int TGT_O_RDONLY = 00000000; //!< O_RDONLY
+ static const int TGT_O_WRONLY = 00000001; //!< O_WRONLY
+ static const int TGT_O_RDWR = 00000002; //!< O_RDWR
+ static const int TGT_O_NONBLOCK = 00000004; //!< O_NONBLOCK
+ static const int TGT_O_APPEND = 00000010; //!< O_APPEND
+ static const int TGT_O_CREAT = 00001000; //!< O_CREAT
+ static const int TGT_O_TRUNC = 00002000; //!< O_TRUNC
+ static const int TGT_O_EXCL = 00004000; //!< O_EXCL
+ static const int TGT_O_NOCTTY = 00010000; //!< O_NOCTTY
+ static const int TGT_O_SYNC = 00040000; //!< O_SYNC
+ static const int TGT_O_DRD = 00100000; //!< O_DRD
+ static const int TGT_O_DIRECTIO = 00200000; //!< O_DIRECTIO
+ static const int TGT_O_CACHE = 00400000; //!< O_CACHE
+ static const int TGT_O_DSYNC = 02000000; //!< O_DSYNC
+ static const int TGT_O_RSYNC = 04000000; //!< O_RSYNC
+ //@}
+
+ /// This table maps the target open() flags to the corresponding
+ /// host open() flags.
+ static OpenFlagTransTable openFlagTable[];
+
+ /// Number of entries in openFlagTable[].
+ static const int NUM_OPEN_FLAGS;
+
+ /// Stat buffer. Note that we can't call it 'stat' since that
+ /// gets #defined to something else on some systems.
+ struct tgt_stat {
+ uint32_t st_dev; //!< device
+ uint32_t st_ino; //!< inode
+ uint32_t st_mode; //!< mode
+ uint32_t st_nlink; //!< link count
+ uint32_t st_uid; //!< owner's user ID
+ uint32_t st_gid; //!< owner's group ID
+ uint32_t st_rdev; //!< device number
+ int32_t _pad1; //!< for alignment
+ int64_t st_size; //!< file size in bytes
+ uint64_t st_atimeX; //!< time of last access
+ uint64_t st_mtimeX; //!< time of last modification
+ uint64_t st_ctimeX; //!< time of last status change
+ uint32_t st_blksize; //!< optimal I/O block size
+ int32_t st_blocks; //!< number of blocks allocated
+ uint32_t st_flags; //!< flags
+ uint32_t st_gen; //!< unknown
+ };
+
+ // same for stat64
+ struct tgt_stat64 {
+ uint64_t st_dev;
+ uint64_t st_ino;
+ uint64_t st_rdev;
+ int64_t st_size;
+ uint64_t st_blocks;
+
+ uint32_t st_mode;
+ uint32_t st_uid;
+ uint32_t st_gid;
+ uint32_t st_blksize;
+ uint32_t st_nlink;
+ uint32_t __pad0;
+
+ uint64_t tgt_st_atime;
+ uint64_t st_atime_nsec;
+ uint64_t tgt_st_mtime;
+ uint64_t st_mtime_nsec;
+ uint64_t tgt_st_ctime;
+ uint64_t st_ctime_nsec;
+ int64_t ___unused[3];
+ };
+
+ /// Length of strings in struct utsname (plus 1 for null char).
+ static const int _SYS_NMLN = 65;
+
+ /// Interface struct for uname().
+ struct utsname {
+ char sysname[_SYS_NMLN]; //!< System name.
+ char nodename[_SYS_NMLN]; //!< Node name.
+ char release[_SYS_NMLN]; //!< OS release.
+ char version[_SYS_NMLN]; //!< OS version.
+ char machine[_SYS_NMLN]; //!< Machine type.
+ };
+
+
+ //@{
+ /// ioctl() command codes.
+ static const unsigned TIOCGETP = 0x40067408;
+ static const unsigned TIOCSETP = 0x80067409;
+ static const unsigned TIOCSETN = 0x8006740a;
+ static const unsigned TIOCSETC = 0x80067411;
+ static const unsigned TIOCGETC = 0x40067412;
+ static const unsigned FIONREAD = 0x4004667f;
+ static const unsigned TIOCISATTY = 0x2000745e;
+ static const unsigned TIOCGETS = 0x402c7413;
+ static const unsigned TIOCGETA = 0x40127417;
+ //@}
+
+ /// Resource enumeration for getrlimit().
+ enum rlimit_resources {
+ TGT_RLIMIT_CPU = 0,
+ TGT_RLIMIT_FSIZE = 1,
+ TGT_RLIMIT_DATA = 2,
+ TGT_RLIMIT_STACK = 3,
+ TGT_RLIMIT_CORE = 4,
+ TGT_RLIMIT_RSS = 5,
+ TGT_RLIMIT_NOFILE = 6,
+ TGT_RLIMIT_AS = 7,
+ TGT_RLIMIT_VMEM = 7,
+ TGT_RLIMIT_NPROC = 8,
+ TGT_RLIMIT_MEMLOCK = 9,
+ TGT_RLIMIT_LOCKS = 10
+ };
+
+ /// Limit struct for getrlimit/setrlimit.
+ struct rlimit {
+ uint64_t rlim_cur; //!< soft limit
+ uint64_t rlim_max; //!< hard limit
+ };
+
+
+ /// For mmap().
+ static const unsigned TGT_MAP_ANONYMOUS = 0x10;
+
+ /// For gettimeofday().
+ struct timeval {
+ int64_t tv_sec; //!< seconds
+ int64_t tv_usec; //!< microseconds
+ };
+
+ // For writev/readv
+ struct tgt_iovec {
+ uint64_t iov_base; // void *
+ uint64_t iov_len;
+ };
+
+ //@{
+ /// For getrusage().
+ static const int TGT_RUSAGE_SELF = 0;
+ static const int TGT_RUSAGE_CHILDREN = -1;
+ static const int TGT_RUSAGE_BOTH = -2;
+ //@}
+
+ /// For getrusage().
+ struct rusage {
+ struct timeval ru_utime; //!< user time used
+ struct timeval ru_stime; //!< system time used
+ int64_t ru_maxrss; //!< max rss
+ int64_t ru_ixrss; //!< integral shared memory size
+ int64_t ru_idrss; //!< integral unshared data "
+ int64_t ru_isrss; //!< integral unshared stack "
+ int64_t ru_minflt; //!< page reclaims - total vmfaults
+ int64_t ru_majflt; //!< page faults
+ int64_t ru_nswap; //!< swaps
+ int64_t ru_inblock; //!< block input operations
+ int64_t ru_oublock; //!< block output operations
+ int64_t ru_msgsnd; //!< messages sent
+ int64_t ru_msgrcv; //!< messages received
+ int64_t ru_nsignals; //!< signals received
+ int64_t ru_nvcsw; //!< voluntary context switches
+ int64_t ru_nivcsw; //!< involuntary "
+ };
+
+ /// Helper function to convert a host stat buffer to a target stat
+ /// buffer. Also copies the target buffer out to the simulated
+ /// memory space. Used by stat(), fstat(), and lstat().
+#if !BSD_HOST
+ static void
+ copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat *host)
+ {
+ TypedBufferArg<Linux::tgt_stat> tgt(addr);
+
+ tgt->st_dev = htog(host->st_dev);
+ tgt->st_ino = htog(host->st_ino);
+ tgt->st_mode = htog(host->st_mode);
+ tgt->st_nlink = htog(host->st_nlink);
+ tgt->st_uid = htog(host->st_uid);
+ tgt->st_gid = htog(host->st_gid);
+ tgt->st_rdev = htog(host->st_rdev);
+ tgt->st_size = htog(host->st_size);
+ tgt->st_atimeX = htog(host->st_atime);
+ tgt->st_mtimeX = htog(host->st_mtime);
+ tgt->st_ctimeX = htog(host->st_ctime);
+ tgt->st_blksize = htog(host->st_blksize);
+ tgt->st_blocks = htog(host->st_blocks);
+
+ tgt.copyOut(mem);
+ }
+#else
+ // Third version for bsd systems which no longer have any support for
+ // the old stat() call and stat() is actually a stat64()
+ static void
+ copyOutStatBuf(FunctionalMemory *mem, Addr addr, hst_stat64 *host)
+ {
+ TypedBufferArg<Linux::tgt_stat> tgt(addr);
+
+ tgt->st_dev = htog(host->st_dev);
+ tgt->st_ino = htog(host->st_ino);
+ tgt->st_mode = htog(host->st_mode);
+ tgt->st_nlink = htog(host->st_nlink);
+ tgt->st_uid = htog(host->st_uid);
+ tgt->st_gid = htog(host->st_gid);
+ tgt->st_rdev = htog(host->st_rdev);
+ tgt->st_size = htog(host->st_size);
+ tgt->st_atimeX = htog(host->st_atime);
+ tgt->st_mtimeX = htog(host->st_mtime);
+ tgt->st_ctimeX = htog(host->st_ctime);
+ tgt->st_blksize = htog(host->st_blksize);
+ tgt->st_blocks = htog(host->st_blocks);
+
+ tgt.copyOut(mem);
+ }
+#endif
+
+
+ // Same for stat64
+ static void
+ copyOutStat64Buf(FunctionalMemory *mem, int fd, Addr addr, hst_stat64 *host)
+ {
+ TypedBufferArg<Linux::tgt_stat64> tgt(addr);
+
+ // fd == 1 checks are because libc does some checks
+ // that the stdout is interactive vs. a file
+ // this makes it work on non-linux systems
+ if (fd == 1)
+ tgt->st_dev = htog((uint64_t)0xA);
+ else
+ tgt->st_dev = htog((uint64_t)host->st_dev);
+ // XXX What about STAT64_HAS_BROKEN_ST_INO ???
+ tgt->st_ino = htog((uint64_t)host->st_ino);
+ if (fd == 1)
+ tgt->st_rdev = htog((uint64_t)0x880d);
+ else
+ tgt->st_rdev = htog((uint64_t)host->st_rdev);
+ tgt->st_size = htog((int64_t)host->st_size);
+ tgt->st_blocks = htog((uint64_t)host->st_blocks);
+
+ if (fd == 1)
+ tgt->st_mode = htog((uint32_t)0x2190);
+ else
+ tgt->st_mode = htog((uint32_t)host->st_mode);
+ tgt->st_uid = htog((uint32_t)host->st_uid);
+ tgt->st_gid = htog((uint32_t)host->st_gid);
+ tgt->st_blksize = htog((uint32_t)host->st_blksize);
+ tgt->st_nlink = htog((uint32_t)host->st_nlink);
+ tgt->tgt_st_atime = htog((uint64_t)host->st_atime);
+ tgt->tgt_st_mtime = htog((uint64_t)host->st_mtime);
+ tgt->tgt_st_ctime = htog((uint64_t)host->st_ctime);
+#if defined(STAT_HAVE_NSEC)
+ tgt->st_atime_nsec = htog(host->st_atime_nsec);
+ tgt->st_mtime_nsec = htog(host->st_mtime_nsec);
+ tgt->st_ctime_nsec = htog(host->st_ctime_nsec);
+#else
+ tgt->st_atime_nsec = 0;
+ tgt->st_mtime_nsec = 0;
+ tgt->st_ctime_nsec = 0;
+#endif
+
+ tgt.copyOut(mem);
+ }
+
+}; // class Linux
+
+
+#endif // FULL_SYSTEM
+
#endif // __LINUX_HH__
diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc
deleted file mode 100644
index 1144b9bdd..000000000
--- a/kern/linux/linux_system.cc
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * @file
- * This code loads the linux kernel, console, pal and patches certain
- * functions. The symbol tables are loaded so that traces can show
- * the executing function and we can skip functions. Various delay
- * loops are skipped and their final values manually computed to speed
- * up boot time.
- */
-
-#include "base/loader/symtab.hh"
-#include "cpu/exec_context.hh"
-#include "cpu/base.hh"
-#include "kern/linux/linux_system.hh"
-#include "kern/linux/linux_threadinfo.hh"
-#include "kern/linux/printk.hh"
-#include "mem/functional/memory_control.hh"
-#include "mem/functional/physical.hh"
-#include "sim/builder.hh"
-#include "dev/platform.hh"
-#include "targetarch/arguments.hh"
-#include "targetarch/vtophys.hh"
-
-using namespace std;
-
-LinuxSystem::LinuxSystem(Params *p)
- : System(p)
-{
- Addr addr = 0;
- Addr paddr = 0;
-
- /**
- * The symbol swapper_pg_dir marks the beginning of the kernel and
- * the location of bootloader passed arguments
- */
- if (!kernelSymtab->findAddress("swapper_pg_dir", KernelStart)) {
- panic("Could not determine start location of kernel");
- }
-
- /**
- * Since we aren't using a bootloader, we have to copy the
- * kernel arguments directly into the kernel's memory.
- */
- paddr = vtophys(physmem, CommandLine());
- char *commandline = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
- if (commandline)
- strncpy(commandline, params->boot_osflags.c_str(), CommandLineSize);
-
- /**
- * find the address of the est_cycle_freq variable and insert it
- * so we don't through the lengthly process of trying to
- * calculated it by using the PIT, RTC, etc.
- */
- if (kernelSymtab->findAddress("est_cycle_freq", addr)) {
- paddr = vtophys(physmem, addr);
- uint8_t *est_cycle_frequency =
- physmem->dma_addr(paddr, sizeof(uint64_t));
-
- if (est_cycle_frequency)
- *(uint64_t *)est_cycle_frequency =
- Clock::Frequency / p->boot_cpu_frequency;
- }
-
-
- /**
- * EV5 only supports 127 ASNs so we are going to tell the kernel that the
- * paritiuclar EV6 we have only supports 127 asns.
- * @todo At some point we should change ev5.hh and the palcode to support
- * 255 ASNs.
- */
- if (kernelSymtab->findAddress("dp264_mv", addr)) {
- paddr = vtophys(physmem, addr);
- char *dp264_mv = (char *)physmem->dma_addr(paddr, sizeof(uint64_t));
-
- if (dp264_mv) {
- *(uint32_t*)(dp264_mv+0x18) = htog((uint32_t)127);
- } else
- panic("could not translate dp264_mv addr\n");
-
- } else
- panic("could not find dp264_mv\n");
-
-#ifndef NDEBUG
- kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
- if (!kernelPanicEvent)
- panic("could not find kernel symbol \'panic\'");
-
-#if 0
- kernelDieEvent = addKernelFuncEvent<BreakPCEvent>("die_if_kernel");
- if (!kernelDieEvent)
- panic("could not find kernel symbol \'die_if_kernel\'");
-#endif
-
-#endif
-
- /**
- * Any time ide_delay_50ms, calibarte_delay or
- * determine_cpu_caches is called just skip the
- * function. Currently determine_cpu_caches only is used put
- * information in proc, however if that changes in the future we
- * will have to fill in the cache size variables appropriately.
- */
-
- skipIdeDelay50msEvent =
- addKernelFuncEvent<SkipFuncEvent>("ide_delay_50ms");
- skipDelayLoopEvent =
- addKernelFuncEvent<SkipDelayLoopEvent>("calibrate_delay");
- skipCacheProbeEvent =
- addKernelFuncEvent<SkipFuncEvent>("determine_cpu_caches");
- debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
- idleStartEvent = addKernelFuncEvent<IdleStartEvent>("cpu_idle");
-
- if (kernelSymtab->findAddress("alpha_switch_to", addr) && DTRACE(Thread)) {
- printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo",
- addr + sizeof(MachInst) * 6);
- } else {
- printThreadEvent = NULL;
- }
-
- if (params->bin_int) {
- intStartEvent = addPalFuncEvent<InterruptStartEvent>("sys_int_21");
- if (!intStartEvent)
- panic("could not find symbol: sys_int_21\n");
-
- intEndEvent = addPalFuncEvent<InterruptEndEvent>("rti_to_kern");
- if (!intEndEvent)
- panic("could not find symbol: rti_to_kern\n");
-
- intEndEvent2 = addPalFuncEvent<InterruptEndEvent>("rti_to_user");
- if (!intEndEvent2)
- panic("could not find symbol: rti_to_user\n");
-
- intEndEvent3 = addKernelFuncEvent<InterruptEndEvent>("do_softirq");
- if (!intEndEvent3)
- panic("could not find symbol: do_softirq\n");
- }
-}
-
-LinuxSystem::~LinuxSystem()
-{
-#ifndef NDEBUG
- delete kernelPanicEvent;
-#endif
- delete skipIdeDelay50msEvent;
- delete skipDelayLoopEvent;
- delete skipCacheProbeEvent;
- delete debugPrintkEvent;
- delete idleStartEvent;
- delete printThreadEvent;
- delete intStartEvent;
- delete intEndEvent;
- delete intEndEvent2;
-}
-
-
-void
-LinuxSystem::setDelayLoop(ExecContext *xc)
-{
- Addr addr = 0;
- if (kernelSymtab->findAddress("loops_per_jiffy", addr)) {
- Addr paddr = vtophys(physmem, addr);
-
- uint8_t *loops_per_jiffy =
- physmem->dma_addr(paddr, sizeof(uint32_t));
-
- Tick cpuFreq = xc->cpu->frequency();
- Tick intrFreq = platform->intrFrequency();
- *(uint32_t *)loops_per_jiffy =
- (uint32_t)((cpuFreq / intrFreq) * 0.9988);
- }
-}
-
-void
-LinuxSystem::SkipDelayLoopEvent::process(ExecContext *xc)
-{
- SkipFuncEvent::process(xc);
- // calculate and set loops_per_jiffy
- ((LinuxSystem *)xc->system)->setDelayLoop(xc);
-}
-
-void
-LinuxSystem::DebugPrintkEvent::process(ExecContext *xc)
-{
- if (DTRACE(DebugPrintf)) {
- if (!raw) {
- StringWrap name(xc->system->name() + ".dprintk");
- DPRINTFN("");
- }
-
- AlphaArguments args(xc);
- Printk(args);
- SkipFuncEvent::process(xc);
- }
-}
-
-void
-LinuxSystem::PrintThreadInfo::process(ExecContext *xc)
-{
- Linux::ThreadInfo ti(xc);
-
- DPRINTF(Thread, "Currently Executing Thread %s, pid %d, started at: %d\n",
- ti.curTaskName(), ti.curTaskPID(), ti.curTaskStart());
-}
-
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
-
- Param<Tick> boot_cpu_frequency;
- SimObjectParam<MemoryController *> memctrl;
- SimObjectParam<PhysicalMemory *> physmem;
-
- Param<string> kernel;
- Param<string> console;
- Param<string> pal;
-
- Param<string> boot_osflags;
- Param<string> readfile;
- Param<unsigned int> init_param;
-
- Param<uint64_t> system_type;
- Param<uint64_t> system_rev;
-
- Param<bool> bin;
- VectorParam<string> binned_fns;
- Param<bool> bin_int;
-
-END_DECLARE_SIM_OBJECT_PARAMS(LinuxSystem)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
-
- INIT_PARAM(boot_cpu_frequency, "Frequency of the boot CPU"),
- INIT_PARAM(memctrl, "memory controller"),
- INIT_PARAM(physmem, "phsyical memory"),
- INIT_PARAM(kernel, "file that contains the kernel code"),
- INIT_PARAM(console, "file that contains the console code"),
- INIT_PARAM(pal, "file that contains palcode"),
- INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
- "a"),
- INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
- INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
- INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 34),
- INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 1<<10),
- INIT_PARAM_DFLT(bin, "is this system to be binned", false),
- INIT_PARAM(binned_fns, "functions to be broken down and binned"),
- INIT_PARAM_DFLT(bin_int, "is interrupt code binned seperately?", true)
-
-END_INIT_SIM_OBJECT_PARAMS(LinuxSystem)
-
-CREATE_SIM_OBJECT(LinuxSystem)
-{
- System::Params *p = new System::Params;
- p->name = getInstanceName();
- p->boot_cpu_frequency = boot_cpu_frequency;
- p->memctrl = memctrl;
- p->physmem = physmem;
- p->kernel_path = kernel;
- p->console_path = console;
- p->palcode = pal;
- p->boot_osflags = boot_osflags;
- p->init_param = init_param;
- p->readfile = readfile;
- p->system_type = system_type;
- p->system_rev = system_rev;
- p->bin = bin;
- p->binned_fns = binned_fns;
- p->bin_int = bin_int;
- return new LinuxSystem(p);
-}
-
-REGISTER_SIM_OBJECT("LinuxSystem", LinuxSystem)
-
diff --git a/kern/linux/linux_system.hh b/kern/linux/linux_system.hh
deleted file mode 100644
index f883bef93..000000000
--- a/kern/linux/linux_system.hh
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * 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_SYSTEM_HH__
-#define __KERN_LINUX_LINUX_SYSTEM_HH__
-
-class ExecContext;
-
-class BreakPCEvent;
-class IdleStartEvent;
-class PrintThreadInfo;
-
-/**
- * This class contains linux specific system code (Loading, Events, Binning).
- * It points to objects that are the system binaries to load and patches them
- * appropriately to work in simulator.
- */
-class LinuxSystem : public System
-{
- private:
- class SkipDelayLoopEvent : public SkipFuncEvent
- {
- public:
- SkipDelayLoopEvent(PCEventQueue *q, const std::string &desc, Addr addr)
- : SkipFuncEvent(q, desc, addr) {}
- virtual void process(ExecContext *xc);
- };
-
- 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);
- };
-
- class PrintThreadInfo : public PCEvent
- {
- public:
- PrintThreadInfo(PCEventQueue *q, const std::string &desc, Addr addr)
- : PCEvent(q, desc, addr) {}
- virtual void process(ExecContext *xc);
- };
-
- /**
- * Addresses defining where the kernel bootloader places various
- * elements. Details found in include/asm-alpha/system.h
- */
- Addr KernelStart; // Lookup the symbol swapper_pg_dir
-
- public:
- Addr InitStack() const { return KernelStart + 0x02000; }
- Addr EmptyPGT() const { return KernelStart + 0x04000; }
- Addr EmptyPGE() const { return KernelStart + 0x08000; }
- Addr ZeroPGE() const { return KernelStart + 0x0A000; }
- Addr StartAddr() const { return KernelStart + 0x10000; }
-
- Addr Param() const { return ZeroPGE() + 0x0; }
- Addr CommandLine() const { return Param() + 0x0; }
- Addr InitrdStart() const { return Param() + 0x100; }
- Addr InitrdSize() const { return Param() + 0x108; }
- static const int CommandLineSize = 256;
-
- private:
-#ifndef NDEBUG
- /** Event to halt the simulator if the kernel calls panic() */
- BreakPCEvent *kernelPanicEvent;
-
- /** Event to halt the simulator if the kernel calls die_if_kernel */
- BreakPCEvent *kernelDieEvent;
-#endif
-
- /**
- * Event to skip determine_cpu_caches() because we don't support
- * the IPRs that the code can access to figure out cache sizes
- */
- SkipFuncEvent *skipCacheProbeEvent;
-
- /** PC based event to skip the ide_delay_50ms() call */
- SkipFuncEvent *skipIdeDelay50msEvent;
-
- /**
- * PC based event to skip the dprink() call and emulate its
- * functionality
- */
- DebugPrintkEvent *debugPrintkEvent;
-
- /**
- * Skip calculate_delay_loop() rather than waiting for this to be
- * calculated
- */
- SkipDelayLoopEvent *skipDelayLoopEvent;
-
- /**
- * Event to print information about thread switches if the trace flag
- * Thread is set
- */
- PrintThreadInfo *printThreadEvent;
-
- /**
- * Event to bin Interrupts seperately from kernel code
- */
- InterruptStartEvent *intStartEvent;
-
- /**
- * Event to bin Interrupts seperately from kernel code
- */
- InterruptEndEvent *intEndEvent;
- InterruptEndEvent *intEndEvent2;
- InterruptEndEvent *intEndEvent3;
-
- /** Grab the PCBB of the idle process when it starts */
- IdleStartEvent *idleStartEvent;
-
- public:
- LinuxSystem(Params *p);
- ~LinuxSystem();
-
- void setDelayLoop(ExecContext *xc);
-};
-
-#endif // __KERN_LINUX_LINUX_SYSTEM_HH__
diff --git a/kern/linux/linux_threadinfo.hh b/kern/linux/linux_threadinfo.hh
deleted file mode 100644
index 0c60b9f5c..000000000
--- a/kern/linux/linux_threadinfo.hh
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (c) 2004 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_TREADNIFO_HH__
-#define __KERN_LINUX_LINUX_TREADNIFO_HH__
-
-#include "kern/linux/thread_info.hh"
-#include "kern/linux/sched.hh"
-#include "targetarch/vptr.hh"
-
-namespace Linux {
-
-class ThreadInfo
-{
- private:
- ExecContext *xc;
-
- public:
- ThreadInfo(ExecContext *exec) : xc(exec) {}
- ~ThreadInfo() {}
-
- inline VPtr<thread_info>
- curThreadInfo()
- {
- Addr current;
-
- /* Each kernel stack is only 2 pages, the start of which is the
- * thread_info struct. So we can get the address by masking off
- * the lower 14 bits.
- */
- current = xc->regs.intRegFile[StackPointerReg] & ~0x3fff;
- return VPtr<thread_info>(xc, current);
- }
-
- inline VPtr<task_struct>
- curTaskInfo()
- {
- Addr task = curThreadInfo()->task;
- return VPtr<task_struct>(xc, task);
- }
-
- std::string
- curTaskName()
- {
- return curTaskInfo()->name;
- }
-
- int32_t
- curTaskPID()
- {
- return curTaskInfo()->pid;
- }
-
- uint64_t
- curTaskStart()
- {
- return curTaskInfo()->start;
- }
-};
-
-/* namespace Linux */ }
-
-#endif // __KERN_LINUX_LINUX_THREADINFO_HH__
diff --git a/kern/linux/printk.cc b/kern/linux/printk.cc
index fbc8bdad1..f5313759b 100644
--- a/kern/linux/printk.cc
+++ b/kern/linux/printk.cc
@@ -30,7 +30,7 @@
#include <algorithm>
#include "base/trace.hh"
-#include "targetarch/arguments.hh"
+#include "arch/arguments.hh"
using namespace std;
diff --git a/kern/system_events.cc b/kern/system_events.cc
index ba3c9274a..9b9861497 100644
--- a/kern/system_events.cc
+++ b/kern/system_events.cc
@@ -29,20 +29,22 @@
#include "encumbered/cpu/full/cpu.hh"
#include "kern/kernel_stats.hh"
+using namespace TheISA;
+
void
SkipFuncEvent::process(ExecContext *xc)
{
- Addr newpc = xc->regs.intRegFile[ReturnAddressReg];
+ Addr newpc = xc->readIntReg(ReturnAddressReg);
DPRINTF(PCEvent, "skipping %s: pc=%x, newpc=%x\n", description,
- xc->regs.pc, newpc);
+ xc->readPC(), newpc);
- xc->regs.pc = newpc;
- xc->regs.npc = xc->regs.pc + sizeof(MachInst);
+ xc->setPC(newpc);
+ xc->setNextPC(xc->readPC() + sizeof(TheISA::MachInst));
- BranchPred *bp = xc->cpu->getBranchPred();
+ BranchPred *bp = xc->getCpuPtr()->getBranchPred();
if (bp != NULL) {
- bp->popRAS(xc->thread_num);
+ bp->popRAS(xc->getThreadNum());
}
}
@@ -59,20 +61,21 @@ FnEvent::process(ExecContext *xc)
if (xc->misspeculating())
return;
- xc->system->kernelBinning->call(xc, mybin);
+ xc->getSystemPtr()->kernelBinning->call(xc, mybin);
}
void
IdleStartEvent::process(ExecContext *xc)
{
- xc->kernelStats->setIdleProcess(xc->regs.ipr[AlphaISA::IPR_PALtemp23]);
+ xc->getCpuPtr()->kernelStats->setIdleProcess(
+ xc->readMiscReg(AlphaISA::IPR_PALtemp23), xc);
remove();
}
void
InterruptStartEvent::process(ExecContext *xc)
{
- xc->kernelStats->mode(Kernel::interrupt);
+ xc->getCpuPtr()->kernelStats->mode(Kernel::interrupt, xc);
}
void
@@ -80,5 +83,5 @@ 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->kernelStats->mode(Kernel::kernel);
+ xc->getCpuPtr()->kernelStats->mode(Kernel::kernel, xc);
}
diff --git a/kern/tru64/dump_mbuf.cc b/kern/tru64/dump_mbuf.cc
index 215930923..c3c37531a 100644
--- a/kern/tru64/dump_mbuf.cc
+++ b/kern/tru64/dump_mbuf.cc
@@ -31,12 +31,16 @@
#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 "targetarch/arguments.hh"
-#include "targetarch/isa_traits.hh"
-#include "targetarch/vtophys.hh"
+#include "sim/system.hh"
+#include "arch/arguments.hh"
+#include "arch/isa_traits.hh"
+#include "arch/vtophys.hh"
+
+using namespace TheISA;
namespace tru64 {
@@ -59,7 +63,7 @@ DumpMbuf(AlphaArguments args)
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->system->name(), (uint8_t *)buffer,
+ Trace::dataDump(curTick, xc->getSystemPtr()->name(), (uint8_t *)buffer,
m.m_len);
delete [] buffer;
diff --git a/kern/tru64/mbuf.hh b/kern/tru64/mbuf.hh
index f89074653..93424858f 100644
--- a/kern/tru64/mbuf.hh
+++ b/kern/tru64/mbuf.hh
@@ -30,7 +30,7 @@
#define __MBUF_HH__
#include "sim/host.hh"
-#include "targetarch/isa_traits.hh"
+#include "arch/isa_traits.hh"
namespace tru64 {
diff --git a/kern/tru64/printf.cc b/kern/tru64/printf.cc
index 12a089c40..77ac17c3a 100644
--- a/kern/tru64/printf.cc
+++ b/kern/tru64/printf.cc
@@ -32,8 +32,8 @@
#include "base/cprintf.hh"
#include "base/trace.hh"
#include "sim/host.hh"
-#include "targetarch/arguments.hh"
-#include "targetarch/vtophys.hh"
+#include "arch/arguments.hh"
+#include "arch/vtophys.hh"
using namespace std;
diff --git a/kern/tru64/tru64.hh b/kern/tru64/tru64.hh
index 07c0d21a7..112f00f31 100644
--- a/kern/tru64/tru64.hh
+++ b/kern/tru64/tru64.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003-2005 The Regents of The University of Michigan
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,1297 @@
#ifndef __TRU64_HH__
#define __TRU64_HH__
+#include "config/full_system.hh"
+
+#if FULL_SYSTEM
class Tru64 {};
+#else //!FULL_SYSTEM
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__)
+#include <sys/param.h>
+#include <sys/mount.h>
+#else
+#include <sys/statfs.h>
+#endif
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h> // for memset()
+#include <unistd.h>
+
+#include "cpu/base.hh"
+#include "sim/root.hh"
+#include "sim/syscall_emul.hh"
+
+using namespace std;
+
+typedef struct stat global_stat;
+typedef struct statfs global_statfs;
+typedef struct dirent global_dirent;
+
+///
+/// This class encapsulates the types, structures, constants,
+/// functions, and syscall-number mappings specific to the Alpha Tru64
+/// syscall interface.
+///
+class Tru64 {
+
+ public:
+
+ //@{
+ /// Basic Tru64 types.
+ typedef uint64_t size_t;
+ typedef uint64_t off_t;
+ typedef uint16_t nlink_t;
+ typedef int32_t dev_t;
+ typedef uint32_t uid_t;
+ typedef uint32_t gid_t;
+ typedef uint32_t time_t;
+ typedef uint32_t mode_t;
+ typedef uint32_t ino_t;
+ typedef struct { int val[2]; } quad;
+ typedef quad fsid_t;
+ //@}
+
+ //@{
+ /// open(2) flag values.
+ static const int TGT_O_RDONLY = 00000000;
+ static const int TGT_O_WRONLY = 00000001;
+ static const int TGT_O_RDWR = 00000002;
+ static const int TGT_O_NONBLOCK = 00000004;
+ static const int TGT_O_APPEND = 00000010;
+ static const int TGT_O_CREAT = 00001000;
+ static const int TGT_O_TRUNC = 00002000;
+ static const int TGT_O_EXCL = 00004000;
+ static const int TGT_O_NOCTTY = 00010000;
+ static const int TGT_O_SYNC = 00040000;
+ static const int TGT_O_DRD = 00100000;
+ static const int TGT_O_DIRECTIO = 00200000;
+ static const int TGT_O_CACHE = 00400000;
+ static const int TGT_O_DSYNC = 02000000;
+ static const int TGT_O_RSYNC = 04000000;
+ //@}
+
+ /// This table maps the target open() flags to the corresponding
+ /// host open() flags.
+ static OpenFlagTransTable openFlagTable[];
+
+ /// Number of entries in openFlagTable[].
+ static const int NUM_OPEN_FLAGS;
+
+ /// Stat buffer. Note that Tru64 v5.0+ use a new "F64" stat
+ /// structure, and a new set of syscall numbers for stat calls.
+ /// On some hosts (notably Linux) define st_atime, st_mtime, and
+ /// st_ctime as macros, so we append an X to get around this.
+ struct F64_stat {
+ dev_t st_dev; //!< st_dev
+ int32_t st_retired1; //!< st_retired1
+ mode_t st_mode; //!< st_mode
+ nlink_t st_nlink; //!< st_nlink
+ uint16_t st_nlink_reserved; //!< st_nlink_reserved
+ uid_t st_uid; //!< st_uid
+ gid_t st_gid; //!< st_gid
+ dev_t st_rdev; //!< st_rdev
+ dev_t st_ldev; //!< st_ldev
+ off_t st_size; //!< st_size
+ time_t st_retired2; //!< st_retired2
+ int32_t st_uatime; //!< st_uatime
+ time_t st_retired3; //!< st_retired3
+ int32_t st_umtime; //!< st_umtime
+ time_t st_retired4; //!< st_retired4
+ int32_t st_uctime; //!< st_uctime
+ int32_t st_retired5; //!< st_retired5
+ int32_t st_retired6; //!< st_retired6
+ uint32_t st_flags; //!< st_flags
+ uint32_t st_gen; //!< st_gen
+ uint64_t st_spare[4]; //!< st_spare[4]
+ ino_t st_ino; //!< st_ino
+ int32_t st_ino_reserved; //!< st_ino_reserved
+ time_t st_atimeX; //!< st_atime
+ int32_t st_atime_reserved; //!< st_atime_reserved
+ time_t st_mtimeX; //!< st_mtime
+ int32_t st_mtime_reserved; //!< st_mtime_reserved
+ time_t st_ctimeX; //!< st_ctime
+ int32_t st_ctime_reserved; //!< st_ctime_reserved
+ uint64_t st_blksize; //!< st_blksize
+ uint64_t st_blocks; //!< st_blocks
+ };
+
+
+ /// Old Tru64 v4.x stat struct.
+ /// Tru64 maintains backwards compatibility with v4.x by
+ /// implementing another set of stat functions using the old
+ /// structure definition and binding them to the old syscall
+ /// numbers.
+
+ struct pre_F64_stat {
+ dev_t st_dev;
+ ino_t st_ino;
+ mode_t st_mode;
+ nlink_t st_nlink;
+ uid_t st_uid __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.
+ };
+
+ //@{
+ /// ioctl() command codes.
+ static const unsigned TIOCGETP = 0x40067408;
+ static const unsigned TIOCSETP = 0x80067409;
+ static const unsigned TIOCSETN = 0x8006740a;
+ static const unsigned TIOCSETC = 0x80067411;
+ static const unsigned TIOCGETC = 0x40067412;
+ static const unsigned FIONREAD = 0x4004667f;
+ static const unsigned TIOCISATTY = 0x2000745e;
+ // TIOCGETS not defined in tru64, so I made up a number
+ static const unsigned TIOCGETS = 0x40000000;
+ static const unsigned TIOCGETA = 0x402c7413;
+ //@}
+
+ /// Resource enumeration for getrlimit().
+ enum rlimit_resources {
+ TGT_RLIMIT_CPU = 0,
+ TGT_RLIMIT_FSIZE = 1,
+ TGT_RLIMIT_DATA = 2,
+ TGT_RLIMIT_STACK = 3,
+ TGT_RLIMIT_CORE = 4,
+ TGT_RLIMIT_RSS = 5,
+ TGT_RLIMIT_NOFILE = 6,
+ TGT_RLIMIT_AS = 7,
+ TGT_RLIMIT_VMEM = 7
+ };
+
+ /// Limit struct for getrlimit/setrlimit.
+ struct rlimit {
+ uint64_t rlim_cur; //!< soft limit
+ uint64_t rlim_max; //!< hard limit
+ };
+
+
+ /// For mmap().
+ static const unsigned TGT_MAP_ANONYMOUS = 0x10;
+
+
+ //@{
+ /// For getsysinfo().
+ static const unsigned GSI_PLATFORM_NAME = 103; //!< platform name as string
+ static const unsigned GSI_CPU_INFO = 59; //!< CPU information
+ static const unsigned GSI_PROC_TYPE = 60; //!< get proc_type
+ static const unsigned GSI_MAX_CPU = 30; //!< max # cpu's on this machine
+ static const unsigned GSI_CPUS_IN_BOX = 55; //!< number of CPUs in system
+ static const unsigned GSI_PHYSMEM = 19; //!< Physical memory in KB
+ static const unsigned GSI_CLK_TCK = 42; //!< clock freq in Hz
+ //@}
+
+ /// For getsysinfo() GSI_CPU_INFO option.
+ struct cpu_info {
+ uint32_t current_cpu; //!< current_cpu
+ uint32_t cpus_in_box; //!< cpus_in_box
+ uint32_t cpu_type; //!< cpu_type
+ uint32_t ncpus; //!< ncpus
+ uint64_t cpus_present; //!< cpus_present
+ uint64_t cpus_running; //!< cpus_running
+ uint64_t cpu_binding; //!< cpu_binding
+ uint64_t cpu_ex_binding; //!< cpu_ex_binding
+ uint32_t mhz; //!< mhz
+ uint32_t unused[3]; //!< future expansion
+ };
+
+ //@{
+ /// For setsysinfo().
+ static const unsigned SSI_IEEE_FP_CONTROL = 14; //!< ieee_set_fp_control()
+ //@}
+
+ /// For gettimeofday.
+ struct timeval {
+ uint32_t tv_sec; //!< seconds
+ uint32_t tv_usec; //!< microseconds
+ };
+
+ //@{
+ /// For getrusage().
+ static const int TGT_RUSAGE_THREAD = 1;
+ static const int TGT_RUSAGE_SELF = 0;
+ static const int TGT_RUSAGE_CHILDREN = -1;
+ //@}
+
+ /// For getrusage().
+ struct rusage {
+ struct timeval ru_utime; //!< user time used
+ struct timeval ru_stime; //!< system time used
+ uint64_t ru_maxrss; //!< ru_maxrss
+ uint64_t ru_ixrss; //!< integral shared memory size
+ uint64_t ru_idrss; //!< integral unshared data "
+ uint64_t ru_isrss; //!< integral unshared stack "
+ uint64_t ru_minflt; //!< page reclaims - total vmfaults
+ uint64_t ru_majflt; //!< page faults
+ uint64_t ru_nswap; //!< swaps
+ uint64_t ru_inblock; //!< block input operations
+ uint64_t ru_oublock; //!< block output operations
+ uint64_t ru_msgsnd; //!< messages sent
+ uint64_t ru_msgrcv; //!< messages received
+ uint64_t ru_nsignals; //!< signals received
+ uint64_t ru_nvcsw; //!< voluntary context switches
+ uint64_t ru_nivcsw; //!< involuntary "
+ };
+
+ /// For sigreturn().
+ struct sigcontext {
+ int64_t sc_onstack; //!< sigstack state to restore
+ int64_t sc_mask; //!< signal mask to restore
+ int64_t sc_pc; //!< pc at time of signal
+ int64_t sc_ps; //!< psl to retore
+ int64_t sc_regs[32]; //!< processor regs 0 to 31
+ int64_t sc_ownedfp; //!< fp has been used
+ int64_t sc_fpregs[32]; //!< fp regs 0 to 31
+ uint64_t sc_fpcr; //!< floating point control reg
+ uint64_t sc_fp_control; //!< software fpcr
+ int64_t sc_reserved1; //!< reserved for kernel
+ uint32_t sc_kreserved1; //!< reserved for kernel
+ uint32_t sc_kreserved2; //!< reserved for kernel
+ size_t sc_ssize; //!< stack size
+ caddr_t sc_sbase; //!< stack start
+ uint64_t sc_traparg_a0; //!< a0 argument to trap on exc
+ uint64_t sc_traparg_a1; //!< a1 argument to trap on exc
+ uint64_t sc_traparg_a2; //!< a2 argument to trap on exc
+ uint64_t sc_fp_trap_pc; //!< imprecise pc
+ uint64_t sc_fp_trigger_sum; //!< Exception summary at trigg
+ uint64_t sc_fp_trigger_inst; //!< Instruction at trigger pc
+ };
+
+
+ /// For table().
+ static const int TBL_SYSINFO = 12;
+
+ /// For table().
+ struct tbl_sysinfo {
+ uint64_t si_user; //!< User time
+ uint64_t si_nice; //!< Nice time
+ uint64_t si_sys; //!< System time
+ uint64_t si_idle; //!< Idle time
+ uint64_t si_hz; //!< hz
+ uint64_t si_phz; //!< phz
+ uint64_t si_boottime; //!< Boot time in seconds
+ uint64_t wait; //!< Wait time
+ uint32_t si_max_procs; //!< rpb->rpb_numprocs
+ uint32_t pad; //!< padding
+ };
+
+
+ /// For stack_create.
+ struct vm_stack {
+ // was void *
+ Addr address; //!< address hint
+ size_t rsize; //!< red zone size
+ size_t ysize; //!< yellow zone size
+ size_t gsize; //!< green zone size
+ size_t swap; //!< amount of swap to reserve
+ size_t incr; //!< growth increment
+ uint64_t align; //!< address alignment
+ uint64_t flags; //!< MAP_FIXED etc.
+ // was struct memalloc_attr *
+ Addr attr; //!< allocation policy
+ uint64_t reserved; //!< reserved
+ };
+
+ /// Return values for nxm calls.
+ enum {
+ KERN_NOT_RECEIVER = 7,
+ KERN_NOT_IN_SET = 12
+ };
+
+ /// For nxm_task_init.
+ static const int NXM_TASK_INIT_VP = 2; //!< initial thread is VP
+
+ /// Task attribute structure.
+ struct nxm_task_attr {
+ int64_t nxm_callback; //!< nxm_callback
+ unsigned int nxm_version; //!< nxm_version
+ unsigned short nxm_uniq_offset; //!< nxm_uniq_offset
+ unsigned short flags; //!< flags
+ int nxm_quantum; //!< nxm_quantum
+ int pad1; //!< pad1
+ int64_t pad2; //!< pad2
+ };
+
+ /// Signal set.
+ typedef uint64_t sigset_t;
+
+ /// Thread state shared between user & kernel.
+ struct ushared_state {
+ sigset_t sigmask; //!< thread signal mask
+ sigset_t sig; //!< thread pending mask
+ // struct nxm_pth_state *
+ Addr pth_id; //!< out-of-line state
+ int flags; //!< shared flags
+#define US_SIGSTACK 0x1 // thread called sigaltstack
+#define US_ONSTACK 0x2 // thread is running on altstack
+#define US_PROFILE 0x4 // thread called profil
+#define US_SYSCALL 0x8 // thread in syscall
+#define US_TRAP 0x10 // thread has trapped
+#define US_YELLOW 0x20 // thread has mellowed yellow
+#define US_YZONE 0x40 // thread has zoned out
+#define US_FP_OWNED 0x80 // thread used floating point
+
+ int cancel_state; //!< thread's cancelation state
+#define US_CANCEL 0x1 // cancel pending
+#define US_NOCANCEL 0X2 // synch cancel disabled
+#define US_SYS_NOCANCEL 0x4 // syscall cancel disabled
+#define US_ASYNC_NOCANCEL 0x8 // asynch cancel disabled
+#define US_CANCEL_BITS (US_NOCANCEL|US_SYS_NOCANCEL|US_ASYNC_NOCANCEL)
+#define US_CANCEL_MASK (US_CANCEL|US_NOCANCEL|US_SYS_NOCANCEL| \
+ US_ASYNC_NOCANCEL)
+
+ // These are semi-shared. They are always visible to
+ // the kernel but are never context-switched by the library.
+
+ int nxm_ssig; //!< scheduler's synchronous signals
+ int reserved1; //!< reserved1
+ int64_t nxm_active; //!< scheduler active
+ int64_t reserved2; //!< reserved2
+ };
+
+ struct nxm_sched_state {
+ struct ushared_state nxm_u; //!< state own by user thread
+ unsigned int nxm_bits; //!< scheduler state / slot
+ int nxm_quantum; //!< quantum count-down value
+ int nxm_set_quantum; //!< quantum reset value
+ int nxm_sysevent; //!< syscall state
+ // struct nxm_upcall *
+ Addr nxm_uc_ret; //!< stack ptr of null thread
+ // void *
+ Addr nxm_tid; //!< scheduler's thread id
+ int64_t nxm_va; //!< page fault address
+ // struct nxm_pth_state *
+ Addr nxm_pthid; //!< id of null thread
+ uint64_t nxm_bound_pcs_count; //!< bound PCS thread count
+ int64_t pad[2]; //!< pad
+ };
+
+ /// nxm_shared.
+ struct nxm_shared {
+ int64_t nxm_callback; //!< address of upcall routine
+ unsigned int nxm_version; //!< version number
+ unsigned short nxm_uniq_offset; //!< correction factor for TEB
+ unsigned short pad1; //!< pad1
+ int64_t space[2]; //!< future growth
+ struct nxm_sched_state nxm_ss[1]; //!< array of shared areas
+ };
+
+ /// nxm_slot_state_t.
+ enum nxm_slot_state_t {
+ NXM_SLOT_AVAIL,
+ NXM_SLOT_BOUND,
+ NXM_SLOT_UNBOUND,
+ NXM_SLOT_EMPTY
+ };
+
+ /// nxm_config_info
+ struct nxm_config_info {
+ int nxm_nslots_per_rad; //!< max number of VP slots per RAD
+ int nxm_nrads; //!< max number of RADs
+ // nxm_slot_state_t *
+ Addr nxm_slot_state; //!< per-VP slot state
+ // struct nxm_shared *
+ Addr nxm_rad[1]; //!< per-RAD shared areas
+ };
+
+ /// For nxm_thread_create.
+ enum nxm_thread_type {
+ NXM_TYPE_SCS = 0,
+ NXM_TYPE_VP = 1,
+ NXM_TYPE_MANAGER = 2
+ };
+
+ /// Thread attributes.
+ struct nxm_thread_attr {
+ int version; //!< version
+ int type; //!< type
+ int cancel_flags; //!< cancel_flags
+ int priority; //!< priority
+ int policy; //!< policy
+ int signal_type; //!< signal_type
+ // void *
+ Addr pthid; //!< pthid
+ sigset_t sigmask; //!< sigmask
+ /// Initial register values.
+ struct {
+ uint64_t pc; //!< pc
+ uint64_t sp; //!< sp
+ uint64_t a0; //!< a0
+ } registers;
+ uint64_t pad2[2]; //!< pad2
+ };
+
+ /// Helper function to convert a host stat buffer to a target stat
+ /// buffer. Also copies the target buffer out to the simulated
+ /// memory space. Used by stat(), fstat(), and lstat().
+ template <class T>
+ static void
+ copyOutStatBuf(FunctionalMemory *mem, Addr addr, global_stat *host)
+ {
+ TypedBufferArg<T> tgt(addr);
+
+ tgt->st_dev = htog(host->st_dev);
+ tgt->st_ino = htog(host->st_ino);
+ tgt->st_mode = htog(host->st_mode);
+ tgt->st_nlink = htog(host->st_nlink);
+ tgt->st_uid = htog(host->st_uid);
+ tgt->st_gid = htog(host->st_gid);
+ tgt->st_rdev = htog(host->st_rdev);
+ tgt->st_size = htog(host->st_size);
+ tgt->st_atimeX = htog(host->st_atime);
+ tgt->st_mtimeX = htog(host->st_mtime);
+ tgt->st_ctimeX = htog(host->st_ctime);
+ tgt->st_blksize = htog(host->st_blksize);
+ tgt->st_blocks = htog(host->st_blocks);
+
+ tgt.copyOut(mem);
+ }
+
+ /// Helper function to convert a host statfs buffer to a target statfs
+ /// buffer. Also copies the target buffer out to the simulated
+ /// memory space. Used by statfs() and fstatfs().
+ template <class T>
+ static void
+ copyOutStatfsBuf(FunctionalMemory *mem, Addr addr, global_statfs *host)
+ {
+ TypedBufferArg<T> tgt(addr);
+
+#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD__)
+ tgt->f_type = 0;
+#else
+ tgt->f_type = htog(host->f_type);
+#endif
+ tgt->f_bsize = htog(host->f_bsize);
+ tgt->f_blocks = htog(host->f_blocks);
+ tgt->f_bfree = htog(host->f_bfree);
+ tgt->f_bavail = htog(host->f_bavail);
+ tgt->f_files = htog(host->f_files);
+ tgt->f_ffree = htog(host->f_ffree);
+
+ // Is this as string normally?
+ memcpy(&tgt->f_fsid, &host->f_fsid, sizeof(host->f_fsid));
+
+ tgt.copyOut(mem);
+ }
+
+ class F64 {
+ public:
+ static void copyOutStatBuf(FunctionalMemory *mem, Addr addr,
+ global_stat *host)
+ {
+ Tru64::copyOutStatBuf<Tru64::F64_stat>(mem, addr, host);
+ }
+
+ static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr,
+ global_statfs *host)
+ {
+ Tru64::copyOutStatfsBuf<Tru64::F64_statfs>(mem, addr, host);
+ }
+ };
+
+ class PreF64 {
+ public:
+ static void copyOutStatBuf(FunctionalMemory *mem, Addr addr,
+ global_stat *host)
+ {
+ Tru64::copyOutStatBuf<Tru64::pre_F64_stat>(mem, addr, host);
+ }
+
+ static void copyOutStatfsBuf(FunctionalMemory *mem, Addr addr,
+ global_statfs *host)
+ {
+ Tru64::copyOutStatfsBuf<Tru64::pre_F64_statfs>(mem, addr, host);
+ }
+ };
+
+ /// Helper function to convert a host stat buffer to an old pre-F64
+ /// (4.x) target stat buffer. Also copies the target buffer out to
+ /// the simulated memory space. Used by pre_F64_stat(),
+ /// pre_F64_fstat(), and pre_F64_lstat().
+ static void
+ copyOutPreF64StatBuf(FunctionalMemory *mem, Addr addr, struct stat *host)
+ {
+ TypedBufferArg<Tru64::pre_F64_stat> tgt(addr);
+
+ tgt->st_dev = htog(host->st_dev);
+ tgt->st_ino = htog(host->st_ino);
+ tgt->st_mode = htog(host->st_mode);
+ tgt->st_nlink = htog(host->st_nlink);
+ tgt->st_uid = htog(host->st_uid);
+ tgt->st_gid = htog(host->st_gid);
+ tgt->st_rdev = htog(host->st_rdev);
+ tgt->st_size = htog(host->st_size);
+ tgt->st_atimeX = htog(host->st_atime);
+ tgt->st_mtimeX = htog(host->st_mtime);
+ tgt->st_ctimeX = htog(host->st_ctime);
+ tgt->st_blksize = htog(host->st_blksize);
+ tgt->st_blocks = htog(host->st_blocks);
+
+ tgt.copyOut(mem);
+ }
+
+
+ /// The target system's hostname.
+ static const char *hostname;
+
+
+ /// Target getdirentries() handler.
+ static SyscallReturn
+ getdirentriesFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+#ifdef __CYGWIN__
+ panic("getdirent not implemented on cygwin!");
+#else
+ int fd = process->sim_fd(xc->getSyscallArg(0));
+ Addr tgt_buf = xc->getSyscallArg(1);
+ int tgt_nbytes = xc->getSyscallArg(2);
+ Addr tgt_basep = xc->getSyscallArg(3);
+
+ char * const host_buf = new char[tgt_nbytes];
+
+ // just pass basep through uninterpreted.
+ TypedBufferArg<int64_t> basep(tgt_basep);
+ basep.copyIn(xc->getMemPtr());
+ 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->getMemPtr());
+
+ tgt_buf_ptr += tgt_bufsize;
+ host_buf_ptr += host_dp->d_reclen;
+ }
+
+ delete [] host_buf;
+
+ *basep = htog((int64_t)host_basep);
+ basep.copyOut(xc->getMemPtr());
+
+ return tgt_buf_ptr - tgt_buf;
+#endif
+ }
+
+ /// Target sigreturn() handler.
+ static SyscallReturn
+ sigreturnFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ using TheISA::RegFile;
+ TypedBufferArg<Tru64::sigcontext> sc(xc->getSyscallArg(0));
+
+ sc.copyIn(xc->getMemPtr());
+
+ // 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->setFloatRegInt(i, htog(sc->sc_fpregs[i]));
+ }
+
+ xc->setMiscReg(TheISA::Fpcr_DepTag, htog(sc->sc_fpcr));
+
+ return 0;
+ }
+
+ /// Target table() handler.
+ static SyscallReturn
+ tableFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ int id = xc->getSyscallArg(0); // table ID
+ int index = xc->getSyscallArg(1); // index into table
+ // arg 2 is buffer pointer; type depends on table ID
+ int nel = xc->getSyscallArg(3); // number of elements
+ int lel = xc->getSyscallArg(4); // expected element size
+
+ switch (id) {
+ case Tru64::TBL_SYSINFO: {
+ if (index != 0 || nel != 1 || lel != sizeof(Tru64::tbl_sysinfo))
+ return -EINVAL;
+ TypedBufferArg<Tru64::tbl_sysinfo> elp(xc->getSyscallArg(2));
+
+ const int clk_hz = one_million;
+ elp->si_user = htog(curTick / (Clock::Frequency / clk_hz));
+ elp->si_nice = htog(0);
+ elp->si_sys = htog(0);
+ elp->si_idle = htog(0);
+ elp->wait = htog(0);
+ elp->si_hz = htog(clk_hz);
+ elp->si_phz = htog(clk_hz);
+ elp->si_boottime = htog(seconds_since_epoch); // seconds since epoch?
+ elp->si_max_procs = htog(process->numCpus());
+ elp.copyOut(xc->getMemPtr());
+ return 0;
+ }
+
+ default:
+ cerr << "table(): id " << id << " unknown." << endl;
+ return -EINVAL;
+ }
+ }
+
+ //
+ // Mach syscalls -- identified by negated syscall numbers
+ //
+
+ /// Create a stack region for a thread.
+ static SyscallReturn
+ stack_createFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ TypedBufferArg<Tru64::vm_stack> argp(xc->getSyscallArg(0));
+
+ argp.copyIn(xc->getMemPtr());
+
+ // 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->getMemPtr());
+ }
+
+ return 0;
+ }
+
+ /// NXM library version stamp.
+ static
+ const int NXM_LIB_VERSION = 301003;
+
+ /// This call sets up the interface between the user and kernel
+ /// schedulers by creating a shared-memory region. The shared memory
+ /// region has several structs, some global, some per-RAD, some per-VP.
+ static SyscallReturn
+ nxm_task_initFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ TypedBufferArg<Tru64::nxm_task_attr> attrp(xc->getSyscallArg(0));
+ TypedBufferArg<Addr> configptr_ptr(xc->getSyscallArg(1));
+
+ attrp.copyIn(xc->getMemPtr());
+
+ 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->getMemPtr());
+
+ // 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->getMemPtr());
+
+ // 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->getMemPtr());
+
+ //
+ // copy pointer to shared config area out to user
+ //
+ *configptr_ptr = htog(config_addr);
+ configptr_ptr.copyOut(xc->getMemPtr());
+
+ // 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)
+ {
+ 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)
+ {
+ 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->getMemPtr());
+
+ 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->getMemPtr());
+
+ 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->getMemPtr());
+
+ 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->getMemPtr());
+
+ 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->getMemPtr());
+
+ 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->getMemPtr());
+
+ // 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->getMemPtr());
+
+ return 0;
+ }
+ }
+
+ // fell out of loop... no available inactive context
+ cerr << "nxm_thread_create: no idle contexts available." << endl;
+ abort();
+ } else {
+ cerr << "nxm_thread_create: can't handle thread type "
+ << attrp->type << endl;
+ abort();
+ }
+
+ return 0;
+ }
+
+ /// Thread idle call (like yield()).
+ static SyscallReturn
+ nxm_idleFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ return 0;
+ }
+
+ /// Block thread.
+ static SyscallReturn
+ nxm_thread_blockFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ uint64_t tid = xc->getSyscallArg(0);
+ uint64_t secs = xc->getSyscallArg(1);
+ uint64_t flags = xc->getSyscallArg(2);
+ uint64_t action = xc->getSyscallArg(3);
+ uint64_t usecs = xc->getSyscallArg(4);
+
+ cout << xc->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)
+ {
+ 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)
+ {
+ 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)
+ {
+ int num_activated = 0;
+
+ list<Process::WaitRec>::iterator i = process->waitList.begin();
+ list<Process::WaitRec>::iterator end = process->waitList.end();
+
+ while (i != end && (num_activated == 0 || activate_all)) {
+ if (i->waitChan == uaddr) {
+ // found waiting process: make it active
+ ExecContext *newCtx = i->waitingContext;
+ assert(newCtx->status() == ExecContext::Suspended);
+ newCtx->activate();
+
+ // get rid of this record
+ i = process->waitList.erase(i);
+
+ ++num_activated;
+ } else {
+ ++i;
+ }
+ }
+
+ return num_activated;
+ }
+
+ /// M5 hacked-up lock acquire.
+ static void
+ m5_lock_mutex(Addr uaddr, Process *process, ExecContext *xc)
+ {
+ TypedBufferArg<uint64_t> lockp(uaddr);
+
+ lockp.copyIn(xc->getMemPtr());
+
+ if (gtoh(*lockp) == 0) {
+ // lock is free: grab it
+ *lockp = htog(1);
+ lockp.copyOut(xc->getMemPtr());
+ } 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->getMemPtr());
+ 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->getMemPtr());
+ }
+ }
+
+ /// Lock acquire syscall handler.
+ static SyscallReturn
+ m5_mutex_lockFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr uaddr = xc->getSyscallArg(0);
+
+ m5_lock_mutex(uaddr, process, xc);
+
+ // Return 0 since we will always return to the user with the lock
+ // acquired. We will just keep the context inactive until that is
+ // true.
+ return 0;
+ }
+
+ /// Try lock (non-blocking).
+ static SyscallReturn
+ m5_mutex_trylockFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr uaddr = xc->getSyscallArg(0);
+ TypedBufferArg<uint64_t> lockp(uaddr);
+
+ lockp.copyIn(xc->getMemPtr());
+
+ if (gtoh(*lockp) == 0) {
+ // lock is free: grab it
+ *lockp = htog(1);
+ lockp.copyOut(xc->getMemPtr());
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+
+ /// Unlock syscall handler.
+ static SyscallReturn
+ m5_mutex_unlockFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr uaddr = xc->getSyscallArg(0);
+
+ m5_unlock_mutex(uaddr, process, xc);
+
+ return 0;
+ }
+
+ /// Signal ocndition.
+ static SyscallReturn
+ m5_cond_signalFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr cond_addr = xc->getSyscallArg(0);
+
+ // Wake up one process waiting on the condition variable.
+ activate_waiting_context(cond_addr, process);
+
+ return 0;
+ }
+
+ /// Wake up all processes waiting on the condition variable.
+ static SyscallReturn
+ m5_cond_broadcastFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr cond_addr = xc->getSyscallArg(0);
+
+ activate_waiting_context(cond_addr, process, true);
+
+ return 0;
+ }
+
+ /// Wait on a condition.
+ static SyscallReturn
+ m5_cond_waitFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ Addr cond_addr = xc->getSyscallArg(0);
+ Addr lock_addr = xc->getSyscallArg(1);
+ TypedBufferArg<uint64_t> condp(cond_addr);
+ TypedBufferArg<uint64_t> lockp(lock_addr);
+
+ // user is supposed to acquire lock before entering
+ lockp.copyIn(xc->getMemPtr());
+ assert(gtoh(*lockp) != 0);
+
+ m5_unlock_mutex(lock_addr, process, xc);
+
+ process->waitList.push_back(Process::WaitRec(cond_addr, xc));
+ xc->suspend();
+
+ return 0;
+ }
+
+ /// Thread exit.
+ static SyscallReturn
+ m5_thread_exitFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ assert(xc->status() == ExecContext::Active);
+ xc->deallocate();
+
+ return 0;
+ }
+
+ /// Indirect syscall invocation (call #0).
+ static SyscallReturn
+ indirectSyscallFunc(SyscallDesc *desc, int callnum, Process *process,
+ ExecContext *xc)
+ {
+ int new_callnum = xc->getSyscallArg(0);
+ LiveProcess *lp = dynamic_cast<LiveProcess*>(process);
+ assert(lp);
+
+ for (int i = 0; i < 5; ++i)
+ xc->setSyscallArg(i, xc->getSyscallArg(i+1));
+
+
+ SyscallDesc *new_desc = lp->getDesc(new_callnum);
+ if (desc == NULL)
+ fatal("Syscall %d out of range", callnum);
+
+ new_desc->doSyscall(new_callnum, process, xc);
+
+ return 0;
+ }
+
+}; // class Tru64
+
+
+#endif // FULL_SYSTEM
+
#endif // __TRU64_HH__
diff --git a/kern/tru64/tru64_events.cc b/kern/tru64/tru64_events.cc
index 2079922b7..8f2be6d9b 100644
--- a/kern/tru64/tru64_events.cc
+++ b/kern/tru64/tru64_events.cc
@@ -33,8 +33,11 @@
#include "kern/tru64/dump_mbuf.hh"
#include "kern/tru64/printf.hh"
#include "mem/functional/memory_control.hh"
-#include "targetarch/arguments.hh"
-#include "targetarch/isa_traits.hh"
+#include "arch/arguments.hh"
+#include "arch/isa_traits.hh"
+#include "sim/system.hh"
+
+using namespace TheISA;
//void SkipFuncEvent::process(ExecContext *xc);
@@ -45,13 +48,14 @@ BadAddrEvent::process(ExecContext *xc)
// annotation for vmunix::badaddr in:
// simos/simulation/apps/tcl/osf/tlaser.tcl
- uint64_t a0 = xc->regs.intRegFile[ArgumentReg0];
+ uint64_t a0 = xc->readIntReg(ArgumentReg0);
if (!TheISA::IsK0Seg(a0) ||
- xc->memctrl->badaddr(TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask)) {
+ xc->getSystemPtr()->memctrl->badaddr(
+ TheISA::K0Seg2Phys(a0) & EV5::PAddrImplMask)) {
DPRINTF(BADADDR, "badaddr arg=%#x bad\n", a0);
- xc->regs.intRegFile[ReturnValueReg] = 0x1;
+ xc->setIntReg(ReturnValueReg, 0x1);
SkipFuncEvent::process(xc);
}
else
@@ -62,7 +66,7 @@ void
PrintfEvent::process(ExecContext *xc)
{
if (DTRACE(Printf)) {
- DebugOut() << curTick << ": " << xc->cpu->name() << ": ";
+ DebugOut() << curTick << ": " << xc->getCpuPtr()->name() << ": ";
AlphaArguments args(xc);
tru64::Printf(args);
@@ -74,7 +78,7 @@ DebugPrintfEvent::process(ExecContext *xc)
{
if (DTRACE(DebugPrintf)) {
if (!raw)
- DebugOut() << curTick << ": " << xc->cpu->name() << ": ";
+ DebugOut() << curTick << ": " << xc->getCpuPtr()->name() << ": ";
AlphaArguments args(xc);
tru64::Printf(args);
diff --git a/kern/tru64/tru64_system.cc b/kern/tru64/tru64_system.cc
deleted file mode 100644
index f65293474..000000000
--- a/kern/tru64/tru64_system.cc
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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 "base/loader/symtab.hh"
-#include "base/trace.hh"
-#include "cpu/base.hh"
-#include "cpu/exec_context.hh"
-#include "kern/tru64/tru64_events.hh"
-#include "kern/tru64/tru64_system.hh"
-#include "kern/system_events.hh"
-#include "mem/functional/memory_control.hh"
-#include "mem/functional/physical.hh"
-#include "sim/builder.hh"
-#include "targetarch/isa_traits.hh"
-#include "targetarch/vtophys.hh"
-
-using namespace std;
-
-Tru64System::Tru64System(Tru64System::Params *p)
- : System(p)
-{
- Addr addr = 0;
- if (kernelSymtab->findAddress("enable_async_printf", addr)) {
- Addr paddr = vtophys(physmem, addr);
- uint8_t *enable_async_printf =
- physmem->dma_addr(paddr, sizeof(uint32_t));
-
- if (enable_async_printf)
- *(uint32_t *)enable_async_printf = 0;
- }
-
-#ifdef DEBUG
- kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
- if (!kernelPanicEvent)
- panic("could not find kernel symbol \'panic\'");
-#endif
-
- badaddrEvent = addKernelFuncEvent<BadAddrEvent>("badaddr");
- if (!badaddrEvent)
- panic("could not find kernel symbol \'badaddr\'");
-
- skipPowerStateEvent =
- addKernelFuncEvent<SkipFuncEvent>("tl_v48_capture_power_state");
- skipScavengeBootEvent =
- addKernelFuncEvent<SkipFuncEvent>("pmap_scavenge_boot");
-
-#if TRACING_ON
- printfEvent = addKernelFuncEvent<PrintfEvent>("printf");
- debugPrintfEvent = addKernelFuncEvent<DebugPrintfEvent>("m5printf");
- debugPrintfrEvent = addKernelFuncEvent<DebugPrintfrEvent>("m5printfr");
- dumpMbufEvent = addKernelFuncEvent<DumpMbufEvent>("m5_dump_mbuf");
-#endif
-}
-
-Tru64System::~Tru64System()
-{
-#ifdef DEBUG
- delete kernelPanicEvent;
-#endif
- delete badaddrEvent;
- delete skipPowerStateEvent;
- delete skipScavengeBootEvent;
-#if TRACING_ON
- delete printfEvent;
- delete debugPrintfEvent;
- delete debugPrintfrEvent;
- delete dumpMbufEvent;
-#endif
-}
-
-BEGIN_DECLARE_SIM_OBJECT_PARAMS(Tru64System)
-
- Param<Tick> boot_cpu_frequency;
- SimObjectParam<MemoryController *> memctrl;
- SimObjectParam<PhysicalMemory *> physmem;
-
- Param<string> kernel;
- Param<string> console;
- Param<string> pal;
-
- Param<string> boot_osflags;
- Param<string> readfile;
- Param<unsigned int> init_param;
-
- Param<uint64_t> system_type;
- Param<uint64_t> system_rev;
-
- Param<bool> bin;
- VectorParam<string> binned_fns;
-
-END_DECLARE_SIM_OBJECT_PARAMS(Tru64System)
-
-BEGIN_INIT_SIM_OBJECT_PARAMS(Tru64System)
-
- INIT_PARAM(boot_cpu_frequency, "frequency of the boot cpu"),
- INIT_PARAM(memctrl, "memory controller"),
- INIT_PARAM(physmem, "phsyical memory"),
- INIT_PARAM(kernel, "file that contains the kernel code"),
- INIT_PARAM(console, "file that contains the console code"),
- INIT_PARAM(pal, "file that contains palcode"),
- INIT_PARAM_DFLT(boot_osflags, "flags to pass to the kernel during boot",
- "a"),
- INIT_PARAM_DFLT(readfile, "file to read startup script from", ""),
- INIT_PARAM_DFLT(init_param, "numerical value to pass into simulator", 0),
- INIT_PARAM_DFLT(system_type, "Type of system we are emulating", 12),
- INIT_PARAM_DFLT(system_rev, "Revision of system we are emulating", 2<<1),
- INIT_PARAM_DFLT(bin, "is this system to be binned", false),
- INIT_PARAM(binned_fns, "functions to be broken down and binned")
-
-END_INIT_SIM_OBJECT_PARAMS(Tru64System)
-
-CREATE_SIM_OBJECT(Tru64System)
-{
- System::Params *p = new System::Params;
- p->name = getInstanceName();
- p->boot_cpu_frequency = boot_cpu_frequency;
- p->memctrl = memctrl;
- p->physmem = physmem;
- p->kernel_path = kernel;
- p->console_path = console;
- p->palcode = pal;
- p->boot_osflags = boot_osflags;
- p->init_param = init_param;
- p->readfile = readfile;
- p->system_type = system_type;
- p->system_rev = system_rev;
- p->bin = bin;
- p->binned_fns = binned_fns;
- p->bin_int = false;
-
- return new Tru64System(p);
-}
-
-REGISTER_SIM_OBJECT("Tru64System", Tru64System)
diff --git a/kern/tru64/tru64_system.hh b/kern/tru64/tru64_system.hh
deleted file mode 100644
index a9077e112..000000000
--- a/kern/tru64/tru64_system.hh
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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_SYSTEM_HH__
-#define __KERN_TRU64_TRU64_SYSTEM_HH__
-
-#include "sim/system.hh"
-#include "targetarch/isa_traits.hh"
-
-class ExecContext;
-
-class BreakPCEvent;
-class BadAddrEvent;
-class SkipFuncEvent;
-class PrintfEvent;
-class DebugPrintfEvent;
-class DumpMbufEvent;
-class AlphaArguments;
-
-class Tru64System : public System
-{
- private:
-#ifdef DEBUG
- /** Event to halt the simulator if the kernel calls panic() */
- BreakPCEvent *kernelPanicEvent;
-#endif
-
- BadAddrEvent *badaddrEvent;
- SkipFuncEvent *skipPowerStateEvent;
- SkipFuncEvent *skipScavengeBootEvent;
- PrintfEvent *printfEvent;
- DebugPrintfEvent *debugPrintfEvent;
- DebugPrintfrEvent *debugPrintfrEvent;
- DumpMbufEvent *dumpMbufEvent;
-
- public:
- Tru64System(Params *p);
- ~Tru64System();
-
- static void Printf(AlphaArguments args);
- static void DumpMbuf(AlphaArguments args);
-};
-
-#endif // __KERN_TRU64_TRU64_SYSTEM_HH__