Subject: Re: BUS_DMA_CONTROLDATA flag for bus_dma(9)
To: None <cgd@broadcom.com, tech-kern@netbsd.org>
From: Allen Briggs <briggs@wasabisystems.com>
List: tech-kern
Date: 08/15/2003 21:30:23
Reading through the mail that accumulated while I was putting the
kids to bed, it looks like there are some places where we can clean
up the documentation somewhat.
In short, I'm working with the assumptions that BUS_DMA_COHERENT is
mutually exclusive with respect to BUS_DMA_STREAMING. That is, it
is considered an error to specify both as flags to bus_dmamap_load().
Refining the definition of BUS_DMA_COHERENT a little bit more, it
specifies that the region must be coherent when properly synchronized
with bus_dmamap_sync(). This allows for regions mapped without
BUS_DMA_COHERENT to, for example, use cacheable memory with write-back
operations that could cause RMW cycles to write more bytes than
explicitly stated. It also allows for bounce buffers to operate on
either type of memory.
bus_dmamem_map:
BUS_DMA_COHERENT This flag is a hint to the machine-depen-
dent back-end that indicates that
the memory needs to be mapped in a
fashion that is conducive to coherency.
That is, that no writes to the memory
should result in extra data being stored
(through a partial update of a cacheline
followed by a full cacheline write-back,
for example).
The back-end may ignore this if it has a
fully-coherent memory system. The back-
end may also choose to map this memory as
uncachable in some fashion.
This flag may impose a performance penalty
if used when unnecessary. It is most
useful for regions of memory that may
be simultaneously accessed by the CPU
and a device. For example, an ethernet
descriptor ring is commonly accessed by
both the CPU and the ethernet device
while data buffers are not.
If this flag is not specified, the back-end
may map a region cacheable. On some systems
with write-back caches, this might result
in a RMW rewriting memory outside of the
range specified by bus_dmamap_sync()
operations.
Note that if this flag is used, it must
also be used with the corresponding
bus_dmamap_load() function.
Note that all calls to bus_dmamap_sync()
must still be made as there may be machine-
dependent operations required to complete
synchronization before and after DMA
operations.
Also note that this flag only applies
to coherency between the CPU and memory,
making the assumption that there is
coherency between the device and memory.
See also the description of the
bus_dmamap_load() function.
bus_dmamap_load():
BUS_DMA_COHERENT This flag is a notice to the machine-depen-
dent back-end that indicates that the
region being loaded into the DMA map
should be handled in a coherent fashion.
It does not mean that the region is
necessarily inherently coherent, but it
does mean that when the proper
bus_dmamap_sync() operations are used,
the region will be effectively coherent.
Coherency implies that no writes
to the memory should accidentally write
more data than intended (through a write
of an entire cacheline, for example).
This flag must be passed to
bus_dmamap_load() when loading a dmamap
for a region that was mapped using this
flag with bus_dmamem_map().
Note that this flag applies to coherency
between the CPU and memory. Coherency
between memory and the device doing DMA
is assumed. See the description of the
BUS_DMA_STREAMING flag for this function.
BUS_DMA_COHERENT and BUS_DMA_STREAMING
are mutually exclusive.
See further discussion of this flag in
the description of the bus_dmamem_map()
function.
BUS_DMA_STREAMING
...
Note that this flag and BUS_DMA_COHERENT
are mutually exclusive.
Does this make any more sense?
Would it help to mention bounce buffers to help more fully define the
need to bus_dmamap_sync() in the COHERENT case?
-allen
--
Allen Briggs briggs@wasabisystems.com
Wasabi Systems, Inc. http://www.wasabisystems.com/