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 -
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 -
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 -
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. -
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 -
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." -
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 -
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. -
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 -
.../... (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. -
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." -
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/ -
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 -
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." -
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 -
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." -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
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 -
Uh-huh. Check out an IBM Power manual some time.
J
-
Some pointer maybe? -- Krzysztof Halasa -
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
-
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 -
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 ...
