summaryrefslogtreecommitdiffstats
path: root/src/kernel
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2010-06-02 17:45:11 -0500
committerPatrick Williams <iawillia@us.ibm.com>2010-06-02 17:45:11 -0500
commit2cc0de1f136026f13ca6de363d9e57831c6ba10b (patch)
tree5653bf1244af8c97e63745536bf5ca887d06ea36 /src/kernel
parent5235cd52014205f358f1a295c5228091e1847efb (diff)
downloadtalos-hostboot-2cc0de1f136026f13ca6de363d9e57831c6ba10b.tar.gz
talos-hostboot-2cc0de1f136026f13ca6de363d9e57831c6ba10b.zip
Initial cpu / task structs.
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/cpumgr.C72
-rw-r--r--src/kernel/kernel.C8
-rw-r--r--src/kernel/makefile2
-rw-r--r--src/kernel/start.S8
-rw-r--r--src/kernel/taskmgr.C66
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;
+}
+
OpenPOWER on IntegriCloud