# HG changeset patch # User John Tsiombikas # Date 1301196506 -10800 # Node ID 096807345aa28ecda3fe03e36f33a4a034fbcd51 # Parent 098b1cb5eeaa748fb49f16adcb78c324701c301e fixed the stupid mistake. forgot to page-align the page directory diff -r 098b1cb5eeaa -r 096807345aa2 src/vm.c --- a/src/vm.c Sat Mar 26 21:39:14 2011 +0200 +++ b/src/vm.c Sun Mar 27 06:28:26 2011 +0300 @@ -16,7 +16,7 @@ static void pgfault(int inum, uint32_t err); /* page directory */ -static uint32_t pgdir[1024]; +static uint32_t *pgdir; #define KMEM_START 0xc0000000 #define IDMAP_START 0xa0000 @@ -31,6 +31,7 @@ { init_mem(mb); + pgdir = (uint32_t*)alloc_phys_page(); memset(pgdir, 0, sizeof pgdir); /* map the video memory and kernel code 1-1 */ @@ -51,6 +52,8 @@ if(!(pgdir[diridx] & PG_PRESENT)) { uint32_t addr = alloc_phys_page(); pgtbl = (uint32_t*)addr; + memset(pgtbl, 0, PGSIZE); + pgdir[diridx] = addr | (attr & ATTR_PGDIR_MASK) | PG_PRESENT; } else { pgtbl = (uint32_t*)(pgdir[diridx] & ADDR_PGENT_MASK); @@ -128,6 +131,25 @@ } */ +uint32_t virt_to_phys(uint32_t vaddr) +{ + uint32_t pgaddr, *pgtbl; + int diridx = ADDR_TO_PGTBL(vaddr); + int pgidx = ADDR_TO_PGTBL_PG(vaddr); + + if(!(pgdir[diridx] & PG_PRESENT)) { + panic("virt_to_phys(%x): page table %d not present\n", vaddr, diridx); + } + pgtbl = (uint32_t*)(pgdir[diridx] & PGENT_ADDR_MASK); + + if(!(pgtbl[pgidx] & PG_PRESENT)) { + panic("virt_to_phys(%x): page %d not present\n", vaddr, ADDR_TO_PAGE(vaddr)); + } + pgaddr = pgtbl[pgidx] & PGENT_ADDR_MASK; + + return pgaddr | ADDR_TO_PGOFFS(vaddr); +} + static void pgfault(int inum, uint32_t err) { printf("~~~~ PAGE FAULT ~~~~\n"); diff -r 098b1cb5eeaa -r 096807345aa2 src/vm.h --- a/src/vm.h Sat Mar 26 21:39:14 2011 +0200 +++ b/src/vm.h Sun Mar 27 06:28:26 2011 +0300 @@ -20,6 +20,7 @@ #define PGSIZE 4096 #define PGOFFS_MASK 0xfff #define PGNUM_MASK 0xfffff000 +#define PGENT_ADDR_MASK PGNUM_MASK #define ADDR_TO_PAGE(x) ((uint32_t)(x) >> 12) #define PAGE_TO_ADDR(x) ((uint32_t)(x) << 12) @@ -39,4 +40,6 @@ void map_mem_range(uint32_t vaddr, size_t sz, uint32_t paddr, unsigned int attr); +uint32_t virt_to_phys(uint32_t vaddr); + #endif /* VM_H_ */