Index: sys/i386/i386/pmap.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/pmap.c,v retrieving revision 1.345 diff -u -r1.345 pmap.c --- sys/i386/i386/pmap.c 17 Jul 2002 21:47:05 -0000 1.345 +++ sys/i386/i386/pmap.c 18 Jul 2002 13:55:01 -0000 @@ -423,32 +423,26 @@ pt_entry_t *pte; vm_offset_t va, endva; - if (pgeflag && (cpu_feature & CPUID_PGE)) { - load_cr4(rcr4() | CR4_PGE); - invltlb(); /* Insurance */ - } -#ifndef DISABLE_PSE - if (pseflag && (cpu_feature & CPUID_PSE)) { - load_cr4(rcr4() | CR4_PSE); - invltlb(); /* Insurance */ - } -#endif + /* + * This is a little scary. We enable PGE _first_, run through + * to set the PG_G bits in the appropriate page table entries + * (including those 4K pages corresponding to the chunk sitting + * in the first 4M), and only then we enable PSE and change + * the page directory entry for the first 4M page. The reason + * we do it this way may be due to some [undocumented?] Intel + * bug. Or it may be due to something we haven't figured out + * yet. This just makes the pII and PPro work, with PG_G set + * on the 4M page and any (if applicable) 4K pages after that, + * should the kernel be large enough. + */ if (PCPU_GET(cpuid) == 0) { -#ifndef DISABLE_PSE - if (pdir4mb) { - kernel_pmap->pm_pdir[KPTDI] = PTD[KPTDI] = pdir4mb; - invltlb(); /* Insurance */ + if (pgeflag && (cpu_feature & CPUID_PGE)) { + load_cr4(rcr4() | CR4_PGE); + invltlb(); /* Insurance */ } -#endif if (pgeflag) { /* Turn on PG_G for text, data, bss pages. */ va = (vm_offset_t)btext; -#ifndef DISABLE_PSE - if (pseflag && (cpu_feature & CPUID_PSE)) { - if (va < KERNBASE + (1 << PDRSHIFT)) - va = KERNBASE + (1 << PDRSHIFT); - } -#endif endva = KERNBASE + KERNend; while (va < endva) { pte = vtopte(va); @@ -458,11 +452,32 @@ } invltlb(); /* Insurance */ } +#ifndef DISABLE_PSE + if (pseflag && (cpu_feature & CPUID_PSE)) { + load_cr4(rcr4() | CR4_PSE); + invltlb(); /* Insurance */ + } + if (pdir4mb) { + kernel_pmap->pm_pdir[KPTDI] = PTD[KPTDI] = pdir4mb; + invltlb(); /* Insurance */ + } +#endif /* * We do not need to broadcast the invltlb here, because * each AP does it the moment it is released from the boot * lock. See ap_init(). */ + } else { + if (pgeflag && (cpu_feature & CPUID_PGE)) { + load_cr4(rcr4() | CR4_PGE); + invltlb(); /* Insurance */ + } +#ifndef DISABLE_PSE + if (pseflag && (cpu_feature & CPUID_PSE)) { + load_cr4(rcr4() | CR4_PSE); + invltlb(); /* Insurance */ + } +#endif } }