Module Name:    src
Committed By:   cegger
Date:           Tue Jul  6 20:50:36 UTC 2010

Modified Files:
        src/share/man/man9: pmap.9
        src/sys/arch/amd64/include: pte.h
        src/sys/arch/hppa/include: pmap.h
        src/sys/arch/i386/include: pte.h
        src/sys/arch/mips/include: pmap.h
        src/sys/arch/mips/mips: pmap.c
        src/sys/arch/sgimips/sgimips: bus.c
        src/sys/arch/x86/include: cpuvar.h pmap.h specialreg.h
        src/sys/arch/x86/x86: bus_space.c cpu.c pmap.c
        src/sys/arch/xen/x86: cpu.c
Added Files:
        src/sys/arch/x86/include: pte.h

Log Message:
Turn PMAP_NOCACHE into MI flag.
Add MI flags PMAP_WRITE_COMBINE, PMAP_WRITE_BACK, PMAP_NOCACHE_OVR.
Update pmap(9) manpage.

hppa: Remove MD PMAP_NOCACHE flag as it exists as MI flag
mips: Rename MD PMAP_NOCACHE to PGC_NOCACHE.

x86: Implement new MI flags using Page-Attribute Tables.
x86: Implement BUS_SPACE_MAP_PREFETCHABLE.

Patch presented on tech-kern@:
http://mail-index.netbsd.org/tech-kern/2010/06/30/msg008458.html

No comments on this last version.


To generate a diff of this commit:
cvs rdiff -u -r1.42 -r1.43 src/share/man/man9/pmap.9
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/amd64/include/pte.h
cvs rdiff -u -r1.27 -r1.28 src/sys/arch/hppa/include/pmap.h
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/i386/include/pte.h
cvs rdiff -u -r1.57 -r1.58 src/sys/arch/mips/include/pmap.h
cvs rdiff -u -r1.188 -r1.189 src/sys/arch/mips/mips/pmap.c
cvs rdiff -u -r1.59 -r1.60 src/sys/arch/sgimips/sgimips/bus.c
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/x86/include/cpuvar.h
cvs rdiff -u -r1.30 -r1.31 src/sys/arch/x86/include/pmap.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/x86/include/pte.h
cvs rdiff -u -r1.41 -r1.42 src/sys/arch/x86/include/specialreg.h
cvs rdiff -u -r1.29 -r1.30 src/sys/arch/x86/x86/bus_space.c
cvs rdiff -u -r1.70 -r1.71 src/sys/arch/x86/x86/cpu.c
cvs rdiff -u -r1.109 -r1.110 src/sys/arch/x86/x86/pmap.c
cvs rdiff -u -r1.45 -r1.46 src/sys/arch/xen/x86/cpu.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/share/man/man9/pmap.9
diff -u src/share/man/man9/pmap.9:1.42 src/share/man/man9/pmap.9:1.43
--- src/share/man/man9/pmap.9:1.42	Mon Mar 22 18:58:33 2010
+++ src/share/man/man9/pmap.9	Tue Jul  6 20:50:33 2010
@@ -1,4 +1,4 @@
-.\"	$NetBSD: pmap.9,v 1.42 2010/03/22 18:58:33 joerg Exp $
+.\"	$NetBSD: pmap.9,v 1.43 2010/07/06 20:50:33 cegger Exp $
 .\"
 .\" Copyright (c) 2000, 2001, 2002 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -486,8 +486,23 @@
 .Nm
 module must panic.
 .It PMAP_NOCACHE
-The mapping being created is not cached.
+The mapping being created is
+.Em not
+cached.
 Write accesses have a write-through policy.
+No speculative memory accesses.
+.It PMAP_WRITE_COMBINE
+The mapping being created is
+.Em not
+cached.
+Writes are combined and done in one burst.
+Speculative read accesses may be allowed.
+.It PMAP_WRITE_BACK
+All accesses to the created mapping are cached.
+On reads, cachelines become shared or exclusive if allocated on cache miss.
+On writes, cachelines become modified on a cache miss.
+.It PMAP_NOCACHE_OVR
+Same as PMAP_NOCACHE but mapping is overrideable (e.g. on x86 by MTRRs).
 .El
 .Pp
 The access type provided in the
@@ -633,6 +648,19 @@
 .Em not
 cached.
 Write accesses have a write-through policy.
+No speculative memory accesses.
+.It PMAP_WRITE_COMBINE
+The mapping being created is
+.Em not
+cached.
+Writes are combined and done in one burst.
+Speculative read accesses may be allowed.
+.It PMAP_WRITE_BACK
+All accesses to the created mapping are cached.
+On reads, cachelines become shared or exclusive if allocated on cache miss.
+On writes, cachelines become modified on a cache miss.
+.It PMAP_NOCACHE_OVR
+Same as PMAP_NOCACHE but mapping is overrideable (e.g. on x86 by MTRRs).
 .El
 .Pp
 Mappings of this type are always

Index: src/sys/arch/amd64/include/pte.h
diff -u src/sys/arch/amd64/include/pte.h:1.6 src/sys/arch/amd64/include/pte.h:1.7
--- src/sys/arch/amd64/include/pte.h:1.6	Fri Feb 26 19:25:07 2010
+++ src/sys/arch/amd64/include/pte.h	Tue Jul  6 20:50:34 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pte.h,v 1.6 2010/02/26 19:25:07 jym Exp $	*/
+/*	$NetBSD: pte.h,v 1.7 2010/07/06 20:50:34 cegger Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -105,18 +105,23 @@
 #define	PG_RW		0x0000000000000002	/* read-write */
 #define	PG_u		0x0000000000000004	/* user accessible */
 #define	PG_PROT		0x0000000000000006
-#define	PG_N		0x0000000000000018	/* non-cacheable */
+#define PG_WT		0x0000000000000008	/* write-through */
+#define	PG_N		0x0000000000000010	/* non-cacheable */
 #define	PG_U		0x0000000000000020	/* used */
 #define	PG_M		0x0000000000000040	/* modified */
-#define PG_PS		0x0000000000000080	/* 2MB page size */
+#define PG_PAT		0x0000000000000080	/* PAT (on pte) */
+#define PG_PS		0x0000000000000080	/* 2MB page size (on pde) */
 #define PG_G		0x0000000000000100	/* not flushed */
 #define PG_AVAIL1	0x0000000000000200
 #define PG_AVAIL2	0x0000000000000400
 #define PG_AVAIL3	0x0000000000000800
+#define PG_LGPAT	0x0000000000001000	/* PAT on large pages */
 #define	PG_FRAME	0x000ffffffffff000
 #define	PG_NX		0x8000000000000000
 
-#define	PG_LGFRAME	0x000fffffffe00000	/* large (2M) page frame mask */
+#define PG_2MFRAME	0x000fffffffe00000	/* large (2M) page frame mask */
+#define PG_1GFRAME	0x000fffffc0000000	/* large (1G) page frame mask */
+#define	PG_LGFRAME	PG_2MFRAME
 
 /*
  * short forms of protection codes
@@ -125,13 +130,6 @@
 #define	PG_KR		0x0000000000000000	/* kernel read-only */
 #define	PG_KW		0x0000000000000002	/* kernel read-write */
 
-/*
- * page protection exception bits
- */
-
-#define PGEX_P		0x01	/* protection violation (vs. no mapping) */
-#define PGEX_W		0x02	/* exception during a write cycle */
-#define PGEX_U		0x04	/* exception while in user mode (upl) */
-#define PGEX_X		0x10	/* exception during instruction fetch */
+#include <x86/pte.h>
 
 #endif /* _AMD64_PTE_H_ */

Index: src/sys/arch/hppa/include/pmap.h
diff -u src/sys/arch/hppa/include/pmap.h:1.27 src/sys/arch/hppa/include/pmap.h:1.28
--- src/sys/arch/hppa/include/pmap.h:1.27	Mon Jun 21 14:43:34 2010
+++ src/sys/arch/hppa/include/pmap.h	Tue Jul  6 20:50:34 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.h,v 1.27 2010/06/21 14:43:34 skrll Exp $	*/
+/*	$NetBSD: pmap.h,v 1.28 2010/07/06 20:50:34 cegger Exp $	*/
 
 /*	$OpenBSD: pmap.h,v 1.35 2007/12/14 18:32:23 deraadt Exp $	*/
 
@@ -192,11 +192,6 @@
 	((((va) & 0xc0000000) != 0xc0000000) ? \
 	 (pmap)->pm_space : HPPA_SID_KERNEL)
 
-/*
- * MD flags that we use for pmap_kenter_pa:
- */
-#define	PMAP_NOCACHE	0x01000000	/* set the non-cacheable bit */
-
 #endif /* _KERNEL */
 
 #endif /* _HPPA_PMAP_H_ */

Index: src/sys/arch/i386/include/pte.h
diff -u src/sys/arch/i386/include/pte.h:1.23 src/sys/arch/i386/include/pte.h:1.24
--- src/sys/arch/i386/include/pte.h:1.23	Tue May  4 23:27:14 2010
+++ src/sys/arch/i386/include/pte.h	Tue Jul  6 20:50:34 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pte.h,v 1.23 2010/05/04 23:27:14 jym Exp $	*/
+/*	$NetBSD: pte.h,v 1.24 2010/07/06 20:50:34 cegger Exp $	*/
 
 /*
  * Copyright (c) 2001 Wasabi Systems, Inc.
@@ -218,7 +218,9 @@
 /* macros to get real L2 and L3 index, from our "extended" L2 index */
 #define l2tol3(idx)	((idx) >> (L3_SHIFT - L2_SHIFT))
 #define l2tol2(idx)	((idx) & (L2_REALMASK >>  L2_SHIFT))
+
 #else /* PAE */
+
 #define	L1_SHIFT	12
 #define	L2_SHIFT	22
 #define	NBPD_L1		(1UL << L1_SHIFT) /* # bytes mapped by L1 ent (4K) */
@@ -245,14 +247,17 @@
 #define	PG_RW		0x00000002	/* read-write page */
 #define	PG_u		0x00000004	/* user accessible page */
 #define	PG_PROT		0x00000806	/* all protection bits */
-#define	PG_N		0x00000018	/* non-cacheable */
+#define PG_WT		0x00000008	/* write through */
+#define	PG_N		0x00000010	/* non-cacheable */
 #define	PG_U		0x00000020	/* has been used */
 #define	PG_M		0x00000040	/* has been modified */
+#define PG_PAT		0x00000080	/* PAT (on pte) */
 #define PG_PS		0x00000080	/* 4MB page size */
 #define PG_G		0x00000100	/* global, don't TLB flush */
 #define PG_AVAIL1	0x00000200	/* ignored by hardware */
 #define PG_AVAIL2	0x00000400	/* ignored by hardware */
 #define PG_AVAIL3	0x00000800	/* ignored by hardware */
+#define PG_LGPAT	0x00001000	/* PAT on large pages */
 
 /*
  * various short-hand protection codes
@@ -267,13 +272,6 @@
 #define	PG_NX		0		/* dummy */
 #endif
 
-/*
- * page protection exception bits
- */
-
-#define PGEX_P		0x01	/* protection violation (vs. no mapping) */
-#define PGEX_W		0x02	/* exception during a write cycle */
-#define PGEX_U		0x04	/* exception while in user mode (upl) */
-#define PGEX_X		0x10	/* exception during instruction fetch */
+#include <x86/pte.h>
 
 #endif /* _I386_PTE_H_ */

Index: src/sys/arch/mips/include/pmap.h
diff -u src/sys/arch/mips/include/pmap.h:1.57 src/sys/arch/mips/include/pmap.h:1.58
--- src/sys/arch/mips/include/pmap.h:1.57	Mon Dec 14 00:46:05 2009
+++ src/sys/arch/mips/include/pmap.h	Tue Jul  6 20:50:34 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.h,v 1.57 2009/12/14 00:46:05 matt Exp $	*/
+/*	$NetBSD: pmap.h,v 1.58 2010/07/06 20:50:34 cegger Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -202,7 +202,7 @@
 #define	PMAP_CCA_FOR_PA(pa)	CCA_UNCACHED		/* uncached */
 
 #if defined(_MIPS_PADDR_T_64BIT) || defined(_LP64)
-#define PMAP_NOCACHE	0x4000000000000000ULL
+#define PGC_NOCACHE	0x4000000000000000ULL
 #endif
 
 #endif	/* _KERNEL */

Index: src/sys/arch/mips/mips/pmap.c
diff -u src/sys/arch/mips/mips/pmap.c:1.188 src/sys/arch/mips/mips/pmap.c:1.189
--- src/sys/arch/mips/mips/pmap.c:1.188	Mon Dec 14 00:46:07 2009
+++ src/sys/arch/mips/mips/pmap.c	Tue Jul  6 20:50:34 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.188 2009/12/14 00:46:07 matt Exp $	*/
+/*	$NetBSD: pmap.c,v 1.189 2010/07/06 20:50:34 cegger Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.188 2009/12/14 00:46:07 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.189 2010/07/06 20:50:34 cegger Exp $");
 
 /*
  *	Manages physical address maps.
@@ -1177,9 +1177,12 @@
 #endif
 
 #if defined(_MIPS_PADDR_T_64BIT) || defined(_LP64)
-	if (pa & PMAP_NOCACHE) {
+	if (flags & PMAP_NOCACHE) {
 		cached = 0;
-		pa &= ~PMAP_NOCACHE;
+		pa &= ~PGC_NOCACHE;
+	} else {
+		cached = 1;
+		pa |= PGC_NOCACHE;
 	}
 #endif
 

Index: src/sys/arch/sgimips/sgimips/bus.c
diff -u src/sys/arch/sgimips/sgimips/bus.c:1.59 src/sys/arch/sgimips/sgimips/bus.c:1.60
--- src/sys/arch/sgimips/sgimips/bus.c:1.59	Thu Dec 17 03:59:31 2009
+++ src/sys/arch/sgimips/sgimips/bus.c	Tue Jul  6 20:50:35 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: bus.c,v 1.59 2009/12/17 03:59:31 macallan Exp $	*/
+/*	$NetBSD: bus.c,v 1.60 2010/07/06 20:50:35 cegger Exp $	*/
 
 /*
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bus.c,v 1.59 2009/12/17 03:59:31 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bus.c,v 1.60 2010/07/06 20:50:35 cegger Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1116,6 +1116,7 @@
 	int curseg;
 	const uvm_flag_t kmflags =
 	    (flags & BUS_DMA_NOWAIT) != 0 ? UVM_KMF_NOWAIT : 0;
+	u_int pmapflags;
 
 	/*
 	 * If we're only mapping 1 segment, use KSEG0 or KSEG1, to avoid
@@ -1139,21 +1140,19 @@
 
 	*kvap = (void *)va;
 
+	pmapflags = VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED;
+	if (flags & BUS_DMA_COHERENT)
+		pmapflags |= PMAP_NOCACHE;
+
 	for (curseg = 0; curseg < nsegs; curseg++) {
 		for (addr = segs[curseg].ds_addr;
 		    addr < (segs[curseg].ds_addr + segs[curseg].ds_len);
 		    addr += PAGE_SIZE, va += PAGE_SIZE, size -= PAGE_SIZE) {
 			if (size == 0)
 				panic("_bus_dmamem_map: size botch");
-			pmap_enter(pmap_kernel(), va, 
-#if defined(_MIPS_PADDR_T_64BIT) || defined(_LP64)
-			    (flags & BUS_DMA_COHERENT) ?
-			      addr | PMAP_NOCACHE : addr,
-#else
-			    addr,
-#endif
+			pmap_enter(pmap_kernel(), va, addr,
 			    VM_PROT_READ | VM_PROT_WRITE,
-			    VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED);
+			    pmapflags);
 		}
 	}
 	pmap_update(pmap_kernel());

Index: src/sys/arch/x86/include/cpuvar.h
diff -u src/sys/arch/x86/include/cpuvar.h:1.32 src/sys/arch/x86/include/cpuvar.h:1.33
--- src/sys/arch/x86/include/cpuvar.h:1.32	Sun Apr 18 23:47:51 2010
+++ src/sys/arch/x86/include/cpuvar.h	Tue Jul  6 20:50:35 2010
@@ -1,4 +1,4 @@
-/* 	$NetBSD: cpuvar.h,v 1.32 2010/04/18 23:47:51 jym Exp $ */
+/* 	$NetBSD: cpuvar.h,v 1.33 2010/07/06 20:50:35 cegger Exp $ */
 
 /*-
  * Copyright (c) 2000, 2007 The NetBSD Foundation, Inc.
@@ -140,12 +140,13 @@
 #endif
 
 void	cpu_get_tsc_freq(struct cpu_info *);
+void	pat_init(struct cpu_info *);
 
 extern int cpu_vendor;
 extern bool x86_mp_online;
 
 extern uint32_t cpu_feature[5];
 
-#endif
+#endif /* _KERNEL */
 
 #endif /* !_X86_CPUVAR_H_ */

Index: src/sys/arch/x86/include/pmap.h
diff -u src/sys/arch/x86/include/pmap.h:1.30 src/sys/arch/x86/include/pmap.h:1.31
--- src/sys/arch/x86/include/pmap.h:1.30	Mon May 10 18:46:58 2010
+++ src/sys/arch/x86/include/pmap.h	Tue Jul  6 20:50:35 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.h,v 1.30 2010/05/10 18:46:58 dyoung Exp $	*/
+/*	$NetBSD: pmap.h,v 1.31 2010/07/06 20:50:35 cegger Exp $	*/
 
 /*
  *
@@ -178,7 +178,6 @@
 /*
  * MD flags that we use for pmap_enter and pmap_kenter_pa:
  */
-#define PMAP_NOCACHE	0x01000000	/* set the non-cacheable bit */
 
 /*
  * global kernel variables

Index: src/sys/arch/x86/include/specialreg.h
diff -u src/sys/arch/x86/include/specialreg.h:1.41 src/sys/arch/x86/include/specialreg.h:1.42
--- src/sys/arch/x86/include/specialreg.h:1.41	Tue May  4 23:27:14 2010
+++ src/sys/arch/x86/include/specialreg.h	Tue Jul  6 20:50:35 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: specialreg.h,v 1.41 2010/05/04 23:27:14 jym Exp $	*/
+/*	$NetBSD: specialreg.h,v 1.42 2010/07/06 20:50:35 cegger Exp $	*/
 
 /*-
  * Copyright (c) 1991 The Regents of the University of California.
@@ -343,6 +343,7 @@
 #define	MSR_MTRRfix4K_E8000	0x26d
 #define	MSR_MTRRfix4K_F0000	0x26e
 #define	MSR_MTRRfix4K_F8000	0x26f
+#define	MSR_CR_PAT		0x277
 #define MSR_MTRRdefType		0x2ff
 #define MSR_MC0_CTL		0x400
 #define MSR_MC0_STATUS		0x401

Index: src/sys/arch/x86/x86/bus_space.c
diff -u src/sys/arch/x86/x86/bus_space.c:1.29 src/sys/arch/x86/x86/bus_space.c:1.30
--- src/sys/arch/x86/x86/bus_space.c:1.29	Mon May 10 18:46:58 2010
+++ src/sys/arch/x86/x86/bus_space.c	Tue Jul  6 20:50:35 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: bus_space.c,v 1.29 2010/05/10 18:46:58 dyoung Exp $	*/
+/*	$NetBSD: bus_space.c,v 1.30 2010/07/06 20:50:35 cegger Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.29 2010/05/10 18:46:58 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.30 2010/07/06 20:50:35 cegger Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -199,8 +199,7 @@
 	 * For memory space, map the bus physical address to
 	 * a kernel virtual address.
 	 */
-	error = x86_mem_add_mapping(bpa, size,
-		(flags & BUS_SPACE_MAP_CACHEABLE) != 0, bshp);
+	error = x86_mem_add_mapping(bpa, size, flags, bshp);
 	if (error) {
 		if (extent_free(ex, bpa, size, EX_NOWAIT |
 		    (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
@@ -232,8 +231,7 @@
 	 * For memory space, map the bus physical address to
 	 * a kernel virtual address.
 	 */
-	return (x86_mem_add_mapping(bpa, size,
-	    (flags & BUS_SPACE_MAP_CACHEABLE) != 0, bshp));
+	return x86_mem_add_mapping(bpa, size, flags, bshp);
 }
 
 int
@@ -286,8 +284,7 @@
 	 * For memory space, map the bus physical address to
 	 * a kernel virtual address.
 	 */
-	error = x86_mem_add_mapping(bpa, size,
-	    (flags & BUS_SPACE_MAP_CACHEABLE) != 0, bshp);
+	error = x86_mem_add_mapping(bpa, size, flags, bshp);
 	if (error) {
 		if (extent_free(iomem_ex, bpa, size, EX_NOWAIT |
 		    (ioport_malloc_safe ? EX_MALLOCOK : 0))) {
@@ -304,17 +301,20 @@
 
 int
 x86_mem_add_mapping(bus_addr_t bpa, bus_size_t size,
-		int cacheable, bus_space_handle_t *bshp)
+		int flags, bus_space_handle_t *bshp)
 {
 	paddr_t pa, endpa;
 	vaddr_t va, sva;
-	u_int pmapflags = 0;
+	u_int pmapflags;
 
 	pa = x86_trunc_page(bpa);
 	endpa = x86_round_page(bpa + size);
 
-	if (!cacheable)
-		pmapflags |= PMAP_NOCACHE;
+	pmapflags = PMAP_NOCACHE;
+	if ((flags & BUS_SPACE_MAP_CACHEABLE) != 0)
+		pmapflags = 0;
+	else if (flags & BUS_SPACE_MAP_PREFETCHABLE)
+		pmapflags = PMAP_WRITE_COMBINE;
 
 #ifdef DIAGNOSTIC
 	if (endpa != 0 && endpa <= pa)

Index: src/sys/arch/x86/x86/cpu.c
diff -u src/sys/arch/x86/x86/cpu.c:1.70 src/sys/arch/x86/x86/cpu.c:1.71
--- src/sys/arch/x86/x86/cpu.c:1.70	Sun Apr 18 23:47:51 2010
+++ src/sys/arch/x86/x86/cpu.c	Tue Jul  6 20:50:35 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.70 2010/04/18 23:47:51 jym Exp $	*/
+/*	$NetBSD: cpu.c,v 1.71 2010/07/06 20:50:35 cegger Exp $	*/
 
 /*-
  * Copyright (c) 2000, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.70 2010/04/18 23:47:51 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.71 2010/07/06 20:50:35 cegger Exp $");
 
 #include "opt_ddb.h"
 #include "opt_mpbios.h"		/* for MPDEBUG */
@@ -424,6 +424,7 @@
 		panic("unknown processor type??\n");
 	}
 
+	pat_init(ci);
 	atomic_or_32(&cpus_attached, ci->ci_cpumask);
 
 	if (!pmf_device_register(self, cpu_suspend, cpu_resume))

Index: src/sys/arch/x86/x86/pmap.c
diff -u src/sys/arch/x86/x86/pmap.c:1.109 src/sys/arch/x86/x86/pmap.c:1.110
--- src/sys/arch/x86/x86/pmap.c:1.109	Mon May 10 18:46:58 2010
+++ src/sys/arch/x86/x86/pmap.c	Tue Jul  6 20:50:35 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.109 2010/05/10 18:46:58 dyoung Exp $	*/
+/*	$NetBSD: pmap.c,v 1.110 2010/07/06 20:50:35 cegger Exp $	*/
 
 /*
  * Copyright (c) 2007 Manuel Bouyer.
@@ -149,7 +149,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.109 2010/05/10 18:46:58 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.110 2010/07/06 20:50:35 cegger Exp $");
 
 #include "opt_user_ldt.h"
 #include "opt_lockdebug.h"
@@ -361,6 +361,20 @@
 struct pmap_mbox pmap_mbox __aligned(64);
 
 /*
+ * PAT
+ */
+#define	PATENTRY(n, type)	(type << ((n) * 8))
+#define	PAT_UC		0x0ULL
+#define	PAT_WC		0x1ULL
+#define	PAT_WT		0x4ULL
+#define	PAT_WP		0x5ULL
+#define	PAT_WB		0x6ULL
+#define	PAT_UCMINUS	0x7ULL
+
+static bool cpu_pat_enabled = false;
+
+
+/*
  * Per-CPU data.  The pmap mailbox is cache intensive so gets its
  * own line.  Note that the mailbox must be the first item.
  */
@@ -1004,6 +1018,57 @@
 }
 #endif /* !defined(__x86_64__) */
 
+void
+pat_init(struct cpu_info *ci)
+{
+	uint64_t pat;
+
+	if (!(ci->ci_feat_val[0] & CPUID_PAT))
+		return;
+
+	/* We change WT to WC. Leave all other entries the default values. */
+	pat = PATENTRY(0, PAT_WB) | PATENTRY(1, PAT_WC) |
+	      PATENTRY(2, PAT_UCMINUS) | PATENTRY(3, PAT_UC) |
+	      PATENTRY(4, PAT_WB) | PATENTRY(5, PAT_WC) |
+	      PATENTRY(6, PAT_UCMINUS) | PATENTRY(7, PAT_UC);
+
+	wrmsr(MSR_CR_PAT, pat);
+	cpu_pat_enabled = true;
+	aprint_debug_dev(ci->ci_dev, "PAT enabled\n");
+}
+
+static pt_entry_t
+pmap_pat_flags(u_int flags)
+{
+	u_int cacheflags = (flags & PMAP_CACHE_MASK);
+
+	if (!cpu_pat_enabled) {
+		switch (cacheflags) {
+		case PMAP_NOCACHE:
+		case PMAP_NOCACHE_OVR:
+			/* results in PGC_UCMINUS on cpus which have
+			 * the cpuid PAT but PAT "disabled"
+			 */
+			return PG_N;
+		default:
+			return 0;
+		}
+	}
+
+	switch (cacheflags) {
+	case PMAP_NOCACHE:
+		return PGC_UC;
+	case PMAP_WRITE_COMBINE:
+		return PGC_WC;
+	case PMAP_WRITE_BACK:
+		return PGC_WB;
+	case PMAP_NOCACHE_OVR:
+		return PGC_UCMINUS;
+	}
+
+	return 0;
+}
+
 /*
  * p m a p   k e n t e r   f u n c t i o n s
  *
@@ -1041,8 +1106,7 @@
 #endif /* DOM0OPS */
 		npte = pmap_pa2pte(pa);
 	npte |= protection_codes[prot] | PG_k | PG_V | pmap_pg_g;
-	if (flags & PMAP_NOCACHE)
-		npte |= PG_N;
+	npte |= pmap_pat_flags(flags);
 	opte = pmap_pte_testset(pte, npte); /* zap! */
 #if defined(DIAGNOSTIC)
 	/* XXX For now... */
@@ -3961,10 +4025,9 @@
 #endif /* XEN */
 
 	npte = ma | protection_codes[prot] | PG_V;
+	npte |= pmap_pat_flags(flags);
 	if (wired)
 	        npte |= PG_W;
-	if (flags & PMAP_NOCACHE)
-		npte |= PG_N;
 	if (va < VM_MAXUSER_ADDRESS)
 		npte |= PG_u;
 	else if (va < VM_MAX_ADDRESS)

Index: src/sys/arch/xen/x86/cpu.c
diff -u src/sys/arch/xen/x86/cpu.c:1.45 src/sys/arch/xen/x86/cpu.c:1.46
--- src/sys/arch/xen/x86/cpu.c:1.45	Mon Jun 28 00:47:53 2010
+++ src/sys/arch/xen/x86/cpu.c	Tue Jul  6 20:50:35 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.45 2010/06/28 00:47:53 rmind Exp $	*/
+/*	$NetBSD: cpu.c,v 1.46 2010/07/06 20:50:35 cegger Exp $	*/
 /* NetBSD: cpu.c,v 1.18 2004/02/20 17:35:01 yamt Exp  */
 
 /*-
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.45 2010/06/28 00:47:53 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.46 2010/07/06 20:50:35 cegger Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -517,6 +517,7 @@
 		panic("unknown processor type??\n");
 	}
 
+	pat_init(ci);
 	atomic_or_32(&cpus_attached, ci->ci_cpumask);
 
 #if 0

Added files:

Index: src/sys/arch/x86/include/pte.h
diff -u /dev/null src/sys/arch/x86/include/pte.h:1.1
--- /dev/null	Tue Jul  6 20:50:36 2010
+++ src/sys/arch/x86/include/pte.h	Tue Jul  6 20:50:35 2010
@@ -0,0 +1,50 @@
+/*	$NetBSD: pte.h,v 1.1 2010/07/06 20:50:35 cegger Exp $	*/
+
+/*
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christoph Egger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _X86_PTE_H
+#define _X86_PTE_H
+
+/* Cacheability bits when we are using PAT */
+#define PGC_WB          0               /* The default */
+#define PGC_WC          PG_WT           /* WT and CD is WC */
+#define PGC_UCMINUS     PG_N            /* UC but mtrr can override */
+#define PGC_UC          (PG_WT | PG_N)  /* hard UC */
+
+/*
+ * page protection exception bits
+ */
+
+#define PGEX_P		0x01	/* protection violation (vs. no mapping) */
+#define PGEX_W		0x02	/* exception during a write cycle */
+#define PGEX_U		0x04	/* exception while in user mode (upl) */
+#define PGEX_X		0x10	/* exception during instruction fetch */
+
+#endif /* _X86_PTE_H */

Reply via email to