BCM1250/BCM1125/BCM1125H
User Manual
10/21/02
B r o a d c o m C o r p o r a t i o n
Page
204
Section 8: PCI Bus and HyperTransport Fabric
Document
1250_1125-UM100CB-R
As an example consider accessing control registers with the same layout as the standard PCI header (this
layout is used only as a familiar one for the example, the interface does not allow 64 bit accesses in
configuration space so this cannot be used directly). Looking at the fields at o0 and +4 with a big endian
viewpoint the expected behavior for a 64 bit read should give the data at low memory address in the high (big)
end of the register:
63:48
Device ID
47:32
Vendor ID
31:16
Status
15:0
Command
This is what a 64 bit read using the Match Bits policy will give. Looking at a PCI 64 bit BAR instead of the control
registers (or equivalently a 64 bit DMA address register) shows that 64 bit accesses will not work directly for
access to 64 bit addresses in HyperTransport peripherals. A 64 bit BAR would span two 32 bit words, but has
the low address bits in the first word and the high address bits in the second word. Looking at this picture with
the big endian viewpoint (as above) the 64 bit read will give:
63:32
Low address bits
31:0
High address bits
This is word swapped compared to what would be ideal, but is still consistent with the 64 bit world-view
because it was originally defined as two 32 bit quantities.
V
IEWING
E
NDIAN
P
OLICY
AS
AN
O
PTIMIZATION
One way to view the endian policy selection is as a way to optimize code. This section considers the software
viewpoint assuming a portable operating system is being used.
To summarize the issue: The PCI/HyperTransport bus and peripherals are little endian, thus when storing a
32 bit value in a register the least significant byte (i.e. bits [7:0]) are assigned to the lowest memory address.
When an access is done from a big endian CPU, which stores a 32 bit value with the most significant byte in
the lowest memory address, the data appears swapped. Consider a 32 bit control register in the PCI device
that contains the 32 bit value 32'h12345678, on the PCI bus the byte containing '78' will be on the byte lane
with the lowest memory address marked with CBE[0] asserted. If the CPU does a read it will place the lowest
memory address into the high bits of the register so will see the 32 bit value 32'h78563412.
In most multi-platform operating systems the first cut way of fixing this is to put an endian swap in if required:
#ifdef BIG_ENDIAN /* Need to swap the bytes */
result = endian_swap(*pci_reg_address);
#else /* on a LITTLE_ENDIAN system can read directly */
result = *pci_reg_address;
#endif
This will work as expected using the Match Bytes access area of the PCI/HyperTransport regions. The Match
Bits space allows the hardware to automatically do the swapping. A single physical address bit (bit [29] in the
standard memory mapped I/O space) is set to switch from Match Bytes to Match Bits. So the code can become:
#ifdef BIG_ENDIAN /* Get hardware to swap the bytes */
result = *(pci_reg_address | BYTES_TO_BITS_ADDRESS_BIT);
#else /* on a LITTLE_ENDIAN system can read directly */
result = *pci_reg_address;
#endif