1 #include <lunaix/mm/pmm.h>
2 #include <lunaix/mm/vmm.h>
3 #include <lunaix/spike.h>
5 #define VMAP_START PG_MOUNT_BASE + MEM_4MB
6 #define VMAP_END PD_REFERENCED
8 static uintptr_t start = VMAP_START;
11 vmm_vmap(uintptr_t paddr, size_t size, pt_attr attr)
14 assert_msg((paddr & 0xfff) == 0, "vmap: bad alignment");
15 size = ROUNDUP(size, PG_SIZE);
17 uintptr_t current_addr = start;
18 size_t examed_size = 0, wrapped = 0;
19 x86_page_table* pd = (x86_page_table*)L1_BASE_VADDR;
21 while (!wrapped || current_addr >= start) {
22 size_t l1inx = L1_INDEX(current_addr);
23 if (!(pd->entry[l1inx])) {
25 examed_size += MEM_4MB;
26 current_addr = (current_addr & 0xffc00000) + MEM_4MB;
28 x86_page_table* ptd = (x86_page_table*)(L2_VADDR(l1inx));
29 size_t i = L2_INDEX(current_addr);
30 for (; i < PG_MAX_ENTRIES && examed_size < size; i++) {
32 examed_size += PG_SIZE;
33 } else if (examed_size) {
34 // found a discontinuity, start from beginning
40 current_addr += i << 12;
43 if (examed_size >= size) {
47 if (current_addr >= VMAP_END) {
49 current_addr = VMAP_START;
56 uintptr_t alloc_begin = current_addr - examed_size;
57 for (size_t i = 0; i < size; i += PG_SIZE) {
59 PD_REFERENCED, alloc_begin + i, paddr + i, PG_PREM_RW, 0);
60 pmm_ref_page(KERNEL_PID, paddr + i);
62 start = alloc_begin + size;
64 return (void*)alloc_begin;