Subject: Re: bus_space_read/write_multi_stream?
To: Allen Briggs <briggs@ninthwonder.com>
From: Chris G. Demetriou <cgd@sibyte.com>
List: tech-kern
Date: 07/31/2000 10:43:29
briggs@ninthwonder.com (Allen Briggs) writes:
> /* 
>  *      void bus_space_read_multi_stream_N __P((bus_space_tag_t tag,
>  *          bus_space_handle_t bsh, bus_size_t offset,
>  *          u_intN_t *addr, size_t count));
>  *
>  * Read `count' 2, 4, or 8 byte stream quantities from bus space
>  * described by tag/handle/offset and copy into buffer provided.
>  */
> 
> My question has now become, what is a "stream quantity"?

Well, I didn't write that bit of documentation, but really it probably
means "stream values," but that's still not so clear.

More below.


> Are
> these functions redundant with the bus_space_read/write_multi_N?

No.


> Why aren't these functions documented at all in bus_space(9)?

Because they were added after the initial definition and documentation
of the interface, and nobody bothered updating the manual pages (or
any of the ports which didn't Need to implement them).

Really, there should be _no_ #ifdefs like that left by now, but that's
beside the point.


The issue is one of reading groups of values, or byte streams (hence
the name).

the non-stream bus_space functions are defined to operate on N byte
wide quantities, and present them to the program in CPU order.  That
means, for instance, that if you've got a big-endian CPU and a
little-endian bus (say, ISA or PCI), the bus_space-non-multi ops imply
a byte swap (either by the code, or by an intervening bridge).

So, for instance, what that means is:

	PCI addr: 0:	0xa
		  1:	0xb
		  2:	0xc
		  3:	0xd

	bus_space_read_4 at PCI addr 0 returns "0x0d0c0b0a"

	on a BE system, store that into memory, you get:

	memory addr: 0:	0xd
		     1:	0xc
		     2:	0xb
		     3: 0xa

Of course, that's talking about code like:

	uint32_t foo, *mem;

	foo = bus_space_read_4(...);
	*mem = foo;

not bus_space_read_multi_N().  However, the behaviour defined for
bus_space_read_multi_N() basically wraps a loop around the above
pseudo-code.  8-)

If what you're accessing is 4-byte integers (or similar), that's just
grand.

However, if what you're accessing is logically a byte stream (e.g. a
string, or an ethernet packet) where you need the byte ordering to
remain constant, that doesn't work so well.

When this problem was noticed, some of the BE systems folks (i forget
who, now 8-), came up with the bus_space_*_stream_* methods.

They're the right thing, and every port should implement them (at
least as no-ops).  And they should be documented.


chris