summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/kernel/pagemgr.H5
-rw-r--r--src/include/kernel/taskmgr.H4
-rw-r--r--src/include/kernel/types.h3
-rw-r--r--src/include/kernel/vmmmgr.H124
-rw-r--r--src/include/sys/task.h3
-rw-r--r--src/kernel/kernel.C2
-rw-r--r--src/kernel/makefile2
-rw-r--r--src/kernel/vmmmgr.C65
-rw-r--r--src/lib/syscall_task.C2
9 files changed, 202 insertions, 8 deletions
diff --git a/src/include/kernel/pagemgr.H b/src/include/kernel/pagemgr.H
index fded2c6c1..95d7bf21c 100644
--- a/src/include/kernel/pagemgr.H
+++ b/src/include/kernel/pagemgr.H
@@ -3,6 +3,7 @@
#include <stdint.h>
#include <util/lockfree/stack.H>
+#include <kernel/vmmmgr.H>
/** @class PageManager
* @brief Manages the allocation of memory pages.
@@ -18,8 +19,8 @@ class PageManager
enum
{
- PAGESIZE = 4096,
- MEMLEN = 8 * 1024 * 1024,
+ PAGESIZE = VmmManager::PAGESIZE,
+ MEMLEN = VmmManager::HTABORG,
BUCKETS = 16,
};
diff --git a/src/include/kernel/taskmgr.H b/src/include/kernel/taskmgr.H
index 3cf036f37..b34a1d3b1 100644
--- a/src/include/kernel/taskmgr.H
+++ b/src/include/kernel/taskmgr.H
@@ -3,6 +3,7 @@
#include <kernel/types.h>
#include <util/lockfree/counter.H>
+#include <kernel/vmmmgr.H>
class TaskManager
{
@@ -21,7 +22,8 @@ class TaskManager
static task_t* createIdleTask();
private:
- tid_t getNextTid() { return iv_nextTid.next(); };
+ tid_t getNextTid()
+ { return iv_nextTid.next() + VmmManager::FirstPid; };
Util::Lockfree::Counter<tid_t> iv_nextTid;
static void idleTaskLoop(void*);
diff --git a/src/include/kernel/types.h b/src/include/kernel/types.h
index c994308c2..056486b4a 100644
--- a/src/include/kernel/types.h
+++ b/src/include/kernel/types.h
@@ -3,7 +3,8 @@
#include <stdint.h>
-typedef uint64_t tid_t;
+typedef uint16_t tid_t; // This is 16-bit for the VMM mapping of
+ // stacks. See VmmManager.
struct task_t;
typedef uint64_t cpuid_t;
diff --git a/src/include/kernel/vmmmgr.H b/src/include/kernel/vmmmgr.H
new file mode 100644
index 000000000..18d1f0862
--- /dev/null
+++ b/src/include/kernel/vmmmgr.H
@@ -0,0 +1,124 @@
+#ifndef __KERNEL_VMMMGR_H
+#define __KERNEL_VMMMGR_H
+
+#include <kernel/types.h>
+
+class VmmManager
+{
+ public:
+ struct pte_t
+ {
+ uint64_t a,b;
+ };
+
+ enum VMM_CONSTS
+ {
+ FULL_MEM_SIZE = 8 * 1024 * 1024,
+ PAGESIZE = 4096,
+
+ PTSIZE = (1 << 18),
+ PTEG_SIZE = 8,
+ PTEG_COUNT = (PTSIZE / sizeof(pte_t)) / PTEG_SIZE,
+
+ HTABORG = (FULL_MEM_SIZE - PTSIZE),
+ };
+
+ enum ACCESS_TYPES
+ {
+ NO_USER_ACCESS,
+ NORMAL_ACCESS,
+ CI_ACCESS,
+ };
+
+ enum PID_ALLOCATIONS
+ {
+ LinearSpace = 0,
+ MMIOSpace = 1,
+ FirstPid,
+ };
+
+ static void init();
+
+ protected:
+ VmmManager();
+ ~VmmManager() {};
+
+ private:
+ void initSLB();
+ void initPTEs();
+ void initSDR1();
+
+ static pte_t* page_table;
+
+ inline pte_t& getPte(uint64_t pteg, uint64_t idx)
+ {
+ return page_table[pteg * PTEG_SIZE + idx];
+ }
+
+ inline void defaultPte(pte_t& pte)
+ {
+ pte.a = 0x4000000000000000; // B = 01 (1TB).
+ pte.b = 0x0;
+ }
+
+ inline void setValid(bool valid, pte_t& pte)
+ {
+ // Adding a page requires EIEIO to ensure update of PTE prior
+ // to making valid and PTESYNC afterwards.
+ // Removing a page just requires PTESYNC afterwards.
+ if (valid)
+ {
+ asm volatile("eieio" ::: "memory");
+ }
+
+ pte.a &= ~0x01;
+ pte.a |= (valid ? 0x1 : 0x0);
+
+ asm volatile("ptesync" ::: "memory");
+ }
+
+ inline bool isValid(pte_t& pte)
+ {
+ return ((pte.a & 0x01) == 0x01);
+ }
+
+ inline void setTid(tid_t tid, pte_t& pte)
+ {
+ pte.a &= 0xC00000000000007F;
+ pte.a |= ((uint64_t) tid) << 7;
+ }
+
+ inline tid_t getTid(pte_t& pte)
+ {
+ return (tid_t) ((pte.a & 0xC00000000000007F) >> 7);
+ }
+
+ inline void setAccess(ACCESS_TYPES t, pte_t& pte)
+ {
+ uint64_t pteMask = ~0x800000000000007B;
+ pte.b &= pteMask;
+ pte.b |= (NO_USER_ACCESS == t ? 0x0000000000000010 :
+ (NORMAL_ACCESS == t ? 0x0000000000000012 :
+ (CI_ACCESS == t ? 0x000000000000002A :
+ 0x0)));
+ }
+
+ inline void setPage(uint64_t page, pte_t& pte)
+ {
+ pte.b &= ~0x0FFFFFFFFFFFF000;
+ pte.b |= page << 12;
+ }
+
+ inline uint64_t getPage(pte_t& pte)
+ {
+ return (pte.b & 0x0FFFFFFFFFFFF000) >> 12;
+ }
+
+ inline void pteSync()
+ {
+ asm volatile("ptesync" ::: "memory");
+ }
+
+};
+
+#endif
diff --git a/src/include/sys/task.h b/src/include/sys/task.h
index fa9838723..e50c6daee 100644
--- a/src/include/sys/task.h
+++ b/src/include/sys/task.h
@@ -2,14 +2,13 @@
#define __SYS_TASK_H
#include <stdint.h>
+#include <kernel/types.h>
#ifdef __cplusplus
extern "C"
{
#endif
-typedef uint64_t tid_t;
-
void task_yield();
tid_t task_create(void(*)(void*), void*);
void task_end();
diff --git a/src/kernel/kernel.C b/src/kernel/kernel.C
index b071d9999..00f3002e5 100644
--- a/src/kernel/kernel.C
+++ b/src/kernel/kernel.C
@@ -8,6 +8,7 @@
#include <kernel/task.H>
#include <kernel/scheduler.H>
#include <kernel/taskmgr.H>
+#include <kernel/vmmmgr.H>
#include <stdlib.h>
@@ -59,6 +60,7 @@ void Kernel::memBootstrap()
{
PageManager::init();
HeapManager::init();
+ VmmManager::init();
}
void Kernel::cpuBootstrap()
diff --git a/src/kernel/makefile b/src/kernel/makefile
index 4bdc0d02d..7d33a056e 100644
--- a/src/kernel/makefile
+++ b/src/kernel/makefile
@@ -2,7 +2,7 @@ OBJDIR = ../../obj
include ../../config.mk
OBJS = start.o kernel.o console.o pagemgr.o heapmgr.o taskmgr.o cpumgr.o
-OBJS += syscall.o scheduler.o spinlock.o exception.o
+OBJS += syscall.o scheduler.o spinlock.o exception.o vmmmgr.o
OBJECTS = $(addprefix ${OBJDIR}/, ${OBJS})
all: ${OBJECTS}
diff --git a/src/kernel/vmmmgr.C b/src/kernel/vmmmgr.C
new file mode 100644
index 000000000..db19d36a3
--- /dev/null
+++ b/src/kernel/vmmmgr.C
@@ -0,0 +1,65 @@
+#include <util/singleton.H>
+#include <kernel/vmmmgr.H>
+#include <kernel/console.H>
+
+VmmManager::VmmManager()
+{
+}
+
+void VmmManager::init()
+{
+ printk("Starting VMM...");
+
+ VmmManager& v = Singleton<VmmManager>::instance();
+
+ //v.initSLB();
+ v.initPTEs();
+ v.initSDR1();
+
+ printk("done.\n");
+};
+
+void VmmManager::initSLB()
+{
+ register uint64_t slbRS, slbRB;
+
+ // ESID = 0, V = 1, Index = 0.
+ slbRB = 0x0000000008000000;
+
+ // B = 01 (1TB), VSID = 0, Ks = 0, Kp = 1, NLCLP = 0
+ slbRS = 0x4000000000000400;
+
+ asm volatile("slbmte %0, %1" :: "r"(slbRS), "r"(slbRB) : "memory");
+}
+
+void VmmManager::initPTEs()
+{
+ // Invalidate all.
+ for(int i = 0; i < PTEG_COUNT; i++)
+ for (int j = 0; j < PTEG_SIZE; j++)
+ setValid(false, getPte(i,j));
+
+ // Set up linear map.
+ for(int i = 0; i < (FULL_MEM_SIZE / PAGESIZE); i++)
+ {
+ pte_t& pte = getPte(i, 0);
+ defaultPte(pte);
+ setTid(LinearSpace, pte);
+ setAccess( (0 == i) ? NO_USER_ACCESS : NORMAL_ACCESS, pte);
+ setPage(i, pte);
+ setValid(true, pte);
+ }
+
+ // PTE sync.
+ pteSync();
+}
+
+void VmmManager::initSDR1()
+{
+ // HTABORG << 17, HTABSIZE = 0 (11 bits, 256k table)
+ register uint64_t sdr1 = (((uint64_t)HTABORG) << 17);
+ asm volatile("mtsdr1 %0" :: "r"(sdr1) : "memory");
+}
+
+
+VmmManager::pte_t* VmmManager::page_table = (VmmManager::pte_t*) HTABORG;
diff --git a/src/lib/syscall_task.C b/src/lib/syscall_task.C
index 405e4f202..a29a9a94c 100644
--- a/src/lib/syscall_task.C
+++ b/src/lib/syscall_task.C
@@ -13,7 +13,7 @@ void task_yield()
tid_t task_create(void(*fn)(void*), void* ptr)
{
- return (tid_t) _syscall2(TASK_START, (void*)fn, ptr);
+ return (tid_t)(uint64_t) _syscall2(TASK_START, (void*)fn, ptr);
}
void task_end()
OpenPOWER on IntegriCloud