pat support in the kernel
Hello all,
I've discussed adding Page Attribute Table (PAT) support to the kernel w/ a few developers offline. They were very supportive and suggested I bring the discussion to lkml so others could get involved.
PAT support allows setting cache attributes via the virtual page table entries that are traditionally set via the MTRRs. The specific cache attribute graphics companies such as ourselves (nvidia), ATI, Matrox, and others are becoming interested in is Write-Combining (WC), both for the AGP and framebuffer apertures. Traditionally, these apertures are marked WC by setting the physical memory ranges to WC in the MTRRs. This has traditionally worked very well, but is becoming a problem with workstation systems with 1+ Gigs of memory.
The problem here is that the system bios typically covers physical ram with Write-Back (WB) MTRRs. On systems with large amounts of physical ram, especially when physical memory ranges can intersperse with ram, the bioses are using multiple MTRRs with strange results. In some cases, enough MTRRs are used to cover physical ram, such that MTRRs are not left over for the AGP or framebuffer apertures. In other cases, 1 MTRR is used to mark non-physical ram as Uncached (which covers both apertures). When trying to mark the appropriate apertures as WC, the kernel refuses to overlap the MTRRs.
Windows works around this MTRR issue by using the PATs.
An example of such a report recently sent to lkml is here:
http://www.ussg.iu.edu/hypermail/linux/kernel/0303.1/0606.html
I discussed this some with Jeff Hartmann, who had some initial development code that was integrated into agpgart, for marking agp pages WC as they were allocated. I think it would be preferable to have pat support seperate from agpgart. In that way, other drivers could make use of PAT support for other means (such as mapping the framebuffer). Jeff Hartmann sent us a pass at adding PAT support to agpgart. We've modified his code slightly to be more generic (standalone from agpgart) and usable via the traditional __pgprot() macros (and therefore with the change_page_attr() function).
Please cc me on any responses, as I'm not on the list.
Thanks,
Terence
arch/i386/config.in +4 -0
@@ -103,6 +103,7 @@ define_bool CONFIG_X86_USE_PPRO_CHECKSUM y define_bool CONFIG_X86_PPRO_FENCE y define_bool CONFIG_X86_F00F_WORKS_OK y + define_bool CONFIG_X86_PAT y fi if [ "$CONFIG_MPENTIUMIII" = "y" ]; then define_int CONFIG_X86_L1_CACHE_SHIFT 5
@@ -111,6 +112,7 @@ define_bool CONFIG_X86_PGE y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y define_bool CONFIG_X86_F00F_WORKS_OK y + define_bool CONFIG_X86_PAT y fi if [ "$CONFIG_MPENTIUM4" = "y" ]; then define_int CONFIG_X86_L1_CACHE_SHIFT 7
@@ -119,6 +121,7 @@ define_bool CONFIG_X86_PGE y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y define_bool CONFIG_X86_F00F_WORKS_OK y + define_bool CONFIG_X86_PAT y fi if [ "$CONFIG_MK6" = "y" ]; then define_int CONFIG_X86_L1_CACHE_SHIFT 5
@@ -134,6 +137,7 @@ define_bool CONFIG_X86_PGE y define_bool CONFIG_X86_USE_PPRO_CHECKSUM y define_bool CONFIG_X86_F00F_WORKS_OK y + define_bool CONFIG_X86_PAT y fi if [ "$CONFIG_MELAN" = "y" ]; then define_int CONFIG_X86_L1_CACHE_SHIFT 4
arch/i386/kernel/Makefile +1 -0
@@ -40,5 +40,6 @@ obj-$(CONFIG_X86_LOCAL_APIC) += mpparse.o apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o acpitable.o obj-$(CONFIG_X86_VISWS_APIC) += visws_apic.o +obj-$(CONFIG_X86_PAT) += pat.o include $(TOPDIR)/Rules.make
arch/i386/kernel/pat.c +97 -0
97 lines not on this page · raw message
Binary files linux-2.4.20/include/asm-i386/.pat.h.swp and linux-2.4.20-pat/include/asm-i386/.pat.h.swp differ
include/asm-i386/pat.h +78 -0
78 lines not on this page · raw message
include/asm-i386/pgtable.h +6 -0
@@ -194,6 +194,9 @@#define _PAGE_PSE 0x080/* 4 MB (or 2MB) page, Pentium+, if present.. */ #define _PAGE_GLOBAL 0x100/* Global TLB entry PPro+ */ +/* Added define for write combining page, only valid if pat enabled. */ +#define _PAGE_WRTCOMB _PAGE_PWT +#define _PAGE_PROTNONE 0x080/* If not present */ #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
@@ -207,6 +210,8 @@#define __PAGE_KERNEL \ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) +#define __PAGE_KERNEL_WRTCOMB \ + (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_WRTCOMB | _PAGE_ACCESSED)#define __PAGE_KERNEL_NOCACHE \ (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_PCD | _PAGE_ACCESSED)#define __PAGE_KERNEL_RO \
@@ -229,6 +234,7 @@#define PAGE_KERNEL MAKE_GLOBAL(__PAGE_KERNEL)#define PAGE_KERNEL_RO MAKE_GLOBAL(__PAGE_KERNEL_RO) +#define PAGE_KERNEL_WRTCOMB MAKE_GLOBAL(__PAGE_KERNEL_WRTCOMB)#define PAGE_KERNEL_NOCACHE MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)/*
init/main.c +12 -0
@@ -52,6 +52,10 @@# include <asm/mtrr.h> #endif +#ifdef CONFIG_X86_PAT +#include <asm/pat.h> +#endif +#ifdef CONFIG_NUBUS #include <linux/nubus.h> #endif
@@ -480,6 +484,14 @@mtrr_init ();#endif +#if defined(CONFIG_X86_PAT ) +/* +* Initialize PAT support on all configured CPUs. This should be +* in an architecture specific file (x86, x86-64). +*/ +pat_global_setup (); +#endif +#ifdef CONFIG_SYSCTL sysctl_init ();#endif
Quoted 3 lines · Terence Ripperda <[email protected]>, <[email protected]> writes:
Hello all,
I've discussed adding Page Attribute Table (PAT) support to the kernel w/ a few developers offline. They were very supportive and suggested I bring the discussion to lkml so others could get involved.
Not that I disagre with utilising the PAT, but I don't see anything in this code to deal with the widespread PAT indexing erratum in Intel's processors. I don't have the errata sheets here, but it definitely affected the PIIIs and I think also some P4s. (Large pages ignoring PAT index bit 2, or something like that.)
/Mikael
Thanks Mikael,
I was unaware of the errata, I'll check into that.
Terence
Quoted 11 lines · On Tue, May 20, 2003 at 09:30:35PM +0200, [email protected] wrote:
Quoted 3 lines · Terence Ripperda <[email protected]>, <[email protected]> writes:
Hello all,
I've discussed adding Page Attribute Table (PAT) support to the kernel w/ a few developers offline. They were very supportive and suggested I bring the discussion to lkml so others could get involved.
Not that I disagre with utilising the PAT, but I don't see anything in this code to deal with the widespread PAT indexing erratum in Intel's processors. I don't have the errata sheets here, but it definitely affected the PIIIs and I think also some P4s. (Large pages ignoring PAT index bit 2, or something like that.)
/Mikael