Module Name: src Committed By: cegger Date: Sat Apr 18 08:51:46 UTC 2009
Modified Files: src/sys/arch/x86/include: pmap.h src/sys/arch/x86/x86: bus_dma.c pmap.c Log Message: Introduce PMAP_NOCACHE as first PMAP MD bit in x86. Make use of it in pmap_enter(). This safes one extra TLB flush when mapping dma-safe memory. Presented on tech-kern@, port-i386@ and port-amd64@ ok ad@ To generate a diff of this commit: cvs rdiff -u -r1.22 -r1.23 src/sys/arch/x86/include/pmap.h cvs rdiff -u -r1.49 -r1.50 src/sys/arch/x86/x86/bus_dma.c cvs rdiff -u -r1.82 -r1.83 src/sys/arch/x86/x86/pmap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/include/pmap.h diff -u src/sys/arch/x86/include/pmap.h:1.22 src/sys/arch/x86/include/pmap.h:1.23 --- src/sys/arch/x86/include/pmap.h:1.22 Sat Mar 21 14:41:30 2009 +++ src/sys/arch/x86/include/pmap.h Sat Apr 18 08:51:45 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.h,v 1.22 2009/03/21 14:41:30 ad Exp $ */ +/* $NetBSD: pmap.h,v 1.23 2009/04/18 08:51:45 cegger Exp $ */ /* * @@ -176,6 +176,11 @@ #endif /* + * MD flags that we use for pmap_enter: + */ +#define PMAP_NOCACHE 0x00000100 /* set the non-cacheable bit */ + +/* * global kernel variables */ Index: src/sys/arch/x86/x86/bus_dma.c diff -u src/sys/arch/x86/x86/bus_dma.c:1.49 src/sys/arch/x86/x86/bus_dma.c:1.50 --- src/sys/arch/x86/x86/bus_dma.c:1.49 Sat Mar 14 14:46:08 2009 +++ src/sys/arch/x86/x86/bus_dma.c Sat Apr 18 08:51:45 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: bus_dma.c,v 1.49 2009/03/14 14:46:08 dsl Exp $ */ +/* $NetBSD: bus_dma.c,v 1.50 2009/04/18 08:51:45 cegger Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2007 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.49 2009/03/14 14:46:08 dsl Exp $"); +__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.50 2009/04/18 08:51:45 cegger Exp $"); /* * The following is included because _bus_dma_uiomove is derived from @@ -1017,26 +1017,23 @@ _bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, size_t size, void **kvap, int flags) { - vaddr_t sva, va, eva; + vaddr_t va; bus_addr_t addr; int curseg; - int nocache; - pt_entry_t *pte, opte, xpte; const uvm_flag_t kmflags = (flags & BUS_DMA_NOWAIT) != 0 ? UVM_KMF_NOWAIT : 0; + int pmapflags = PMAP_WIRED | VM_PROT_READ | VM_PROT_WRITE; size = round_page(size); - nocache = (flags & BUS_DMA_NOCACHE) != 0; + if (flags & BUS_DMA_NOCACHE) + pmapflags |= PMAP_NOCACHE; va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY | kmflags); if (va == 0) - return (ENOMEM); + return ENOMEM; *kvap = (void *)va; - sva = va; - eva = sva + size; - xpte = 0; for (curseg = 0; curseg < nsegs; curseg++) { for (addr = segs[curseg].ds_addr; @@ -1046,30 +1043,12 @@ panic("_bus_dmamem_map: size botch"); _BUS_PMAP_ENTER(pmap_kernel(), va, addr, VM_PROT_READ | VM_PROT_WRITE, - PMAP_WIRED | VM_PROT_READ | VM_PROT_WRITE); - /* - * mark page as non-cacheable - */ - if (nocache) { - pte = kvtopte(va); - opte = *pte; - if ((opte & PG_N) == 0) { - pmap_pte_setbits(pte, PG_N); - xpte |= opte; - } - } + pmapflags); } } -#ifndef XEN /* XXX */ - if ((xpte & (PG_V | PG_U)) == (PG_V | PG_U)) { - kpreempt_disable(); - pmap_tlb_shootdown(pmap_kernel(), sva, eva, xpte); - kpreempt_enable(); - } pmap_update(pmap_kernel()); -#endif - return (0); + return 0; } /* Index: src/sys/arch/x86/x86/pmap.c diff -u src/sys/arch/x86/x86/pmap.c:1.82 src/sys/arch/x86/x86/pmap.c:1.83 --- src/sys/arch/x86/x86/pmap.c:1.82 Sat Mar 21 22:55:08 2009 +++ src/sys/arch/x86/x86/pmap.c Sat Apr 18 08:51:45 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.82 2009/03/21 22:55:08 ad Exp $ */ +/* $NetBSD: pmap.c,v 1.83 2009/04/18 08:51:45 cegger Exp $ */ /* * Copyright (c) 2007 Manuel Bouyer. @@ -154,7 +154,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.82 2009/03/21 22:55:08 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.83 2009/04/18 08:51:45 cegger Exp $"); #include "opt_user_ldt.h" #include "opt_lockdebug.h" @@ -4044,6 +4044,8 @@ npte = ma | protection_codes[prot] | PG_V; 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)