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;
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to