feat: hook up the keyboard input into our vfs
[lunaix-os.git] / lunaix-os / kernel / mm / vmap.c
1 #include <lunaix/mm/pmm.h>
2 #include <lunaix/mm/vmm.h>
3 #include <lunaix/spike.h>
4
5 #define VMAP_START PG_MOUNT_BASE + MEM_4MB
6 #define VMAP_END PD_REFERENCED
7
8 static uintptr_t start = VMAP_START;
9
10 void*
11 vmm_vmap(uintptr_t paddr, size_t size, pt_attr attr)
12 {
13     // next fit
14     assert_msg((paddr & 0xfff) == 0, "vmap: bad alignment");
15     size = ROUNDUP(size, PG_SIZE);
16
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;
20
21     while (!wrapped || current_addr >= start) {
22         size_t l1inx = L1_INDEX(current_addr);
23         if (!(pd->entry[l1inx])) {
24             // empty 4mb region
25             examed_size += MEM_4MB;
26             current_addr = (current_addr & 0xffc00000) + MEM_4MB;
27         } else {
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++) {
31                 if (!ptd->entry[i]) {
32                     examed_size += PG_SIZE;
33                 } else if (examed_size) {
34                     // found a discontinuity, start from beginning
35                     examed_size = 0;
36                     i++;
37                     break;
38                 }
39             }
40             current_addr += i << 12;
41         }
42
43         if (examed_size >= size) {
44             goto done;
45         }
46
47         if (current_addr >= VMAP_END) {
48             wrapped = 1;
49             current_addr = VMAP_START;
50         }
51     }
52     panick("vmm: out of memory");
53
54 done:
55     uintptr_t alloc_begin = current_addr - examed_size;
56     for (size_t i = 0; i < size; i += PG_SIZE) {
57         vmm_set_mapping(
58           PD_REFERENCED, alloc_begin + i, paddr + i, PG_PREM_RW, 0);
59         pmm_ref_page(KERNEL_PID, paddr + i);
60     }
61     start = alloc_begin + size;
62
63     return (void*)alloc_begin;
64 }