summaryrefslogtreecommitdiffstats
path: root/src/kernel/syscall.C
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2011-08-11 00:17:29 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2011-08-16 08:11:55 -0500
commit82fa7a749fbd1d8f17891dbd97b17a3bdae36c53 (patch)
tree5e4857f1fc30e6b9506ac4973f597f17c8b16738 /src/kernel/syscall.C
parentab9e15e2e44eb52d4d0aa3602498a62db0cc0c37 (diff)
downloadblackbird-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.C58
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)
OpenPOWER on IntegriCloud