diff --git a/src/kernel/include/memory.h b/src/kernel/include/memory.h index b9de088..ffaccb8 100644 --- a/src/kernel/include/memory.h +++ b/src/kernel/include/memory.h @@ -26,20 +26,24 @@ #ifndef __ASSEMBLER__ #include + +extern uint64_t kernel_P4; + void *memcpy(void *dst, const void *src, size_t n); void *memset(void *s, int c, size_t n); void *memmove(void *dest, const void *src, size_t n); int memcmp(const void *s1, const void *s2, size_t n); size_t strlen(const char *s); -void pmm_free(uintptr_t page); -uintptr_t pmm_alloc(); -uintptr_t pmm_calloc(); +void pmm_free(uint64_t page); +uint64_t pmm_alloc(); +uint64_t pmm_calloc(); -uintptr_t vmm_get_page(void *P4, uintptr_t addr); -int vmm_set_page(void *P4, uintptr_t addr, uintptr_t page, uint16_t flags); -int touch_page(void *P4, uintptr_t addr, uint16_t flags); -void free_page(void *P4, uintptr_t addr, int free); +uint64_t vmm_get_page(uint64_t P4, uint64_t addr); +#define PAGE_EXIST(p) ((p) != (uint64_t)-1) +int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags); +int touch_page(uint64_t P4, uint64_t addr, uint16_t flags); +void free_page(uint64_t P4, uint64_t addr, int free); extern union PTE BootP4; extern int kernel_start, kernel_end; diff --git a/src/kernel/memory/memory.c b/src/kernel/memory/memory.c index 4e6fd54..9f2f53f 100644 --- a/src/kernel/memory/memory.c +++ b/src/kernel/memory/memory.c @@ -2,25 +2,29 @@ #include #include +uint64_t kernel_P4; + void memory_init() { - uintptr_t start, end; + kernel_P4 = (uint64_t)&BootP4; + uint64_t start, end; uint32_t type, i = 0; debug_info("Parsing memory map\n"); while(!multiboot_get_memory_area(i++, &start, &end, &type)) { debug("0x%016x-0x%016x (%d)\n", start, end, type); - for(uintptr_t p = start; p < end; p += PAGE_SIZE) + for(uint64_t p = start; p < end; p += PAGE_SIZE) { if(p >= V2P(&kernel_start) && p < V2P(&kernel_end)) continue; - uintptr_t page = vmm_get_page(&BootP4, (uintptr_t)P2V(p)); - if(page == (uintptr_t)-1 || !(page & PAGE_PRESENT)) + uint64_t addr = (uint64_t)P2V(p); + uint64_t page = vmm_get_page(kernel_P4, addr); + if(!PAGE_EXIST(page) || !(page & PAGE_PRESENT)) { uint16_t flags = PAGE_GLOBAL | PAGE_HUGE | PAGE_WRITE; - touch_page(&BootP4, (uintptr_t)P2V(p), flags); - vmm_set_page(&BootP4, (uintptr_t)P2V(p), p, flags | PAGE_PRESENT); + touch_page(kernel_P4, addr, flags); + vmm_set_page(kernel_P4, addr, p, flags | PAGE_PRESENT); } if(type == MMAP_FREE) diff --git a/src/kernel/memory/pmm.c b/src/kernel/memory/pmm.c index 78cd3f8..e15c4bd 100644 --- a/src/kernel/memory/pmm.c +++ b/src/kernel/memory/pmm.c @@ -1,25 +1,25 @@ #include -uintptr_t first = 0; +uint64_t first = 0; -void pmm_free(uintptr_t page) +void pmm_free(uint64_t page) { - page = (uintptr_t)P2V(page); - *(uintptr_t *)page = first; + page = (uint64_t)P2V(page); + *(uint64_t *)page = first; first = page; } -uintptr_t pmm_alloc() +uint64_t pmm_alloc() { - uintptr_t page = first; - first = page?*(uintptr_t *)page:0; - page = (uintptr_t)(page?V2P(page):0); + uint64_t page = first; + first = page?*(uint64_t *)page:0; + page = (uint64_t)(page?V2P(page):0); return page; } -uintptr_t pmm_calloc() +uint64_t pmm_calloc() { - uintptr_t page = pmm_alloc(); + uint64_t page = pmm_alloc(); memset(P2V(page), 0, 0x1000); return page; } diff --git a/src/kernel/memory/pmm.tt b/src/kernel/memory/pmm.tt index 969009b..70d5958 100644 --- a/src/kernel/memory/pmm.tt +++ b/src/kernel/memory/pmm.tt @@ -15,19 +15,19 @@ struct { TEST(alloc_returns_freed_page) { pmm_free(V2P(&mem[0])); - uintptr_t a = pmm_alloc(); + uint64_t a = pmm_alloc(); ASSERT_EQ_PTR(a, V2P(&mem[0])); } TEST(alloc_returns_0_if_no_free_pages) { - uintptr_t a = pmm_alloc(); + uint64_t a = pmm_alloc(); ASSERT_EQ_PTR(a, 0); } TEST(alloc_zero_after_all_free_pages) { pmm_free(V2P(&mem[0])); pmm_alloc(); - uintptr_t a = pmm_alloc(); + uint64_t a = pmm_alloc(); ASSERT_EQ_PTR(a, 0); } @@ -35,7 +35,7 @@ TEST(alloc_two_pages___first_page_is_not_zero) { pmm_free(V2P(&mem[0])); pmm_free(V2P(&mem[1])); - uintptr_t a = pmm_alloc(); + uint64_t a = pmm_alloc(); pmm_alloc(); ASSERT_NEQ_PTR(a, 0); } @@ -44,14 +44,14 @@ TEST(alloc_two_pages___second_page_is_not_zero) pmm_free(V2P(&mem[0])); pmm_free(V2P(&mem[1])); pmm_alloc(); - uintptr_t a = pmm_alloc(); + uint64_t a = pmm_alloc(); ASSERT_NEQ_PTR(a, 0); } TEST(alloc_two_pages___doesnt_return_same_page_twice) { pmm_free(V2P(&mem[0])); pmm_free(V2P(&mem[1])); - uintptr_t a = pmm_alloc(); - uintptr_t b = pmm_alloc(); + uint64_t a = pmm_alloc(); + uint64_t b = pmm_alloc(); ASSERT_NEQ_PTR(a, b); } diff --git a/src/kernel/memory/vmm.c b/src/kernel/memory/vmm.c index f67c1a6..754ae1e 100644 --- a/src/kernel/memory/vmm.c +++ b/src/kernel/memory/vmm.c @@ -1,21 +1,21 @@ #include #define FLAGS_MASK (PAGE_SIZE-1) -#define MASK_FLAGS(addr) ((uintptr_t)addr & ~FLAGS_MASK) +#define MASK_FLAGS(addr) ((uint64_t)addr & ~FLAGS_MASK) union PTE { uint64_t value; struct { - uintptr_t present:1; - uintptr_t write:1; - uintptr_t user:1; - uintptr_t write_through:1; - uintptr_t nocache:1; - uintptr_t accessed:1; - uintptr_t dirty:1; - uintptr_t huge:1; - uintptr_t global:1; - uintptr_t flags:3; + uint64_t present:1; + uint64_t write:1; + uint64_t user:1; + uint64_t write_through:1; + uint64_t nocache:1; + uint64_t accessed:1; + uint64_t dirty:1; + uint64_t huge:1; + uint64_t global:1; + uint64_t flags:3; }; }; @@ -25,7 +25,7 @@ union PTE { #define P2e(pt, addr) PT(P3e(pt, addr).value)[P2_OFFSET(addr)] #define P1e(pt, addr) PT(P2e(pt, addr).value)[P1_OFFSET(addr)] -int page_exists(void *P4, uintptr_t addr) +static int page_exists(uint64_t P4, uint64_t addr) { if(P4 && P4e(P4, addr).present @@ -36,7 +36,7 @@ int page_exists(void *P4, uintptr_t addr) return 0; } -uintptr_t vmm_get_page(void *P4, uintptr_t addr) +uint64_t vmm_get_page(uint64_t P4, uint64_t addr) { if(page_exists(P4, addr)) if(P2e(P4, addr).huge) @@ -47,7 +47,7 @@ uintptr_t vmm_get_page(void *P4, uintptr_t addr) return -1; } -int vmm_set_page(void *P4, uintptr_t addr, uintptr_t page, uint16_t flags) +int vmm_set_page(uint64_t P4, uint64_t addr, uint64_t page, uint16_t flags) { if(flags & PAGE_HUGE) { @@ -69,7 +69,7 @@ int vmm_set_page(void *P4, uintptr_t addr, uintptr_t page, uint16_t flags) return 0; } -int touch_page(void *P4, uintptr_t addr, uint16_t flags) +int touch_page(uint64_t P4, uint64_t addr, uint16_t flags) { if(!P4) return -1; @@ -96,7 +96,7 @@ int touch_page(void *P4, uintptr_t addr, uint16_t flags) return 0; } -void free_page(void *P4, uintptr_t addr, int free) +void free_page(uint64_t P4, uint64_t addr, int free) { if(!page_exists(P4, addr)) return; diff --git a/src/kernel/memory/vmm.tt b/src/kernel/memory/vmm.tt index 3d292e8..272234d 100644 --- a/src/kernel/memory/vmm.tt +++ b/src/kernel/memory/vmm.tt @@ -8,13 +8,14 @@ #include "vmm.c" void *data; -uintptr_t *p4, *p3, *p2, *p1; +uint64_t *p4, *p3, *p2, *p1; +uint64_t P4; #define ADDR1234 ((1UL<<39) + (2UL<<30) + (3UL<<21) + (4UL<<12)) #define BUILD_PT(o4, o3, o2) \ - p4[(o4)] = (uintptr_t)p3; p4[(o4)] |= PAGE_PRESENT; \ - p3[(o3)] = (uintptr_t)p2; p3[(o3)] |= PAGE_PRESENT; \ - p2[(o2)] = (uintptr_t)p1; p2[(o2)] |= PAGE_PRESENT; + p4[(o4)] = (uint64_t)p3; p4[(o4)] |= PAGE_PRESENT; \ + p3[(o3)] = (uint64_t)p2; p3[(o3)] |= PAGE_PRESENT; \ + p2[(o2)] = (uint64_t)p1; p2[(o2)] |= PAGE_PRESENT; BEFORE() { @@ -23,6 +24,7 @@ BEFORE() p3 = &p4[512]; p2 = &p4[1024]; p1 = &p4[1536]; + P4 = (uint64_t)p4; } AFTER() { @@ -34,7 +36,7 @@ TEST(get_page_returns_correct_address) BUILD_PT(0,0,0); p1[0] = 0x1234567890ABC000 | PAGE_PRESENT; - uintptr_t ret = vmm_get_page(p4, 0); + uint64_t ret = vmm_get_page(P4, 0); ASSERT_EQ_PTR(ret, 0x1234567890ABC000 | PAGE_PRESENT); } @@ -43,7 +45,7 @@ TEST(get_page_ignores_flags) BUILD_PT(0,0,0); p1[0] = 0x1234567890ABC000 | PAGE_PRESENT; - uintptr_t ret = vmm_get_page(p4, 0); + uint64_t ret = vmm_get_page(P4, 0); ASSERT_EQ_PTR(ret, 0x1234567890ABC000 | PAGE_PRESENT); } @@ -52,27 +54,27 @@ TEST(get_page_works_for_different_address) BUILD_PT(1,2,3) p1[4] = 0x34567890ABCDE000 | PAGE_PRESENT; - uintptr_t ret = vmm_get_page(p4, ADDR1234); + uint64_t ret = vmm_get_page(P4, ADDR1234); ASSERT_EQ_PTR(ret, 0x34567890ABCDE000 | PAGE_PRESENT); } TEST(get_page_fails_if_PTE_not_present) { BUILD_PT(0,0,0); - p2[0] = (uintptr_t)p1; + p2[0] = (uint64_t)p1; p1[0] = 0x1234567890ABC000 | PAGE_PRESENT; - uintptr_t ret = vmm_get_page(p4, 0); + uint64_t ret = vmm_get_page(P4, 0); ASSERT_EQ_PTR(ret, -1); } TEST(get_page_gets_2mb_pages) { - p4[1] = (uintptr_t)p3; p4[1] |= PAGE_PRESENT; - p3[2] = (uintptr_t)p2; p3[2] |= PAGE_PRESENT; + p4[1] = (uint64_t)p3; p4[1] |= PAGE_PRESENT; + p3[2] = (uint64_t)p2; p3[2] |= PAGE_PRESENT; p2[3] = 0x1234567890A00000 | PAGE_HUGE | PAGE_PRESENT; - uintptr_t ret = vmm_get_page(p4, ADDR1234); + uint64_t ret = vmm_get_page(P4, ADDR1234); ASSERT_EQ_PTR(ret, 0x1234567890A00000 | PAGE_HUGE | PAGE_PRESENT); } @@ -80,7 +82,7 @@ TEST(set_page_sets_page) { BUILD_PT(0,0,0); - vmm_set_page(p4, 0, 0x1234567890ABC000, PAGE_PRESENT); + vmm_set_page(P4, 0, 0x1234567890ABC000, PAGE_PRESENT); ASSERT_EQ_PTR(p1[0], 0x1234567890ABC000 | PAGE_PRESENT); } @@ -88,25 +90,25 @@ TEST(set_page_returns_success_if_working) { BUILD_PT(0,0,0); - int retval = vmm_set_page(p4, 0, 0x1234567890ABC000, PAGE_PRESENT); + int retval = vmm_set_page(P4, 0, 0x1234567890ABC000, PAGE_PRESENT); ASSERT_EQ_INT(retval, 0); } TEST(set_page_fails_if_PT_missing) { BUILD_PT(0,0,0); - p3[0] = (uintptr_t)p2; + p3[0] = (uint64_t)p2; - int retval = vmm_set_page(p4, 0, 0x1234567890ABC000, PAGE_PRESENT); + int retval = vmm_set_page(P4, 0, 0x1234567890ABC000, PAGE_PRESENT); ASSERT_NEQ_INT(retval, 0); } TEST(set_page_sets_2mb_pages) { - p4[1] = (uintptr_t)p3; p4[1] |= PAGE_PRESENT; - p3[2] = (uintptr_t)p2; p3[2] |= PAGE_PRESENT; + p4[1] = (uint64_t)p3; p4[1] |= PAGE_PRESENT; + p3[2] = (uint64_t)p2; p3[2] |= PAGE_PRESENT; - vmm_set_page(p4, (1UL<<39)+(2UL<<30)+(3UL<<21), 0x1234567890A00000, PAGE_HUGE | PAGE_PRESENT); + vmm_set_page(P4, (1UL<<39)+(2UL<<30)+(3UL<<21), 0x1234567890A00000, PAGE_HUGE | PAGE_PRESENT); ASSERT_EQ_PTR(p2[3], 0x1234567890A00000 | PAGE_HUGE | PAGE_PRESENT); } @@ -114,52 +116,52 @@ TEST(set_page_does_not_overwrite_4kb_pages_with_2mb) { BUILD_PT(0,0,0); - int retval = vmm_set_page(p4, 0, 0, PAGE_HUGE | PAGE_PRESENT); + int retval = vmm_set_page(P4, 0, 0, PAGE_HUGE | PAGE_PRESENT); ASSERT_NEQ_INT(retval, 0); } -uintptr_t pmm_calloc() +uint64_t pmm_calloc() { - uintptr_t *pages[] = {p3, p2, p1}; + uint64_t *pages[] = {p3, p2, p1}; static int counter=0; if(counter >= 3) return 0; - return (uintptr_t)pages[counter++]; + return (uint64_t)pages[counter++]; } TEST(touch_page_adds_P3) { - touch_page(p4, ADDR1234, 0); + touch_page(P4, ADDR1234, 0); - ASSERT_EQ_PTR(p4[1], (uintptr_t)p3 | PAGE_PRESENT); + ASSERT_EQ_PTR(p4[1], (uint64_t)p3 | PAGE_PRESENT); } TEST(touch_page_adds_P2) { - touch_page(p4, ADDR1234, 0); + touch_page(P4, ADDR1234, 0); - ASSERT_EQ_PTR(p3[2], (uintptr_t)p2 | PAGE_PRESENT); + ASSERT_EQ_PTR(p3[2], (uint64_t)p2 | PAGE_PRESENT); } TEST(touch_page_adds_P1) { - touch_page(p4, ADDR1234, 0); + touch_page(P4, ADDR1234, 0); - ASSERT_EQ_PTR(p2[3], (uintptr_t)p1 | PAGE_PRESENT); + ASSERT_EQ_PTR(p2[3], (uint64_t)p1 | PAGE_PRESENT); } TEST(touch_page_sets_flags) { - touch_page(p4, 0, PAGE_WRITE); + touch_page(P4, 0, PAGE_WRITE); - ASSERT_EQ_PTR(p2[0], (uintptr_t)p1 | PAGE_WRITE | PAGE_PRESENT); + ASSERT_EQ_PTR(p2[0], (uint64_t)p1 | PAGE_WRITE | PAGE_PRESENT); } TEST(touch_page_fails_if_out_of_pages) { pmm_calloc(); - int retval = touch_page(p4, 0, 0); + int retval = touch_page(P4, 0, 0); ASSERT_NEQ_INT(retval, 0); } TEST(touch_page_stops_at_P2_for_huge_pages) { - touch_page(p4, 0, PAGE_HUGE); + touch_page(P4, 0, PAGE_HUGE); ASSERT_EQ_PTR(p2[0], 0); } @@ -168,7 +170,7 @@ TEST(free_page_unsets_page) BUILD_PT(1,2,3); p1[4] = PAGE_PRESENT; - free_page(p4, ADDR1234, 0); + free_page(P4, ADDR1234, 0); ASSERT_EQ_PTR(p1[4], 0); } @@ -177,7 +179,7 @@ TEST(free_page_unsets_P2_entry_if_P1_is_empty) BUILD_PT(1,2,3); p1[4] = PAGE_PRESENT; - free_page(p4, ADDR1234, 1); + free_page(P4, ADDR1234, 1); ASSERT_EQ_PTR(p2[3], 0); } @@ -186,7 +188,7 @@ TEST(free_page_does_not_unset_P2_entry_if_not_asked_to) BUILD_PT(1,2,3); p1[4] = PAGE_PRESENT; - free_page(p4, ADDR1234, 0); + free_page(P4, ADDR1234, 0); ASSERT_NEQ_PTR(p2[3], 0); } @@ -196,7 +198,7 @@ TEST(free_page_does_not_unset_P2_entry_if_P1_is_not_empty) p1[4] = PAGE_PRESENT; p1[0] = PAGE_PRESENT; - free_page(p4, ADDR1234, 1); + free_page(P4, ADDR1234, 1); ASSERT_NEQ_PTR(p2[3], 0); } @@ -207,13 +209,13 @@ TEST(free_page_does_not_stop_if_P2_pointed_page_is_not_empty) p1[4] = PAGE_PRESENT; p1[0] = PAGE_PRESENT; - free_page(p4, ADDR1234, 1); + free_page(P4, ADDR1234, 1); ASSERT_EQ_PTR(p2[3], 0); } -uintptr_t freed[] = {0,0,0,0,0}; -void pmm_free(uintptr_t page) +uint64_t freed[] = {0,0,0,0,0}; +void pmm_free(uint64_t page) { static int counter = 0; freed[counter++] = page; @@ -223,7 +225,7 @@ TEST(free_page_returns_P1_to_PMM_if_empty) BUILD_PT(1,2,3); p1[4] = PAGE_PRESENT; - free_page(p4, ADDR1234, 1); + free_page(P4, ADDR1234, 1); ASSERT_EQ_PTR(freed[0], p1); }