summaryrefslogtreecommitdiff
path: root/kern/linux
diff options
context:
space:
mode:
Diffstat (limited to 'kern/linux')
-rw-r--r--kern/linux/aligned.hh21
-rw-r--r--kern/linux/hwrpb.hh18
-rw-r--r--kern/linux/linux_system.cc6
-rw-r--r--kern/linux/linux_system.hh3
-rw-r--r--kern/linux/linux_threadinfo.hh91
-rw-r--r--kern/linux/sched.hh110
-rw-r--r--kern/linux/thread_info.hh27
7 files changed, 276 insertions, 0 deletions
diff --git a/kern/linux/aligned.hh b/kern/linux/aligned.hh
new file mode 100644
index 000000000..55035c6e4
--- /dev/null
+++ b/kern/linux/aligned.hh
@@ -0,0 +1,21 @@
+#ifndef __ALIGNED_HH__
+#define __ALIGNED_HH__
+
+#include <stdint.h>
+#include "targetarch/isa_traits.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 /* __ALIGNED_H__ */
diff --git a/kern/linux/hwrpb.hh b/kern/linux/hwrpb.hh
new file mode 100644
index 000000000..3ce03efd7
--- /dev/null
+++ b/kern/linux/hwrpb.hh
@@ -0,0 +1,18 @@
+#ifndef __ALPHA_HWRPB_H__
+#define __ALPHA_HWRPB_H__
+
+#include "kern/linux/aligned.hh"
+
+namespace Linux {
+ struct pcb_struct {
+ uint64_ta ksp;
+ uint64_ta usp;
+ uint64_ta ptbr;
+ uint32_t pcc;
+ uint32_t asn;
+ uint64_ta unique;
+ uint64_ta flags;
+ uint64_ta res1, res2;
+ };
+}
+#endif /* __ALPHA_HWRPB_H */
diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc
index bc2753908..dd188ffe0 100644
--- a/kern/linux/linux_system.cc
+++ b/kern/linux/linux_system.cc
@@ -132,6 +132,8 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
debugPrintkEvent = new DebugPrintkEvent(&pcEventQueue, "dprintk");
+ printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo");
+
Addr addr = 0;
/**
@@ -242,6 +244,10 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param,
if (kernelSymtab->findAddress("dprintk", addr))
debugPrintkEvent->schedule(addr+sizeof(MachInst)*2);
+
+ if (kernelSymtab->findAddress("alpha_switch_to", addr) &&
+ DTRACE(Thread))
+ printThreadEvent->schedule(addr+sizeof(MachInst)*6);
}
LinuxSystem::~LinuxSystem()
diff --git a/kern/linux/linux_system.hh b/kern/linux/linux_system.hh
index e7cdf140d..fbfcb788f 100644
--- a/kern/linux/linux_system.hh
+++ b/kern/linux/linux_system.hh
@@ -52,6 +52,7 @@ class LinuxSkipDelayLoopEvent;
class SkipFuncEvent;
class FnEvent;
class AlphaArguments;
+class PrintThreadInfo;
/**
* This class contains linux specific system code (Loading, Events, Binning).
@@ -95,6 +96,8 @@ class LinuxSystem : public System
*/
LinuxSkipDelayLoopEvent *skipDelayLoopEvent;
+ PrintThreadInfo *printThreadEvent;
+
/** Begining of kernel code */
Addr kernelStart;
diff --git a/kern/linux/linux_threadinfo.hh b/kern/linux/linux_threadinfo.hh
new file mode 100644
index 000000000..83a746059
--- /dev/null
+++ b/kern/linux/linux_threadinfo.hh
@@ -0,0 +1,91 @@
+/*
+ * 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 __LINUX_TREADNIFO_HH__
+#define __LINUX_TREADNIFO_HH__
+
+
+#include "targetarch/isa_traits.hh"
+#include "targetarch/vptr.hh"
+#include "cpu/exec_context.hh"
+#include "kern/linux/thread_info.hh"
+#include "kern/linux/sched.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);
+ }
+
+ string
+ curTaskName()
+ {
+ return curTaskInfo()->comm;
+ }
+
+ int32_t
+ curTaskPID()
+ {
+ return curTaskInfo()->pid;
+ }
+
+ uint64_t
+ curTaskStart()
+ {
+ return curTaskInfo()->start_time;
+ }
+};
+}
+
+#endif /* __LINUX_THREADINFO_HH__ */
diff --git a/kern/linux/sched.hh b/kern/linux/sched.hh
new file mode 100644
index 000000000..287214b2b
--- /dev/null
+++ b/kern/linux/sched.hh
@@ -0,0 +1,110 @@
+#ifndef __LINUX_SCHED_H__
+#define __LINUX_SCHED_H__
+
+#include "targetarch/isa_traits.hh"
+#include "kern/linux/atomic.hh"
+#include "kern/linux/list.hh"
+#include "kern/linux/wait.hh"
+#include "kern/linux/timer.hh"
+#include "kern/linux/pid.hh"
+#include "kern/linux/aligned.hh"
+
+namespace Linux {
+
+ struct rlimit {
+ uint64_ta rlim_cur;
+ uint64_ta rlim_max;
+ };
+
+ const uint32_t RLIM_NLIMITS = 11;
+
+ struct task_struct {
+ int64_ta state; /* -1 unrunnable, 0 runnable, >0 stopped */
+ Addr_a thread_info;
+ atomic_t usage;
+
+ uint64_ta flags; /* per process flags, defined below */
+ uint64_ta ptrace;
+
+ int32_t lock_depth; /* Lock depth */
+
+ int32_t prio, static_prio;
+
+ struct list_head run_list;
+ Addr_a array;
+
+ uint64_ta sleep_avg;
+ int64_ta interactive_credit;
+ uint64_ta timestamp;
+ int32_t activated;
+
+ uint64_ta policy;
+ uint64_ta cpus_allowed;
+ uint32_t time_slice, first_time_slice;
+
+ struct list_head tasks;
+ struct list_head ptrace_children;
+ struct list_head ptrace_list;
+
+ Addr_a mm, active_mm;
+
+ /* task state */
+ Addr_a binfmt;
+ int32_t exit_code, exit_signal;
+ int32_t pdeath_signal; /* The signal sent when the parent dies */
+ /* ??? */
+ uint64_ta personality;
+ int32_t did_exec:1;
+ int32_t pid;
+ int32_t __pgrp; /* Accessed via process_group() */
+ int32_t tty_old_pgrp;
+ int32_t session;
+ int32_t tgid;
+ /* boolean value for session group leader */
+ int32_t leader;
+ /*
+ * pointers to (original) parent process, youngest child, younger sibling,
+ * older sibling, respectively. (p->father can be replaced with
+ * p->parent->pid)
+ */
+ Addr_a real_parent; /* real parent process (when being debugged) */
+ Addr_a parent; /* parent process */
+ struct list_head children; /* list of my children */
+ struct list_head sibling; /* linkage in my parent's children list */
+ Addr_a group_leader; /* threadgroup leader */
+
+ /* PID/PID hash table linkage. */
+ struct pid_link pids[PIDTYPE_MAX];
+
+ wait_queue_head_t wait_chldexit; /* for wait4() */
+ Addr_a vfork_done; /* for vfork() */
+ Addr_a set_child_tid; /* CLONE_CHILD_SETTID */
+ Addr_a clear_child_tid; /* CLONE_CHILD_CLEARTID */
+
+ uint64_ta rt_priority;
+ uint64_ta it_real_value, it_prof_value, it_virt_value;
+ uint64_ta it_real_incr, it_prof_incr, it_virt_incr;
+ struct timer_list real_timer;
+ struct list_head posix_timers; /* POSIX.1b Interval Timers */
+ uint64_ta utime, stime, cutime, cstime;
+ uint64_ta nvcsw, nivcsw, cnvcsw, cnivcsw; /* context switch counts */
+ uint64_ta start_time;
+ /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
+ uint64_ta min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
+ /* process credentials */
+ uint32_t uid,euid,suid,fsuid;
+ uint32_t gid,egid,sgid,fsgid;
+ Addr_a group_info;
+ uint32_t cap_effective, cap_inheritable, cap_permitted;
+ int32_t keep_capabilities:1;
+ Addr user;
+ /* limits */
+ struct rlimit rlim[RLIM_NLIMITS];
+ uint16_t used_math;
+ char comm[16];
+ };
+
+
+}
+
+#endif
diff --git a/kern/linux/thread_info.hh b/kern/linux/thread_info.hh
new file mode 100644
index 000000000..1b4053a78
--- /dev/null
+++ b/kern/linux/thread_info.hh
@@ -0,0 +1,27 @@
+#ifndef __ALPHA_THREAD_INFO_H__
+#define __ALPHA_THREAD_INFO_H__
+
+#include "kern/linux/hwrpb.hh"
+#include "kern/linux/aligned.hh"
+
+namespace Linux {
+ struct thread_info {
+ struct pcb_struct pcb; /* palcode state */
+
+ Addr_a task; /* main task structure */
+ uint32_t flags; /* low level flags */
+ uint32_t ieee_state; /* see fpu.h */
+
+ Addr_a exec_domain; /* execution domain */
+ uint64_ta addr_limit; /* thread address space */
+ int64_ta cpu; /* current CPU */
+ int32_t preempt_count; /* 0 => preemptable, <0 => BUG */
+
+ int32_t bpt_nsaved;
+ uint64_ta bpt_addr[2]; /* breakpoint handling */
+ uint32_t bpt_insn[2];
+
+ /*restart_block;*/
+ };
+}
+#endif /* __ALPHA_THREAD_INFO_H__ */