Subject: DMA COHERENCY [ was Re: CVS commit: syssrc ]
To: Manuel Bouyer <>
From: Matthew Jacob <>
List: tech-kern
Date: 02/27/2001 11:12:50
> On Mon, Feb 26, 2001 at 01:39:48PM -0800, Matthew Jacob wrote:
> > I still would have to change the sparc64 implementation to grok this I
> > believe. Note that BUS_DMA_COHERENT for bus_dmamem_map means make the
> > CPU's view coherent (i.e., set PG_NVC (no vcache)) of memory. There's no tying
> > this to setting iommu TTE bits.
> Ha OK, on sparc64 we have two places to deal with: CPU<->Memory and
> Memory<->device, which have each their own cache, rigth ?

Yes. It isn't just sparc- there are other architectures have this issue as
well- alpha for example. But alpha has an instruction that can ensure
coherency at bus_dmamap_sync time (mb).

> I still believe that memory bus_dmamem_map()'ed BUS_DMA_COHERENT should be
> from CPU to device (and vice-versa), so both caches should be configured for
> this.

But you may not be mapping it into a CPU's virtual address space. Otherwise,
yes, BUS_DMA_COHERENT for a CPU mapping should probably imply coherence for IO
mappings as well.

> > 
> > And lacking any architectural *requirement* for requiring such ordering, in
> > fact, I'd rather have a big fat rule breakage with a comment than things just
> > working because the order of function calls makes things work.
> Hum, you're rigth. For me it was obvious that a DMA map should be mapped
> before loaded but this is definitively 2 different things. So maybe we
> need to handle BUS_DMA_COHERENT in bus_dmamap_load* too, but the behavior
> needs to be clearly specified before, and documentation updated at the
> same time.

That's the request I have on the table here for. It's not all that complex
when you get down to this. I believe that all you need is to simply modify the
man page to state that BUS_DMA_COHERENT maybe specified in bus_dmamap_load*,
or you need to state that bus_dmamem_alloc'd memory implies BUS_DMA_COHERENT
for both CPU and IO mappings.

     bus_dmamap_load(tag, dmam, buf, buflen, p, flags)
...			BUS_DMA_NOWAIT    It is not safe to wait (sleep) for
			                  sources during this call.

++                      BUS_DMA_COHERENT  This flag is a request to the
                                          machine dependent code that
                                          any IOMMU mappings will be
                                          established in a away to provide
                                          for byte coherency for the mapped
                                          memory. If this cannot be achieved
                                          an error will be returned. Usage of
                                          bus_dmamap_sync is still required.

                                          The reason for this flag is that
                                          some systems need to know at
                                          IOMMU load time whether or not
                                          the mapping will be to support
                                          byte coherency or streaming
                                          unidirectional I/O in order to
                                          select which hardware bits to set.


     bus_dmamem_alloc(tag, size, alignment, boundary, segs, ...)
            All pages allocated by bus_dmamem_alloc will be assumed
            to be BUS_DMA_COHERENT even if never mapped via bus_dmamem_map.
            This is so the bus_dmamap_load implementation will select
            the correct hardware bits to use when establishing IOMMU mappings.


     bus_dmamem_alloc(tag, size, alignment, boundary, segs, ...)
...			BUS_DMA_NOWAIT    It is not safe to wait (sleep) for
			                  sources during this call.

++                      BUS_DMA_COHERENT  This flag is a request to the
                                          machine dependent code that
                                          memory allocated here will always
                                          be mapped (whether by CPU or
                                          IO MMUs) to support byte coherency
                                          or unidirectional I/O streaming.


    If you need to ensure byte coherency for both IOMMU and CPU caches,
    you *must* call bus_dmamem_map prior to bus_dmamap_load with the flag

(wrt the last: *barf*)