Date: Thu, 4 Mar 2010 05:23:08 +0000 (UTC) From: Neel Natu <neel@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r204689 - in head/sys/mips: include mips sibyte Message-ID: <201003040523.o245N86s076889@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: neel Date: Thu Mar 4 05:23:08 2010 New Revision: 204689 URL: http://svn.freebsd.org/changeset/base/204689 Log: Add support for CPUs with cache coherent DMA. The two main changes are: - We don't need to fall back to uncacheable memory to satisfy BUS_DMA_COHERENT requests on these CPUs. - The bus_dmamap_sync() is a no-op for these CPUs. A side-effect of this change is rename DMAMAP_COHERENT flag to DMAMAP_UNCACHEABLE. This conveys the purpose of the flag more accurately. Reviewed by: gonzo, imp Modified: head/sys/mips/include/cpuinfo.h head/sys/mips/mips/busdma_machdep.c head/sys/mips/mips/cpu.c head/sys/mips/sibyte/sb_machdep.c Modified: head/sys/mips/include/cpuinfo.h ============================================================================== --- head/sys/mips/include/cpuinfo.h Thu Mar 4 05:19:46 2010 (r204688) +++ head/sys/mips/include/cpuinfo.h Thu Mar 4 05:23:08 2010 (r204689) @@ -56,6 +56,7 @@ struct mips_cpuinfo { u_int8_t tlb_type; u_int16_t tlb_nentries; u_int8_t icache_virtual; + boolean_t cache_coherent_dma; struct { u_int32_t ic_size; u_int8_t ic_linesize; @@ -68,6 +69,8 @@ struct mips_cpuinfo { } l1; }; +extern struct mips_cpuinfo cpuinfo; + /* TODO: Merge above structure with NetBSD's below. */ struct cpu_info { Modified: head/sys/mips/mips/busdma_machdep.c ============================================================================== --- head/sys/mips/mips/busdma_machdep.c Thu Mar 4 05:19:46 2010 (r204688) +++ head/sys/mips/mips/busdma_machdep.c Thu Mar 4 05:23:08 2010 (r204689) @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include <machine/bus.h> #include <machine/cache.h> #include <machine/cpufunc.h> +#include <machine/cpuinfo.h> #include <machine/md_var.h> #define MAX_BPAGES 64 @@ -124,7 +125,7 @@ SYSCTL_INT(_hw_busdma, OID_AUTO, total_b #define DMAMAP_MBUF 0x2 #define DMAMAP_UIO 0x4 #define DMAMAP_TYPE_MASK (DMAMAP_LINEAR|DMAMAP_MBUF|DMAMAP_UIO) -#define DMAMAP_COHERENT 0x8 +#define DMAMAP_UNCACHEABLE 0x8 #define DMAMAP_ALLOCATED 0x10 #define DMAMAP_MALLOCUSED 0x20 @@ -340,6 +341,8 @@ bus_dma_tag_create(bus_dma_tag_t parent, newtag->nsegments = nsegments; newtag->maxsegsz = maxsegsz; newtag->flags = flags; + if (cpuinfo.cache_coherent_dma) + newtag->flags |= BUS_DMA_COHERENT; newtag->ref_count = 1; /* Count ourself */ newtag->map_count = 0; if (lockfunc != NULL) { @@ -517,9 +520,6 @@ bus_dmamap_create(bus_dma_tag_t dmat, in bz->map_count++; } - if (flags & BUS_DMA_COHERENT) - newmap->flags |= DMAMAP_COHERENT; - CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d", __func__, dmat, dmat->flags, error); @@ -577,13 +577,23 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, voi *mapp = newmap; newmap->dmat = dmat; + /* + * If all the memory is coherent with DMA then we don't need to + * do anything special for a coherent mapping request. + */ + if (dmat->flags & BUS_DMA_COHERENT) + flags &= ~BUS_DMA_COHERENT; + + /* + * Allocate uncacheable memory if all else fails. + */ if (flags & BUS_DMA_COHERENT) - newmap->flags |= DMAMAP_COHERENT; - + newmap->flags |= DMAMAP_UNCACHEABLE; + if (dmat->maxsize <= PAGE_SIZE && (dmat->alignment < dmat->maxsize) && !_bus_dma_can_bounce(dmat->lowaddr, dmat->highaddr) && - !(flags & BUS_DMA_COHERENT)) { + !(newmap->flags & DMAMAP_UNCACHEABLE)) { *vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags); newmap->flags |= DMAMAP_MALLOCUSED; } else { @@ -619,7 +629,7 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, voi return (ENOMEM); } - if (flags & BUS_DMA_COHERENT) { + if (newmap->flags & DMAMAP_UNCACHEABLE) { void *tmpaddr = (void *)*vaddr; if (tmpaddr) { @@ -1177,8 +1187,13 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus return; if (STAILQ_FIRST(&map->bpages)) _bus_dmamap_sync_bp(dmat, map, op); - if (map->flags & DMAMAP_COHERENT) + + if (dmat->flags & BUS_DMA_COHERENT) return; + + if (map->flags & DMAMAP_UNCACHEABLE) + return; + CTR3(KTR_BUSDMA, "%s: op %x flags %x", __func__, op, map->flags); switch(map->flags & DMAMAP_TYPE_MASK) { case DMAMAP_LINEAR: Modified: head/sys/mips/mips/cpu.c ============================================================================== --- head/sys/mips/mips/cpu.c Thu Mar 4 05:19:46 2010 (r204688) +++ head/sys/mips/mips/cpu.c Thu Mar 4 05:23:08 2010 (r204689) @@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$"); #include <machine/pte.h> #include <machine/hwfunc.h> -static struct mips_cpuinfo cpuinfo; +struct mips_cpuinfo cpuinfo; union cpuprid cpu_id; union cpuprid fpu_id; Modified: head/sys/mips/sibyte/sb_machdep.c ============================================================================== --- head/sys/mips/sibyte/sb_machdep.c Thu Mar 4 05:19:46 2010 (r204688) +++ head/sys/mips/sibyte/sb_machdep.c Thu Mar 4 05:23:08 2010 (r204689) @@ -220,6 +220,13 @@ mips_init(void) mips_cpu_init(); /* + * Sibyte has a L1 data cache coherent with DMA. This includes + * on-chip network interfaces as well as PCI/HyperTransport bus + * masters. + */ + cpuinfo.cache_coherent_dma = TRUE; + + /* * XXX * The kernel is running in 32-bit mode but the CFE is running in * 64-bit mode. So the SR_KX bit in the status register is turned
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003040523.o245N86s076889>