The i960® CA and CF microprocessors can access memory in two byte order formats: Little-endian and big-endian. This document shows the difference between the two modes and describes how application developers can use the big-endian support of the i960® processor family.
The following scenario describes a problem:
I am designing a high performance upgrade to an existing product. The new design must provide more CPU horsepower than our current design provides. I have some C source code from the current design that I hope to use for the upgrade. Our current design uses a processor that accesses memory in "big-endian" form. I feel locked into the processor family that we are already using. How can I use an 80960 processor for my upgrade?
BIG vs. LITTLE ENDIAN
Addressing Fixed Length Data
Let's examine a hypothetical processor that can address 8-bit words. This conceptual processor has registers that are 8 bits wide; each 8-bit work has a unique individual address. Table 1 shows an example of this processor addressing an 8-bit word at location 5. When the processor accesses this 8-bit quantity, the word's address is placed on the bus (5), then the 8-bit word (0xab) is transferred between memory and an internal register. If the processor has the ability to address and transfer only 8-bit words, and the software uses only 8-bit words, there is no "endian-ness".
Data Larger Than a Word
Referring back to the hypothetical 8-bit processor of Table 1, assume that software can assemble multiple 8-bit words to form larger data types; 16-bit integers for example. Since this processor can transfer only 8-bit words, there are two options in transferring a 16-bit quantity:
1) transfer the most significant 8-bit word of the integer first, then transfer the least significant 8-bit word, or
2) transfer the least significant 8-bit word, then transfer the most significant 8-bit word.
A programmer could access one 16-bit value with the high-order byte first and a different 16-bit value low-order byte first; however, to avoid unnecessary confusion, the programmer should follow an ordering convention to transfer a 16-bit quantity. If a 16-bit quantity is stored into memory high byte first and read out of memory low byte first, then the value will be scrambled. Byte order is not important when working only with 8-bit words butwith a 16-bit value possible byte order is very important. Referring to Table 1, a 16-bit word access to location 5 has two possible values: 0xabcd (big endian) or 0xcdab (little endian).
Data smaller than a Word
Byte order is important when assembling multiple addressable units into a larger data type as in the above example. In the above case, an 8-bit processor is accessing 16-bit data. A similar byte ordering problem exists with a 16-bit processor accessing 8-bit data.
In Table 2, which shows a 16-bit processor accessing 16-bit words, address 5 refers to the fifth addressable unit. Since an addressable unit in Table 2 is 16 bits wide, the word at address 5 is the fifth 16-bit word. Other complications arise when byte addressing capability is added to this 16-bit processor. Table 4 shows a 16-bit word machine with byte addressing capability. Even though this 16-bit processor can now address bytes, a word is still 16 bits wide.
To access the fifth 16-bit word, no longer can address 5 be used as shown in Table 2. Since each address now refers to a bytenot a 16-bit word the address of the fifth word is 10: 5 words x 2 bytes per word. A 16-bit word at byte address 10 is the fifth word.
Comparing Table 2 with Table 4, a word access at address 5 on the 16-bit word-addressable processor is the same as a word access at address 10 on the byte addressable 16-bit processor. This word's value is 0x6655. This processor supports byte addressing: therefore, the fifth word consists of two addressable bytes: address 5 and address 6.
On a big endian processor, the byte value of address 10 is 0x66; on a little endian processor, the byte value of address 10 is 0x55.
In general, endian-ness exists when it is possible to address items of more than one size, such as 8, 16 and 32-bit integers.
INTEL i960® PROCESSOR ADDRESSING FEATURES
All i960® processors share some addressing features:
i960® Little Endian Addressing
Little endian refers to the addressing convention where the least significant portion of multi-byte values is stored at lower addresses in a little endian region.
ld 12, r3 loads 0x12345678 into register r3Data is transferred over the bus according to Table 6 for an 8-bit bus, Table 7 for a 16-bit bus and Table 8 for a 32-bit bus.
ldob 12, r3 loads 0x78 into r3
ldos 12, r3 loads 0x5678 into r3
Note the data lines that transfer the data:
Byte 0 is always transferred on data lines D7-D0
Byte 1 is transferred on data lines D7-D0 for an 8-bit bus; lines D15-D8 for 16 and 32-bit buses
Byte 2 is transferred on data lines D7-D0 for 8 and 16-bit buses; D23-16 for 32-bit buses
Byte 3 is transferred on data lines D7-D0 for an 8-bit bus; D15-D7 for a 16-bit bus; D31-D24 for a 32-bit bus
Table 6. Byte Addresses on 8-bit Bus
Table 7. Byte Addresses on 16-bit Bus
Table 12. Byte Addresses on 32-bit Bus
When the i960® processor performs a big endian access, it stores the most significant byte to the lowest address. Table 9 shows eight words stored in big endian memory:
ld 12, r3 loads 0x12345678 into register r3 as in the little endian example aboveThe data lines are the same ones used in the little endian model (see Tables 10, 11 and 12).
ldob 12, r3 loads 0x12 into r3 which is different than little endian, which loaded 0x78
ldos 12, r3 loads 0x1234 into r3
Table 10. Byte Addresses on 8-bit Bus
Table 11. Byte Addresses on 16-bit Bus
Table 12. Byte Addresses on 32-bit Bus
Many 32-bit processors and DMA devices that perform big endian transfers use different data lines for the transfers. Byte 0 on such processors use data lines D31-D24. If any other processors or big endian DMA devices are used in a i960® processor-based system, be sure to match the byte addresses. Connect byte address 0 on the "other" system to byte address 0 on the i960® processor. As shown in Figure 1, this causes bits D31-D24 to connect to D7-D0; D23-D16 to D15-D7; D7-D0 to D31-D24.
The previous section explained the differences between little and big endian modes. This section covers the steps required to use another processor's big endian code on a i960® processor.
Starting From C Code
Figure 2 is an example of application code that looks at Ethernet frames and filters out IP frames.
Address checking may or may not be performed in the address_check routine; the important thing to notice is that a structure is being passed as a parameter to that function. If the address_check function returns a non-zero value, frame_check returns the value 1, which means that the frame passed the filter. If the frame is not an IP frame or if address_check returns zero, frame_check returns zero, which means that the frame did not pass the filter.
Other Big Endian Processors
Assume that an external Ethernet controller chip, programmed in big endian mode, creates the Ethernet structure. Note that Ethernet controller byte 0 connects to the processor's byte 0. Assume that the Ethernet controller transfers the most significant byte over data lines D31-D24. Assuming also that the processor's most significant byte is D31-D24, the data lines are connected as shown in Table 13.
The buffer is filled with data in the form:
The structure enet_hdr is defined as six bytes of destination address, followed by six bytes of source address, followed by a 16-bit integer that is the length field. Table 14 shows the structure member offsets.
Little Endian Processor
What would happen if the big endian processor, interfaced to a big endian Ethernet controller, is replaced with a little endian processor? If the program described above is compiled for a little endian processor, the structure changes. Table 15 shows the locations used for the structure members.
i960® Processor Big Endian Support
Currently the i960® processor family has two members that support both little endian and big endian accesses: the i960® CA and i960® CF processors. There are at least two Intel compilers that support big endian data: the GNU960 C compiler and the CTOOLS960 compiler. There is a command line switch for each compiler to tell the tools to compile for a little endian or big endian system (-Gbe for CTOOLS960; -G for GNU960). The example program above creates the following structure when using the big endian switch:
Unaligned Big Endian Accesses
The i960® CA processor's D-step and the i960® CF processor's C-step both support unaligned big endian data. Steppings previous to these did not support unaligned big endian. Aligned big endian data can be accessed using any load or store instructions without any restrictions; however, there is a restriction when using unaligned big endian accesses. Unaligned accesses larger than 32 bits are not supported.
There are very few instances where multi-word unaligned accesses can occur using the GNU960 or CTOOLS960 C compilers. The compilers generate aligned data unless a #pragma align or #pragma pack (available on the GNU960 compiler) are used to force different alignment of structure elements. It is possible that a pointer to a structure is unaligned. In the example C code in Figure 2, the compiler generates a quad-word load to pass (*hdr) to the address_check function. If hdr was not aligned this would cause problems if compiled with the Intel CTOOLS960 compiler. The CTOOLS960 compiler requires proper alignment when performing structure assignments and when performing structure parameter passing by value as in this example.
When using the GNU960 compiler, the programmer must use the #pragma align directive to ensure that the compiler recognizes the potential for unaligned structures. With the proper #pragma align directive, the compiler properly handles any alignment. Structure assignments and passing structures to functions were not allowed in the Kernighan & Ritchie version of C, but ANSI C does not have this restriction.
This is correct for CTOOLS960 Release 4.0; however, the next release is expected to limit unaligned big endian accesses to one word.
Legal Stuff © 1997 Intel Corporation