Subject: Re: bus_dmamem accessors
To: Chris G. Demetriou <cgd@sibyte.com>
From: Eduardo Horvath <eeh@turbolinux.com>
List: tech-kern
Date: 07/31/2000 11:36:43
On 31 Jul 2000, Chris G. Demetriou wrote:
> 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
Looks like you're allways reading the same location there 8^).
> (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.)
If the device does `swapping' it should be doing so based on individual
accesses. Otherwise the `swapping' is broken and should be turned
off. It should not be doing swapping on arbitrary bit/byte boundaries.
HME is an example of a device that does swapping correctly. When it reads
a short it swaps 2 bytes. When it reads a long it swaps 4 bytes.
ISP is a device that does it wrong. It's a word machine and always swaps
on 2-byte boundaries. This means that the memory layout of the ISP queue
entries is different for SBus and PCI.
Don't you just love it when the H/W guys who don't really understand the
problem decide to be `helpful'?
> * 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.
No. In both cases that should be byte 0.
>
> 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.
Once again that should always be byte 1.
> 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.
In this case, bytes 3 and 4 should be swapped, depending on whether you
specify that this is a BE device or a LE device.
> 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-)
That is not `highly bogus'. The swapping must be done on the "unit of
access". Anything else is broken. Your so-called `swapping' device's
unit of access is 4. Hence, if you insist on taking advantage of that
`swapping' you need to always do rmw accesses through
bus_dmamem_{read,write}_4.
Eduardo Horvath