Subject: bus_dmamem accessors
To: None <tech-kern@netbsd.org>
From: Chris G. Demetriou <cgd@sibyte.com>
List: tech-kern
Date: 07/31/2000 11:11:01
So, the issue of bus_dmamem accessors came up about a month ago
(starting with
http://mail-index.netbsd.org/tech-kern/2000/06/25/0000.html), and i
was trying to ask a question about the specification of their
behaviour and got what I thought was an inadequate reply (query quoted
and response at
http://mail-index.netbsd.org/tech-kern/2000/06/25/0010.html).

(btw, bus_dmamem_read_1 seemed to be missing from the original
proposal, i dunno about the followups.  looking at the original
proposal, i don't think i get the use of addr vs. offsets -- i'd think
the latter would be more correct -- but since the list archives don't
support reading my thread...)


To be a bit more concrete about my example:

* PCI.

* HBA which can support byte swapping, and does byte swapping on PCI
"word" (4-byte naturally aligned) boundaries.  i.e., it's willing to
do:

	(BE) mem addr 0:	1
	(BE) mem addr 1:	2
	(BE) mem addr 2:	3
	(BE) mem addr 3:	4

	->

	PCI byte 0 (BE#[0]):	1
	PCI byte 1 (BE#[0]):	2
	PCI byte 2 (BE#[0]):	3
	PCI byte 3 (BE#[0]):	4

(it's also willing to do unswapped accesses.)  This works regardless
of sizing, i.e. if a PCI device asks for bytes 2 and 3, it'll always
get values 3 and 4 respectively in those bytes.  (This makes sense,
since PCI has a bus width of 4 bytes -- at least 32-bit wide PCI does,
i dunno how 64-bit PCI affects things w.r.t. word ordering.)

* another HBA which doesn't support swapping in HW.

* the DMA memory being fiddled with is actually a DMA descriptor,
consisting for sake of argument of:

	* 1 byte field at offset 0
	* 1 byte field at offset 1
	* 2 byte field at offset 2


What is the correct set of bus_dmamem accessor calls to set and get
the value of each of those fields, and what do those functions do
internally?


I believe the answer should be:

accessing the first:

	bus_dmamem_{read,write}_1(map, 0);	/* 0 is offset */

	which, on my first hypothetical ("swapping") system would
	access byte 0, but which on my second hypotehtical
	("non-swapping") system would access byte 3.

accessing the second:

	bus_dmamem_{read,write}_1(map, 1);	/* 1 is offset */

	accessing byte 1 on swapping system, or 2 on non-swapping
	system.

accessing the third:

	bus_dmamem_{read,write}_2(map, 2);	/* 2 is offset */
	
	on a swapping system, this accesses bytes 2 and 3, and
	reads/writes a value in host order.  on a non-swapping system,
	this would access bytes 0 and 1, and need to do a byte-swap
	in software.


The response to my question (URL included above) could easily be read
to indicate that the semantics are other than this, and specifically
are that the HW will access and swap according to the "unit of
access."

in other words, it might be that the intent is to require for the
above:

	bus_dmamem_{read,write}_1(map, be_host ? 3 : 0);
	bus_dmamem_{read,write}_1(map, be_host ? 2 : 1);
	bus_dmamem_{read,write}_2(map, be_host ? 0 : 2);

I'd argue that that's highly bogus.  8-)


any comment?


chris