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