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 */