summaryrefslogtreecommitdiff
path: root/kernel/vmem.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/vmem.c')
-rw-r--r--kernel/vmem.c146
1 files changed, 127 insertions, 19 deletions
diff --git a/kernel/vmem.c b/kernel/vmem.c
index 9d34810..b1ecfa1 100644
--- a/kernel/vmem.c
+++ b/kernel/vmem.c
@@ -1,5 +1,12 @@
+// http://www.brokenthorn.com/Resources/OSDev18.html
+
#include "kernel.h"
+#include "x86.h"
+#include "../lib/logger/log.h" // logger facilities
+#define FOOLOS_MODULE_NAME "vmem"
+
+// TODO : why is the frame not 0xfffff??
enum PAGE_PTE_FLAGS {
I86_PTE_PRESENT = 1, //0000000000000000000000000000001
@@ -12,7 +19,7 @@ enum PAGE_PTE_FLAGS {
I86_PTE_PAT = 0x80, //0000000000000000000000010000000
I86_PTE_CPU_GLOBAL = 0x100, //0000000000000000000000100000000
I86_PTE_LV4_GLOBAL = 0x200, //0000000000000000000001000000000
- I86_PTE_FRAME = 0x7FFFF000 //1111111111111111111000000000000
+ I86_PTE_FRAME = 0xFFFFF000 //1111111111111111111000000000000
};
enum PAGE_PDE_FLAGS {
@@ -27,7 +34,7 @@ enum PAGE_PDE_FLAGS {
I86_PDE_4MB = 0x80, //0000000000000000000000010000000
I86_PDE_CPU_GLOBAL = 0x100, //0000000000000000000000100000000
I86_PDE_LV4_GLOBAL = 0x200, //0000000000000000000001000000000
- I86_PDE_FRAME = 0x7FFFF000 //1111111111111111111000000000000
+ I86_PDE_FRAME = 0xFFFFF000 //1111111111111111111000000000000
};
//! page table entry
@@ -62,53 +69,65 @@ typedef uint8_t bool;
#define PAGE_SIZE 4096
//! page table
-struct ptable {
+typedef struct ptable_struct {
pt_entry m_entries[PAGES_PER_TABLE];
-};
+}ptable ;
//! page directory
-struct pdirectory {
+typedef struct pdirectory_struct {
pd_entry m_entries[PAGES_PER_DIR];
-};
+}pdirectory;
-void pt_entry_add_attrib (pt_entry* e, uint32_t attrib)
+void pt_entry_add_attrib (pt_entry* e, uint32_t attrib)
{
+ *e|=attrib;
}
-void pt_entry_del_attrib (pt_entry* e, uint32_t attrib)
+void pt_entry_del_attrib (pt_entry* e, uint32_t attrib)
{
+ *e&=~attrib;
}
-void pt_entry_set_frame (pt_entry* e , physical_addr addr)
+void pt_entry_set_frame (pt_entry* e , physical_addr addr)
{
+ // *e = (*e & ~I86_PTE_FRAME) | addr;
+
+ *e|=I86_PTE_FRAME&addr;
+
}
-bool pt_entry_is_present (pt_entry e)
+bool pt_entry_is_present (pt_entry e)
{
- return 1;
+ return e&I86_PTE_PRESENT;
}
-bool pt_entry_is_writable (pt_entry e)
+
+bool pt_entry_is_writable (pt_entry e)
{
- return 1;
+ return e&I86_PTE_WRITABLE;
}
-physical_addr pt_entry_pfn (pt_entry e)
+
+physical_addr pt_entry_pfn (pt_entry e)
{
- return 1;
+ return e&I86_PTE_FRAME;
}
void pd_entry_add_attrib (pd_entry* e, uint32_t attrib)
{
+ *e|=attrib;
}
void pd_entry_del_attrib (pd_entry* e, uint32_t attrib)
{
+ *e&=~attrib;
}
void pd_entry_set_frame (pd_entry* e, physical_addr add)
{
+ *e|=I86_PDE_FRAME&add;
}
bool pd_entry_is_present (pd_entry e)
{
- return 1;
+ return e&I86_PDE_PRESENT;
}
+/*
bool pd_entry_is_user (pd_entry e)
{
return 1;
@@ -118,20 +137,23 @@ bool pd_entry_is_4mb (pd_entry e)
{
return 1;
}
+*/
bool pd_entry_is_writable (pd_entry e)
{
- return 1;
+ return e&I86_PDE_WRITABLE;
}
physical_addr pd_entry_pfn (pd_entry e)
{
- return 1;
+ return e&I86_PDE_FRAME;
}
+/*
void pd_entry_enable_global (pd_entry e)
{
}
+*/
uint8_t vmmngr_alloc_page (pt_entry* e)
{
@@ -148,8 +170,94 @@ uint8_t vmmngr_alloc_page (pt_entry* e)
return 1;
}
-void vmem_init()
+void vmmngr_free_page (pt_entry* e)
+{
+ void* p = (void*)pt_entry_pfn (*e);
+ if (p)
+ pmmngr_free_block (p);
+
+ pt_entry_del_attrib (e, I86_PTE_PRESENT);
+}
+
+pt_entry* vmmngr_ptable_lookup_entry (ptable* p, virtual_addr addr)
+{
+
+ if (p)
+ return &p->m_entries[ PAGE_TABLE_INDEX (addr) ];
+
+ return 0;
+}
+
+// TODO !? http://www.brokenthorn.com/Resources/OSDev18.html
+void vmmngr_map_page (void* phys, void* virt)
+{
+
+}
+
+void vmem_init(uint32_t vesa_physbase)
{
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"init paging (vesa base: 0x%08x)",vesa_physbase);
+
+ ptable* table1 = (ptable*) pmmngr_alloc_block ();
+
+ if (!table1)panic(FOOLOS_MODULE_NAME,"unable to alloc table1");
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"table1: 0x%X",table1);
+
+ ptable* table2 = (ptable*) pmmngr_alloc_block ();
+
+ if (!table1)panic(FOOLOS_MODULE_NAME,"unable to alloc table2");
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"table2: 0x%X",table2);
+
+ // TODO: 3blocks?
+ pdirectory* dir = (pdirectory*) pmmngr_alloc_block ();
+ if (!dir)panic(FOOLOS_MODULE_NAME,"unable to alloc pdirectory");
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"pdirectory: 0x%X",dir);
+
+ //! map 1mb to 3gb (where we are at)
+ for (int i=0, frame=vesa_physbase, virt=vesa_physbase; i<1024; i++, frame+=4096, virt+=4096) {
+
+ //! create a new page
+ pt_entry page=0;
+ pt_entry_add_attrib (&page, I86_PTE_PRESENT);
+ pt_entry_set_frame (&page, frame);
+
+ //! ...and add it to the page table
+ table1->m_entries [PAGE_TABLE_INDEX (virt) ] = page;
+ }
+
+ //! 1st 4mb are idenitity mapped
+ for (int i=0, frame=0x0, virt=0x00000000; i<1024; i++, frame+=4096, virt+=4096)
+ {
+
+ //! create a new page
+ pt_entry page=0;
+ pt_entry_add_attrib (&page, I86_PTE_PRESENT);
+ pt_entry_set_frame (&page, frame);
+
+ //! ...and add it to the page table
+ table2->m_entries [PAGE_TABLE_INDEX (virt) ] = page;
+ }
+
+
+ pd_entry* entry = &dir->m_entries [PAGE_DIRECTORY_INDEX (vesa_physbase) ];
+ *entry=0;
+ pd_entry_add_attrib (entry, I86_PDE_PRESENT);
+ pd_entry_add_attrib (entry, I86_PDE_WRITABLE);
+ pd_entry_set_frame (entry, (physical_addr)table1);
+
+
+ pd_entry* entry2 = &dir->m_entries [PAGE_DIRECTORY_INDEX (0x00000000) ];
+ *entry2=0;
+ pd_entry_add_attrib (entry2, I86_PDE_PRESENT);
+ pd_entry_add_attrib (entry2, I86_PDE_WRITABLE);
+ pd_entry_set_frame (entry2, (physical_addr)table2);
+
+
+ x86_set_pdbr(dir);
+
+ log(FOOLOS_MODULE_NAME,FOOLOS_LOG_INFO,"enabling paging...");
+ x86_paging_enable();
+
}