summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2011-06-16 11:22:46 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2011-06-20 11:45:44 -0500
commita1450c913cb7864234ae1adea8aaffe561a627d6 (patch)
tree936121c609a5c54782efbb6d23293ee7dc2500ee
parentd38781779ba33ce8fb4d0ce562c0fb9283a1d63c (diff)
downloadtalos-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.h8
-rw-r--r--src/kernel/taskmgr.C9
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
OpenPOWER on IntegriCloud