summaryrefslogtreecommitdiff
path: root/Source/Kernel/MemoryManager/PageDirectory.class.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Kernel/MemoryManager/PageDirectory.class.cpp')
-rw-r--r--Source/Kernel/MemoryManager/PageDirectory.class.cpp65
1 files changed, 29 insertions, 36 deletions
diff --git a/Source/Kernel/MemoryManager/PageDirectory.class.cpp b/Source/Kernel/MemoryManager/PageDirectory.class.cpp
index 575b14c..064b423 100644
--- a/Source/Kernel/MemoryManager/PageDirectory.class.cpp
+++ b/Source/Kernel/MemoryManager/PageDirectory.class.cpp
@@ -5,23 +5,6 @@
extern "C" void copy_page_physical(u32int src, u32int dest);
-/* FOR MAPPING FRAMES TO PAGES */
-void PageDirectory::map(page_t* p, u32int frame, bool is_user, bool is_writable) {
- if (p == 0) return;
- p->present = 1;
- p->user = (is_user ? 1 : 0);
- p->rw = (is_writable ? 1 : 0);
- p->frame = (frame);
-}
-
-void PageDirectory::unmap(page_t *p, bool freePhys) {
- if (p == 0) return;
- if (freePhys) PhysMem::freeFrame(p->frame);
- p->present = 0;
- p->frame = 0;
-}
-
-/* FOR PAGE DIRECTORES */
PageDirectory::PageDirectory() {
tablesPhysical = (u32int*)PageAlloc::alloc(&physicalAddr);
for (u32int i = 0; i < 1024; i++) {
@@ -41,7 +24,7 @@ PageDirectory::PageDirectory(PageDirectory* other) {
if (!(other->tables[i]->pages[j].frame))
continue;
if (i == 0 and j < 256) continue; //Frame is below 1M, probably used by some V86 stuff. Ignore it.
- map(&tables[i]->pages[j], PhysMem::getFrame(), true, true);
+ PhysMem::allocFrame(&tables[i]->pages[j], true, true);
tables[i]->pages[j].present = other->tables[i]->pages[j].present;
tables[i]->pages[j].rw = other->tables[i]->pages[j].rw;
tables[i]->pages[j].user = other->tables[i]->pages[j].user;
@@ -61,48 +44,58 @@ PageDirectory::PageDirectory(PageDirectory* other) {
}
PageDirectory::~PageDirectory() {
- for (u32int i = 0; i < mappedSegs.size(); i++) {
- mappedSegs[i].seg->unmap(this, &mappedSegs[i]);
- }
for (int i = 0; i < 768; i++) { //Only free addresses below 0xC0000000, upper is kernel space
if (tables[i] != 0) {
+ for (int j = 0; j < 1024; j++) {
+ if (i == 0 and j < 256) continue; //Frame is below 1M, probably used by some V86 stuff. Ignore it.
+ PhysMem::freeFrame(&(tables[i]->pages[j]));
+ }
PageAlloc::free((void*)tables[i]);
}
}
PageAlloc::free((void*)tablesPhysical);
}
-void PageDirectory::map(Segment* seg) {
- mappedSegs.push(seg->map(this));
-}
-
-void PageDirectory::unmap(Segment* seg) {
- for (u32int i = 0; i < mappedSegs.size(); i++) {
- if (mappedSegs[i].seg == seg) {
- seg->unmap(this, &mappedSegs[i]);
- mappedSegs[i] = mappedSegs.back();
- return;
- }
- }
-}
-
page_t *PageDirectory::getPage(u32int address, bool make) {
address /= 0x1000;
u32int tableIdx = address / 1024;
if (tables[tableIdx] != 0) {
return &(tables[tableIdx]->pages[address % 1024]);
} else if (make) {
- if (address >= 0xC0000000) return 0;
u32int tmp;
tables[tableIdx] = (page_table_t*)PageAlloc::alloc(&tmp);
CMem::memset((u8int*)tables[tableIdx], 0, 0x1000);
tablesPhysical[tableIdx] = tmp | 0x07;
+ if (tableIdx >= 768)
+ Task::allocKernelPageTable(tableIdx, tables[tableIdx], tablesPhysical[tableIdx]);
return &(tables[tableIdx]->pages[address % 1024]);
} else {
return 0;
}
}
+void PageDirectory::map(page_t* p, u32int frame, bool is_user, bool is_writable) {
+ p->present = 1;
+ p->user = (is_user ? 1 : 0);
+ p->rw = (is_writable ? 1 : 0);
+ p->frame = (frame);
+}
+
+void PageDirectory::allocFrame(u32int address, bool is_user, bool is_writable) {
+ page_t *p = getPage(address, true);
+ if (address < 0x100000) {
+ map(p, address / 0x1000, is_user, is_writable);
+ } else {
+ if (p != 0) PhysMem::allocFrame(p, is_user, is_writable);
+ }
+}
+
+void PageDirectory::freeFrame(u32int address) {
+ page_t *p = getPage(address, false);
+ if (p == 0) return;
+ PhysMem::freeFrame(p);
+}
+
void PageDirectory::switchTo() {
asm volatile("mov %0, %%cr3" :: "r"(physicalAddr));
u32int cr0;