diff options
author | Freya Murphy <freya@freyacat.org> | 2024-02-03 14:36:26 -0500 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2024-02-03 14:41:52 -0500 |
commit | 8e74123683072deed9ecd29e76037a16a47e3295 (patch) | |
tree | 2a4d6394688ed23b9360ff87c8d9861ab40da01d /src/arch/amd64/paging.c | |
parent | refactor exception panic (diff) | |
download | corn-8e74123683072deed9ecd29e76037a16a47e3295.tar.gz corn-8e74123683072deed9ecd29e76037a16a47e3295.tar.bz2 corn-8e74123683072deed9ecd29e76037a16a47e3295.zip |
alloc on write paging, -O3 compile works, 'volatile' is the story of my life
Diffstat (limited to 'src/arch/amd64/paging.c')
-rw-r--r-- | src/arch/amd64/paging.c | 153 |
1 files changed, 77 insertions, 76 deletions
diff --git a/src/arch/amd64/paging.c b/src/arch/amd64/paging.c index 1c1c56c..fd24af4 100644 --- a/src/arch/amd64/paging.c +++ b/src/arch/amd64/paging.c @@ -54,34 +54,34 @@ struct pte { }; // bss segment, can write to -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 +extern volatile struct pml4e kernel_pml4[512]; +extern volatile struct pdpte kernel_pdpt_0[512]; +extern volatile struct pde kernel_pd_0[512]; +extern volatile struct pte bootstrap_pt[512]; +extern volatile 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 -void *addr_mapped = (void *) (uintptr_t) 0x204000; -static struct pml4e *pml4_mapped = (void *) (uintptr_t) 0x200000; -static struct pdpte *pdpt_mapped = (void *) (uintptr_t) 0x201000; -static struct pde *pd_mapped = (void *) (uintptr_t) 0x202000; -static struct pte *pt_mapped = (void *) (uintptr_t) 0x203000; +void volatile *addr_mapped = (void *) (uintptr_t) 0x204000; +static volatile struct pml4e *pml4_mapped = (void *) (uintptr_t) 0x200000; +static volatile struct pdpte *pdpt_mapped = (void *) (uintptr_t) 0x201000; +static volatile struct pde *pd_mapped = (void *) (uintptr_t) 0x202000; +static volatile struct pte *pt_mapped = (void *) (uintptr_t) 0x203000; -static inline void invlpg(void *addr) { +static inline void invlpg(volatile void *addr) { __asm__ volatile("invlpg (%0)" ::"r" (addr) : "memory"); } -static void load_addr(void *phys_addr) { - static struct pte *pt = &paging_pt[4]; +static void load_addr(volatile void *phys_addr) { + static volatile struct pte *pt = &paging_pt[4]; pt->address = (uint64_t)phys_addr >> 12; pt->flags = F_PRESENT | F_WRITEABLE; invlpg(addr_mapped); } -static void load_pml4(void *phys) { - static struct pte *pt = &paging_pt[0]; +static void load_pml4(volatile void *phys) { + static volatile struct pte *pt = &paging_pt[0]; if ((uint64_t)phys >> 12 == pt->address) return; pt->address = (uint64_t)phys >> 12; @@ -89,8 +89,8 @@ static void load_pml4(void *phys) { invlpg(pml4_mapped); } -static void load_pdpt(void *phys) { - static struct pte *pt = &paging_pt[1]; +static void load_pdpt(volatile void *phys) { + static volatile struct pte *pt = &paging_pt[1]; if ((uint64_t)phys >> 12 == pt->address) return; pt->address = (uint64_t)phys >> 12; @@ -98,8 +98,8 @@ static void load_pdpt(void *phys) { invlpg(pdpt_mapped); } -static void load_pd(void *phys) { - static struct pte *pt = &paging_pt[2]; +static void load_pd(volatile void *phys) { + static volatile struct pte *pt = &paging_pt[2]; if ((uint64_t)phys >> 12 == pt->address) return; pt->address = (uint64_t)phys >> 12; @@ -107,8 +107,8 @@ static void load_pd(void *phys) { invlpg(pd_mapped); } -static void load_pt(void *phys) { - static struct pte *pt = &paging_pt[3]; +static void load_pt(volatile void *phys) { + static volatile struct pte *pt = &paging_pt[3]; if ((uint64_t)phys >> 12 == pt->address) return; pt->address = (uint64_t)phys >> 12; @@ -123,13 +123,13 @@ static void load_pt(void *phys) { static int select_pdpt( void *virt, unsigned int flags, - struct pml4e *root, - struct pdpte **res, + volatile struct pml4e *root, + volatile struct pdpte **res, bool create ) { load_pml4(root); uint64_t offset = (uint64_t)virt >> 39; - struct pml4e *pml4e = &pml4_mapped[offset]; + volatile struct pml4e *pml4e = &pml4_mapped[offset]; if (!(pml4e->flags & F_PRESENT)) { if (!create) { return PAG_NOT_PRESENT; @@ -139,26 +139,26 @@ static int select_pdpt( return PAG_CANNOT_ALLOC; } load_addr(new_page); - memset(addr_mapped, 0, PAGE_SIZE); + memsetv(addr_mapped, 0, PAGE_SIZE); pml4e->address = ((uint64_t)new_page) >> 12; pml4e->flags = F_PRESENT; } if (flags) pml4e->flags = F_PRESENT | flags; - *res = (struct pdpte *)(uintptr_t)(pml4e->address << 12); + *res = (volatile struct pdpte *)(uintptr_t)(pml4e->address << 12); return PAG_SUCCESS; } static int select_pd( void *virt, unsigned int flags, - struct pdpte *pdpt, - struct pde **res, + volatile struct pdpte *pdpt, + volatile struct pde **res, bool create ) { load_pdpt(pdpt); uint64_t offset = ((uint64_t)virt >> 30) & 0x1ff; - struct pdpte *pdpte = &pdpt_mapped[offset]; + volatile struct pdpte *pdpte = &pdpt_mapped[offset]; if (!(pdpte->flags & F_PRESENT)) { if (!create) { return PAG_NOT_PRESENT; @@ -168,26 +168,26 @@ static int select_pd( return PAG_CANNOT_ALLOC; } load_addr(new_page); - memset(addr_mapped, 0, PAGE_SIZE); + memsetv(addr_mapped, 0, PAGE_SIZE); pdpte->address = ((uint64_t)new_page) >> 12; pdpte->flags = F_PRESENT; } if (flags) pdpte->flags = F_PRESENT | flags; - *res = (struct pde *)(uintptr_t)(pdpte->address << 12); + *res = (volatile struct pde *)(uintptr_t)(pdpte->address << 12); return PAG_SUCCESS; } static int select_pt( void *virt, unsigned int flags, - struct pde *pd, - struct pte **res, + volatile struct pde *pd, + volatile struct pte **res, bool create ) { load_pd(pd); uint64_t offset = ((uint64_t)virt >> 21) & 0x1ff; - struct pde *pde = &pd_mapped[offset]; + volatile struct pde *pde = &pd_mapped[offset]; if (!(pde->flags & F_PRESENT)) { if (!create) { return PAG_NOT_PRESENT; @@ -197,24 +197,24 @@ static int select_pt( return PAG_CANNOT_ALLOC; } load_addr(new_page); - memset(addr_mapped, 0, PAGE_SIZE); + memsetv(addr_mapped, 0, PAGE_SIZE); pde->address = ((uint64_t)new_page) >> 12; pde->flags = F_PRESENT; } if (flags) pde->flags = F_PRESENT | flags; - *res = (struct pte *)(uintptr_t)(pde->address << 12); + *res = (volatile struct pte *)(uintptr_t)(pde->address << 12); return PAG_SUCCESS; } static void select_page( void *virt, - struct pte *pt, - struct pte **res + volatile struct pte *pt, + volatile struct pte **res ) { load_pt(pt); uint64_t offset = ((uint64_t)virt >> 12) & 0x1ff; - struct pte *page = &pt_mapped[offset]; + volatile struct pte *page = &pt_mapped[offset]; *res = page; return; } @@ -275,13 +275,13 @@ static inline void try_unmap_pt(void) { } static void unmap_page( - struct pml4e *root, + volatile struct pml4e *root, void *virt ) { - struct pdpte *pdpt; - struct pde *pd; - struct pte *pt; - struct pte *page; + volatile struct pdpte *pdpt; + volatile struct pde *pd; + volatile struct pte *pt; + volatile struct pte *page; unsigned int df = 0; @@ -308,7 +308,7 @@ static void unmap_page( } static void unmap_pages( - struct pml4e *root, + volatile struct pml4e *root, void *virt_start, long page_count ) { @@ -320,10 +320,10 @@ static void unmap_pages( pdpt_n, pd_n; - struct pdpte *pdpt = NULL; - struct pde *pd = NULL; - struct pte *pt = NULL; - struct pte *page = NULL; + volatile struct pdpte *pdpt = NULL; + volatile struct pde *pd = NULL; + volatile struct pte *pt = NULL; + volatile struct pte *page = NULL; unsigned int df = 0; @@ -372,14 +372,14 @@ static void unmap_pages( return; } -static struct pte *get_page( - struct pml4e *root, +static volatile struct pte *get_page( + volatile struct pml4e *root, void *virt ) { - struct pdpte *pdpt; - struct pde *pd; - struct pte *pt; - struct pte *page; + volatile struct pdpte *pdpt; + volatile struct pde *pd; + volatile struct pte *pt; + volatile struct pte *page; unsigned int df = 0; @@ -398,15 +398,15 @@ static struct pte *get_page( } static int map_page( - struct pml4e *root, + volatile struct pml4e *root, void *virt, void *phys, unsigned int flags ) { - struct pdpte *pdpt; - struct pde *pd; - struct pte *pt; - struct pte *page; + volatile struct pdpte *pdpt; + volatile struct pde *pd; + volatile struct pte *pt; + volatile struct pte *page; unsigned int df = F_WRITEABLE; @@ -439,7 +439,7 @@ static int map_page( } static int map_pages( - struct pml4e *root, + volatile struct pml4e *root, void *virt_start, void *phys_start, unsigned int flags, @@ -453,10 +453,10 @@ static int map_pages( pdpt_n, pd_n; - struct pdpte *pdpt = NULL; - struct pde *pd = NULL; - struct pte *pt = NULL; - struct pte *page = NULL; + volatile struct pdpte *pdpt = NULL; + volatile struct pde *pd = NULL; + volatile struct pte *pt = NULL; + volatile struct pte *page = NULL; void *virt, *phys; @@ -533,8 +533,8 @@ void paging_init(void) { kernel_pd_0[2].flags = F_PRESENT | F_WRITEABLE; kernel_pd_0[2].address = (uint64_t)(&bootstrap_pt) >> 12; - memset(&paging_pt, 0, 4096); - memset(&bootstrap_pt, 0, 4096); + memsetv(&paging_pt, 0, 4096); + memsetv(&bootstrap_pt, 0, 4096); } static inline void *page_align(void *addr) { @@ -577,15 +577,17 @@ void *alloc_pages(int count) { void *virt = virtaddr_alloc(count); if (virt == NULL) return NULL; - void *phys = alloc_phys_pages(count); - if (phys == NULL) { - virtaddr_free(virt); - return NULL; - } + //void *phys = alloc_phys_pages(count); + //if (phys == NULL) { + // virtaddr_free(virt); + // return NULL; + //} if (map_pages( kernel_pml4, virt, - phys, + //phys, + //F_WRITEABLE, + NULL, F_WRITEABLE, count )) { @@ -625,7 +627,7 @@ int kunmap_page(void *virt_addr) { } int kload_page(void *virt_addr) { - struct pte *page = get_page(kernel_pml4, virt_addr); + volatile struct pte *page = get_page(kernel_pml4, virt_addr); if (page == NULL) return -1; if (page->loaded) @@ -636,8 +638,7 @@ int kload_page(void *virt_addr) { return -2; page->loaded = 1; page->address = (uint64_t)phys >> 12; - page->flags |= F_PRESENT | F_WRITEABLE; + page->flags |= F_PRESENT; invlpg(virt_addr); - __asm__ volatile ("movq %cr3, %rax; movq %rax, %cr3;"); return 0; } |