Subject: Re: diff betw. bus_space_{read,write} and bus_space_{read,write}_stream?
To: Ken Nakata <kenn@synap.ne.jp>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: tech-kern
Date: 07/28/1998 06:03:06
On Aug 24, Ken Nakata wrote
> Ok... I think I'm getting at it.  In my notion, a byte-swapper is a
> hardware entity (well, it's just a bunch of wirings but
> nevertheless...) but in your notion, byte-swapping occurs when order
> of bytes changes.  So, when host's bits 24-31 and bits 16-23 are wired
> to IDE bus's bits 0-7 and bits 8-16, respectively, I see a byte-
> swapper there, but in the bus_space context, I should not.  It
> preserves byte order between IDE and host buses, so there is NO
> byte-swapping occurring.

No it doesn't preserve byte order. If you have the string "Ne" on the IDE
device you will get "eN" in the host memory if you use a 16 bit read.
If you used bus_space_read_2 this is ok (as the IDE bus and CPU have a
different byte order) but if you used bus_space_stream_read_2 it is not
(the stream funtions should always preserve strings).

> 
> bus_space_read{,_multi}_2() read values as 16-bit quantities from the
> I/O bus, therefore it has to byte-swap each quantity read if host and
> I/O buses' byte orders are different _and_ the bridge between them
> preserves the order of byte stream.
> 
> So, in mac68k's case, bus_space_read_muilti_2() should byte-swap each
> u_int16_t, but it does not.

No, because the bridge doesn't preserve the byte order.
bus_space_read{,_multi}_2() should be a simple read here.

> A minor nit: I think it is also important for IEEE floats.  They are
> usually not treated as strings of bytes.

Possible, I'm not sure about this one.

> 
> > So doing byte-swapping at hardware level is plain wrong, because only some
> > values need to be byte-swapped.
> 
> Ok, if I understand it correctly, the bridge does not byte-swap, so
> it's okay, right?

If IDE's data lines 0-7 are wirred to 24-31 it does byte swap.

> 
> No, its behavior is consistent.  And, you're right, in this context,
> the hardware bridge does NOT byte-swap.  See my argument about the
> notion of byte-swapper above.

I didn't understand it: if IDE bit 0-7 are wired to host's bit 24-31 and IDE
8-15 to host 16-23, then when I read "Ne" from the IDE device the
bridge will give me "eN": it does byte swap.

> 
> > It's a standart IDE drive (i.e a quantun, IBM or something else you've
> > purchased in a PC hardware reseller) or an APPLE one ?
> 
> Doesn't matter.  They behave the same in this respect (If they did
> not, the IDE Mac owners would not be able to purchase a third-party
> IDE drive and swap the original drive with it!)

There have been precedents (the last one which did it me was AAUI: close
to AUI, but not enouth to work with standart transeivers).
> 
> My proposal to "fix" wdc.c for mac68k:
> 
> Since mac68k bus_space_{read,write}{,_multi}_2() do not byte-swap, and
> making them conditionally do so depending on the tag would give all
> other bus_space_{read,write}*() a performance hit,

Why ? Just do it like for ATARI: redefine them for the tag passed to
the independant wdc part.


> not just the
> byte-swapping accesses, I propose wdc_get_parms() be changed like
> this:
> 
>                 /* Read in parameter block. */
>                 bus_space_read_multi_2(wdc->sc_iot, wdc->sc_ioh, wd_data,
>                     (u_int16_t *)tb, sizeof(tb) >> 1);
> #if !defined(__BUS_SPACE_HAS_STREAM_METHODS) && (BYTE_ORDER == BIG_ENDIAN)
> 		for (i = 0; i < sizeof(tb); i += 2) {
> 			register u_int16_t t = *(u_int16_t *)(&tb[i]);
> 			*(u_int16_t *)(&tbl[i]) = (t << 8) | (t >> 8);
> 		}
> #endif

THIS IS WRONG ! IDE is little-endian, m68k is big endian, so the access method
should have done the rigth thing, either by hardware or in
bus_space_read_multi_2()

You'll need this kind of hack at many other places to get ATAPI working.

And I persist: if you need this, either the bridge doesn't do byte-swapping,
bus_space_read_multi_2() does, or your IDE drive has his bytes inverted in
firmware.
Are you sure your IDE cable is pin to pin ?

> 
> If the arch does not have the stream methods, I don't think you can
> expect the non-stream bus_space_read_multi_2() to handle endian
> difference.

It should, with or without stream methods.

The streams methods have been added to handle the case where bus and host
byte order are different, and you need to write raw data with 16 or 32 bits
access (initially I think this was for a NE2000 on ISA on a big-endian
system: you need to read/write the ethernet packet from/to the ne2000 memory
with 32 bit access, and byte-swapping them would have been wrong).

>  You cannot, at least with the mac68k bus_space
> implementation.

Then fix the implementation. This can be needed for other things as well.

--
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
--