Date: Sun, 02 Nov 2014 07:27:24 -0800 From: Nathan Whitehorn <nwhitehorn@freebsd.org> To: Tijl Coosemans <tijl@freebsd.org>, src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r273963 - head/sys/dev/agp Message-ID: <54564D5C.8090100@freebsd.org> In-Reply-To: <201411021126.sA2BQcx4053562@svn.freebsd.org> References: <201411021126.sA2BQcx4053562@svn.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
There is actually a write-combining memory type on PowerPC. You can set it the same way as on x86 (with VM_MEMATTR_WRITE_COMBINING). -Nathan On 11/02/14 03:26, Tijl Coosemans wrote: > 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?54564D5C.8090100>