7-ps2_keyboard.md and 8-multitasking.md (#29)
[lunaix-os.git] / lunaix-os / kernel / mm / vmap.c
1 #include <lunaix/mm/pmm.h>
2 #include <lunaix/mm/valloc.h>
3 #include <lunaix/mm/vmm.h>
4 #include <lunaix/spike.h>
5 #include <lunaix/syslog.h>
6
7 #include <sys/mm/mempart.h>
8
9 static ptr_t start = VMAP;
10 static volatile ptr_t prev_va = 0;
11
12 static pte_t*
13 __alloc_contig_ptes(pte_t* ptep, size_t base_sz, int n)
14 {
15     int _n     = 0;
16     size_t sz  = L0T_SIZE;
17     ptr_t va   = page_addr(ptep_pfn(ptep));
18
19     ptep = mkl0tep(ptep);
20
21     while (_n < n && va < VMAP_END) {
22         pte_t pte = *ptep;
23         if (pte_isnull(pte)) {
24             _n += sz / base_sz;
25         } 
26         else if ((sz / LEVEL_SIZE) < base_sz) {
27             _n = 0;
28         }
29         else {
30             sz = sz / LEVEL_SIZE;
31             ptep = ptep_step_into(ptep);
32             continue;
33         }
34
35         if (ptep_vfn(ptep) + 1 == LEVEL_SIZE) {
36             ptep = ptep_step_out(++ptep);
37             va += sz;
38             
39             sz = sz * LEVEL_SIZE;
40             continue;
41         }
42         
43         va += sz;
44         ptep++;
45     }
46
47     if (va >= VMAP_END) {
48         return NULL;
49     }
50
51     va -= base_sz * _n;
52     assert(prev_va < va);
53     
54     prev_va = va;
55     return mkptep_va(ptep_vm_mnt(ptep), va);
56 }
57
58 ptr_t
59 vmap_ptes_at(pte_t pte, size_t lvl_size, int n)
60 {
61     pte_t* ptep = mkptep_va(VMS_SELF, start);
62     ptep = __alloc_contig_ptes(ptep, lvl_size, n);
63
64     if (!ptep) {
65         return 0;
66     }
67
68     vmm_set_ptes_contig(ptep, pte, lvl_size, n);
69
70     return page_addr(ptep_pfn(ptep));
71 }