summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2010-06-07 16:39:45 -0500
committerPatrick Williams <iawillia@us.ibm.com>2010-06-07 16:39:45 -0500
commit9a4698af6ee4c095a97b8800d2d5f0a4bb282b15 (patch)
tree9f5241ee1f91d21c8043b359d7bfaeb309ecd5b8 /src
parentaa1db69f1de27bba8ee5e128f717557780f21e0d (diff)
downloadtalos-hostboot-9a4698af6ee4c095a97b8800d2d5f0a4bb282b15.tar.gz
talos-hostboot-9a4698af6ee4c095a97b8800d2d5f0a4bb282b15.zip
Add task control syscalls.
Diffstat (limited to 'src')
-rw-r--r--src/include/kernel/syscalls.H3
-rw-r--r--src/include/kernel/task.H2
-rw-r--r--src/include/kernel/taskmgr.H3
-rw-r--r--src/include/sys/syscall.h2
-rw-r--r--src/include/sys/task.h20
-rw-r--r--src/kernel/syscall.C47
-rw-r--r--src/kernel/taskmgr.C3
-rw-r--r--src/lib/makefile3
-rw-r--r--src/lib/syscall_task.C26
-rw-r--r--src/sys/init/init_main.C14
10 files changed, 115 insertions, 8 deletions
diff --git a/src/include/kernel/syscalls.H b/src/include/kernel/syscalls.H
index a7a0ef6b7..826ac93b9 100644
--- a/src/include/kernel/syscalls.H
+++ b/src/include/kernel/syscalls.H
@@ -6,6 +6,9 @@ namespace Systemcalls
enum SysCalls
{
TASK_YIELD = 0,
+ TASK_START,
+ TASK_END,
+ TASK_GETTID,
SYSCALL_MAX
};
diff --git a/src/include/kernel/task.H b/src/include/kernel/task.H
index d9256c365..4cd19bd04 100644
--- a/src/include/kernel/task.H
+++ b/src/include/kernel/task.H
@@ -23,4 +23,6 @@ struct task_t
task_t* next;
};
+enum { TASK_DEFAULT_STACK_SIZE = 4 };
+
#endif
diff --git a/src/include/kernel/taskmgr.H b/src/include/kernel/taskmgr.H
index 34267324c..2bdb39c16 100644
--- a/src/include/kernel/taskmgr.H
+++ b/src/include/kernel/taskmgr.H
@@ -10,15 +10,14 @@ class TaskManager
static void setCurrentTask(task_t* t);
typedef void(*task_fn_t)(void*);
+ static task_t* createTask(task_fn_t, void*);
friend class CpuManager;
- friend class Kernel;
protected:
TaskManager();
~TaskManager() {};
static task_t* createIdleTask();
- static task_t* createTask(task_fn_t, void*);
private:
tid_t getNextTid();
diff --git a/src/include/sys/syscall.h b/src/include/sys/syscall.h
index b418b5d15..36f84a51f 100644
--- a/src/include/sys/syscall.h
+++ b/src/include/sys/syscall.h
@@ -19,7 +19,7 @@ void* _syscall7(uint64_t, void*, void*, void*, void*, void*, void*, void*);
#ifdef __cplusplus
}
+#include <kernel/syscalls.H>
#endif
-#include <kernel/syscalls.H>
#endif
diff --git a/src/include/sys/task.h b/src/include/sys/task.h
new file mode 100644
index 000000000..84ddb10f9
--- /dev/null
+++ b/src/include/sys/task.h
@@ -0,0 +1,20 @@
+#ifndef __SYS_TASK_H
+#define __SYS_TASK_H
+
+#include <sys/syscall.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+void task_yield();
+int task_create(void(*)(void*), void*);
+void task_end();
+
+uint64_t task_gettid();
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C
index 9cabeebd3..b993bf222 100644
--- a/src/kernel/syscall.C
+++ b/src/kernel/syscall.C
@@ -5,6 +5,7 @@
#include <kernel/task.H>
#include <kernel/syscalls.H>
#include <kernel/console.H>
+#include <kernel/pagemgr.H>
extern "C"
void kernel_execute_decrementer()
@@ -22,10 +23,16 @@ namespace Systemcalls
{
typedef void(*syscall)(task_t*);
void TaskYield(task_t*);
+ void TaskStart(task_t*);
+ void TaskEnd(task_t*);
+ void TaskGettid(task_t*);
syscall syscalls[] =
{
&TaskYield,
+ &TaskStart,
+ &TaskEnd,
+ &TaskGettid,
};
};
@@ -48,6 +55,18 @@ void kernel_execute_systemcall()
}
}
+#define TASK_GETARGN(t, n) (t->context.gprs[n+4])
+#define TASK_GETARG0(t) (TASK_GETARGN(t,0))
+#define TASK_GETARG1(t) (TASK_GETARGN(t,1))
+#define TASK_GETARG2(t) (TASK_GETARGN(t,2))
+#define TASK_GETARG3(t) (TASK_GETARGN(t,3))
+#define TASK_GETARG4(t) (TASK_GETARGN(t,4))
+#define TASK_GETARG5(t) (TASK_GETARGN(t,5))
+#define TASK_GETARG6(t) (TASK_GETARGN(t,6))
+#define TASK_GETARG7(t) (TASK_GETARGN(t,7))
+
+#define TASK_SETRTN(t, n) (t->context.gprs[3] = (n))
+
namespace Systemcalls
{
void TaskYield(task_t* t)
@@ -56,4 +75,32 @@ namespace Systemcalls
s->returnRunnable();
s->setNextRunnable();
}
+
+ void TaskStart(task_t* t)
+ {
+ task_t* newTask =
+ TaskManager::createTask((TaskManager::task_fn_t)TASK_GETARG0(t),
+ (void*)TASK_GETARG1(t));
+ newTask->cpu = t->cpu;
+ t->cpu->scheduler->addTask(newTask);
+
+ TASK_SETRTN(t, newTask->tid);
+ }
+
+ void TaskEnd(task_t* t)
+ {
+ // Make sure task pointers are updated before we delete this task.
+ t->cpu->scheduler->setNextRunnable();
+
+ // TODO: Deal with join.
+
+ // Clean up task memory.
+ PageManager::freePage(t->context.stack_ptr, TASK_DEFAULT_STACK_SIZE);
+ delete t;
+ }
+
+ void TaskGettid(task_t* t)
+ {
+ TASK_SETRTN(t, t->tid);
+ }
};
diff --git a/src/kernel/taskmgr.C b/src/kernel/taskmgr.C
index fabb70cde..d060b0029 100644
--- a/src/kernel/taskmgr.C
+++ b/src/kernel/taskmgr.C
@@ -66,7 +66,8 @@ task_t* TaskManager::_createTask(TaskManager::task_fn_t t,
// Setup stack.
if (withStack)
{
- task->context.stack_ptr = PageManager::allocatePage(4);
+ task->context.stack_ptr =
+ PageManager::allocatePage(TASK_DEFAULT_STACK_SIZE);
task->context.gprs[1] = ((uint64_t)task->context.stack_ptr) + 16320;
}
else
diff --git a/src/lib/makefile b/src/lib/makefile
index 9ea27377e..1071dc75e 100644
--- a/src/lib/makefile
+++ b/src/lib/makefile
@@ -1,7 +1,8 @@
OBJDIR = ../../obj
include ../../config.mk
-OBJS = string.o stdlib.o syscall_stub.o
+OBJS = string.o stdlib.o
+OBJS += syscall_stub.o syscall_task.o
OBJECTS = $(addprefix ${OBJDIR}/, ${OBJS})
all: ${OBJECTS}
diff --git a/src/lib/syscall_task.C b/src/lib/syscall_task.C
new file mode 100644
index 000000000..bfd522933
--- /dev/null
+++ b/src/lib/syscall_task.C
@@ -0,0 +1,26 @@
+#include <sys/task.h>
+#include <kernel/task.H>
+
+using namespace Systemcalls;
+
+void task_yield()
+{
+ _syscall0(TASK_YIELD);
+ return;
+}
+
+int task_create(void(*fn)(void*), void* ptr)
+{
+ return (int64_t) _syscall2(TASK_START, (void*)fn, ptr);
+}
+
+void task_end()
+{
+ _syscall0(TASK_END); // no return.
+ return;
+}
+
+uint64_t task_gettid()
+{
+ return (uint64_t)_syscall0(TASK_GETTID);
+}
diff --git a/src/sys/init/init_main.C b/src/sys/init/init_main.C
index e2447bc3f..8be5ae6c3 100644
--- a/src/sys/init/init_main.C
+++ b/src/sys/init/init_main.C
@@ -1,5 +1,12 @@
#include <kernel/console.H> // TODO : Remove this.
-#include <sys/syscall.h> // TODO : Remove this.
+
+#include <sys/task.h>
+
+void init_child(void* unused)
+{
+ printk("Here I am %d\n", task_gettid());
+ task_end();
+}
void init_main(void* unused)
{
@@ -7,7 +14,8 @@ void init_main(void* unused)
while(1)
{
- _syscall0(Systemcalls::TASK_YIELD);
- for (volatile int i = 0 ; i < 100000; i++);
+ int t = task_create(&init_child, NULL);
+ printk("Created child %d\n", t);
+ for (volatile int i = 0 ; i < 10000000; i++);
}
}
OpenPOWER on IntegriCloud