diff --git a/src/kernel/memory/vmm.c b/src/kernel/memory/vmm.c new file mode 100644 index 0000000..d5dbf47 --- /dev/null +++ b/src/kernel/memory/vmm.c @@ -0,0 +1,26 @@ +#include + +#define FLAGS_MASK (PAGE_SIZE-1) + +struct PT { + struct PT *p[ENTRIES_PER_PT]; +}__attribute__((packed)); + +#define P(pt) ((struct PT *)((uintptr_t)pt & ~(FLAGS_MASK))) + +#define P3(pt, addr) (P(pt)->p[P4_OFFSET(addr)]) +#define P2(pt, addr) (P(P3(pt, addr))->p[P3_OFFSET(addr)]) +#define P1(pt, addr) (P(P2(pt, addr))->p[P2_OFFSET(addr)]) +#define P0(pt, addr) (P(P1(pt, addr))->p[P1_OFFSET(addr)]) + + +uintptr_t vmm_get_page(uintptr_t *P4, uintptr_t addr) +{ + if(P4 + && P3(P4, addr) + && P2(P4, addr) + && P1(P4, addr) + ) + return (uintptr_t)P0(P4, addr); + return 0; +} diff --git a/src/kernel/memory/vmm.tt b/src/kernel/memory/vmm.tt new file mode 100644 index 0000000..469f2fc --- /dev/null +++ b/src/kernel/memory/vmm.tt @@ -0,0 +1,32 @@ +// vim: ft=c +#include + +#include "vmm.c" + +void *data; +uintptr_t *p4, *p3, *p2, *p1; + +BEFORE() +{ + data = calloc(PAGE_SIZE, 5); + p4 = (void *)(((uintptr_t)data + PAGE_SIZE) & ~(PAGE_SIZE-1)); + p3 = &p4[512]; + p2 = &p4[1024]; + p1 = &p4[1536]; +} +AFTER() +{ + free(data); +} + +TEST(get_page_returns_correct_address) +{ + p4[0] = (uintptr_t)p3; + p3[0] = (uintptr_t)p2; + p2[0] = (uintptr_t)p1; + p1[0] = 0x1234567890ABC000; + + uintptr_t ret = vmm_get_page(p4, 0); + + ASSERT_EQ_PTR(ret, 0x1234567890ABC000); +}