diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2010-06-02 17:45:11 -0500 |
---|---|---|
committer | Patrick Williams <iawillia@us.ibm.com> | 2010-06-02 17:45:11 -0500 |
commit | 2cc0de1f136026f13ca6de363d9e57831c6ba10b (patch) | |
tree | 5653bf1244af8c97e63745536bf5ca887d06ea36 /src/kernel | |
parent | 5235cd52014205f358f1a295c5228091e1847efb (diff) | |
download | talos-hostboot-2cc0de1f136026f13ca6de363d9e57831c6ba10b.tar.gz talos-hostboot-2cc0de1f136026f13ca6de363d9e57831c6ba10b.zip |
Initial cpu / task structs.
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/cpumgr.C | 72 | ||||
-rw-r--r-- | src/kernel/kernel.C | 8 | ||||
-rw-r--r-- | src/kernel/makefile | 2 | ||||
-rw-r--r-- | src/kernel/start.S | 8 | ||||
-rw-r--r-- | src/kernel/taskmgr.C | 66 |
5 files changed, 147 insertions, 9 deletions
diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C new file mode 100644 index 000000000..3c2c3b907 --- /dev/null +++ b/src/kernel/cpumgr.C @@ -0,0 +1,72 @@ +#include <kernel/cpumgr.H> +#include <kernel/task.H> +#include <kernel/cpu.H> +#include <kernel/scheduler.H> +#include <kernel/taskmgr.H> +#include <kernel/pagemgr.H> +#include <kernel/console.H> +#include <util/singleton.H> + +CpuManager::CpuManager() +{ + for (int i = 0; i < MAXCPUS; i++) + iv_cpus[i] = NULL; +} + +cpu_t* CpuManager::getCurrentCPU() +{ + register task_t* current_task = NULL; + asm volatile("mfsprg3 %0" : "=r" (current_task) ); + return current_task->cpu; +} + +void CpuManager::init() +{ + Singleton<CpuManager>::instance().startCPU(); +} + +void CpuManager::startCPU(ssize_t i) +{ + bool currentCPU = false; + if (i < 0) + { + // TODO: Determine position of this CPU, somehow. + i = 0; + + currentCPU = true; + } + + printk("Starting CPU %d...", i); + + // Initialize CPU structure. + if (NULL == iv_cpus[i]) + { + cpu_t* cpu = iv_cpus[i] = new cpu_t; + + // Initialize CPU. + cpu->cpu = i; + cpu->scheduler = new Scheduler(); + cpu->kernel_stack = PageManager::allocatePage(4); + + // Create idle task. + task_t * idle_task = TaskManager::createIdleTask(); + idle_task->cpu = cpu; + + // Add to scheduler. + cpu->scheduler->setIdleTask(idle_task); + } + + if (currentCPU) + { + register task_t* idle_task = iv_cpus[i]->scheduler->getIdleTask(); + asm volatile("mtsprg3 %0" :: "r" (idle_task)); + } + else + { + // TODO once we get to SMP. + } + + printk("done\n"); + + return; +} diff --git a/src/kernel/kernel.C b/src/kernel/kernel.C index c7379e75d..ed2794dd7 100644 --- a/src/kernel/kernel.C +++ b/src/kernel/kernel.C @@ -2,6 +2,7 @@ #include <kernel/console.H> #include <kernel/pagemgr.H> #include <kernel/heapmgr.H> +#include <kernel/cpumgr.H> #include <util/singleton.H> #include <stdlib.h> @@ -11,6 +12,7 @@ class Kernel public: void cppBootstrap(); void memBootstrap(); + void cpuBootstrap(); protected: Kernel() {}; @@ -23,6 +25,7 @@ int main() Kernel& kernel = Singleton<Kernel>::instance(); kernel.cppBootstrap(); kernel.memBootstrap(); + kernel.cpuBootstrap(); while(1); return 0; @@ -47,3 +50,8 @@ void Kernel::memBootstrap() HeapManager::init(); } +void Kernel::cpuBootstrap() +{ + CpuManager::init(); +} + diff --git a/src/kernel/makefile b/src/kernel/makefile index 41d9f706c..3ff471de2 100644 --- a/src/kernel/makefile +++ b/src/kernel/makefile @@ -1,7 +1,7 @@ OBJDIR = ../../obj include ../../config.mk -OBJS = start.o kernel.o console.o pagemgr.o heapmgr.o +OBJS = start.o kernel.o console.o pagemgr.o heapmgr.o taskmgr.o cpumgr.o OBJECTS = $(addprefix ${OBJDIR}/, ${OBJS}) all: ${OBJECTS} diff --git a/src/kernel/start.S b/src/kernel/start.S index 6906c2c33..9e8a560ba 100644 --- a/src/kernel/start.S +++ b/src/kernel/start.S @@ -77,12 +77,6 @@ _main: ori 1, 1, kernel_stack@l addi 1, 1, 16320 - ;// Set up exception stack, space for 8 double-words - lis 3, exception_stack@h - ori 3, 3, exception_stack@l - addi 3, 3, 16320 - mtsprg0 3 - ;// Call main. bl main _main_loop: @@ -93,8 +87,6 @@ _main_loop: .balign 1024 kernel_stack: .space 16*1024 -exception_stack: - .space 16*1024 .section .text.hreset hreset: diff --git a/src/kernel/taskmgr.C b/src/kernel/taskmgr.C new file mode 100644 index 000000000..0cbdda2d3 --- /dev/null +++ b/src/kernel/taskmgr.C @@ -0,0 +1,66 @@ +#include <util/singleton.H> +#include <kernel/taskmgr.H> +#include <kernel/task.H> +#include <kernel/pagemgr.H> + +void TaskManager::idleTaskLoop() +{ + while(1); +} + +task_t* TaskManager::getCurrentTask() +{ + register task_t* current_task = NULL; + asm volatile("mfsprg3 %0" : "=r" (current_task) ); + return current_task; +} + +TaskManager::TaskManager() : iv_nextTid(0) +{ +} + +task_t* TaskManager::createIdleTask() +{ + return Singleton<TaskManager>::instance()._createIdleTask(); +} + +task_t* TaskManager::createTask(TaskManager::task_fn_t t) +{ + return Singleton<TaskManager>::instance()._createTask(t, true); +} + +tid_t TaskManager::getNextTid() +{ + return __sync_fetch_and_add(&iv_nextTid, 1); +} + +task_t* TaskManager::_createIdleTask() +{ + return this->_createTask(&TaskManager::idleTaskLoop, false); +} + +task_t* TaskManager::_createTask(TaskManager::task_fn_t t, bool withStack) +{ + task_t* task = new task_t; + task->tid = this->getNextTid(); + + // Function pointer 't' is actually a TOC entry. + // TOC[0] = function address + // TOC[1] = TOC base -> r2 + task->context.nip = (void*) ((uint64_t*) t)[0]; + task->context.gprs[2] = ((uint64_t*)t)[1]; + + // Setup stack. + if (withStack) + { + task->context.stack_ptr = PageManager::allocatePage(4); + task->context.gprs[1] = ((uint64_t)task->context.stack_ptr) + 16320; + } + else + { + task->context.stack_ptr = NULL; + } + + return task; +} + |