From e9c35831c0858e8bcc39ccf4a118e0274cf58c5f Mon Sep 17 00:00:00 2001 From: Morten Delenk Date: Sat, 30 Dec 2017 11:24:15 +0100 Subject: [PATCH] added a bit of the x86_64 paging code --- kernel/arch/x86_64/include/paging.h | 4 +- kernel/arch/x86_64/paging.cpp | 174 +++++++++++++++++++++++++--- 2 files changed, 159 insertions(+), 19 deletions(-) diff --git a/kernel/arch/x86_64/include/paging.h b/kernel/arch/x86_64/include/paging.h index 267279b..c6ac94d 100644 --- a/kernel/arch/x86_64/include/paging.h +++ b/kernel/arch/x86_64/include/paging.h @@ -39,7 +39,7 @@ static_assert(sizeof(pagemap)==8); struct pagedir { bool active:1; bool writeable:1; - bool privileged:1; + bool unprivileged:1; bool no_write_cache:1; bool no_read_cache:1; bool accessed:1; @@ -56,7 +56,7 @@ static_assert(sizeof(pagedir)==8); struct pagetbl { bool active:1; bool writeable:1; - bool privileged:1; + bool unprivileged:1; bool no_write_cache:1; bool no_read_cache:1; bool accessed:1; diff --git a/kernel/arch/x86_64/paging.cpp b/kernel/arch/x86_64/paging.cpp index d6df91d..ba09d29 100644 --- a/kernel/arch/x86_64/paging.cpp +++ b/kernel/arch/x86_64/paging.cpp @@ -3,29 +3,169 @@ extern int kernel_start; extern int kernel_end; +const pagemap_tbl *curr_pagemaptbl = pagemap_tbl *(0x8000000000); +const pagemap_tbl *ref_pagemaptbl = pagemap_tbl *(0x8000001000); +const pagemap *curr_pagemap = pagemap *(0x8000200000); +const pagemap *ref_pagemap = pagemap *(0x8000400000); +const pagedir *curr_pagedir = pagedir *(0x8040000000); +const pagedir *ref_pagedir = pagedir *(0x8080000000); +const pagetbl *curr_pagetbl = pagetbl *(0xC000000000); +const pagetbl *ref_pagetbl = pagetbl *(0x10000000000); +inline uint64_t pagemaptbl_index(phys_t addr) { + return addr >> 39; +} +inline uint64_t pagemap_index(phys_t addr) { + return addr >> 30; +} +inline uint64_t pagedir_index(phys_t addr) { + return addr >> 21; +} +inline uint64_t pagetbl_index(phys_t addr) { + return addr >> 12; +} + +inline phys_t wrap(uint64_t x) { + if(x >= 0x800000000000ull) + return x | 0xFFFF000000000000ull; + else + return x; +} + +inline phys_t make_phys(uint64_t i, uint64_t j, uint64_t k, uint64_t l) { + return (i << 39) | (j << 30) | (k << 21) | (l << 12); +} + +inline void* make_virt(uint64_t i, uint64_t j, uint64_t k, uint64_t l) { + return (void*)wrap(make_phys(i,j,k,l)); +} + +pagemap_tbl kernel[256]; paging_context_x86::paging_context_x86(): paging_context() { phys_t pagedir_addr; *pmm >> pagedir_addr; if(context_enabled) { - current_context->mmap(pagedir_addr, (void*)0x800000, protection::RW, false); - pagemap *src=(pagemap *)0x400000; - pagemap *dest=(pagemap*)0x600000; - for(int i=0;i<256;i++) - dest[i]=src[i]; - for(int i=256;i<512;i++) - dest[i].active=false; - dest[0].active=false; - phys_t first_pagedir; - *pmm >> first_pagedir; - dest[0].pagedir = first_pagedir >> 12; - dest[0].writeable=true; - dest[0].unprivileged=false; - dest[0].no_write_cache=true; - dest[0].no_read_cache=false; - dest[0].sbz=0; - dest[0].active=true; + current_context->mmap(pagedir_addr, ref_pagemaptbl, protection::RW, false); + for(int i = 0;i < 256; i++) + ref_pagemaptbl[i] = curr_pagemaptbl[i]; + for(int i = 256; i < 512; i++) + ref_pagemaptbl[i].active = false; + ref_pagemaptbl[1].active = false; + ref_pagemaptbl[2].active = false; + ref_pagemaptbl[3].active = false; + phys_t pagemaptbl_map; + *pmm >> pagemaptbl_map; + ref_pagemaptbl[1].pagemap = pagemaptbl_map >> 12; + ref_pagemaptbl[1].writeable=true; + ref_pagemaptbl[1].unprivileged=false; + ref_pagemaptbl[1].no_write_cache=true; + ref_pagemaptbl[1].no_read_cache=false; + ref_pagemaptbl[1].sbz = 0; + ref_pagemaptbl[1].executable = false; + ref_pagemaptbl[1].active = true; + + phys_t selfmap; + *pmm >> selfmap; + ref_pagemaptbl[2].pagemap = selfmap >> 12; + ref_pagemaptbl[2].writeable=true; + ref_pagemaptbl[2].unprivileged=false; + ref_pagemaptbl[2].no_write_cache=true; + ref_pagemaptbl[2].no_read_cache=false; + ref_pagemaptbl[2].sbz = 0; + ref_pagemaptbl[2].executable = false; + ref_pagemaptbl[2].active = true; + + current_context->map_pagetable(this); + + //remap everything + for(uint64_t i = 0; i < 256; i++) { + if(!ref_pagemaptbl[i].active) + continue; + if(i > 0 && i < 4) + continue; + uint64_t pagemap_start = pagemap_index(make_phys(i,0,0,0)); + for(uint64_t j = pagemap_start; j> kernelpagemap; + pagemaptbl[0].pagemap = kernelpagemap >> 12; + pagemaptbl[0].writeable=true; + pagemaptbl[0].unprivileged=false; + pagemaptbl[0].no_write_cache=false; + pagemaptbl[0].no_read_cache=false; + pagemaptbl[0].sbz = 0; + pagemaptbl[0].executable = false; + pagemaptbl[0].active = true; + + pagemap *kpagemap = (pagemap*)kernelpagemap; + for(int i=0;i<512;i++) + kpagemap[i].active=false; + phys_t kernelpagedir; + *pmm >> kernelpagedir; + kpagemap[0].pagedir = kernelpagedir >> 12; + kpagemap[0].writeable=true; + kpagemap[0].unprivileged=false; + kpagemap[0].no_write_cache=false; + kpagemap[0].no_read_cache=false; + kpagemap[0].sbz = 0; + kpagemap[0]._1G_page=false; + kpagemap[0].global=true; + kpagemap[0].executable=false; + kpagemap[0].active=true; + + pagedir *kpagedir = (pagedir*)kernelpagedir; + for(int i=0;i<512;i++) + kpagedir[i].active=false; + phys_t kernelpagetbl; + *pmm >> kernelpagetbl; + kpagedir[1].pagetbl = kernelpagetbl >> 12; + kpagedir[1].writeable=true; + kpagedir[1].unprivileged=false; + kpagedir[1].no_write_cache=false; + kpagedir[1].no_read_cache=false; + kpagedir[1].sbz=0; + kpagedir[1]._2M_page=false; + kpagedir[1].global=true; + kpagedir[1].executable=false; + kpagedir[1].active=true; + + pagetbl *kpagetbl = (pagetbl*)kernelpagetbl; + for(int i=0;i<512;i++) + kpagetbl[i].active=false; + for(phys_t i=(((phys_t)&kernel_start)>>12)-512,p=(phys_t)&kernel_start;p<(phys_t)&kernel_end;p+=0x1000;i++) { + kpagetbl[i].page=i; + kpagetbl[i].writeable=true; + kpagetbl[i].unprivileged=false; + kpagetbl[i].no_write_cache=false; + kpagetbl[i].no_read_cache=false; + kpagetbl[i].sbz=false; + kpagetbl[i].pat=false; + kpagetbl[i].global=true; + kpagetbl[i].executable=true; + kpagetbl[i].active=true; + } + }