summaryrefslogtreecommitdiff
path: root/Source/Kernel/MemoryManager/PageAlloc.ns.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Kernel/MemoryManager/PageAlloc.ns.cpp')
-rw-r--r--Source/Kernel/MemoryManager/PageAlloc.ns.cpp68
1 files changed, 68 insertions, 0 deletions
diff --git a/Source/Kernel/MemoryManager/PageAlloc.ns.cpp b/Source/Kernel/MemoryManager/PageAlloc.ns.cpp
new file mode 100644
index 0000000..ac2969e
--- /dev/null
+++ b/Source/Kernel/MemoryManager/PageAlloc.ns.cpp
@@ -0,0 +1,68 @@
+#include "PageAlloc.ns.h"
+#include <MemoryManager/PhysMem.ns.h>
+
+#define CACHED_PAGES 3
+
+// This mechanism is supposed to make it impossible to run out of free pages to use as a page table
+
+namespace PageAlloc {
+
+void* freePage[CACHED_PAGES];
+int freec = 0;
+bool usable = false, locked = false;
+
+void init() {
+ freec = CACHED_PAGES;
+ for (u32int i = 0; i < CACHED_PAGES; i++) {
+ freePage[i] = Mem::kalloc(0x1000, true);
+ }
+ usable = true;
+}
+
+void* alloc(u32int* phys) {
+ if (!usable) init();
+
+ while (freec < CACHED_PAGES && (!locked)) {
+ locked = true;
+ void* next = 0;
+ if (!Mem::pagingEnabled) {
+ next = Mem::kalloc(0x1000, true);
+ } else {
+ u32int i = 0xFFFFF000;
+ page_t *p;
+ while (1) {
+ p = kernelPageDirectory->getPage(i, true);
+ if (p->frame == 0) break;
+ i -= 0x1000;
+ }
+ PhysMem::allocFrame(p, true, false);
+ next = (void*)i;
+ }
+ freePage[freec] = next;
+ freec++;
+ locked = false;
+ }
+
+ freec--;
+ void* ret = freePage[freec];
+ if (!Mem::pagingEnabled) {
+ *phys = (u32int)ret - 0xC0000000;
+ } else {
+ page_t* p = kernelPageDirectory->getPage((u32int)ret, false);
+ if (p == 0) { //THIS SHOULD NEVER HAPPEN
+ PANIC("Cached free page does not exist.");
+ } else if (p->frame == 0) {
+ PANIC("Cached free page is not mapped to a frame.");
+ } else {
+ *phys = (p->frame * 0x1000);
+ }
+ }
+ return ret;
+}
+
+void free(void *ptr) {
+ kernelPageDirectory->freeFrame((u32int)ptr);
+ return;
+}
+
+}