This sets up PAT so we can have WB, WC, WT, and UC memory types via the
__PTE flags.  The PCD and PWT bits don't necessarily disable caching or set
write-through anymore; they are indexes into the PAT table.  (This was
always happening btw, since anything we run on has PAT support).

Signed-off-by: Barret Rhoden <[email protected]>
---
 kern/arch/x86/cpuinfo.c |  2 ++
 kern/arch/x86/pmap.c    | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/kern/arch/x86/cpuinfo.c b/kern/arch/x86/cpuinfo.c
index 1fed0725b54a..b857ee28b633 100644
--- a/kern/arch/x86/cpuinfo.c
+++ b/kern/arch/x86/cpuinfo.c
@@ -82,6 +82,8 @@ void print_cpuinfo(void)
                panic("MSRs not supported!");
        if (!(edx & 0x00001000))
                panic("MTRRs not supported!");
+       if (!(edx & (1 << 16)))
+               panic("PAT not supported!");
        if (!(edx & 0x00002000))
                panic("Global Pages not supported!");
        if (!(edx & 0x00000200))
diff --git a/kern/arch/x86/pmap.c b/kern/arch/x86/pmap.c
index 8ca6fb4cf80b..7d59701533b5 100644
--- a/kern/arch/x86/pmap.c
+++ b/kern/arch/x86/pmap.c
@@ -40,6 +40,49 @@ bool enable_pse(void)
                return 0;
 }
 
+#define PAT_UC                                 0x00
+#define PAT_WC                                 0x01
+#define PAT_WT                                 0x04
+#define PAT_WP                                 0x05
+#define PAT_WB                                 0x06
+#define PAT_UCm                                        0x07
+
+static inline uint64_t mk_pat(int pat_idx, int type)
+{
+       return (uint64_t)type << (8 * pat_idx);
+}
+
+static void pat_init(void)
+{
+       uint64_t pat = 0;
+
+       /* Default PAT at boot:
+        *   0: WB, 1: WT, 2: UC-, 3: UC, 4: WB, 5: WT, 6: UC-, 7: UC
+        *
+        * We won't use PATs 4-7, but we'll at least enforce that they are set 
up
+        * the way we think they are.  I'd like to avoid using the PAT flag, 
since
+        * that is also the PTE_PS (jumbo) flag.  That means we can't use 
__PTE_PAT
+        * on jumbo pages, and we'd need to be careful whenever using any 
unorthodox
+        * types.  We're better off just not using it.
+        *
+        * We set PAT 2 to WC.  People should use PTE_WRITECOMB to choose it.  I
+        * picked 2 since we don't need UC-.  The UC- type is UC with the 
ability to
+        * override to WC via MTRR.  I'm hoping to not muck with MTRRs, so we 
can
+        * just use this PAT type whenever we want WC.
+        *
+        * No one should be accessing __PTE_{PAT,PCD,PWT} directly, and everyone
+        * should use things like PTE_NOCACHE. */
+       pat |= mk_pat(0, PAT_WB);       /*           |           |           */
+       pat |= mk_pat(1, PAT_WT);       /*           |           | __PTE_PWT */
+       pat |= mk_pat(2, PAT_WC);       /*           | __PTE_PCD |           */
+       pat |= mk_pat(3, PAT_UC);       /*           | __PTE_PCD | __PTE_PWT */
+       pat |= mk_pat(4, PAT_WB);       /* __PTE_PAT |           |           */
+       pat |= mk_pat(5, PAT_WT);       /* __PTE_PAT |           | __PTE_PWT */
+       pat |= mk_pat(6, PAT_UCm);      /* __PTE_PAT | __PTE_PCD |           */
+       pat |= mk_pat(7, PAT_UC);       /* __PTE_PAT | __PTE_PCD | __PTE_PWT */
+       write_msr(MSR_IA32_CR_PAT, pat);
+}
+
 // could consider having an API to allow these to dynamically change
 // MTRRs are for physical, static ranges.  PAT are linear, more granular, and 
 // more dynamic
@@ -87,6 +130,7 @@ void setup_default_mtrrs(barrier_t* smp_barrier)
        // keeps default type to WB (06), turns MTRRs on, and turns off fixed 
ranges
        write_msr(IA32_MTRR_DEF_TYPE, 0x00000806);
 #endif 
+       pat_init();
        // reflush caches and TLB
        cache_flush();
        tlb_flush_global();
-- 
2.7.0.rc3.207.g0ac5344

-- 
You received this message because you are subscribed to the Google Groups 
"Akaros" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to