__LITTLE_ENDIAN vs. __LITTLE_ENDIAN_BITFIELD

Previous thread: [git patch] net driver fix by Jeff Garzik on Friday, October 5, 2007 - 11:20 am. (1 message)

Next thread: [PATCH] Cute feature: colored printk output by Jan Engelhardt on Friday, October 5, 2007 - 12:13 pm. (22 messages)
From: Timur Tabi
Date: Friday, October 5, 2007 - 11:27 am

What's the difference between __LITTLE_ENDIAN and __LITTLE_ENDIAN_BITFIELD? 
Can someone give me an example when __BIG_ENDIAN and __LITTLE_ENDIAN_BITFIELD 
would both be defined simultaneously?

-- 
Timur Tabi
Linux Kernel Developer @ Freescale
-

From: Jan Engelhardt
Date: Friday, October 5, 2007 - 11:35 am

standard x86:
---LSB-- ---2SB-- ---3SB-- ---MSB-- [bytes] LITTLE_ENDIAN
M765432L M765432L M765432L M765432L  [bits] ?_BITFIELD

(Not sure what bitfield type, but I'd guess BIG_ENDIAN_BITFIELD)

standard sparc:
---MSB-- ---3SB-- ---2SB-- ---LSB-- [bytes] BIG_ENDIAN
M765432L M765432L M765432L M765432L  [bits] ?_BITFIELD

(I hope I got these two right)


Theoretical machine with BIG_ENDIAN but LITTLE_ENDIAN_BITFIELD:
---MSB-- ---3SB-- ---2SB-- ---LSB--
L234567M L234567M L234567M L234567M
-

From: Timur Tabi
Date: Friday, October 5, 2007 - 12:35 pm

Are you sure?  I would think that all machines would have the same byte and 
bit endian, otherwise you'd never be able to put a 16-bit value into a shift 
register.  Your bits will be shifted out like this:

<-- 07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08

So I think x86 is:

---LSB-- ---2SB-- ---3SB-- ---MSB-- [bytes] LITTLE_ENDIAN
L234567M L234567M L234567M L234567M  [bits] LITTLE_ENDIAN_BITFIELD

-- 
Timur Tabi
Linux Kernel Developer @ Freescale
-

From: Jan Engelhardt
Date: Friday, October 5, 2007 - 12:43 pm

Bit representation is left to the CPU, so 1 << 1 will always be 2,
regardless of whether the byte, when sent out to the network,
is 01000000 or 00000010. Endianess becomes important as soon
as the packet is on the network, of course.
-

From: Timur Tabi
Date: Friday, October 5, 2007 - 12:47 pm

Well yes, that's why I'm asking.  I'm not concerned about data from just the 
CPU's perspective.

I'm writing a driver that talks to hardware that has a shift register.  The 
register can be shifted either left or right, so all the bits obviously have 
to be in order, but it can be either order.

What I want to do is to have the driver detect when byte-endianness doesn't 
match bit-endianness when it writes the the word to a memory-mapped device.  I 
think I can do that like this:

#if (defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN_BITFIELD)) || 
(defined(BIG_ENDIAN) && defined(LITTLE_ENDIAN_BITFIELD))
#error "This CPU architecture is not supported"
#endif

-- 
Timur Tabi
Linux Kernel Developer @ Freescale
-

From: Andreas Schwab
Date: Friday, October 5, 2007 - 1:04 pm

Bit addressing is strictly internal to the cpu, the smallest unit that
the cpu can address externally is a byte.  The only place where bit
order matters on the C level is in a bitfield that is overlayed over a

The bit mapping on your device is strictly internal to the device and
has nothing to do with bit order on the C level.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
-

From: Timur Tabi
Date: Friday, October 5, 2007 - 1:07 pm

Then I don't understand that point of defining __LITTLE_ENDIAN_BITFIELD.  What 
does it mean for a C-level bitfield ordering to be little-endian if the 
processor is BIG_ENDIAN?

-- 
Timur Tabi
Linux Kernel Developer @ Freescale
-

From: linux-os (Dick Johnson)
Date: Friday, October 5, 2007 - 1:34 pm

What does it mean for a C-level bitfield ordering to be little-endian if the

It makes no sense because a bitfield is something having to
do with a 'C' compiler and it must NEVER be used as a template
to address hardware! 'C' gives no guarantee of the ordering
within machine words. The only way you can access them is
using 'C'. They don't have addresses like other objects
(of course they do exist --somewhere). They are put into
"storage units," according to the standard, and these
storage units are otherwise undefined although you can
align them (don't go there).

If you want to call machine-control bits by name, just
define them as hexadecimal numbers (unsigned ints) and,
if your hardware is for both little/big endian, use
a macro that resolves the issue between the number
and the hardware.


Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.24 on an i686 machine (5592.59 BogoMips).
My book : http://www.AbominableFirebug.com/
_


****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.
-

From: Timur Tabi
Date: Friday, October 5, 2007 - 1:37 pm

Well, if it doesn't make any sense why do we have __LITTLE_ENDIAN_BITFIELD and 
__BIG_ENDIAN_BITFIELD?  That is, why do we do this:

#if defined(__BIG_ENDIAN_BITFIELD)
	__u8 reserved1		: 2;
	__u8 ili		: 1;
	__u8 reserved2		: 1;
	__u8 sense_key		: 4;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
	__u8 sense_key		: 4;
	__u8 reserved2		: 1;
	__u8 ili		: 1;
	__u8 reserved1		: 2;
#endif

when we can just do this:

#if defined(__BIG_ENDIAN)
	__u8 reserved1		: 2;
	__u8 ili		: 1;
	__u8 reserved2		: 1;
	__u8 sense_key		: 4;
#elif defined(__LITTLE_ENDIAN)
	__u8 sense_key		: 4;
	__u8 reserved2		: 1;
	__u8 ili		: 1;
	__u8 reserved1		: 2;

That wasn't my intention.  I was hoping that __LITTLE_ENDIAN_BITFIELD could be 
used to test bit-endianness, but I guess it can't.

-- 
Timur Tabi
Linux Kernel Developer @ Freescale
-

From: Benjamin Herrenschmidt
Date: Friday, October 5, 2007 - 4:27 pm

.../... (snipped horror use of bitfields)

Bitfields are wrong. Period. Don't use them.

__LITTLE_ENDIAN_BITFIELD vs. __BIG_ENDIAN_BITFIELD is Linux way to cope
with existing code using them that needs fixing on architectures that
have C bitfields in reverse order but that's not even something that can
be properly relied upon generally.

Just don't use bitfields and be happy.

Ben.


-

From: Andreas Schwab
Date: Friday, October 5, 2007 - 2:17 pm

Byte endianess and bit endianness are orthogonal concecpts.  A cpu can
have insns using both little and big endian bit addressing (btst
vs. bftst on m68k).  The bitfield ordering is a property of the ABI and
may even be different from how the cpu numbers the bits in its ISA.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
-

From: Anton Altaparmakov
Date: Friday, October 5, 2007 - 2:06 pm

No it is not.  That makes no sense.  The whole point of little endian  
is that you store LSB, then 2SB, then 3SB, then MSB and then when the  
CPU reads this as a 32-bit word it rotates them all around so that in  
the CPU register you have:

MSB_3SB_2SB_LSB
M765432L_M765432L_M765432L_M765432L

That is what little endian means and that is how shift operations can  
work fine on the CPU.

Best regards,

	Anton
-- 
Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @)
Unix Support, Computing Service, University of Cambridge, CB2 3QH, UK
Linux NTFS maintainer, http://www.linux-ntfs.org/


-

From: Timur Tabi
Date: Friday, October 5, 2007 - 2:10 pm

Why not?  I honestly don't know what x86 does, but I would think that if I 
write a 32-bit value to a memory location, that when I examine that memory 

You're talking about byte endian.  I'm talking about bit endian -- the order 
of bits within a byte.  Software cannot know what the bit endian is, but 

The CPU shift operation, yes.  I'm talking about shift operations on external 
memory-mapped devices.

-- 
Timur Tabi
Linux Kernel Developer @ Freescale
-

From: Andreas Schwab
Date: Friday, October 5, 2007 - 2:29 pm

That is a property of how the device is wired to the bus.  The cpu will
always put a value of 128 on the bus such that D7 = 1 and D0-D6 = 0.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
-

From: Timur Tabi
Date: Friday, October 5, 2007 - 2:32 pm

Yes, but is D7 on the left or on the right?

Anyway, this is academic now.  I now know that __LITTLE_ENDIAN_BITFIELD is not 
what I want, and that there's no macro that will tell how the lines from the 
CPU to external memory are mapped.

-- 
Timur Tabi
Linux Kernel Developer @ Freescale
-

From: Andreas Schwab
Date: Friday, October 5, 2007 - 4:17 pm

This is always the same.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."
-

From: Lennart Sorensen
Date: Tuesday, October 9, 2007 - 10:46 am

Doesn't the bus usually have some definition of bit order which the
device would have to adhere to?  After all there must be address lines
somewhere.

Does this perhaps offer anything useful?
http://www.linuxjournal.com/article/6788

--
Len Sorensen
-

From: Timur Tabi
Date: Tuesday, October 9, 2007 - 10:56 am

I was hoping that there would be some compile-time constant I could check that 

Yeah, I read that article some time ago when trying to diagnose the problem I 
was seeing.  It does explain the point I'm trying to make.  We have a device 
that's used on two product lines: one ARM-based, and one PowerPC.  The ARM is 
little-endian, and the PowerPC is big-endian.  The device can support 
little-endian or big-endian data, as long as the bit-order matches the byte-order.

For now, I'm going to have to assume that they do match.

-- 
Timur Tabi
Linux Kernel Developer @ Freescale
-

From: Lennart Sorensen
Date: Tuesday, October 9, 2007 - 11:34 am

If they are correct, then you should only need to know about byte order

Well that is certainly the normal way it is done.  I think a few odd
machines had options for doing different bit orders, but the normal
setup is that it matches since that is the simplest layout when trying
to implement bit shifts in hardware.

--
Len Sorensen
-

From: Krzysztof Halasa
Date: Tuesday, October 9, 2007 - 11:50 am

There is no such thing as bit-order. The data lines are numbered,
say, D0 - D31, with D0 being LSB (bit) and D31 MSB.

You usually write register bits from MSB to LSB, so shift left
increments and shift right decrements the value. This is orthogonal
to the big/little-endianness.

Now your device can be connected straight to the bus or the data
lanes (4 on 32-bit PCI) can be crossed. This is platform-dependent.
The kernel provides functions/macros to access devices in
a independent way, such as writel/readl/pci_map_* etc.
-- 
Krzysztof Halasa
-

From: Timur Tabi
Date: Tuesday, October 9, 2007 - 11:57 am

Yes, there is.  You need to read the article at 
http://www.linuxjournal.com/article/6788.  Explains what it means for bits to 
be in one order versus another.  This is from the perspective of external 
devices, not the CPU (which is always consistent with regards to bit order)


-- 
Timur Tabi
Linux Kernel Developer @ Freescale
-

From: Krzysztof Halasa
Date: Tuesday, October 9, 2007 - 12:37 pm

Have you ever seen a device or platform with the bits reversed?
I.e. one on which 0x01 from CPU POV is 0x80 or 0x80000000 etc.
from device's POV?

Perhaps I was too brief, I should've written "there is no such
thing WRT the CPU-device connections" because the bit order
actually exists on things like serial lines, though it's totally
independent from big/little endianness of the CPU and/or
peripheral devices, and one can't assume anything matches there.

On parallel bus, all bits (at least of an 8-bit byte) are stored
and transmitted at the same time and address, so no bit can be
first or last.

Once again, you shift left (towards MSBit), you multiply, shifting
right divides. At least as long as you limit it to a single byte.

Perhaps if you tell us what are you exactly trying to achieve...
-- 
Krzysztof Halasa
-

From: Timur Tabi
Date: Tuesday, October 9, 2007 - 12:44 pm

I think when the PowerPC is running in little-endian mode, that might be the 
case.  It needs to be able to write a byte in big-endian mode, and then read 
that byte back in little-endian mode and have it be the same byte.

-- 
Timur Tabi
Linux Kernel Developer @ Freescale
-

From: Krzysztof Halasa
Date: Tuesday, October 9, 2007 - 3:11 pm

But this is exactly what excludes changing bit orders :-)

There are other CPU types which can work both LE and BE.
If you write 0x12345678 and switch endianness you get 0x78563412,
but the individual bits are still in the same (natural) order.

In the kernel, to convert from BE to LE or vice versa you need
something like swab32 (assuming 32-bit ints). It doesn't change
the order of the individual bits, it only swaps the (4 in this case)
bytes ("lanes" for hw swapping, PCI etc).

If you, for example, write an 8-bit integer in BE mode and want
it back in LE mode, you have to XOR the address with 0x3, but
the value already comes in the same natural bit order. Of course
swab32 will do as well.
-- 
Krzysztof Halasa
-

From: Jeremy Fitzhardinge
Date: Tuesday, October 9, 2007 - 12:11 pm

Uh-huh.  Check out an IBM Power manual some time.

    J
-

From: Krzysztof Halasa
Date: Tuesday, October 9, 2007 - 12:39 pm

Some pointer maybe?
-- 
Krzysztof Halasa
-

From: Jeremy Fitzhardinge
Date: Tuesday, October 9, 2007 - 2:40 pm

Erm, a bit of googling will turn one up, but the gist is that IBM has
traditionally bit 0 for MSB and x for LSB.  It's a pain to work with:
for one, bits in the same place in a word (say, control register) are
renumbered in 32 vs 64.  And I've worked on at least one piece of
hardware in which the hardware designer had a brain-fart and first board
had bit 0 on the CPU wired to bit 0 on the northbridge - should have
been 31 -> 0, 30 -> 1, etc...

    J

-

From: Krzysztof Halasa
Date: Tuesday, October 9, 2007 - 3:34 pm

I wasn't aware of that, but it doesn't really change the bit order,
only bit names (numbers actually). Extremely weird BTW but I guess

I suspect the board wasn't able to run any OS, was it? :-)
Would make a real example of the different order of bits, though.
-- 
Krzysztof Halasa
-

From: linux-os (Dick Johnson)
Date: Wednesday, October 10, 2007 - 5:05 am

There are several chips in which bit 0 is the MSB. For instance,
a National Instruments chip used to interface with a GPIB bus,
TNT--something.

Nevertheless, if I write 0x12 to an 8-bit read/write register,
I will read back 0x12, and if I write 0x1234 to an 16-bit
read/write register, I will read back 0x1234. Regardless
of any endian. So, even though the internal 'value' seem
by the chip might not actually be 0x1234, for bit-mapped
registers it doesn't care because you define the function
of each bit.

The only time one would care is if one was setting a
particular value to a divisor of a timer or something
that needed a particular binary value, rather than bits.
In many cases, the value isn't 'pure' anyway. It might
be in BCD or offset-binary or some other perversion
that requires manipulation anyway so, again it is
important --only to the extent the resulting "number"
seen by the chip needs to be correct.

It is instructive to note that RAM is just a bunch
of bits that are uniquely addressable. Often the CPU
can't address one individual bit, but the interface
hardware does and, in particular, modern RAM makes
sure that bits that are adjacent in words are never
adjacent in the physical devices. This is so that
ECC has a chance of working! A nuclear event that
might upset a bit will 'splash' across an area,
upsetting many bits. If they all belonged to the
same few words, the single-bit correction wouldn't
work. The idea in the architecture it to have
nuclear events cause single-bit errors only, so
the bits of a word are never adjacent in physical
space.


Cheers,
Dick Johnson
Penguin : Linux version 2.6.16.24 on an i686 machine (5592.59 BogoMips).
My book : http://www.AbominableFirebug.com/
_


****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the ...
Previous thread: [git patch] net driver fix by Jeff Garzik on Friday, October 5, 2007 - 11:20 am. (1 message)

Next thread: [PATCH] Cute feature: colored printk output by Jan Engelhardt on Friday, October 5, 2007 - 12:13 pm. (22 messages)