diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2011-06-16 11:22:46 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2011-06-20 11:45:44 -0500 |
commit | a1450c913cb7864234ae1adea8aaffe561a627d6 (patch) | |
tree | 936121c609a5c54782efbb6d23293ee7dc2500ee | |
parent | d38781779ba33ce8fb4d0ce562c0fb9283a1d63c (diff) | |
download | talos-hostboot-a1450c913cb7864234ae1adea8aaffe561a627d6.tar.gz talos-hostboot-a1450c913cb7864234ae1adea8aaffe561a627d6.zip |
Set up initial task link-register to point to 'task_end' function.
Change-Id: Id1b122d789b84eebd75feb3bdb7e1ca222e6d76e
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/147
Reviewed-by: Nicholas E. Bofferding <bofferdn@us.ibm.com>
Tested-by: Jenkins Server
Reviewed-by: Mark W. Wenning <wenning@us.ibm.com>
-rw-r--r-- | src/include/sys/task.h | 8 | ||||
-rw-r--r-- | src/kernel/taskmgr.C | 9 |
2 files changed, 14 insertions, 3 deletions
diff --git a/src/include/sys/task.h b/src/include/sys/task.h index 265f175fb..901f938ea 100644 --- a/src/include/sys/task.h +++ b/src/include/sys/task.h @@ -36,9 +36,11 @@ tid_t task_create(void(*start_routine)(void*), void* arg); * * See POSIX pthread_exit. * - * @note A thread must call task_end when it wishes to exit. It is not - * acceptable to simply return from the 'start_routine' and may result - * in unexpected behavior. + * @note A task must call task_end when it wishes to exit. If a task were + * to simply return from its entry point function, the kernel sets up + * the initial task structure with the link-register pointing to this + * function. Therefore, returning from the entry point function will + * also cause the task to end cleanly using this function. */ void task_end(); diff --git a/src/kernel/taskmgr.C b/src/kernel/taskmgr.C index 8225b7da3..0573bab7d 100644 --- a/src/kernel/taskmgr.C +++ b/src/kernel/taskmgr.C @@ -3,8 +3,10 @@ #include <kernel/task.H> #include <kernel/pagemgr.H> #include <kernel/cpumgr.H> +#include <sys/task.h> #include <arch/ppc.H> #include <string.h> +#include <limits.h> void TaskManager::idleTaskLoop(void* unused) { @@ -60,6 +62,11 @@ task_t* TaskManager::_createTask(TaskManager::task_fn_t t, task->context.nip = (void*) ((uint64_t*) t)[0]; task->context.gprs[2] = ((uint64_t*)t)[1]; + // Set up LR to be the entry point for task_end in case a task + // 'returns' from its entry point. By the Power ABI, the entry + // point address is in (func_ptr)[0]. + task->context.lr = reinterpret_cast<uint64_t*>(&task_end)[0]; + // Set up GRP[13] as task structure reserved. task->context.gprs[13] = (uint64_t)task; @@ -71,6 +78,8 @@ task_t* TaskManager::_createTask(TaskManager::task_fn_t t, { task->context.stack_ptr = PageManager::allocatePage(TASK_DEFAULT_STACK_SIZE); + memset(task->context.stack_ptr, '\0', + TASK_DEFAULT_STACK_SIZE * PAGE_SIZE); task->context.gprs[1] = ((uint64_t)task->context.stack_ptr) + 16320; } else |