* Remove the debugging hack in procvm.c
[lunaix-os.git] / lunaix-os / kernel / mm / vmm.c
1 #include <klibc/string.h>
2 #include <lunaix/mm/pmm.h>
3 #include <lunaix/mm/vmm.h>
4 #include <lunaix/spike.h>
5 #include <lunaix/syslog.h>
6
7 #include <sys/cpu.h>
8 #include <sys/mm/mm_defs.h>
9
10 LOG_MODULE("VM")
11
12 void
13 vmm_init()
14 {
15     // XXX: something here?
16 }
17
18 pte_t 
19 vmm_alloc_page(pte_t* ptep, pte_t pte)
20 {
21     ptr_t pa = pmm_alloc_page(PP_FGPERSIST);
22     if (!pa) {
23         return null_pte;
24     }
25
26     pte = pte_setpaddr(pte, pa);
27     pte = pte_mkloaded(pte);
28     set_pte(ptep, pte);
29
30     mount_page(PG_MOUNT_1, pa);
31     memset((void*)PG_MOUNT_1, 0, LFT_SIZE);
32     unmount_page(PG_MOUNT_1);
33
34     cpu_flush_page((ptr_t)ptep);
35
36     return pte;
37 }
38
39 int
40 vmm_set_mapping(ptr_t mnt, ptr_t va, ptr_t pa, pte_attr_t prot)
41 {
42     assert(!va_offset(va));
43
44     pte_t* ptep = mkptep_va(mnt, va);
45     pte_t  pte  = mkpte(pa, prot);
46
47     set_pte(ptep, pte);
48
49     return 1;
50 }
51
52 ptr_t
53 vmm_del_mapping(ptr_t mnt, ptr_t va)
54 {
55     assert(!va_offset(va));
56
57     pte_t* ptep = mkptep_va(mnt, va);
58
59     pte_t old = *ptep;
60
61     set_pte(ptep, null_pte);
62
63     return pte_paddr(old);
64 }
65
66 pte_t
67 vmm_tryptep(pte_t* ptep, size_t lvl_size)
68 {
69     ptr_t va = ptep_va(ptep, lvl_size);
70     pte_t* _ptep = mkl0tep(ptep);
71     pte_t pte;
72
73     if (pte_isnull(pte = *_ptep) || _ptep == ptep) 
74         return pte;
75
76 #if LnT_ENABLED(1)
77     _ptep = getl1tep(_ptep, va);
78     if (_ptep == ptep || pte_isnull(pte = *_ptep)) 
79         return pte;
80 #endif
81 #if LnT_ENABLED(2)
82     _ptep = getl2tep(_ptep, va);
83     if (_ptep == ptep || pte_isnull(pte = *_ptep)) 
84         return pte;
85 #endif
86 #if LnT_ENABLED(3)
87     _ptep = getl3tep(_ptep, va);
88     if (_ptep == ptep || pte_isnull(pte = *_ptep)) 
89         return pte;
90 #endif
91     _ptep = getlftep(_ptep, va);
92     return *_ptep;
93 }
94
95 ptr_t
96 vmm_v2pat(ptr_t mnt, ptr_t va)
97 {
98     ptr_t  va_off = va_offset(va);
99     pte_t* ptep   = mkptep_va(mnt, va);
100
101     return pte_paddr(pte_at(ptep)) + va_off;
102 }
103
104 ptr_t
105 vms_mount(ptr_t mnt, ptr_t vms_root)
106 {
107     assert(vms_root);
108
109     pte_t* ptep = mkl0tep_va(VMS_SELF, mnt);
110     set_pte(ptep, mkpte(vms_root, KERNEL_DATA));
111     cpu_flush_page(mnt);
112     return mnt;
113 }
114
115 ptr_t
116 vms_unmount(ptr_t mnt)
117 {
118     pte_t* ptep = mkl0tep_va(VMS_SELF, mnt);
119     set_pte(ptep, null_pte);
120     cpu_flush_page(mnt);
121     return mnt;
122 }
123
124
125 void
126 ptep_alloc_hierarchy(pte_t* ptep, ptr_t va, pte_attr_t prot)
127 {
128     pte_t* _ptep;
129     
130     _ptep = mkl0tep(ptep);
131     if (_ptep == ptep) {
132         return;
133     }
134
135     _ptep = mkl1t(_ptep, va, prot);
136     if (_ptep == ptep) {
137         return;
138     }
139
140     _ptep = mkl2t(_ptep, va, prot);
141     if (_ptep == ptep) {
142         return;
143     }
144
145     _ptep = mkl3t(_ptep, va, prot);
146     if (_ptep == ptep) {
147         return;
148     }
149
150     _ptep = mklft(_ptep, va, prot);
151     assert(_ptep == ptep);
152 }