Voxia OS v0.0.1
Hobby Project Operating System Targeting x86-64
Loading...
Searching...
No Matches
paging.c
Go to the documentation of this file.
1#include "paging.h"
2#include "autoconf.h"
3#include "init/init.h"
4#include <libk/serial.h>
8#include <memory/vm_manager.h>
9#include <spinlock.h>
10#include <str.h>
11#include <type.h>
12
13static uintptr_t PHYS_BASE_METADATA_ADDR = 0xffffffe000000000;
14
15#define EXPORT_SYMBOL(sym) \
16 __attribute__((used, visibility("default"))) void* __export_##sym = &sym
17
19
20extern uint8_t* bitmap_base_;
23extern size_t dma_bitmap_size;
24
25void paging_physwindow_mmap(page_t page_dir, uint64_t virt, uint64_t phys,
27
28typedef struct paging_page paging_page;
33
35
39 uintptr_t virtual_physwindow_addr = (uintptr_t)page;
40
42 mem_create_physwindow((uintptr_t)page, &virtual_physwindow_addr,
43 0);
44 }
45
46 memset((void*)virtual_physwindow_addr, 0, PAGE_SIZE);
48 return page;
49}
50
53
56 uint64_t index1 = (virt >> 12) & 0x1ff;
57 if (!physwindow_pt) {
58 uint64_t index4 = (virt >> 39) & 0x1ff;
59 uint64_t index3 = (virt >> 30) & 0x1ff;
60 uint64_t index2 = (virt >> 21) & 0x1ff;
61
62 page_t p4 = page_dir;
63 page_t pdpt = (page_t)VMM_PAGE;
64 p4[index4] = (uint64_t)pdpt | flags;
65
66 page_t pdp = (page_t)VMM_PAGE;
67 pdpt[index3] = (uint64_t)pdp | flags;
68
70 pdp[index2] = (uint64_t)physwindow_pt | flags;
71 }
72
73 physwindow_pt[index1] = (phys & PAGE_PHYS_MASK) | flags;
74
75 asm volatile("invlpg (%0)" ::"r"(virt) : "memory");
76}
77
79 for (uint64_t i = 0; i < VOXIA_PHYS_MAX_WINDOW_COUNT; i++) {
81 page, (uint64_t)(mem_vma_phys_window_start + i * 0x1000), 0,
83 }
84
87
88 LOG_INFO("PAGING", "mapping physwindow_pt 0x%lx to 0x%lx",
91}
92
93INIT(paging) {
95 LOG_INFO("PAGING", "PML4: 0x%lx", (uint64_t)kernel_pml4);
96
97 // paging_setup(pml4);
98 for (uint64_t i = 0; i < 0x80000000; i += 0x1000) {
99 vxMmap(kernel_pml4, (uint64_t)i + 0xffffffff80000000, i,
101 }
102
104
109
111
112 LOG_INFO("PAGING", "paging setup done");
113
115}
116
117void paging_debug(page_t pml4_phys, uint64_t virt) {
118 serial_trace("Debugging virtual address: 0x%lx\n", virt);
119
120 uint64_t index4 = (virt >> 39) & 0x1ff;
121 uint64_t index3 = (virt >> 30) & 0x1ff;
122 uint64_t index2 = (virt >> 21) & 0x1ff;
123 uint64_t index1 = (virt >> 12) & 0x1ff;
124
125 uintptr_t pml4_virt = (uintptr_t)pml4_phys;
126 mem_create_physwindow((uintptr_t)pml4_phys, &pml4_virt,
128 page_t p4 = (page_t)pml4_virt;
129
130 serial_trace("PML4[%lu] = 0x%lx flags 0b%b\n", index4, p4[index4],
131 p4[index4] & 0xFFF);
132
133 if (!(p4[index4] & 1)) {
134 serial_trace("PML4 entry not present\n");
136 return;
137 }
138
139 uintptr_t pdpt_phys = p4[index4] & PAGE_PHYS_MASK;
140 uintptr_t pdpt_virt = pdpt_phys;
141 mem_create_physwindow(pdpt_phys, &pdpt_virt,
143 page_t pdpt = (page_t)pdpt_virt;
144
145 serial_trace("PDPT[%lu] = 0x%lx flags 0b%b\n", index3, pdpt[index3],
146 pdpt[index3] & 0xFFF);
147
148 if (!(pdpt[index3] & 1)) {
149 serial_trace("PDPT entry not present\n");
152 return;
153 }
154
155 uintptr_t pdp_phys = pdpt[index3] & PAGE_PHYS_MASK;
156 uintptr_t pdp_virt = pdp_phys;
157 mem_create_physwindow(pdp_phys, &pdp_virt,
159 page_t pdp = (page_t)pdp_virt;
160
161 serial_trace("PDP[%lu] = 0x%lx flags 0b%b\n", index2, pdp[index2],
162 pdp[index2] & 0xFFF);
163
164 if (!(pdp[index2] & 1)) {
165 serial_trace("PDP entry not present\n");
169 return;
170 }
171
172 uintptr_t pt_phys = pdp[index2] & PAGE_PHYS_MASK;
173 uintptr_t pt_virt = pt_phys;
174 mem_create_physwindow(pt_phys, &pt_virt,
176 page_t pt = (page_t)pt_virt;
177
178 serial_trace("PT[%lu] = 0x%lx flags 0b%b\n", index1, pt[index1],
179 pt[index1] & 0xFFF);
180
181 if (!(pt[index1] & 1))
182 serial_trace("PT entry not present\n");
183 else
184 serial_trace("phys = 0x%lx\n", pt[index1] & PAGE_PHYS_MASK);
185
190}
191
192// __attribute__((noreturn)) static void iddle() {
193// for (;;)
194// ;
195// }
196
199 serial2_printf("called after pagging set\n");
200 uintptr_t pml4_virt_addr = (uintptr_t)p;
201 mem_create_physwindow((uintptr_t)p, &pml4_virt_addr,
205
206 uintptr_t pml4_kernel_virt_addr = (uintptr_t)kernel_pml4;
207 mem_create_physwindow((uintptr_t)kernel_pml4, &pml4_kernel_virt_addr,
211
212 page_t dst = (page_t)pml4_virt_addr;
213 page_t src = (page_t)pml4_kernel_virt_addr;
214
215 for (int i = 256; i < 512; i++)
216 dst[i] = src[i];
217
218 mem_release_physwindow(pml4_virt_addr);
219 mem_release_physwindow(pml4_kernel_virt_addr);
220 }
221}
222
223void vxMmap(page_t page_dir, uint64_t virt, uint64_t phys, uint64_t flags) {
225
226 uint64_t index4 = (virt >> 39) & 0x1ff;
227 uint64_t index3 = (virt >> 30) & 0x1ff;
228 uint64_t index2 = (virt >> 21) & 0x1ff;
229 uint64_t index1 = (virt >> 12) & 0x1ff;
230
231 uint64_t inter_flags =
233
234 uint64_t phys_clean = phys & PAGE_PHYS_MASK;
235
236 page_t p4 = page_dir;
237 page_t pdpt = 0;
238 page_t pdp = 0;
239 page_t pt = 0;
240
241 uintptr_t pml4_virt_addr = (uintptr_t)p4;
243 mem_create_physwindow((uintptr_t)p4, &pml4_virt_addr,
247 }
248 p4 = (page_t)pml4_virt_addr;
249
250 if (p4[index4] & 1) {
251 uintptr_t pdpt_phys_addr = p4[index4] & PAGE_PHYS_MASK;
252 uintptr_t pdpt_virt_addr = pdpt_phys_addr;
254 mem_create_physwindow(pdpt_phys_addr, &pdpt_virt_addr,
258 }
259 pdpt = (page_t)pdpt_virt_addr;
260 p4[index4] = pdpt_phys_addr | inter_flags;
261 } else {
262 uintptr_t pdpt_phys_addr = (uintptr_t)phys_base_alloc(1);
263 uintptr_t pdpt_virt_addr = pdpt_phys_addr;
265 mem_create_physwindow(pdpt_phys_addr, &pdpt_virt_addr,
269 }
270 memset((void*)pdpt_virt_addr, 0, PAGE_SIZE);
271 pdpt = (page_t)pdpt_virt_addr;
272 p4[index4] = pdpt_phys_addr | inter_flags;
273 }
274
275 if (pdpt[index3] & 1) {
276 uintptr_t pdp_phys_addr = pdpt[index3] & PAGE_PHYS_MASK;
277 uintptr_t pdp_virt_addr = pdp_phys_addr;
279 mem_create_physwindow(pdp_phys_addr, &pdp_virt_addr,
283 }
284 pdp = (page_t)pdp_virt_addr;
285 pdpt[index3] = pdp_phys_addr | inter_flags;
286 } else {
287 uintptr_t pdp_phys_addr = (uintptr_t)phys_base_alloc(1);
288 uintptr_t pdp_virt_addr = pdp_phys_addr;
290 mem_create_physwindow(pdp_phys_addr, &pdp_virt_addr,
294 }
295 memset((void*)pdp_virt_addr, 0, PAGE_SIZE);
296 pdp = (page_t)pdp_virt_addr;
297 pdpt[index3] = pdp_phys_addr | inter_flags;
298 }
299
300 if (pdp[index2] & 1) {
301 uintptr_t pt_phys_addr = pdp[index2] & PAGE_PHYS_MASK;
302 uintptr_t pt_virt_addr = pt_phys_addr;
304 mem_create_physwindow(pt_phys_addr, &pt_virt_addr,
308 }
309 pt = (page_t)pt_virt_addr;
310 pdp[index2] = pt_phys_addr | inter_flags;
311 } else {
312 uintptr_t pt_phys_addr = (uintptr_t)phys_base_alloc(1);
313 uintptr_t pt_virt_addr = pt_phys_addr;
315 mem_create_physwindow(pt_phys_addr, &pt_virt_addr,
319 }
320 memset((void*)pt_virt_addr, 0, PAGE_SIZE);
321 pt = (page_t)pt_virt_addr;
322 pdp[index2] = pt_phys_addr | inter_flags;
323 }
324
325 pt[index1] = phys_clean | flags;
326
327 asm volatile("" ::: "memory");
328
334 }
335
336 asm volatile("invlpg (%0)" ::"r"(virt) : "memory");
338}
339
340void vxMultipleMmap(page_t page_dir, uint64_t virt, uint64_t phys,
342 uint64_t i = 0;
343
344 for (; i + 3 < size; i += 4) {
345 vxMmap(page_dir, virt + (i + 0) * 4096, phys + (i + 0) * 4096,
346 flags);
347 vxMmap(page_dir, virt + (i + 1) * 4096, phys + (i + 1) * 4096,
348 flags);
349 vxMmap(page_dir, virt + (i + 2) * 4096, phys + (i + 2) * 4096,
350 flags);
351 vxMmap(page_dir, virt + (i + 3) * 4096, phys + (i + 3) * 4096,
352 flags);
353 }
354
355 for (; i < size; i++) {
356 vxMmap(page_dir, virt + i * 4096, phys + i * 4096, flags);
357 }
358}
359
360void paging_unmap_page(page_t page_dir, uint64_t virt) {
362
363 uint64_t index4 = (virt >> 39) & 0x1ff;
364 uint64_t index3 = (virt >> 30) & 0x1ff;
365 uint64_t index2 = (virt >> 21) & 0x1ff;
366 uint64_t index1 = (virt >> 12) & 0x1ff;
367
368 page_t p4 = page_dir;
369 page_t pdpt = 0;
370 page_t pdp = 0;
371 page_t pt = 0;
372
373 uintptr_t pml4_virt_addr = (uintptr_t)p4;
375 mem_create_physwindow((uintptr_t)p4, &pml4_virt_addr,
379 }
380 p4 = (page_t)pml4_virt_addr;
381
382 if (p4[index4] & 1) {
383 uintptr_t pdpt_phys_addr = p4[index4] & PAGE_PHYS_MASK;
384 uintptr_t pdpt_virt_addr = pdpt_phys_addr;
386 mem_create_physwindow(pdpt_phys_addr, &pdpt_virt_addr,
390 }
391 pdpt = (page_t)pdpt_virt_addr;
392 } else {
396 return;
397 }
398
399 if (pdpt[index3] & 1) {
400 uintptr_t pdp_phys_addr = pdpt[index3] & PAGE_PHYS_MASK;
401 uintptr_t pdp_virt_addr = pdp_phys_addr;
403 mem_create_physwindow(pdp_phys_addr, &pdp_virt_addr,
407 }
408 pdp = (page_t)pdp_virt_addr;
409 } else {
413 }
415 return;
416 }
417
418 if (pdp[index2] & 1) {
419 uintptr_t pt_phys_addr = pdp[index2] & PAGE_PHYS_MASK;
420 uintptr_t pt_virt_addr = pt_phys_addr;
422 mem_create_physwindow(pt_phys_addr, &pt_virt_addr,
426 }
427 pt = (page_t)pt_virt_addr;
428 } else {
433 }
435 return;
436 }
437
438 pt[index1] = 0;
439
445 }
446
447 asm volatile("invlpg (%0)" ::"r"(virt) : "memory");
449}
450
451void paging_unmap_fill(page_t page_dir, uint64_t virt, size_t size) {
452 for (uint64_t i = 0; i < size; i++) {
453 paging_unmap_page(page_dir, virt + i * 4096);
454 }
455}
456
458 asm volatile("mfence\n\t"
459 "mov %0, %%cr3" ::"r"((uint64_t)p)
460 : "memory");
461}
462
464
466 uint64_t index4 = (vaddr >> 39) & 0x1ff;
467 uint64_t index3 = (vaddr >> 30) & 0x1ff;
468 uint64_t index2 = (vaddr >> 21) & 0x1ff;
469 uint64_t index1 = (vaddr >> 12) & 0x1ff;
470
471 page_t pdpt = 0;
472 page_t pdp = 0;
473 page_t pt = 0;
474
475 if (p[index4] & 1)
476 pdpt = (page_t)PHYS2VIRT(p[index4] & PAGE_PHYS_MASK);
477 else
478 return 0;
479
480 if (pdpt[index3] & 1)
481 pdp = (page_t)PHYS2VIRT(pdpt[index3] & PAGE_PHYS_MASK);
482 else
483 return 0;
484
485 if (pdp[index2] & 1)
486 pt = (page_t)PHYS2VIRT(pdp[index2] & PAGE_PHYS_MASK);
487 else
488 return 0;
489
490 return pt[index1] & PAGE_PHYS_MASK;
491}
static ssfn_buf_t dst
Definition graphic.c:82
uint16_t flags
Definition thread.h:5
typedef __attribute__
Definition msi.c:47
#define INIT(fn)
Definition init.h:26
void serial2_printf(const char *fmt,...)
#define PHYS2VIRT(x)
volatile boolean_t paging_has_been_set
Definition paging.c:18
static spinlock_t paging_lock
Definition paging.c:34
uint64_t metadata_size
void paging_reload(page_t p)
Definition paging.c:457
void paging_debug(page_t pml4_phys, uint64_t virt)
Definition paging.c:117
uintptr_t page
Definition paging.c:0
page_t paging_get_highest_page_map(void)
Definition paging.c:463
page_t paging_create_page_directory()
Definition paging.c:36
void paging_setup(page_t p)
Definition paging.c:197
static page_t kernel_pml4
Definition paging.c:51
void paging_unmap_page(page_t page_dir, uint64_t virt)
Definition paging.c:360
void vxMmap(page_t page_dir, uint64_t virt, uint64_t phys, uint64_t flags)
Definition paging.c:223
void paging_unmap_fill(page_t page_dir, uint64_t virt, size_t size)
Definition paging.c:451
static page_t physwindow_pt
Definition paging.c:52
static uintptr_t PHYS_BASE_METADATA_ADDR
Definition paging.c:13
void vxMultipleMmap(page_t page_dir, uint64_t virt, uint64_t phys, uint64_t size, uint64_t flags)
Definition paging.c:340
static void initialize_physical_paging_window(page_t page)
Definition paging.c:78
uint64_t vaddr_to_paddr(page_t p, uint64_t vaddr)
Definition paging.c:465
void paging_physwindow_mmap(page_t page_dir, uint64_t virt, uint64_t phys, uint64_t flags)
Definition paging.c:54
size_t dma_bitmap_size
uint8_t * dma_bitmap_base_
uint8_t * bitmap_base_
#define PAGE_PRESENT
Definition paging.h:34
#define PAGE_USER
Definition paging.h:36
#define PAGE_PHYS_MASK
Definition paging.h:46
#define PAGE_SIZE
Definition paging.h:6
#define PAGE_WRITABLE
Definition paging.h:35
volatile uintptr_t * page_t
Definition paging.h:11
#define PAGE_INTER_STRIP
Definition paging.h:49
#define VMM_PAGE
Definition paging.h:31
void * phys_base_alloc(uint64_t block)
mem_physwindow_status_t mem_release_physwindow(uintptr_t virt_addr)
Definition phys_window.c:60
mem_physwindow_status_t mem_create_physwindow(uintptr_t phys_addr, uintptr_t *virt_addr, mem_physwindow_flag_t flag)
Definition phys_window.c:28
@ PHYS_WINDOW_FLAG_READ
Definition phys_window.h:16
@ PHYS_WINDOW_FLAG_LOCK
Definition phys_window.h:18
@ PHYS_WINDOW_FLAG_WRITE
Definition phys_window.h:17
#define LOG_INFO(mod, fmt,...)
Definition serial.h:20
#define serial_trace(...)
Definition serial.h:19
void spin_acquire(spinlock_t *lock)
Definition spinlock.c:8
void spin_release(spinlock_t *lock)
Definition spinlock.c:19
void memset(void *ptr, int value, size_t num)
paging_page * next
Definition paging.c:31
uintptr_t page
Definition paging.c:30
uint8_t boolean_t
Definition type.h:89
unsigned long uintptr_t
Definition type.h:73
unsigned long uint64_t
Definition type.h:25
unsigned char uint8_t
Definition type.h:7
@ mem_vma_phys_window_pt
Definition vm_manager.h:22
@ mem_vma_phys_window_start
Definition vm_manager.h:23
size_t size
Definition vnode.h:3