diff options
Diffstat (limited to 'src/arch/amd64/paging.c')
-rw-r--r-- | src/arch/amd64/paging.c | 85 |
1 files changed, 43 insertions, 42 deletions
diff --git a/src/arch/amd64/paging.c b/src/arch/amd64/paging.c index 3140a2a..836f602 100644 --- a/src/arch/amd64/paging.c +++ b/src/arch/amd64/paging.c @@ -7,18 +7,9 @@ #include <memory/physalloc.h> #include <memory/virtalloc.h> +#include "paging.h" #include "bindings.h" -#define F_PRESENT 0x001 -#define F_WRITEABLE 0x002 -#define F_UNPRIVILEGED 0x004 -#define F_WRITETHROUGH 0x008 -#define F_CACHEDISABLE 0x010 -#define F_ACCESSED 0x020 -#define F_DIRTY 0x040 -#define F_MEGABYTE 0x080 -#define F_GLOBAL 0x100 - // PAGE MAP LEVEL 4 ENTRY struct pml4e { uint64_t flags : 6; @@ -61,19 +52,19 @@ struct pte { }; // bss segment, can write to -extern struct pml4e pml4_list[512]; -extern struct pdpte init_pdpt[512]; -extern struct pde init_pd[512]; -extern struct pte init_pt[512]; +extern struct pml4e kernel_pml4[512]; +extern struct pdpte kernel_pdpt_0[512]; +extern struct pde kernel_pd_0[512]; +extern struct pte bootstrap_pt[512]; extern struct pte paging_pt[512]; // paging_pt should NEVER be outside of this file, NEVER i say // paged address to read page tables // the structures are not gurenteed to be ident mapped // map them here with map_<type>(phys_addr) before useing structures -static struct pdpte *pdpt_mapped = (void *) (uintptr_t) 0x1000; -static struct pdpte *pd_mapped = (void *) (uintptr_t) 0x2000; -static struct pdpte *pt_mapped = (void *) (uintptr_t) 0x3000; -void *addr_mapped = (void *) (uintptr_t) 0x4000; +static struct pdpte *pdpt_mapped = (void *) (uintptr_t) 0x201000; +static struct pdpte *pd_mapped = (void *) (uintptr_t) 0x202000; +static struct pdpte *pt_mapped = (void *) (uintptr_t) 0x203000; +void *addr_mapped = (void *) (uintptr_t) 0x204000; static inline void invlpg(void *addr) { __asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); @@ -172,6 +163,7 @@ int map_page(struct pml4e *pml4, void *virt_addr, void *phys_addr, unsigned int map_pt(__pt); pt_mapped[pt_offset].flags = F_PRESENT | flags; pt_mapped[pt_offset].address = (((uint64_t)phys_addr) >> 12); + invlpg(virt_addr); return 0; } @@ -236,51 +228,52 @@ done: } void paging_init(void) { - memset(pml4_list, 0, 4096); - pml4_list[0].flags = F_PRESENT | F_WRITEABLE; - pml4_list[0].address = (uint64_t)init_pdpt >> 12; - - memset(init_pdpt, 0, 4096); - init_pdpt[0].flags = F_PRESENT | F_WRITEABLE; - init_pdpt[0].address = (uint64_t)init_pd >> 12; - - memset(pml4_list, 0, 4096); - init_pd[0].flags = F_PRESENT | F_WRITEABLE; - init_pd[0].address = (uint64_t)paging_pt >> 12; - init_pd[1].flags = F_PRESENT | F_WRITEABLE; - init_pd[1].address = (uint64_t)init_pt >> 12; + + kernel_pml4[0].flags = F_PRESENT | F_WRITEABLE; + kernel_pml4[0].address = (uint64_t)(&kernel_pdpt_0) >> 12; + + kernel_pdpt_0[0].flags = F_PRESENT | F_WRITEABLE; + kernel_pdpt_0[0].address = (uint64_t)(&kernel_pd_0) >> 12; + + kernel_pd_0[1].flags = F_PRESENT | F_WRITEABLE; + kernel_pd_0[1].address = (uint64_t)(&paging_pt) >> 12; + kernel_pd_0[2].flags = F_PRESENT | F_WRITEABLE; + kernel_pd_0[2].address = (uint64_t)(&bootstrap_pt) >> 12; - memset(init_pt, 0, 4096); - memset(paging_pt, 0, 4096); + memset(&paging_pt, 0, 4096); + memset(&bootstrap_pt, 0, 4096); } static inline void *page_align(void *addr) { uintptr_t a = (uintptr_t) addr; - a += PAGE_SIZE + 1; + a += PAGE_SIZE - 1; a /= PAGE_SIZE; + a *= PAGE_SIZE; return (void *) a; } void *mmap(void *addr, size_t len) { - len += (uintptr_t)addr % PAGE_SIZE; - int pages = (len + PAGE_SIZE - 1) / PAGE_SIZE; + len += (long)addr % PAGE_SIZE; + long pages = (len + PAGE_SIZE - 1) / PAGE_SIZE; void *virt = virtaddr_alloc(pages); - if (virt == NULL) + if (virt == NULL) { return NULL; + } void *phys = page_align(addr); for (long i = 0; i < pages; i++) { void *virt_temp = (char *)virt + (i * PAGE_SIZE); void *phys_temp = (char *)phys + (i * PAGE_SIZE); - map_page(pml4_list, virt_temp, phys_temp, F_WRITEABLE); + map_page(kernel_pml4, virt_temp, phys_temp, F_WRITEABLE); } - return addr; + map_page(kernel_pml4, virt, (void*)0x23443, F_WRITEABLE); + return virt; } void unmap(void *addr) { long pages = virtaddr_free(addr); for (long i = 0; i < pages; i++) { void *virt = (char *)addr + (i * PAGE_SIZE); - unmap_page(pml4_list, virt); + unmap_page(kernel_pml4, virt); } } @@ -296,7 +289,7 @@ void *alloc_pages(int count) { for (int i = 0; i < count; i++) { void *virt_temp = (char *)virt + (i * PAGE_SIZE); void *phys_temp = (char *)phys + (i * PAGE_SIZE); - map_page(pml4_list, virt_temp, phys_temp, F_WRITEABLE); + map_page(kernel_pml4, virt_temp, phys_temp, F_WRITEABLE); } return virt; } @@ -307,7 +300,7 @@ void free_page(void *virt) { return; for (long i = 0; i < pages; i++) { void *virt_temp = (char *)virt + (i * PAGE_SIZE); - unmap_page(pml4_list, virt_temp); + unmap_page(kernel_pml4, virt_temp); } } @@ -318,3 +311,11 @@ void memory_lock(void) { void memory_unlock(void) { sti(); } + +int kmap_page(void *virt_addr, void *phys_addr, unsigned int flags) { + return map_page(kernel_pml4, virt_addr, phys_addr, flags); +} + +int kunmap_page(void *virt_addr) { + return unmap_page(kernel_pml4, virt_addr); +} |