Date: Sun, 2 Nov 2014 11:26:38 +0000 (UTC) From: Tijl Coosemans <tijl@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r273963 - head/sys/dev/agp Message-ID: <201411021126.sA2BQcx4053562@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tijl Date: Sun Nov 2 11:26:37 2014 New Revision: 273963 URL: https://svnweb.freebsd.org/changeset/base/273963 Log: In agp(4) avoid the need to flush all cpu caches with wbinvd between updating the GTT and flushing the AGP TLB by storing the GTT in write-combining memory. On x86 flushing the AGP TLB is done by an I/O operation or a store to a MMIO register in uncacheable memory. Both cases imply that WC buffers are flushed so no memory barriers are needed. On powerpc there is no WC memory type. It maps to uncacheable memory and two stores to uncacheable memory, such as to the GTT and then to an MMIO register, are strongly ordered, so no memory barriers are needed either. MFC after: 1 month Modified: head/sys/dev/agp/agp.c head/sys/dev/agp/agp_amd.c head/sys/dev/agp/agp_amd64.c head/sys/dev/agp/agp_apple.c head/sys/dev/agp/agp_ati.c head/sys/dev/agp/agp_i810.c head/sys/dev/agp/agppriv.h Modified: head/sys/dev/agp/agp.c ============================================================================== --- head/sys/dev/agp/agp.c Sun Nov 2 09:52:22 2014 (r273962) +++ head/sys/dev/agp/agp.c Sun Nov 2 11:26:37 2014 (r273963) @@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$"); #include <dev/pci/pcireg.h> #include <vm/vm.h> +#include <vm/vm_extern.h> +#include <vm/vm_kern.h> #include <vm/vm_param.h> #include <vm/vm_object.h> #include <vm/vm_page.h> @@ -84,14 +86,6 @@ static devclass_t agp_devclass; /* Helper functions for implementing chipset mini drivers. */ -void -agp_flush_cache() -{ -#if defined(__i386__) || defined(__amd64__) - wbinvd(); -#endif -} - u_int8_t agp_find_caps(device_t dev) { @@ -158,17 +152,16 @@ agp_alloc_gatt(device_t dev) return 0; gatt->ag_entries = entries; - gatt->ag_virtual = contigmalloc(entries * sizeof(u_int32_t), M_AGP, 0, - 0, ~0, PAGE_SIZE, 0); + gatt->ag_virtual = (void *)kmem_alloc_contig(kernel_arena, + entries * sizeof(u_int32_t), M_NOWAIT | M_ZERO, 0, ~0, PAGE_SIZE, + 0, VM_MEMATTR_WRITE_COMBINING); if (!gatt->ag_virtual) { if (bootverbose) device_printf(dev, "contiguous allocation failed\n"); free(gatt, M_AGP); return 0; } - bzero(gatt->ag_virtual, entries * sizeof(u_int32_t)); gatt->ag_physical = vtophys((vm_offset_t) gatt->ag_virtual); - agp_flush_cache(); return gatt; } @@ -176,8 +169,8 @@ agp_alloc_gatt(device_t dev) void agp_free_gatt(struct agp_gatt *gatt) { - contigfree(gatt->ag_virtual, - gatt->ag_entries * sizeof(u_int32_t), M_AGP); + kmem_free(kernel_arena, (vm_offset_t)gatt->ag_virtual, + gatt->ag_entries * sizeof(u_int32_t)); free(gatt, M_AGP); } @@ -280,7 +273,6 @@ agp_free_res(device_t dev) bus_release_resource(dev, SYS_RES_MEMORY, sc->as_aperture_rid, sc->as_aperture); mtx_destroy(&sc->as_lock); - agp_flush_cache(); } int @@ -605,12 +597,6 @@ agp_generic_bind_memory(device_t dev, st VM_OBJECT_WUNLOCK(mem->am_obj); /* - * Flush the cpu cache since we are providing a new mapping - * for these pages. - */ - agp_flush_cache(); - - /* * Make sure the chipset gets the new mappings. */ AGP_FLUSH_TLB(dev); @@ -668,7 +654,6 @@ agp_generic_unbind_memory(device_t dev, } VM_OBJECT_WUNLOCK(mem->am_obj); - agp_flush_cache(); AGP_FLUSH_TLB(dev); mem->am_offset = 0; @@ -1040,7 +1025,6 @@ agp_bind_pages(device_t dev, vm_page_t * } } - agp_flush_cache(); AGP_FLUSH_TLB(dev); mtx_unlock(&sc->as_lock); @@ -1063,7 +1047,6 @@ agp_unbind_pages(device_t dev, vm_size_t for (i = 0; i < size; i += AGP_PAGE_SIZE) AGP_UNBIND_PAGE(dev, offset + i); - agp_flush_cache(); AGP_FLUSH_TLB(dev); mtx_unlock(&sc->as_lock); Modified: head/sys/dev/agp/agp_amd.c ============================================================================== --- head/sys/dev/agp/agp_amd.c Sun Nov 2 09:52:22 2014 (r273962) +++ head/sys/dev/agp/agp_amd.c Sun Nov 2 11:26:37 2014 (r273963) @@ -43,6 +43,8 @@ __FBSDID("$FreeBSD$"); #include <dev/pci/pcireg.h> #include <vm/vm.h> +#include <vm/vm_extern.h> +#include <vm/vm_kern.h> #include <vm/vm_object.h> #include <vm/pmap.h> #include <machine/bus.h> @@ -92,34 +94,35 @@ agp_amd_alloc_gatt(device_t dev) /* * The AMD751 uses a page directory to map a non-contiguous - * gatt so we don't need to use contigmalloc. - * Malloc individual gatt pages and map them into the page + * gatt so we don't need to use kmem_alloc_contig. + * Allocate individual GATT pages and map them into the page * directory. */ gatt->ag_entries = entries; - gatt->ag_virtual = malloc(entries * sizeof(u_int32_t), - M_AGP, M_NOWAIT); + gatt->ag_virtual = (void *)kmem_alloc_attr(kernel_arena, + entries * sizeof(u_int32_t), M_NOWAIT | M_ZERO, 0, ~0, + VM_MEMATTR_WRITE_COMBINING); if (!gatt->ag_virtual) { if (bootverbose) device_printf(dev, "allocation failed\n"); free(gatt, M_AGP); return 0; } - bzero(gatt->ag_virtual, entries * sizeof(u_int32_t)); /* * Allocate the page directory. */ - gatt->ag_vdir = malloc(AGP_PAGE_SIZE, M_AGP, M_NOWAIT); + gatt->ag_vdir = (void *)kmem_alloc_attr(kernel_arena, AGP_PAGE_SIZE, + M_NOWAIT | M_ZERO, 0, ~0, VM_MEMATTR_WRITE_COMBINING); if (!gatt->ag_vdir) { if (bootverbose) device_printf(dev, "failed to allocate page directory\n"); - free(gatt->ag_virtual, M_AGP); + kmem_free(kernel_arena, (vm_offset_t)gatt->ag_virtual, + entries * sizeof(u_int32_t)); free(gatt, M_AGP); return 0; } - bzero(gatt->ag_vdir, AGP_PAGE_SIZE); gatt->ag_pdir = vtophys((vm_offset_t) gatt->ag_vdir); if(bootverbose) @@ -158,19 +161,15 @@ agp_amd_alloc_gatt(device_t dev) gatt->ag_vdir[i + pdir_offset] = pa | 1; } - /* - * Make sure the chipset can see everything. - */ - agp_flush_cache(); - return gatt; } static void agp_amd_free_gatt(struct agp_amd_gatt *gatt) { - free(gatt->ag_virtual, M_AGP); - free(gatt->ag_vdir, M_AGP); + kmem_free(kernel_arena, (vm_offset_t)gatt->ag_vdir, AGP_PAGE_SIZE); + kmem_free(kernel_arena, (vm_offset_t)gatt->ag_virtual, + gatt->ag_entries * sizeof(u_int32_t)); free(gatt, M_AGP); } Modified: head/sys/dev/agp/agp_amd64.c ============================================================================== --- head/sys/dev/agp/agp_amd64.c Sun Nov 2 09:52:22 2014 (r273962) +++ head/sys/dev/agp/agp_amd64.c Sun Nov 2 11:26:37 2014 (r273963) @@ -241,8 +241,6 @@ agp_amd64_attach(device_t dev) 4); } - agp_flush_cache(); - return (0); } Modified: head/sys/dev/agp/agp_apple.c ============================================================================== --- head/sys/dev/agp/agp_apple.c Sun Nov 2 09:52:22 2014 (r273962) +++ head/sys/dev/agp/agp_apple.c Sun Nov 2 11:26:37 2014 (r273963) @@ -224,8 +224,6 @@ agp_apple_bind_page(device_t dev, vm_off return EINVAL; sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = physical; - __asm __volatile("dcbst 0,%0; sync" :: - "r"(&sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT]) : "memory"); return (0); } @@ -238,8 +236,6 @@ agp_apple_unbind_page(device_t dev, vm_o return EINVAL; sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT] = 0; - __asm __volatile("dcbst 0,%0; sync" :: - "r"(&sc->gatt->ag_virtual[offset >> AGP_PAGE_SHIFT]) : "memory"); return (0); } Modified: head/sys/dev/agp/agp_ati.c ============================================================================== --- head/sys/dev/agp/agp_ati.c Sun Nov 2 09:52:22 2014 (r273962) +++ head/sys/dev/agp/agp_ati.c Sun Nov 2 11:26:37 2014 (r273963) @@ -45,6 +45,8 @@ __FBSDID("$FreeBSD$"); #include <dev/pci/pcireg.h> #include <vm/vm.h> +#include <vm/vm_extern.h> +#include <vm/vm_kern.h> #include <vm/vm_object.h> #include <vm/pmap.h> #include <machine/bus.h> @@ -129,20 +131,23 @@ agp_ati_alloc_gatt(device_t dev) /* Alloc the GATT -- pointers to pages of AGP memory */ sc->ag_entries = entries; - sc->ag_virtual = malloc(entries * sizeof(u_int32_t), M_AGP, - M_NOWAIT | M_ZERO); + sc->ag_virtual = (void *)kmem_alloc_attr(kernel_arena, + entries * sizeof(u_int32_t), M_NOWAIT | M_ZERO, 0, ~0, + VM_MEMATTR_WRITE_COMBINING); if (sc->ag_virtual == NULL) { if (bootverbose) - device_printf(dev, "aperture allocation failed\n"); + device_printf(dev, "GATT allocation failed\n"); return ENOMEM; } /* Alloc the page directory -- pointers to each page of the GATT */ - sc->ag_vdir = malloc(AGP_PAGE_SIZE, M_AGP, M_NOWAIT | M_ZERO); + sc->ag_vdir = (void *)kmem_alloc_attr(kernel_arena, AGP_PAGE_SIZE, + M_NOWAIT | M_ZERO, 0, ~0, VM_MEMATTR_WRITE_COMBINING); if (sc->ag_vdir == NULL) { if (bootverbose) device_printf(dev, "pagedir allocation failed\n"); - free(sc->ag_virtual, M_AGP); + kmem_free(kernel_arena, (vm_offset_t)sc->ag_virtual, + entries * sizeof(u_int32_t)); return ENOMEM; } sc->ag_pdir = vtophys((vm_offset_t)sc->ag_vdir); @@ -158,11 +163,6 @@ agp_ati_alloc_gatt(device_t dev) sc->ag_vdir[apbase_offset + i] = pa | 1; } - /* - * Make sure the chipset can see everything. - */ - agp_flush_cache(); - return 0; } @@ -264,8 +264,9 @@ agp_ati_detach(device_t dev) temp = pci_read_config(dev, apsize_reg, 4); pci_write_config(dev, apsize_reg, temp & ~1, 4); - free(sc->ag_vdir, M_AGP); - free(sc->ag_virtual, M_AGP); + kmem_free(kernel_arena, (vm_offset_t)sc->ag_vdir, AGP_PAGE_SIZE); + kmem_free(kernel_arena, (vm_offset_t)sc->ag_virtual, + sc->ag_entries * sizeof(u_int32_t)); bus_release_resource(dev, SYS_RES_MEMORY, ATI_GART_MMADDR, sc->regs); agp_free_res(dev); Modified: head/sys/dev/agp/agp_i810.c ============================================================================== --- head/sys/dev/agp/agp_i810.c Sun Nov 2 09:52:22 2014 (r273962) +++ head/sys/dev/agp/agp_i810.c Sun Nov 2 11:26:37 2014 (r273963) @@ -66,6 +66,8 @@ __FBSDID("$FreeBSD$"); #include <dev/pci/pci_private.h> #include <vm/vm.h> +#include <vm/vm_extern.h> +#include <vm/vm_kern.h> #include <vm/vm_param.h> #include <vm/vm_object.h> #include <vm/vm_page.h> @@ -1388,17 +1390,16 @@ agp_i810_install_gatt(device_t dev) sc->dcache_size = 0; /* According to the specs the gatt on the i810 must be 64k. */ - sc->gatt->ag_virtual = contigmalloc(64 * 1024, M_AGP, 0, 0, ~0, - PAGE_SIZE, 0); + sc->gatt->ag_virtual = (void *)kmem_alloc_contig(kernel_arena, + 64 * 1024, M_NOWAIT | M_ZERO, 0, ~0, PAGE_SIZE, + 0, VM_MEMATTR_WRITE_COMBINING); if (sc->gatt->ag_virtual == NULL) { if (bootverbose) device_printf(dev, "contiguous allocation failed\n"); return (ENOMEM); } - bzero(sc->gatt->ag_virtual, sc->gatt->ag_entries * sizeof(u_int32_t)); sc->gatt->ag_physical = vtophys((vm_offset_t)sc->gatt->ag_virtual); - agp_flush_cache(); /* Install the GATT. */ bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, sc->gatt->ag_physical | 1); @@ -1497,7 +1498,7 @@ agp_i810_deinstall_gatt(device_t dev) sc = device_get_softc(dev); bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, 0); - contigfree(sc->gatt->ag_virtual, 64 * 1024, M_AGP); + kmem_free(kernel_arena, (vm_offset_t)sc->gatt->ag_virtual, 64 * 1024); } static void @@ -2052,7 +2053,6 @@ agp_i810_bind_memory(device_t dev, struc sc->match->driver->install_gtt_pte(dev, (offset + i) >> AGP_PAGE_SHIFT, mem->am_physical + i, 0); } - agp_flush_cache(); mem->am_offset = offset; mem->am_is_bound = 1; mtx_unlock(&sc->agp.as_lock); @@ -2093,7 +2093,6 @@ agp_i810_unbind_memory(device_t dev, str sc->match->driver->install_gtt_pte(dev, (mem->am_offset + i) >> AGP_PAGE_SHIFT, 0, 0); } - agp_flush_cache(); mem->am_is_bound = 0; mtx_unlock(&sc->agp.as_lock); return (0); Modified: head/sys/dev/agp/agppriv.h ============================================================================== --- head/sys/dev/agp/agppriv.h Sun Nov 2 09:52:22 2014 (r273962) +++ head/sys/dev/agp/agppriv.h Sun Nov 2 11:26:37 2014 (r273963) @@ -83,7 +83,6 @@ struct agp_gatt { vm_offset_t ag_physical; }; -void agp_flush_cache(void); u_int8_t agp_find_caps(device_t dev); struct agp_gatt *agp_alloc_gatt(device_t dev); void agp_set_aperture_resource(device_t dev, int rid);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201411021126.sA2BQcx4053562>