diff options
| author | Aleksa Vuckovic <aleksav013@gmail.com> | 2022-08-09 09:05:02 +0200 |
|---|---|---|
| committer | Aleksa Vuckovic <aleksav013@gmail.com> | 2022-08-09 09:05:02 +0200 |
| commit | 78579419442f22641368db777120d7e75cbaee94 (patch) | |
| tree | cd49284e7fe0a4c1e8057fce6e2aa66a07f12fee /kernel/src/mem | |
| parent | e11298e56be560de64bbccfe74fef7ff85c623d1 (diff) | |
map on page fault
Diffstat (limited to 'kernel/src/mem')
| -rw-r--r-- | kernel/src/mem/paging.c | 69 |
1 files changed, 48 insertions, 21 deletions
diff --git a/kernel/src/mem/paging.c b/kernel/src/mem/paging.c index fdd1dd2..cd1cb68 100644 --- a/kernel/src/mem/paging.c +++ b/kernel/src/mem/paging.c @@ -2,42 +2,69 @@ #include <paging.h> #include <libk/stdio.h> +#include <debug.h> void load_pt_lvl4(uint64_t*); __attribute__((aligned(4096))) uint64_t page_table_lvl4[512]; __attribute__((aligned(4096))) uint64_t page_table_lvl3[512]; -__attribute__((aligned(4096))) uint64_t page_table_lvl2_hh[512]; +__attribute__((aligned(4096))) uint64_t page_table_lvl2_0[512]; +__attribute__((aligned(4096))) uint64_t page_table_lvl2_1[512]; +__attribute__((aligned(4096))) uint64_t page_table_lvl2_2[512]; +__attribute__((aligned(4096))) uint64_t page_table_lvl2_3[512]; -#define PAGE_SIZE 0x00200000 -#define FLAG_PRESENT 0x1 -#define FLAG_WRITABLE 0x2 -#define FLAG_HUGE 0x80 -#define KERNEL_VMA 0xc0000000 - -void init_paging(void) +void map_addr(uint64_t virt, uint64_t phys, uint32_t flags) { - page_table_lvl4[0] = (uint64_t)page_table_lvl3 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; - page_table_lvl3[3] = (uint64_t)page_table_lvl2_hh + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; + virt -= virt % 0x00200000; + phys -= phys % 0x00200000; - // higher half kernel - // 0xc0000000 - 0xc0400000 : 0xc0000000 - 0xc0400000 - for (uint64_t i = 0; i < 2; i++) { - page_table_lvl2_hh[i] = i * PAGE_SIZE + FLAG_PRESENT + FLAG_WRITABLE + FLAG_HUGE; + // i is in range [0, 511] + size_t pt_lvl4_i = (virt >> 39) % 0x200; // 512gb entry + size_t pt_lvl3_i = (virt >> 30) % 0x200; // 1gb entry + size_t pt_lvl2_i = (virt >> 21) % 0x200; // 2mb entry +// size_t pt_lvl1_i = (virt >> 12) % 0x200; // 4kb entry + + // first 4gb + if (pt_lvl4_i == 0) { + switch(pt_lvl3_i) { + case 0: + page_table_lvl2_0[pt_lvl2_i] = phys | flags; + break; + case 1: + page_table_lvl2_1[pt_lvl2_i] = phys | flags; + break; + case 2: + page_table_lvl2_2[pt_lvl2_i] = phys | flags; + break; + case 3: + page_table_lvl2_3[pt_lvl2_i] = phys | flags; + break; + } } +} - // TODO: remove initial mapping for fb and instead page on demand +void init_paging(void) +{ + page_table_lvl4[0] = (uint64_t)page_table_lvl3 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; + page_table_lvl3[0] = (uint64_t)page_table_lvl2_0 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; + page_table_lvl3[1] = (uint64_t)page_table_lvl2_1 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; + page_table_lvl3[2] = (uint64_t)page_table_lvl2_2 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; + page_table_lvl3[3] = (uint64_t)page_table_lvl2_3 + FLAG_PRESENT + FLAG_WRITABLE - KERNEL_VMA; - // identity paged for fb - // 0xe0000000 - 0xffffffff : 0xe0000000 - 0xffffffff - for (uint64_t i = 2; i < 512; i++) { - page_table_lvl2_hh[i] = i * PAGE_SIZE + 0xc0000000 + FLAG_PRESENT + FLAG_WRITABLE + FLAG_HUGE; - } + // higher half map first 4mb + map_addr(KERNEL_VMA, 0x00000000, FLAG_PRESENT + FLAG_WRITABLE + FLAG_HUGE); + map_addr(KERNEL_VMA + PAGE_SIZE, 0x00000000 + PAGE_SIZE, FLAG_PRESENT + FLAG_WRITABLE + FLAG_HUGE); load_pt_lvl4(page_table_lvl4); } + void page_fault(uint64_t error) { - printf("%d\n", error); + uint64_t addr; + __asm__ volatile ("mov %%cr2, %0" : "=r"(addr) : : "memory"); + + map_addr(addr, addr, FLAG_PRESENT | FLAG_WRITABLE | FLAG_HUGE); + + printf("address: 0x%x, error code: %d\n", addr, error); } |
