svn commit: r204689 - in head/sys/mips: include mips sibyte

Neel Natu neel at FreeBSD.org
Thu Mar 4 05:23:09 UTC 2010


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


More information about the svn-src-all mailing list