fix dependency check logic cause config always disabled
[lunaix-os.git] / lunaix-os / kernel / mm / vmap.c
1 #include <lunaix/mm/page.h>
2 #include <lunaix/mm/valloc.h>
3 #include <lunaix/spike.h>
4 #include <lunaix/syslog.h>
5
6 #include <asm/mempart.h>
7
8 static ptr_t start = VMAP;
9 static volatile ptr_t prev_va = 0;
10
11 void
12 vmap_set_start(ptr_t start_addr) {
13     start = start_addr;
14 }
15
16 static pte_t*
17 __alloc_contig_ptes(pte_t* ptep, size_t base_sz, int n)
18 {
19     int _n     = 0;
20     size_t sz  = L0T_SIZE;
21     ptr_t va   = page_addr(ptep_pfn(ptep));
22
23     ptep = mkl0tep(ptep);
24
25     while (_n < n && va < VMAP_END) {
26         pte_t pte = *ptep;
27         if (pte_isnull(pte)) {
28             _n += sz / base_sz;
29         } 
30         else if ((sz / LEVEL_SIZE) < base_sz) {
31             _n = 0;
32         }
33         else {
34             sz = sz / LEVEL_SIZE;
35             ptep = ptep_step_into(ptep);
36             continue;
37         }
38
39         if (ptep_vfn(ptep) + 1 == LEVEL_SIZE) {
40             ptep = ptep_step_out(++ptep);
41             va += sz;
42             
43             sz = sz * LEVEL_SIZE;
44             continue;
45         }
46         
47         va += sz;
48         ptep++;
49     }
50
51     if (va >= VMAP_END) {
52         return NULL;
53     }
54
55     va -= base_sz * _n;
56     
57     prev_va = va;
58     return mkptep_va(ptep_vm_mnt(ptep), va);
59 }
60
61 ptr_t
62 vmap_ptes_at(pte_t pte, size_t lvl_size, int n)
63 {
64     pte_t* ptep = mkptep_va(VMS_SELF, start);
65     ptep = __alloc_contig_ptes(ptep, lvl_size, n);
66
67     if (!ptep) {
68         return 0;
69     }
70
71     vmm_set_ptes_contig(ptep, pte, lvl_size, n);
72
73     ptr_t va = page_addr(ptep_pfn(ptep));
74
75     tlb_flush_kernel_ranged(va, n);
76     
77     return va;
78 }
79
80 void
81 vunmap(ptr_t ptr, struct leaflet* leaflet)
82 {    
83     pte_t* ptep;
84     unsigned int npages;
85  
86     assert(start <= ptr && ptr <= VMAP_END);
87     
88     npages = leaflet_nfold(leaflet);
89     ptep = mkptep_va(VMS_SELF, ptr);
90
91     vmm_unset_ptes(ptep, npages);
92
93     tlb_flush_kernel_ranged(ptr, npages);
94 }