diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2010-06-07 16:39:45 -0500 |
---|---|---|
committer | Patrick Williams <iawillia@us.ibm.com> | 2010-06-07 16:39:45 -0500 |
commit | 9a4698af6ee4c095a97b8800d2d5f0a4bb282b15 (patch) | |
tree | 9f5241ee1f91d21c8043b359d7bfaeb309ecd5b8 /src/kernel/syscall.C | |
parent | aa1db69f1de27bba8ee5e128f717557780f21e0d (diff) | |
download | talos-hostboot-9a4698af6ee4c095a97b8800d2d5f0a4bb282b15.tar.gz talos-hostboot-9a4698af6ee4c095a97b8800d2d5f0a4bb282b15.zip |
Add task control syscalls.
Diffstat (limited to 'src/kernel/syscall.C')
-rw-r--r-- | src/kernel/syscall.C | 47 |
1 files changed, 47 insertions, 0 deletions
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); + } }; |