diff options
Diffstat (limited to 'kernel/memory')
-rw-r--r-- | kernel/memory/memory.c | 26 | ||||
-rw-r--r-- | kernel/memory/paging.c | 25 | ||||
-rw-r--r-- | kernel/memory/paging.h | 7 |
3 files changed, 41 insertions, 17 deletions
diff --git a/kernel/memory/memory.c b/kernel/memory/memory.c index 7ceb491..295823e 100644 --- a/kernel/memory/memory.c +++ b/kernel/memory/memory.c @@ -52,7 +52,7 @@ mem_ctx_t mem_ctx_alloc(void) if (ctx == NULL) return NULL; - if ((ctx->pml4 = paging_alloc()) == NULL) + if ((ctx->pml4 = pgdir_alloc()) == NULL) return NULL; virtaddr_init(&ctx->virtctx); @@ -64,17 +64,31 @@ mem_ctx_t mem_ctx_alloc(void) return ctx; } -mem_ctx_t mem_ctx_clone(mem_ctx_t ctx, bool cow) +mem_ctx_t mem_ctx_clone(const mem_ctx_t old, bool cow) { - (void)ctx; - (void)cow; + mem_ctx_t new = user_mem_ctx_next; + if (new == NULL) + return NULL; + + if ((new->pml4 = pgdir_clone(old->pml4, cow)) == NULL) + return NULL; + + if (virtaddr_clone(&old->virtctx, &new->virtctx)) { + pgdir_free(new->pml4); + return NULL; + } + + user_mem_ctx_next = new->prev; + if (new->prev) + new->prev->next = NULL; + new->prev = NULL; - panic("not yet implemented"); + return new; } void mem_ctx_free(mem_ctx_t ctx) { - paging_free(ctx->pml4); + pgdir_free(ctx->pml4); virtaddr_cleanup(&ctx->virtctx); if (user_mem_ctx_next == NULL) { diff --git a/kernel/memory/paging.c b/kernel/memory/paging.c index 24a9ea7..c6e6a82 100644 --- a/kernel/memory/paging.c +++ b/kernel/memory/paging.c @@ -5,7 +5,6 @@ #include "physalloc.h" #include "paging.h" #include "memory.h" -#include <stdint.h> // PAGE MAP LEVEL 4 ENTRY struct pml4e { @@ -139,7 +138,7 @@ extern char kernel_start[]; extern char kernel_end[]; // invalidate page cache at a vitural address -static inline void invlpg(volatile void *vADDR) +static inline void invlpg(volatile const void *vADDR) { __asm__ volatile("invlpg (%0)" ::"r"(vADDR) : "memory"); } @@ -150,7 +149,7 @@ static inline void invlpg(volatile void *vADDR) // @returns VIRTUAL ADDRESS static volatile struct pml4 *pml4_map(volatile struct pml4 *pPML4) { - static struct pml4 *vPML4 = (void *)(uintptr_t)0x40000000; + static volatile struct pml4 *vPML4 = (void *)(uintptr_t)0x40000000; static volatile struct pte *vPTE = &paging_pt.entries[0]; if ((uint64_t)pPML4 >> 12 == vPTE->address) @@ -166,7 +165,7 @@ static volatile struct pml4 *pml4_map(volatile struct pml4 *pPML4) // @returns VIRTUAL ADDRESS static volatile struct pdpt *pdpt_map(volatile struct pdpt *pPDPT) { - static struct pdpt *vPDPT = (void *)(uintptr_t)0x40001000; + static volatile struct pdpt *vPDPT = (void *)(uintptr_t)0x40001000; static volatile struct pte *vPTE = &paging_pt.entries[1]; if ((uint64_t)pPDPT >> 12 == vPTE->address) @@ -182,7 +181,7 @@ static volatile struct pdpt *pdpt_map(volatile struct pdpt *pPDPT) // @returns VIRTUAL ADDRESS static volatile struct pd *pd_map(volatile struct pd *pPD) { - static struct pd *vPD = (void *)(uintptr_t)0x40002000; + static volatile struct pd *vPD = (void *)(uintptr_t)0x40002000; static volatile struct pte *vPTE = &paging_pt.entries[2]; if ((uint64_t)pPD >> 12 == vPTE->address) @@ -198,7 +197,7 @@ static volatile struct pd *pd_map(volatile struct pd *pPD) // @returns VIRTUAL ADDRESS static volatile struct pt *pt_map(volatile struct pt *pPT) { - static struct pt *vPT = (void *)(uintptr_t)0x40003000; + static volatile struct pt *vPT = (void *)(uintptr_t)0x40003000; static volatile struct pte *vPTE = &paging_pt.entries[3]; if ((uint64_t)pPT >> 12 == vPTE->address) @@ -678,14 +677,14 @@ void paging_init(void) kernel_pd_1.entries[0].flags = F_PRESENT | F_WRITEABLE; kernel_pd_1.entries[0].address = (uint64_t)(paging_pt.entries) >> 12; - memsetv(paging_pt.entries, 0, 4096); + memsetv(paging_pt.entries, 0, PAGE_SIZE); // make sure we are using THESE pagetables // EFI doesnt on boot __asm__ volatile("mov %0, %%cr3" ::"r"(kernel_pml4.entries) : "memory"); } -volatile void *paging_alloc(void) +volatile void *pgdir_alloc(void) { volatile struct pml4 *pPML4; @@ -702,7 +701,15 @@ volatile void *paging_alloc(void) return pPML4; } -void paging_free(volatile void *addr) +volatile void *pgdir_clone(volatile const void *old_pgdir, bool cow) +{ + // TODO: + (void) old_pgdir; + (void) cow; + return NULL; +} + +void pgdir_free(volatile void *addr) { pml4_free(addr, true); } diff --git a/kernel/memory/paging.h b/kernel/memory/paging.h index d80a9bf..94b7260 100644 --- a/kernel/memory/paging.h +++ b/kernel/memory/paging.h @@ -9,9 +9,12 @@ #ifndef PAGING_H_ #define PAGING_H_ +#include <stdbool.h> + void paging_init(void); -volatile void *paging_alloc(void); -void paging_free(volatile void *addr); +volatile void *pgdir_alloc(void); +volatile void *pgdir_clone(volatile const void *pdir, bool cow); +void pgdir_free(volatile void *addr); #endif /* paging.h */ |