kern
changeset 24:53588744382c
switched the vm to use recursive page tables
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 05 Apr 2011 02:09:02 +0300 |
parents | 5454cee245a3 |
children | 9939a6d7a45a |
files | src/vm.c |
diffstat | 1 files changed, 17 insertions(+), 9 deletions(-) [+] |
line diff
1.1 --- a/src/vm.c Mon Apr 04 23:34:06 2011 +0300 1.2 +++ b/src/vm.c Tue Apr 05 02:09:02 2011 +0300 1.3 @@ -11,6 +11,10 @@ 1.4 #define KMEM_START 0xc0000000 1.5 #define IDMAP_START 0xa0000 1.6 1.7 +#define PGDIR_ADDR 0xfffff000 1.8 +#define PGTBL_BASE (0xffffffff - 4096 * 1024 + 1) 1.9 +#define PGTBL(x) ((uint32_t*)(PGTBL_BASE + PGSIZE * (x))) 1.10 + 1.11 #define ATTR_PGDIR_MASK 0x3f 1.12 #define ATTR_PGTBL_MASK 0x1ff 1.13 #define ADDR_PGENT_MASK 0xfffff000 1.14 @@ -59,12 +63,16 @@ 1.15 /* setup the page tables */ 1.16 pgdir = (uint32_t*)alloc_phys_page(); 1.17 memset(pgdir, 0, PGSIZE); 1.18 - set_pgdir_addr((int32_t)pgdir); 1.19 + set_pgdir_addr((uint32_t)pgdir); 1.20 1.21 /* map the video memory and kernel code 1-1 */ 1.22 get_kernel_mem_range(0, &idmap_end); 1.23 map_mem_range(IDMAP_START, idmap_end - IDMAP_START, IDMAP_START, 0); 1.24 1.25 + /* make the last page directory entry point to the page directory */ 1.26 + pgdir[1023] = ((uint32_t)pgdir & ADDR_PGENT_MASK) | PG_PRESENT; 1.27 + pgdir = (uint32_t*)PGDIR_ADDR; 1.28 + 1.29 /* set the page fault handler */ 1.30 interrupt(PAGEFAULT, pgfault); 1.31 1.32 @@ -92,7 +100,6 @@ 1.33 int diridx, pgidx, pgon; 1.34 1.35 pgon = get_paging_status(); 1.36 - disable_paging(); 1.37 1.38 if(ppage < 0) { 1.39 uint32_t addr = alloc_phys_page(); 1.40 @@ -107,20 +114,21 @@ 1.41 1.42 if(!(pgdir[diridx] & PG_PRESENT)) { 1.43 uint32_t addr = alloc_phys_page(); 1.44 - pgtbl = (uint32_t*)addr; 1.45 + pgdir[diridx] = addr | (attr & ATTR_PGDIR_MASK) | PG_PRESENT; 1.46 + 1.47 + pgtbl = pgon ? PGTBL(diridx) : (uint32_t*)addr; 1.48 memset(pgtbl, 0, PGSIZE); 1.49 - 1.50 - pgdir[diridx] = addr | (attr & ATTR_PGDIR_MASK) | PG_PRESENT; 1.51 } else { 1.52 - pgtbl = (uint32_t*)(pgdir[diridx] & ADDR_PGENT_MASK); 1.53 + if(pgon) { 1.54 + pgtbl = PGTBL(diridx); 1.55 + } else { 1.56 + pgtbl = (uint32_t*)(pgdir[diridx] & ADDR_PGENT_MASK); 1.57 + } 1.58 } 1.59 1.60 pgtbl[pgidx] = PAGE_TO_ADDR(ppage) | (attr & ATTR_PGTBL_MASK) | PG_PRESENT; 1.61 flush_tlb_page(vpage); 1.62 1.63 - if(pgon) { 1.64 - enable_paging(); 1.65 - } 1.66 return 0; 1.67 } 1.68