diff --git a/kernel/src/vmm.c b/kernel/src/vmm.c new file mode 100644 index 0000000..3c8ec6f --- /dev/null +++ b/kernel/src/vmm.c @@ -0,0 +1,49 @@ +#include "kernel.h" +#include +#include +#include +#include +#include +#include + +// allocates set number of pages at address provided +// if address is NULL address is chosen internaly +int vmm_alloc(void** vaddr, uint64_t count, uint64_t flags) { + if (flags == 0) { + flags = PTE_FLAG_PRESENT | PTE_FLAG_WRITE | PTE_FLAG_NOEXEC; + } + + uint64_t* pml4 = pag_get_pml4(); + for (uint64_t i = 0; i < count; i++) { + uint64_t* pte = pag_get_pte(pml4, vaddr); + if (!IS_ERR(pte) && (*pte & PTE_FLAG_PRESENT)) { + // TODO actualy handle conflict + return EEXIST; + } + } + + for (uint64_t i = 0; i < count; i++) { + void* paddr = pmm_alloc(); + int pag_map_ret = + pag_map(pml4, (void*)(((size_t)vaddr) * i * PAGE_SIZE), + paddr, flags); + if (pag_map_ret != SUCCESS) { + if (i != 0) { + for (i -= 1; i != UINT64_MAX; i--) { + if (pag_unmap(pml4, + (void*)(((size_t)vaddr) * + i * PAGE_SIZE)) != + SUCCESS) { + panic(NULL, + "failed to unmap " + "previously mapped " + "page. %s:%d", + __FILE_NAME__, __LINE__); + } + } + } + return pag_map_ret; + } + } + return SUCCESS; +} \ No newline at end of file