forked from PoliEcho-holding-org/kern
basic vmm_alloc structure
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
#include "kernel.h"
|
||||
#include <errno.h>
|
||||
#include <isr.h>
|
||||
#include <limits.h>
|
||||
#include <paging.h>
|
||||
#include <pmm.h>
|
||||
#include <types.h>
|
||||
|
||||
// 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;
|
||||
}
|
||||
Reference in New Issue
Block a user