Unifying the Lunaix's Physical Memory Model (#28)
[lunaix-os.git] / lunaix-os / arch / i386 / includes / sys / mm / tlb.h
1 #ifndef __LUNAIX_ARCH_TLB_H
2 #define __LUNAIX_ARCH_TLB_H
3
4 #include <lunaix/compiler.h>
5 #include <lunaix/mm/procvm.h>
6 #include <lunaix/mm/physical.h>
7
8 /**
9  * @brief Invalidate an entry of all address space
10  * 
11  * @param va 
12  */
13 static inline void must_inline
14 __tlb_invalidate(ptr_t va) 
15 {
16     asm volatile("invlpg (%0)" ::"r"(va) : "memory");
17 }
18
19 /**
20  * @brief Invalidate an entry of an address space indetified
21  *        by ASID
22  * 
23  * @param va 
24  */
25 static inline void must_inline
26 __tlb_flush_asid(unsigned int asid, ptr_t va) 
27 {
28     // not supported on x86_32
29     asm volatile("invlpg (%0)" ::"r"(va) : "memory");
30 }
31
32 /**
33  * @brief Invalidate an entry of global address space
34  * 
35  * @param va 
36  */
37 static inline void must_inline
38 __tlb_flush_global(ptr_t va) 
39 {
40     // not supported on x86_32
41     asm volatile("invlpg (%0)" ::"r"(va) : "memory");
42 }
43
44 /**
45  * @brief Invalidate an entire TLB
46  * 
47  * @param va 
48  */
49 static inline void must_inline
50 __tlb_flush_all() 
51 {
52     asm volatile(
53         "movl %%cr3, %%eax\n"
54         "movl %%eax, %%cr3"
55         :::"eax"
56     );
57 }
58
59 /**
60  * @brief Invalidate an entire address space
61  * 
62  * @param va 
63  */
64 static inline void must_inline
65 __tlb_flush_asid_all(unsigned int asid) 
66 {
67     // not supported on x86_32
68     __tlb_flush_all();
69 }
70
71
72 /**
73  * @brief Invalidate entries of all address spaces
74  * 
75  * @param asid 
76  * @param addr 
77  * @param npages 
78  */
79 static inline void 
80 tlb_flush_range(ptr_t addr, unsigned int npages)
81 {
82     for (unsigned int i = 0; i < npages; i++)
83     {
84         __tlb_invalidate(addr + i * PAGE_SIZE);
85     }
86 }
87
88 /**
89  * @brief Invalidate entries of an address space identified
90  *        by ASID
91  * 
92  * @param asid 
93  * @param addr 
94  * @param npages 
95  */
96 static inline void 
97 tlb_flush_asid_range(unsigned int asid, ptr_t addr, unsigned int npages)
98 {
99     for (unsigned int i = 0; i < npages; i++)
100     {
101         __tlb_flush_asid(asid, addr + i * PAGE_SIZE);
102     }
103 }
104
105 /**
106  * @brief Invalidate an entry of kernel address spaces
107  * 
108  * @param asid 
109  * @param addr 
110  * @param npages 
111  */
112 static inline void 
113 tlb_flush_kernel(ptr_t addr)
114 {
115     __tlb_flush_global(addr);
116 }
117
118 /**
119  * @brief Invalidate entries of kernel address spaces
120  * 
121  * @param asid 
122  * @param addr 
123  * @param npages 
124  */
125 static inline void 
126 tlb_flush_kernel_ranged(ptr_t addr, unsigned int npages)
127 {
128     for (unsigned int i = 0; i < npages; i++)
129     {
130         tlb_flush_kernel(addr + i * PAGE_SIZE);
131     }
132 }
133
134 /**
135  * @brief Invalidate an entry within a process memory space
136  * 
137  * @param asid 
138  * @param addr 
139  * @param npages 
140  */
141 void
142 tlb_flush_mm(struct proc_mm* mm, ptr_t addr);
143
144 /**
145  * @brief Invalidate entries within a process memory space
146  * 
147  * @param asid 
148  * @param addr 
149  * @param npages 
150  */
151 void
152 tlb_flush_mm_range(struct proc_mm* mm, ptr_t addr, unsigned int npages);
153
154 /**
155  * @brief Invalidate an entry within a vm region
156  * 
157  * @param asid 
158  * @param addr 
159  * @param npages 
160  */
161 void
162 tlb_flush_vmr(struct mm_region* vmr, ptr_t va);
163
164 /**
165  * @brief Invalidate all entries within a vm region
166  * 
167  * @param asid 
168  * @param addr 
169  * @param npages 
170  */
171 void
172 tlb_flush_vmr_all(struct mm_region* vmr);
173
174 /**
175  * @brief Invalidate entries within a vm region
176  * 
177  * @param asid 
178  * @param addr 
179  * @param npages 
180  */
181 void
182 tlb_flush_vmr_range(struct mm_region* vmr, ptr_t addr, unsigned int npages);
183
184 #endif /* __LUNAIX_VMTLB_H */