Subject: Re: bus.h style question
To: Martin Husemann <firstname.lastname@example.org>
From: Leo Weppelman <email@example.com>
Date: 08/14/1997 13:43:56
On Thu 14 Aug 1997, Martin Husemann wrote:
> I have two question on usage of the bus.h interface:
> My card is mapped into ISA memory. At one time it generates a zero terminated
> string in this memory area, followed by a u_int32_t value. So what I do is:
> int i;
> u_int32_t value;
> u_int8_t *p, buffer[MAX_BUF_SIZE];
> for (p = buffer, i = 0; *p && i < sizeof buffer; i++, p++)
> *p++ = bus_space_read_1(sc->sc_iot, sc->sc_ioh, MYOFF+i);
> if (i >= sizeof buffer)
> return EIO;
> value = bus_space_read_1(sc->sc_iot, sc->sc_ioh, MYOFF+1+i) |
> (bus_space_read_1(sc->sc_iot, sc->sc_ioh, MYOFF+1+i) << 8) |
> (bus_space_read_1(sc->sc_iot, sc->sc_ioh, MYOFF+1+i) << 16) |
> (bus_space_read_1(sc->sc_iot, sc->sc_ioh, MYOFF+1+i) << 24);
> Could I use bus_space_read_4 savely to get value? Are there alignement
> constraints in the bus.h interface?
No, you can't use a 'read_4' here. AFAIK, the bus interface does not specify
endian conversion. Besides, the conversion is dependent on the _card_ and
not on the machine or bus (some network cards allow endian selection).
This is also the problem when defining structures in the cards memory space!
Alignment constraints are not forced by the bus-interface.
> The other question is the expected byte order. At another point I do check
> a signature with:
> u_int16_t signature;
> signature = bus_space_read_2(sc->sc_iot, sc->sc_ioh, MYOFF);
> if (signature != SIGNATURE_VALUE)
> return EIO;
> On the i386 the signature I get is 0x4447 - should I expect 0x4744 on
> the atari or amiga? I guess (hope?) not.
Might, might not (read on...)
> But when doing it this way:
> bus_space_read_region_1(sc->sc_iot, sc->sc_ioh, MYOFF, &signature, 2);
> I would get 0x4447 or 0x4744 depending on host byte order, right?
Might, might not...
To make things a bit more complicated, the Hades (= atari) allows me to
select either a 'native m68k' or 'byte swapped' I/O address range. What
is used, is dependent on the address range accessed (and is hidden in the
I/O tag). I choose to select the 'byte swapped' method as only method. This
turned out to be the most practical method because I didn't have to swap
all the card register values ;-)
Note that this feature is not available for the memory range.
I'm sorry if I only added to the problem, instead of solving anything :-(
What I want to make clear however is that relying on the byte ordering in
case of read/write_n() functions is 'bad'. Defining the read/write_n()
functions to do the endian conversion will not work, because you can't
expect these functions to know anything about the endianess of the
device/card mapped into the bus-space.