Global pages support.
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 14 Apr 2009 08:00:13 +0000 (01:00 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 14 Apr 2009 08:00:13 +0000 (01:00 -0700)
Used for all of the boot_mappings.  Someone should check to see if they
are getting applied.  More difficult would be to see how effective they
are (TLB hits on context switches for the kernel mappings), and if the
non-jumbo PDEs do anything with the PTE_G flag.

kern/pmap.c
kern/smp_entry.S

index 145a87a..6ea71da 100644 (file)
@@ -199,7 +199,7 @@ boot_pgdir_walk(pde_t *pgdir, uintptr_t la, int create)
        }
        new_table = boot_alloc(PGSIZE, PGSIZE);
        memset(new_table, 0, PGSIZE);
-       *the_pde = (pde_t)PADDR(new_table) | PTE_P | PTE_W | PTE_U;
+       *the_pde = (pde_t)PADDR(new_table) | PTE_P | PTE_W | PTE_U | PTE_G;
        return &((pde_t*)KADDR(PTE_ADDR(*the_pde)))[PTX(la)];
 }
 
@@ -230,12 +230,12 @@ boot_map_segment(pde_t *pgdir, uintptr_t la, size_t size, physaddr_t pa, int per
                // need to index with i instead of la + size, in case of wrap-around
                for (i = 0; i < size; i += JPGSIZE, la += JPGSIZE, pa += JPGSIZE) {
                        pte = boot_pgdir_walk(pgdir, la, 2);
-                       *pte = PTE_ADDR(pa) | PTE_P | perm;
+                       *pte = PTE_ADDR(pa) | PTE_P | PTE_G | perm;
                }
        } else {
                for (i = 0; i < size; i += PGSIZE, la += PGSIZE, pa += PGSIZE) {
                        pte = boot_pgdir_walk(pgdir, la, 1);
-                       *pte = PTE_ADDR(pa) | PTE_P | perm;
+                       *pte = PTE_ADDR(pa) | PTE_P | PTE_G | perm;
                }
        }
 }
@@ -322,6 +322,11 @@ i386_vm_init(void)
        if (pse)
                cprintf("PSE capability detected.\n");
 
+       // we paniced earlier if we don't support PGE.  turn it on now.
+       // it's used in boot_map_segment, which covers all of the mappings that are
+       // the same for all address spaces.  and also for the VPT mapping below.
+       lcr4(rcr4() | CR4_PGE);
+
        // set up mtrr's for core0.  other cores will do the same later
        setup_default_mtrrs(0);
 
@@ -356,12 +361,12 @@ i386_vm_init(void)
        // following two lines.  Unless you are eagle-eyed, in which case you
        // should already know.)
 
-       // Permissions: kernel RW, user NONE
-       pgdir[PDX(VPT)] = PADDR(pgdir)|PTE_W|PTE_P;
+       // Permissions: kernel RW, user NONE, Global Page
+       pgdir[PDX(VPT)] = PADDR(pgdir) | PTE_W | PTE_P | PTE_G;
 
        // same for UVPT
-       // Permissions: kernel R, user R 
-       pgdir[PDX(UVPT)] = PADDR(pgdir)|PTE_U|PTE_P;
+       // Permissions: kernel R, user R, Global Page
+       pgdir[PDX(UVPT)] = PADDR(pgdir) | PTE_U | PTE_P | PTE_G;
 
        //////////////////////////////////////////////////////////////////////
        // Map the kernel stack (symbol name "bootstack").  The complete VA
index ec0e517..f9a1e30 100644 (file)
@@ -54,6 +54,10 @@ protcseg:    .code32
        orl             $CR4_PSE, %eax
        movl    %eax, %cr4
 past_pse:
+       # Turn on PGE, no matter what.  Ghetto, but we panic if it's not supported.
+       movl    %cr4, %eax
+       orl             $CR4_PGE, %eax
+       movl    %eax, %cr4
        movl    %cr0, %eax      
        # These cr0 flags are the same as in pmap.c.  Keep them in sync
        orl             $(CR0_PE|CR0_PG|CR0_AM|CR0_WP|CR0_NE|CR0_MP), %eax