svn commit: r189055 - in head/sys: amd64/amd64 i386/i386

Jung-uk Kim jkim at FreeBSD.org
Wed Feb 25 12:26:49 PST 2009


Author: jkim
Date: Wed Feb 25 20:26:48 2009
New Revision: 189055
URL: http://svn.freebsd.org/changeset/base/189055

Log:
  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

Modified:
  head/sys/amd64/amd64/pmap.c
  head/sys/i386/i386/pmap.c

Modified: head/sys/amd64/amd64/pmap.c
==============================================================================
--- head/sys/amd64/amd64/pmap.c	Wed Feb 25 20:24:13 2009	(r189054)
+++ head/sys/amd64/amd64/pmap.c	Wed Feb 25 20:26:48 2009	(r189055)
@@ -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_p
 			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_p
 	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;

Modified: head/sys/i386/i386/pmap.c
==============================================================================
--- head/sys/i386/i386/pmap.c	Wed Feb 25 20:24:13 2009	(r189054)
+++ head/sys/i386/i386/pmap.c	Wed Feb 25 20:26:48 2009	(r189055)
@@ -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_p
 	}
 	
 	/* 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;


More information about the svn-src-head mailing list