Subject: Re: PCI-audio & endianness (eso.c/mulaw.c)
To: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
From: Eduardo E. Horvath <eeh@one-o.com>
List: tech-kern
Date: 10/27/1999 09:17:31
> In <19991027083347.B2826@wau.mis.ah.nl>
> leo@wau.mis.ah.nl wrote:
>
> > 1 - dev/sys/pci/eso.c:
> >
> > This file defines htopci() and pcitoh() macro's that do a bswap32()
> > when BIG_ENDIAN. This swapped value is than written using
> > bus_space_write_4() - this is wrong! The bus-functions for a PCI-bus
> > on a big-endian machine should do the necessary swapping. I'll
> > remove this endian stuff from this file later this week.
>
> I think bswap32() should not be needed in bus_space(9) functions, too.
Huh? bswap32() should be done inside the bus_space(9) macros if/when
appropriate. Drivers should not be involved in this at all.
>
> > 2 - dev/mulaw.c
> >
> > Here also, endianness is taken into account. However, I can not play
> > '.au' files when compiling for big-endian. If I compile for the little
> > endian case, the samples play fine. Now it isn't obvious to me what
> > is the 'correct' case here. I have absolutely no experience with
> > audio drivers. From my observation of the eso.c file, it is clear that
> > the sound-card uses DMA to fetch the data (== no endian conversion) and
> > from the docs on the Hades PCI-bus it looks that there is no magic
> > like hardware swaps involved.
>
> I guess most PCI bus-master devices assume the host is little endian,
> so bswap*() functions are needed on passing non-bytestream data via DMA.
> (i.e. on accessing variables allocated by bus_dmamem_alloc(9) and
> bus_dmamem_map(9))
Once again this should be handled by bus_space(9) macros. We may need
to add some new ones specifically for the host to access DMA memory,
if it's only being mapped in once and used statically as an area for
host/device communication.
One rather annoying situation is when a big-endian device is being
placed on a PCI card. Sometimes the H/W engineers decide to be
helpful and add byte swapping to the DMA engine. Now everything needs
to be pre-swapped before being DMA'ed. Ugh!
Byte swapping can happen in:
o CPU registers
o The CPU's MMU
o The PCI Bus controller's MMU
o The PCI Bus controller
o The PCI card
o The PCI card's DMA engine
o The PCI device
What's more it can happen in multiple locations. If swapping is
happening in the CPU, MMU, or the PCI bus controller or its MMU,
swapping would be of a constant size and should be taken care of by
dmamap_load() and dmamap_unload(), but sections created by
dmamem_map() may require bus_space(9) macros if additional swapping is
needed.
The last two need to be handled by the device driver itself, which is
rather unfortunate if the configuration consists of a big-endian CPU
communicating with a big-endian device and this results in two
completely redundant byte-swaps.
If the world were kind then all DMA would be done as byte-streams and
endianness would be irrelevant. Unfortunately this is not the case.
=========================================================================
Eduardo Horvath eeh@one-o.com
"I need to find a pithy new quote." -- me