Subject: Proposal for modification of bus_dma(9)
To: None <tech-kern@NetBSD.ORG>
From: Jason Thorpe <thorpej@nas.nasa.gov>
List: tech-kern
Date: 02/01/1998 02:12:00
[ Ross - please make sure to point out any mistakes I might make wrt. to
  things that can and can't be done on the A12... Everyone - note that
  this was written at around 1.45am after I got home, having just thought
  of this in the car on the way; please just dismiss anything that might
  look like sheer stupidity as simply the effects of being tired :-]

Hi folks...

With the recent commit of preliminary support for the Avalon Computer Systems
A12 Scalable Parallel Processor to NetBSD/alpha, I have been rethinking
the semantics of bus_dmamap_sync().

In particular, I am no longer very happy with the BUS_DMAMEM_NOSYNC option
to bus_dmamem_map(), which allows DMA-safe memory to be mapped in such a
way that bus_dmamap_sync() calls are not required.  I agree with Ross Harvey's
assessment of this option: it's really the only hole in the bus_dma
abstraction, and is meant as a way to map memory non-cacheable for things
like SCSI controller mailbox entries or network interface transmit descriptors,
and other device control structures that are given to the device via DMA.

Unfortunately, NOSYNC isn't something which can be implementd on the A12
(at least in current incarnations of the A12 hardware).  The A12 cannot
DMA directly to main memory.  Instead, PCI devices DMA into SRAM bounce
buffers (which are implemented in hardware) which must then be copied into
the host buffer.

Because the A12 requirementes necessitate consistent synchronization,
I would like to alter the interface to bus_dmamap_sync() to make doing
this synchronization easier and less expensive.

The bus_dmamap_sync() interface currently looks like:

	void bus_dmamap_sync __P((bus_dma_tag_t tag, bus_dmamap_t dmamap,
		bus_dmasync_op_t op));

I would like to change it to:

	void bus_dmamap_sync __P((bus_dma_tag_t tag, bus_dmamap_t dmamap,
		bus_addr_t offset, bus_size_t len, int ops));

Where:
	offset		offset into the mapping to synchronize

	len		length of mapping from offset to synchronize

	ops		one or more DMA synchronization operations

In order to support this change, the bus_dmamap_t will gain an additional
public member:

	int dm_mapsize;	The size of the current DMA mapping.  A size of
			0 indicates the mapping is invalid.

Now, the "ops" change allows us to perform multiple synchronization
operations in a single call, unlike the previous version, which allowed
only one per call.

The offset and len arguments allow finer control over which parts of the
DMA mapping are synchronized.  This is intended primarily to support
synchronization of individual mailbox entries or i/o descriptors.

In the common case of synchronizing a DMA buffer for data (the current
use of bus_dmamap_sync(), and the meat of the i386 ISA bounce buffer
implementation), calls that were once:

	bus_dmamap_sync(dmat, dmamap, BUS_DMASYNC_POSTREAD);

would now become:

	bus_dmamap_sync(dmat, dmamap, 0, dmamap->dm_mapsize,
	    BUS_DMASYNC_POSTREAD);

...or in the case of synchronizing a single transmit descriptor for the "foo"
network interface:

	bus_dmamap_sync(dmat, txdescmap, 4 * sizeof(struct foo_txdesc),
	    sizeof(struct foo_txdesc),
	    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);

I would also like to clarify the meaning of the DMASYNC operations.  Ross
Harvey sent me this description, which I find very clear:

	BUS_DMASYNC_PREREAD:	transfer ownership to device
	BUS_DMASYNC_PREWRITE:	transfer ownership to device
	BUS_DMASYNC_POSTREAD:	return ownership to CPU
	BUS_DMASYNC_POSTWRITE:	return ownership to CPU

Anyhow, I'd like to resove this fairly quickly, since in addition to fixing
up the bus_dma interface, I'm also writing a paper about it, and I'd like
to have this fixed for the paper, too :-)

Ciao.

Jason R. Thorpe                                       thorpej@nas.nasa.gov
NASA Ames Research Center                            Home: +1 408 866 1912
NAS: M/S 258-5                                       Work: +1 650 604 0935
Moffett Field, CA 94035                             Pager: +1 415 428 6939