diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2011-08-23 15:16:35 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2011-08-31 13:39:51 -0500 |
commit | f7b7b56dea28dd69a44a877f7b7073c4496ced9e (patch) | |
tree | 640fdb38b13df41c5f0835374033d53b21d163ca /src/kernel/syscall.C | |
parent | e6b1dcfdee1467cf7f43b64c8dddb87f13bf2f10 (diff) | |
download | talos-hostboot-f7b7b56dea28dd69a44a877f7b7073c4496ced9e.tar.gz talos-hostboot-f7b7b56dea28dd69a44a877f7b7073c4496ced9e.zip |
Ensure scratch operations happen on master core.
Change-Id: I970d645108de041d410599847edce877cb794015
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/275
Tested-by: Jenkins Server
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/kernel/syscall.C')
-rw-r--r-- | src/kernel/syscall.C | 307 |
1 files changed, 162 insertions, 145 deletions
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C index 098474d8e..8f69e934e 100644 --- a/src/kernel/syscall.C +++ b/src/kernel/syscall.C @@ -60,7 +60,7 @@ namespace Systemcalls void TaskYield(task_t*); void TaskStart(task_t*); void TaskEnd(task_t*); - void TaskGettid(task_t*); + void TaskMigrateToMaster(task_t*); void MsgQCreate(task_t*); void MsgQDestroy(task_t*); void MsgQRegisterRoot(task_t*); @@ -82,38 +82,39 @@ namespace Systemcalls void MmAllocBlock(task_t *t); syscall syscalls[] = - { - &TaskYield, // TASK_YIELD - &TaskStart, // TASK_START - &TaskEnd, // TASK_END - - &MsgQCreate, // MSGQ_CREATE - &MsgQDestroy, // MSGQ_DESTROY - &MsgQRegisterRoot, // MSGQ_REGISTER_ROOT - &MsgQResolveRoot, // MSGQ_RESOLVE_ROOT - - &MsgSend, // MSG_SEND - &MsgSendRecv, // MSG_SENDRECV - &MsgRespond, // MSG_RESPOND - &MsgWait, // MSG_WAIT - - &MmioMap, // MMIO_MAP - &MmioUnmap, // MMIO_UNMAP + { + &TaskYield, // TASK_YIELD + &TaskStart, // TASK_START + &TaskEnd, // TASK_END + &TaskMigrateToMaster, // TASK_MIGRATE_TO_MASTER + + &MsgQCreate, // MSGQ_CREATE + &MsgQDestroy, // MSGQ_DESTROY + &MsgQRegisterRoot, // MSGQ_REGISTER_ROOT + &MsgQResolveRoot, // MSGQ_RESOLVE_ROOT + + &MsgSend, // MSG_SEND + &MsgSendRecv, // MSG_SENDRECV + &MsgRespond, // MSG_RESPOND + &MsgWait, // MSG_WAIT + + &MmioMap, // MMIO_MAP + &MmioUnmap, // MMIO_UNMAP &DevMap, // DEV_MAP &DevUnmap, // DEV_UNMAP - &TimeNanosleep, // TIME_NANOSLEEP + &TimeNanosleep, // TIME_NANOSLEEP - &FutexWait, // FUTEX_WAIT - &FutexWake, // FUTEX_WAKE + &FutexWait, // FUTEX_WAIT + &FutexWake, // FUTEX_WAKE - &Shutdown, // MISC_SHUTDOWN + &Shutdown, // MISC_SHUTDOWN - &CpuCoreType, // MISC_CPUCORETYPE - &CpuDDLevel, // MISC_CPUDDLEVEL + &CpuCoreType, // MISC_CPUCORETYPE + &CpuDDLevel, // MISC_CPUDDLEVEL - &MmAllocBlock, // MM_ALLOC_BLOCK - }; + &MmAllocBlock, // MM_ALLOC_BLOCK + }; }; extern "C" @@ -125,13 +126,13 @@ void kernel_execute_system_call() uint64_t syscall = t->context.gprs[3]; if (syscall > SYSCALL_MAX) { - // TODO : kill task. - printk("Invalid syscall : %ld\n", syscall); - while(1); + // TODO : kill task. + printk("Invalid syscall : %ld\n", syscall); + while(1); } else { - syscalls[syscall](t); + syscalls[syscall](t); } } @@ -139,65 +140,81 @@ namespace Systemcalls { void TaskYield(task_t* t) { - Scheduler* s = t->cpu->scheduler; - s->returnRunnable(); - s->setNextRunnable(); + Scheduler* s = t->cpu->scheduler; + 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_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); + 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(); + // Make sure task pointers are updated before we delete this task. + t->cpu->scheduler->setNextRunnable(); - // TODO: Deal with join. + // TODO: Deal with join. - // Clean up task memory. - PageManager::freePage(t->context.stack_ptr, TASK_DEFAULT_STACK_SIZE); - delete t; + // Clean up task memory. + PageManager::freePage(t->context.stack_ptr, TASK_DEFAULT_STACK_SIZE); + delete t; + } + + void TaskMigrateToMaster(task_t* t) + { + // Move r6 to r3. + // This is needed so that this system call can be called from + // within a "fast" system call in start.S. The fast system call + // will populate r6 with it's own syscall number. When we return + // from this system call, on the master processor, we'll be back + // at the 'sc' instruction with r3 back to the fast syscall, and + // the fast syscall will be executed on the master processor. + TASK_SETRTN(t, TASK_GETARG2(t)); + + // Move task to master CPU and pick a new task. + t->cpu->scheduler->addTaskMasterCPU(t); + t->cpu->scheduler->setNextRunnable(); } void MsgQCreate(task_t* t) { - TASK_SETRTN(t, (uint64_t) new MessageQueue()); + TASK_SETRTN(t, (uint64_t) new MessageQueue()); } void MsgQDestroy(task_t* t) { - MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t); - if (NULL != mq) - delete mq; - TASK_SETRTN(t, 0); + MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t); + if (NULL != mq) + delete mq; + TASK_SETRTN(t, 0); } static MessageQueue* msgQRoot = NULL; void MsgQRegisterRoot(task_t* t) { - msgQRoot = (MessageQueue*) TASK_GETARG0(t); - TASK_SETRTN(t, 0); + msgQRoot = (MessageQueue*) TASK_GETARG0(t); + TASK_SETRTN(t, 0); } void MsgQResolveRoot(task_t* t) { - TASK_SETRTN(t, (uint64_t) msgQRoot); + TASK_SETRTN(t, (uint64_t) msgQRoot); } void MsgSend(task_t* t) { - MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t); - msg_t* m = (msg_t*) TASK_GETARG1(t); - m->__reserved__async = 0; // set to async msg. + MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t); + msg_t* m = (msg_t*) TASK_GETARG1(t); + m->__reserved__async = 0; // set to async msg. if (m->type >= MSG_FIRST_SYS_TYPE) { @@ -206,32 +223,32 @@ namespace Systemcalls return; } - mq->lock.lock(); - - // Get waiting (server) task. - task_t* waiter = mq->waiting.remove(); - if (NULL == waiter) // None found, add to 'messages' queue. - { - MessagePending* mp = new MessagePending(); - mp->key = m; - mp->task = t; - mq->messages.insert(mp); - } - else // Add waiter back to its scheduler. - { - TASK_SETRTN(waiter, (uint64_t) m); - waiter->cpu->scheduler->addTask(waiter); - } - - mq->lock.unlock(); - TASK_SETRTN(t, 0); + mq->lock.lock(); + + // Get waiting (server) task. + task_t* waiter = mq->waiting.remove(); + if (NULL == waiter) // None found, add to 'messages' queue. + { + MessagePending* mp = new MessagePending(); + mp->key = m; + mp->task = t; + mq->messages.insert(mp); + } + else // Add waiter back to its scheduler. + { + TASK_SETRTN(waiter, (uint64_t) m); + waiter->cpu->scheduler->addTask(waiter); + } + + mq->lock.unlock(); + TASK_SETRTN(t, 0); } void MsgSendRecv(task_t* t) { - MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t); - msg_t* m = (msg_t*) TASK_GETARG1(t); - m->__reserved__async = 1; // set to sync msg. + MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t); + msg_t* m = (msg_t*) TASK_GETARG1(t); + m->__reserved__async = 1; // set to sync msg. if (m->type >= MSG_FIRST_SYS_TYPE) { @@ -241,45 +258,45 @@ namespace Systemcalls } // 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. - { - mq->messages.insert(mp); - // Choose next thread to execute, this one is delayed. - t->cpu->scheduler->setNextRunnable(); - } - else // Context switch to waiter. - { - TASK_SETRTN(waiter, (uint64_t) m); - mq->responses.insert(mp); - waiter->cpu = t->cpu; - TaskManager::setCurrentTask(waiter); - } - - mq->lock.unlock(); + 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. + { + mq->messages.insert(mp); + // Choose next thread to execute, this one is delayed. + t->cpu->scheduler->setNextRunnable(); + } + else // Context switch to waiter. + { + TASK_SETRTN(waiter, (uint64_t) m); + mq->responses.insert(mp); + waiter->cpu = t->cpu; + TaskManager::setCurrentTask(waiter); + } + + mq->lock.unlock(); } void MsgRespond(task_t* t) { - MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t); - msg_t* m = (msg_t*) TASK_GETARG1(t); + MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t); + msg_t* m = (msg_t*) TASK_GETARG1(t); - mq->lock.lock(); - MessagePending* mp = mq->responses.find(m); - if (NULL != mp) - { - task_t* waiter = mp->task; + mq->lock.lock(); + MessagePending* mp = mq->responses.find(m); + if (NULL != mp) + { + task_t* waiter = mp->task; - mq->responses.erase(mp); + mq->responses.erase(mp); mq->lock.unlock(); - delete mp; + delete mp; if (m->type >= MSG_FIRST_SYS_TYPE) { @@ -300,52 +317,52 @@ namespace Systemcalls TASK_SETRTN(t,0); t->cpu->scheduler->addTask(t); } - } - else - { - TASK_SETRTN(t, -1); + } + else + { + TASK_SETRTN(t, -1); mq->lock.unlock(); - } + } } void MsgWait(task_t* t) { - MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t); - - mq->lock.lock(); - MessagePending* mp = mq->messages.remove(); - - if (NULL == mp) - { - mq->waiting.insert(t); - t->cpu->scheduler->setNextRunnable(); - } - else - { - msg_t* m = mp->key; - if (m->__reserved__async) - mq->responses.insert(mp); - else - delete mp; - TASK_SETRTN(t, (uint64_t) m); - } - mq->lock.unlock(); + MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t); + + mq->lock.lock(); + MessagePending* mp = mq->messages.remove(); + + if (NULL == mp) + { + mq->waiting.insert(t); + t->cpu->scheduler->setNextRunnable(); + } + else + { + msg_t* m = mp->key; + if (m->__reserved__async) + mq->responses.insert(mp); + else + delete mp; + TASK_SETRTN(t, (uint64_t) m); + } + mq->lock.unlock(); } void MmioMap(task_t* t) { - void* ra = (void*)TASK_GETARG0(t); - size_t pages = TASK_GETARG1(t); + void* ra = (void*)TASK_GETARG0(t); + size_t pages = TASK_GETARG1(t); - TASK_SETRTN(t, (uint64_t) VmmManager::mmioMap(ra,pages)); + TASK_SETRTN(t, (uint64_t) VmmManager::mmioMap(ra,pages)); } void MmioUnmap(task_t* t) { - void* ea = (void*)TASK_GETARG0(t); - size_t pages = TASK_GETARG1(t); + void* ea = (void*)TASK_GETARG0(t); + size_t pages = TASK_GETARG1(t); - TASK_SETRTN(t, VmmManager::mmioUnmap(ea,pages)); + TASK_SETRTN(t, VmmManager::mmioUnmap(ea,pages)); } /** @@ -374,11 +391,11 @@ namespace Systemcalls void TimeNanosleep(task_t* t) { - TimeManager::delayTask(t, TASK_GETARG0(t), TASK_GETARG1(t)); - TASK_SETRTN(t, 0); + TimeManager::delayTask(t, TASK_GETARG0(t), TASK_GETARG1(t)); + TASK_SETRTN(t, 0); - Scheduler* s = t->cpu->scheduler; - s->setNextRunnable(); + Scheduler* s = t->cpu->scheduler; + s->setNextRunnable(); } /** |