diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2011-08-11 00:17:29 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2011-08-16 08:11:55 -0500 |
commit | 82fa7a749fbd1d8f17891dbd97b17a3bdae36c53 (patch) | |
tree | 5e4857f1fc30e6b9506ac4973f597f17c8b16738 /src/kernel/syscall.C | |
parent | ab9e15e2e44eb52d4d0aa3602498a62db0cc0c37 (diff) | |
download | blackbird-hostboot-82fa7a749fbd1d8f17891dbd97b17a3bdae36c53.tar.gz blackbird-hostboot-82fa7a749fbd1d8f17891dbd97b17a3bdae36c53.zip |
Implement Kernel->User-space message bridge.
Change-Id: Icf6fc9e10b1c39e981dddf180607b710c597112b
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/249
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/kernel/syscall.C')
-rw-r--r-- | src/kernel/syscall.C | 58 |
1 files changed, 38 insertions, 20 deletions
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C index 51009195d..a71217bec 100644 --- a/src/kernel/syscall.C +++ b/src/kernel/syscall.C @@ -1,4 +1,5 @@ #include <assert.h> +#include <errno.h> #include <kernel/cpu.H> #include <kernel/cpumgr.H> #include <kernel/scheduler.H> @@ -12,6 +13,7 @@ #include <kernel/futexmgr.H> #include <kernel/cpuid.H> #include <kernel/misc.H> +#include <kernel/msghandler.H> extern "C" void kernel_execute_decrementer() @@ -110,18 +112,6 @@ void kernel_execute_system_call() } } -#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) @@ -186,6 +176,12 @@ namespace Systemcalls msg_t* m = (msg_t*) TASK_GETARG1(t); m->__reserved__async = 0; // set to async msg. + if (m->type >= MSG_FIRST_SYS_TYPE) + { + TASK_SETRTN(t, -EINVAL); + return; + } + mq->lock.lock(); // Get waiting (server) task. @@ -213,11 +209,19 @@ namespace Systemcalls msg_t* m = (msg_t*) TASK_GETARG1(t); m->__reserved__async = 1; // set to sync msg. - mq->lock.lock(); + if (m->type >= MSG_FIRST_SYS_TYPE) + { + TASK_SETRTN(t, -EINVAL); + return; + } + + // Create pending response object. MessagePending* mp = new MessagePending(); mp->key = m; mp->task = t; + mq->lock.lock(); + // Get waiting (server) task. task_t* waiter = mq->waiting.remove(); if (NULL == waiter) // None found, add to 'messages' queue. @@ -249,20 +253,34 @@ namespace Systemcalls task_t* waiter = mp->task; mq->responses.erase(mp); + mq->lock.unlock(); delete mp; - waiter->cpu = t->cpu; - TaskManager::setCurrentTask(waiter); - TASK_SETRTN(waiter,0); - - TASK_SETRTN(t,0); - t->cpu->scheduler->addTask(t); + if (m->type >= MSG_FIRST_SYS_TYPE) + { + TASK_SETRTN(t, + ((MessageHandler*)waiter)->recvMessage(m)); + + if (TaskManager::getCurrentTask() != t) + { + t->cpu->scheduler->addTask(t); + } + } + else + { + waiter->cpu = t->cpu; + TaskManager::setCurrentTask(waiter); + TASK_SETRTN(waiter,0); + + TASK_SETRTN(t,0); + t->cpu->scheduler->addTask(t); + } } else { TASK_SETRTN(t, -1); + mq->lock.unlock(); } - mq->lock.unlock(); } void MsgWait(task_t* t) |