#include #include "syscall.h" #include "mman.h" #include "spinlock/spinlock.h" #include "proc/proc.h" #include "hal/hal.h" #include "pmm/pmm.h" #include "util/util.h" #include "errors.h" #include "sysdefs/mman.h" #include "bootinfo/bootinfo.h" #include "dlmalloc/malloc.h" int32_t SYSCALL5(sys_mman_map, addr1, size1, prot1, flags1, out1) { uint8_t *addr = (uint8_t *)addr1; size_t size = size1; uint64_t prot = prot1; uint64_t flags = flags1; uint8_t **out = (uint8_t **)out1; if (size % HAL_PAGE_SIZE != 0) { if (out != NULL) { *out = NULL; } return E_INVALIDARGUMENT; } size_t pages = _DIV_ROUNDUP(size, HAL_PAGE_SIZE); uint8_t *phys = (uint8_t *)pmm_alloc(pages); if (phys == NULL) { return E_NOMEMORY; } hal_memset(VIRT(phys), 0, pages * HAL_PAGE_SIZE); spinlock_acquire(&PROCS.spinlock); Proc *proc = PROCS.current; spinlock_release(&PROCS.spinlock); uint8_t *virt = NULL; if (flags & MMAN_MAP_F_FIXED && addr != NULL) { virt = addr; } else { virt = (uint8_t *)proc->mman_map_base; proc->mman_map_base += size; } uint64_t pflags = HAL_PG_USER | HAL_PG_PRESENT; if (prot & MMAN_MAP_PF_RW) { pflags |= HAL_PG_RW; } hal_vmm_map_range(VIRT(proc->platformdata.cr3), virt, phys, size, pflags); VasRange *range = dlmalloc(sizeof(*range)); range->virtstart = virt; range->physstart = phys; range->size = size * HAL_PAGE_SIZE; range->pgflags = pflags; LL_APPEND(proc->vas, range); if (out != NULL) { *out = virt; } return E_OK; } int32_t SYSCALL1(sys_mman_unmap, addr1) { uint8_t *addr = (uint8_t *)addr1; if (addr == NULL) { return E_INVALIDARGUMENT; } spinlock_acquire(&PROCS.spinlock); Proc *proc = PROCS.current; spinlock_release(&PROCS.spinlock); uint8_t *virt = NULL; VasRange *tofree = NULL; VasRange *range = proc->vas; while (range) { if (range->virtstart == addr) { tofree = range; break; } range = range->next; } if (tofree == NULL) { return E_INVALIDARGUMENT; } hal_vmm_unmap_range(VIRT(proc->platformdata.cr3), tofree->virtstart, tofree->physstart, tofree->size); LL_REMOVE(proc->vas, tofree); pmm_free((uintptr_t)tofree->physstart, tofree->size / HAL_PAGE_SIZE); dlfree(tofree); return E_OK; }