// IBM_PROLOG_BEGIN_TAG // This is an automatically generated prolog. // // $Source: src/kernel/taskmgr.C $ // // IBM CONFIDENTIAL // // COPYRIGHT International Business Machines Corp. 2010 - 2011 // // p1 // // Object Code Only (OCO) source materials // Licensed Internal Code Source Materials // IBM HostBoot Licensed Internal Code // // The source code for this program is not published or other- // wise divested of its trade secrets, irrespective of what has // been deposited with the U.S. Copyright Office. // // Origin: 30 // // IBM_PROLOG_END #include #include #include #include #include #include #include #include #include extern "C" void userspace_task_entry(); void TaskManager::idleTaskLoop(void* unused) { while(1) { setThreadPriorityLow(); } } task_t* TaskManager::getCurrentTask() { register task_t* current_task = (task_t*) getSPRG3(); return current_task; } void TaskManager::setCurrentTask(task_t* t) { t->cpu = CpuManager::getCurrentCPU(); setSPRG3((uint64_t)t); return; } TaskManager::TaskManager() : iv_nextTid() { } task_t* TaskManager::createIdleTask() { return Singleton::instance()._createIdleTask(); } task_t* TaskManager::createTask(TaskManager::task_fn_t t, void* p) { return Singleton::instance()._createTask(t, p, true); } task_t* TaskManager::_createIdleTask() { return this->_createTask(&TaskManager::idleTaskLoop, NULL, false); } task_t* TaskManager::_createTask(TaskManager::task_fn_t t, void* p, bool withStack) { task_t* task = new task_t; memset(task, '\0', sizeof(task_t)); task->tid = this->getNextTid(); // Set NIP to be userspace_task_entry stub and GPR3 to be the // function pointer for the desired task entry point. task->context.nip = reinterpret_cast(&userspace_task_entry); task->context.gprs[4] = reinterpret_cast(t); // 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(&task_end)[0]; // Set up GRP[13] as task structure reserved. task->context.gprs[13] = (uint64_t)task; // Set up argument. task->context.gprs[3] = (uint64_t) p; // Setup stack. if (withStack) { task->context.stack_ptr = PageManager::allocatePage(TASK_DEFAULT_STACK_SIZE); memset(task->context.stack_ptr, '\0', TASK_DEFAULT_STACK_SIZE * PAGESIZE); task->context.gprs[1] = ((uint64_t)task->context.stack_ptr) + TASK_DEFAULT_STACK_SIZE * PAGESIZE - 8; } else { task->context.stack_ptr = NULL; task->context.gprs[1] = NULL; } return task; }