summaryrefslogtreecommitdiffstats
path: root/src
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
parent5235cd52014205f358f1a295c5228091e1847efb (diff)
downloadtalos-hostboot-2cc0de1f136026f13ca6de363d9e57831c6ba10b.tar.gz
talos-hostboot-2cc0de1f136026f13ca6de363d9e57831c6ba10b.zip
Initial cpu / task structs.
Diffstat (limited to 'src')
-rw-r--r--src/include/kernel/cpu.H16
-rw-r--r--src/include/kernel/cpumgr.H32
-rw-r--r--src/include/kernel/scheduler.H26
-rw-r--r--src/include/kernel/task.H25
-rw-r--r--src/include/kernel/taskmgr.H31
-rw-r--r--src/include/kernel/types.h12
-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
11 files changed, 289 insertions, 9 deletions
diff --git a/src/include/kernel/cpu.H b/src/include/kernel/cpu.H
new file mode 100644
index 000000000..6dd513b2c
--- /dev/null
+++ b/src/include/kernel/cpu.H
@@ -0,0 +1,16 @@
+#ifndef __KERNEL_CPU_H
+#define __KERNEL_CPU_H
+
+#include <kernel/types.h>
+
+class Scheduler;
+
+struct cpu_t
+{
+ cpuid_t cpu;
+
+ Scheduler* scheduler;
+ void* kernel_stack;
+};
+
+#endif
diff --git a/src/include/kernel/cpumgr.H b/src/include/kernel/cpumgr.H
new file mode 100644
index 000000000..06ca8dbc1
--- /dev/null
+++ b/src/include/kernel/cpumgr.H
@@ -0,0 +1,32 @@
+#ifndef __KERNEL_CPUMGR_H
+#define __KERNEL_CPUMGR_H
+
+#include <kernel/types.h>
+
+class CpuManager
+{
+ public:
+ enum { MAXCPUS = 8 };
+
+ /** @fn getCurrentCPU
+ * Returns a pointer to the current CPU structure by using the
+ * task structure in SPRG3.
+ */
+ cpu_t* getCurrentCPU();
+
+ static void init();
+
+ protected:
+ CpuManager();
+ ~CpuManager() {};
+
+ /** @fn startCPU
+ * Starts the requested CPU. Default of -1 implies current CPU.
+ */
+ void startCPU(ssize_t i = -1);
+
+ private:
+ cpu_t* iv_cpus[MAXCPUS];
+};
+
+#endif
diff --git a/src/include/kernel/scheduler.H b/src/include/kernel/scheduler.H
new file mode 100644
index 000000000..06c3adcee
--- /dev/null
+++ b/src/include/kernel/scheduler.H
@@ -0,0 +1,26 @@
+#ifndef __KERNEL_SCHEDULER_H
+#define __KERNEL_SCHEDULER_H
+
+#include <kernel/types.h>
+#include <util/lockfree/stack.H>
+
+class Scheduler
+{
+ public:
+ friend class CpuManager;
+
+ protected:
+ Scheduler() : iv_direction(false) {};
+ ~Scheduler() {};
+
+ void setIdleTask(task_t* t) { iv_idleTask = t; };
+ task_t* getIdleTask() { return iv_idleTask; };
+
+ private:
+ bool iv_direction;
+ Util::Lockfree::Stack<task_t> iv_taskList[2];
+
+ task_t* iv_idleTask;
+};
+
+#endif
diff --git a/src/include/kernel/task.H b/src/include/kernel/task.H
new file mode 100644
index 000000000..c2ae51de1
--- /dev/null
+++ b/src/include/kernel/task.H
@@ -0,0 +1,25 @@
+#ifndef __KERNEL_TASK_H
+#define __KERNEL_TASK_H
+
+#include <kernel/types.h>
+
+struct context_t
+{
+ void* stack_ptr;
+ void* nip;
+ uint64_t gprs[32];
+ uint64_t lr;
+ uint64_t ctr;
+ uint64_t xer;
+};
+
+struct task_t
+{
+ cpu_t* cpu;
+ context_t context;
+
+ tid_t tid;
+ task_t* next;
+};
+
+#endif
diff --git a/src/include/kernel/taskmgr.H b/src/include/kernel/taskmgr.H
new file mode 100644
index 000000000..7f23c8821
--- /dev/null
+++ b/src/include/kernel/taskmgr.H
@@ -0,0 +1,31 @@
+#ifndef __KERNEL_TASKMGR_H
+#define __KENREL_TASKMGR_H
+
+#include <kernel/types.h>
+
+class TaskManager
+{
+ public:
+ static task_t* getCurrentTask();
+
+ typedef void(*task_fn_t)();
+
+ friend class CpuManager;
+ protected:
+ TaskManager();
+ ~TaskManager() {};
+
+ static task_t* createIdleTask();
+ static task_t* createTask(task_fn_t);
+
+ private:
+ tid_t getNextTid();
+
+ tid_t iv_nextTid;
+
+ static void idleTaskLoop();
+ task_t* _createIdleTask();
+ task_t* _createTask(task_fn_t, bool);
+};
+
+#endif
diff --git a/src/include/kernel/types.h b/src/include/kernel/types.h
new file mode 100644
index 000000000..c994308c2
--- /dev/null
+++ b/src/include/kernel/types.h
@@ -0,0 +1,12 @@
+#ifndef __KERNEL_TYPES_H
+#define __KNERLE_TYPES_H
+
+#include <stdint.h>
+
+typedef uint64_t tid_t;
+struct task_t;
+
+typedef uint64_t cpuid_t;
+struct cpu_t;
+
+#endif
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