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-head
mailing list