diff options
author | jkim <jkim@FreeBSD.org> | 2009-02-25 20:26:48 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2009-02-25 20:26:48 +0000 |
commit | c7f643835f11d01864499c4be0c419c56a709d2c (patch) | |
tree | 961df520d7e3659cc7018a6821a8d5f6cb68c0ad /sys | |
parent | 35f0e5ba8fbb4c47932378b8941120b11386e5ae (diff) | |
download | FreeBSD-src-c7f643835f11d01864499c4be0c419c56a709d2c.zip FreeBSD-src-c7f643835f11d01864499c4be0c419c56a709d2c.tar.gz |
Enable support for PAT_WRITE_PROTECTED and PAT_UNCACHED cache modes
unconditionally on amd64. On i386, we assume PAT is usable if the CPU
vendor is not Intel or CPU model is newer than Pentium IV.
Reviewed by: alc, jhb
Diffstat (limited to 'sys')
-rw-r--r-- | sys/amd64/amd64/pmap.c | 39 | ||||
-rw-r--r-- | sys/i386/i386/pmap.c | 141 |
2 files changed, 77 insertions, 103 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 573b1f4..4050bd9 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -594,7 +594,6 @@ pmap_init_pat(void) if (!(cpu_feature & CPUID_PAT)) panic("no PAT??"); -#ifdef PAT_WORKS /* * Leave the indices 0-3 at the default of WB, WT, UC, and UC-. * Program 4 and 5 as WP and WC. @@ -604,23 +603,6 @@ pmap_init_pat(void) pat_msr &= ~(PAT_MASK(4) | PAT_MASK(5)); pat_msr |= PAT_VALUE(4, PAT_WRITE_PROTECTED) | PAT_VALUE(5, PAT_WRITE_COMBINING); -#else - /* - * Due to some Intel errata, we can only safely use the lower 4 - * PAT entries. Thus, just replace PAT Index 2 with WC instead - * of UC-. - * - * Intel Pentium III Processor Specification Update - * Errata E.27 (Upper Four PAT Entries Not Usable With Mode B - * or Mode C Paging) - * - * Intel Pentium IV Processor Specification Update - * Errata N46 (PAT Index MSB May Be Calculated Incorrectly) - */ - pat_msr = rdmsr(MSR_PAT); - pat_msr &= ~PAT_MASK(2); - pat_msr |= PAT_VALUE(2, PAT_WRITE_COMBINING); -#endif wrmsr(MSR_PAT, pat_msr); } @@ -783,10 +765,9 @@ pmap_cache_bits(int mode, boolean_t is_pde) break; } } - + /* Map the caching mode to a PAT index. */ switch (mode) { -#ifdef PAT_WORKS case PAT_UNCACHEABLE: pat_index = 3; break; @@ -805,25 +786,9 @@ pmap_cache_bits(int mode, boolean_t is_pde) case PAT_WRITE_PROTECTED: pat_index = 4; break; -#else - case PAT_UNCACHED: - case PAT_UNCACHEABLE: - case PAT_WRITE_PROTECTED: - pat_index = 3; - break; - case PAT_WRITE_THROUGH: - pat_index = 1; - break; - case PAT_WRITE_BACK: - pat_index = 0; - break; - case PAT_WRITE_COMBINING: - pat_index = 2; - break; -#endif default: panic("Unknown caching mode %d\n", mode); - } + } /* Map the 3-bit index value into the PAT, PCD, and PWT bits. */ cache_bits = 0; diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 15796b3..83da708 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -211,6 +211,8 @@ pt_entry_t pg_nx; static uma_zone_t pdptzone; #endif +static int pat_works; /* Is page attribute table sane? */ + SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD, 0, "VM/pmap parameters"); static int pg_ps_enabled; @@ -477,33 +479,36 @@ pmap_init_pat(void) if (!(cpu_feature & CPUID_PAT)) return; -#ifdef PAT_WORKS - /* - * Leave the indices 0-3 at the default of WB, WT, UC, and UC-. - * Program 4 and 5 as WP and WC. - * Leave 6 and 7 as UC and UC-. - */ - pat_msr = rdmsr(MSR_PAT); - pat_msr &= ~(PAT_MASK(4) | PAT_MASK(5)); - pat_msr |= PAT_VALUE(4, PAT_WRITE_PROTECTED) | - PAT_VALUE(5, PAT_WRITE_COMBINING); -#else - /* - * Due to some Intel errata, we can only safely use the lower 4 - * PAT entries. Thus, just replace PAT Index 2 with WC instead - * of UC-. - * - * Intel Pentium III Processor Specification Update - * Errata E.27 (Upper Four PAT Entries Not Usable With Mode B - * or Mode C Paging) - * - * Intel Pentium IV Processor Specification Update - * Errata N46 (PAT Index MSB May Be Calculated Incorrectly) - */ - pat_msr = rdmsr(MSR_PAT); - pat_msr &= ~PAT_MASK(2); - pat_msr |= PAT_VALUE(2, PAT_WRITE_COMBINING); -#endif + if (cpu_vendor_id != CPU_VENDOR_INTEL || + (I386_CPU_FAMILY(cpu_id) == 6 && I386_CPU_MODEL(cpu_id) >= 0xe)) { + /* + * Leave the indices 0-3 at the default of WB, WT, UC, and UC-. + * Program 4 and 5 as WP and WC. + * Leave 6 and 7 as UC and UC-. + */ + pat_msr = rdmsr(MSR_PAT); + pat_msr &= ~(PAT_MASK(4) | PAT_MASK(5)); + pat_msr |= PAT_VALUE(4, PAT_WRITE_PROTECTED) | + PAT_VALUE(5, PAT_WRITE_COMBINING); + pat_works = 1; + } else { + /* + * Due to some Intel errata, we can only safely use the lower 4 + * PAT entries. Thus, just replace PAT Index 2 with WC instead + * of UC-. + * + * Intel Pentium III Processor Specification Update + * Errata E.27 (Upper Four PAT Entries Not Usable With Mode B + * or Mode C Paging) + * + * Intel Pentium IV Processor Specification Update + * Errata N46 (PAT Index MSB May Be Calculated Incorrectly) + */ + pat_msr = rdmsr(MSR_PAT); + pat_msr &= ~PAT_MASK(2); + pat_msr |= PAT_VALUE(2, PAT_WRITE_COMBINING); + pat_works = 0; + } wrmsr(MSR_PAT, pat_msr); } @@ -753,45 +758,49 @@ pmap_cache_bits(int mode, boolean_t is_pde) } /* Map the caching mode to a PAT index. */ - switch (mode) { -#ifdef PAT_WORKS - case PAT_UNCACHEABLE: - pat_index = 3; - break; - case PAT_WRITE_THROUGH: - pat_index = 1; - break; - case PAT_WRITE_BACK: - pat_index = 0; - break; - case PAT_UNCACHED: - pat_index = 2; - break; - case PAT_WRITE_COMBINING: - pat_index = 5; - break; - case PAT_WRITE_PROTECTED: - pat_index = 4; - break; -#else - case PAT_UNCACHED: - case PAT_UNCACHEABLE: - case PAT_WRITE_PROTECTED: - pat_index = 3; - break; - case PAT_WRITE_THROUGH: - pat_index = 1; - break; - case PAT_WRITE_BACK: - pat_index = 0; - break; - case PAT_WRITE_COMBINING: - pat_index = 2; - break; -#endif - default: - panic("Unknown caching mode %d\n", mode); - } + if (pat_works) { + switch (mode) { + case PAT_UNCACHEABLE: + pat_index = 3; + break; + case PAT_WRITE_THROUGH: + pat_index = 1; + break; + case PAT_WRITE_BACK: + pat_index = 0; + break; + case PAT_UNCACHED: + pat_index = 2; + break; + case PAT_WRITE_COMBINING: + pat_index = 5; + break; + case PAT_WRITE_PROTECTED: + pat_index = 4; + break; + default: + panic("Unknown caching mode %d\n", mode); + } + } else { + switch (mode) { + case PAT_UNCACHED: + case PAT_UNCACHEABLE: + case PAT_WRITE_PROTECTED: + pat_index = 3; + break; + case PAT_WRITE_THROUGH: + pat_index = 1; + break; + case PAT_WRITE_BACK: + pat_index = 0; + break; + case PAT_WRITE_COMBINING: + pat_index = 2; + break; + default: + panic("Unknown caching mode %d\n", mode); + } + } /* Map the 3-bit index value into the PAT, PCD, and PWT bits. */ cache_bits = 0; |