[PATCH 1/2] PAT setting write combining on PAT6 at boot time

From: Cédric Augonnet
Date: Mon Aug 06 2007 - 22:03:51 EST



This sets PAT6 to write combining during boot on i386 and x86_64

Signed-off-by: Cedric Augonnet <cedric.augonnet@xxxxxxxxxxxx>
CC: Loic Prylli <loic@xxxxxxxx>
CC: Brice Goglin <brice@xxxxxxxx>
---
diff -urN 2.6.23-rc2/arch/i386/kernel/cpu/Makefile 2.6.23-rc2-pat/arch/i386/kernel/cpu/Makefile
--- 2.6.23-rc2/arch/i386/kernel/cpu/Makefile 2007-08-06 15:16:16.000000000 -0400
+++ 2.6.23-rc2-pat/arch/i386/kernel/cpu/Makefile 2007-08-06 17:44:36.000000000 -0400
@@ -11,6 +11,7 @@
obj-y += intel.o intel_cacheinfo.o addon_cpuid_features.o
obj-y += nexgen.o
obj-y += umc.o
+obj-y += pat.o

obj-$(CONFIG_X86_MCE) += mcheck/

diff -urN 2.6.23-rc2/arch/i386/kernel/cpu/pat.c 2.6.23-rc2-pat/arch/i386/kernel/cpu/pat.c
--- 2.6.23-rc2/arch/i386/kernel/cpu/pat.c 1969-12-31 19:00:00.000000000 -0500
+++ 2.6.23-rc2-pat/arch/i386/kernel/cpu/pat.c 2007-08-06 18:16:37.000000000 -0400
@@ -0,0 +1,36 @@
+/*
+ * x86 Page Attribute Table (PAT) support.
+ * Copyright (C) 2007 Cedric Augonnet.
+ * (C) 2007 Myricom, Inc.
+ * (C) 2003 Jeff Hartmann
+ * (C) 2001 Jeff Hartmann
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <asm/pat.h>
+#include <asm/cpufeature.h>
+
+static inline void
+enable_pat_on_cpu(void *info)
+{
+ uint32_t low;
+ uint32_t high;
+
+ /* use PAT 6 for write combining */
+ rdmsr(MSR_CR_PAT, low, high);
+ if ((high & 0xff0000) != 0x010000) {
+ high = (high & 0xff00ffff) | 0x00010000;
+ wrmsr(MSR_CR_PAT, low, high);
+ }
+}
+
+void __init
+pat_init(void)
+{
+ /* enable PAT is CPU supports it */
+ if (cpu_has_pat)
+ on_each_cpu(enable_pat_on_cpu, 0, 0, 1);
+}
diff -urN 2.6.23-rc2/arch/i386/kernel/setup.c 2.6.23-rc2-pat/arch/i386/kernel/setup.c
--- 2.6.23-rc2/arch/i386/kernel/setup.c 2007-08-06 15:16:17.000000000 -0400
+++ 2.6.23-rc2-pat/arch/i386/kernel/setup.c 2007-08-06 17:44:36.000000000 -0400
@@ -62,6 +62,7 @@
#include <asm/vmi.h>
#include <setup_arch.h>
#include <bios_ebda.h>
+#include <asm/pat.h>

/* This value is set up by the early boot code to point to the value
immediately after the boot time page tables. It contains a *physical*
@@ -650,4 +651,5 @@
conswitchp = &dummy_con;
#endif
#endif
+ pat_init();
}
diff -urN 2.6.23-rc2/arch/x86_64/kernel/Makefile 2.6.23-rc2-pat/arch/x86_64/kernel/Makefile
--- 2.6.23-rc2/arch/x86_64/kernel/Makefile 2007-08-06 15:16:27.000000000 -0400
+++ 2.6.23-rc2-pat/arch/x86_64/kernel/Makefile 2007-08-06 17:44:36.000000000 -0400
@@ -16,6 +16,7 @@
obj-$(CONFIG_X86_MCE_INTEL) += mce_intel.o
obj-$(CONFIG_X86_MCE_AMD) += mce_amd.o
obj-$(CONFIG_MTRR) += ../../i386/kernel/cpu/mtrr/
+obj-y += pat.o
obj-$(CONFIG_ACPI) += acpi/
obj-$(CONFIG_X86_MSR) += msr.o
obj-$(CONFIG_MICROCODE) += microcode.o
@@ -61,3 +62,4 @@
alternative-y += ../../i386/kernel/alternative.o
pcspeaker-y += ../../i386/kernel/pcspeaker.o
perfctr-watchdog-y += ../../i386/kernel/cpu/perfctr-watchdog.o
+pat-y += ../../i386/kernel/cpu/pat.o
diff -urN 2.6.23-rc2/arch/x86_64/kernel/setup.c 2.6.23-rc2-pat/arch/x86_64/kernel/setup.c
--- 2.6.23-rc2/arch/x86_64/kernel/setup.c 2007-08-06 15:16:27.000000000 -0400
+++ 2.6.23-rc2-pat/arch/x86_64/kernel/setup.c 2007-08-06 17:44:36.000000000 -0400
@@ -64,6 +64,7 @@
#include <asm/numa.h>
#include <asm/sections.h>
#include <asm/dmi.h>
+#include <asm/pat.h>

/*
* Machine setup..
@@ -416,6 +417,7 @@
conswitchp = &dummy_con;
#endif
#endif
+ pat_init();
}

static int __cpuinit get_model_name(struct cpuinfo_x86 *c)
diff -urN 2.6.23-rc2/include/asm-i386/cpufeature.h 2.6.23-rc2-pat/include/asm-i386/cpufeature.h
--- 2.6.23-rc2/include/asm-i386/cpufeature.h 2007-08-06 15:17:12.000000000 -0400
+++ 2.6.23-rc2-pat/include/asm-i386/cpufeature.h 2007-08-06 17:44:36.000000000 -0400
@@ -164,6 +164,7 @@
#define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS)
#define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH)
#define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS)
+#define cpu_has_pat boot_cpu_has(X86_FEATURE_PAT)

#endif /* __ASM_I386_CPUFEATURE_H */

diff -urN 2.6.23-rc2/include/asm-i386/pat.h 2.6.23-rc2-pat/include/asm-i386/pat.h
--- 2.6.23-rc2/include/asm-i386/pat.h 1969-12-31 19:00:00.000000000 -0500
+++ 2.6.23-rc2-pat/include/asm-i386/pat.h 2007-08-06 18:26:11.000000000 -0400
@@ -0,0 +1,32 @@
+/*
+ * x86 Page Attribute Table (PAT) support.
+ * Copyright (C) 2007 Cedric Augonnet.
+ * (C) 2007 Myricom, Inc.
+ * (C) 2003 Jeff Hartmann
+ * (C) 2001 Jeff Hartmann
+ */
+
+#ifndef _LINUX_PAT_H
+#define _LINUX_PAT_H
+
+#define MSR_CR_PAT 0x277
+
+/*
+ * Once PAT is enabled using pat_init on each CPU,we should have the
+ * following layout : the first four are not changed for backward
+ * compatibility with processors not implementing PAT . PAT 6 is changed
+ * to write combining mode.
+ *
+ * PAT 0 : WB PAT 4 : WB
+ * PAT 1 : WT PAT 5 : WT
+ * PAT 2 : UC- PAT 6 : WC
+ * PAT 3 : UC PAT 7 : UC-
+ *
+ */
+
+/*
+ * This function enables write combining on PAT6 on each CPU.
+ */
+extern void pat_init(void);
+
+#endif
diff -urN 2.6.23-rc2/include/asm-x86_64/pat.h 2.6.23-rc2-pat/include/asm-x86_64/pat.h
--- 2.6.23-rc2/include/asm-x86_64/pat.h 1969-12-31 19:00:00.000000000 -0500
+++ 2.6.23-rc2-pat/include/asm-x86_64/pat.h 2007-08-06 17:44:36.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef _LINUX_PAT_X86_64_H
+#define _LINUX_PAT_X86_64_H
+
+#include <asm-i386/pat.h>
+
+#endif