decoding sparc pci addresses

All modern Sparc Sun machines use the PCI bus to connect peripherals to the system. A PCI bus is a physically addressed bus that can best be represented as an inverted tree. Each level of bus is connected to the next using pci bridge device. The bridge knows the phyical addresses of the devices below itself so it accepts transactions from the higher bus and passes them down. The root of the bus is the host-to-pci bus bridge.

This means that physical PCI bus addresses must be unique within a tree of buses but can be duplicated between seperate trees. This means that there must be a unique way of identifying which tree a pci command is being sent to. Solaris does this by assigning segment of the SPARC chips physical addressable space to each host-to-pci bridge.

If you use prtconf -vp  you can find the host-to-pci bus devices and all their properties. On modern SPARC machine look for schizo devices, on slightly older ones look for psycho nodes. You will find the ranges property , this is in 4 segments , one for configuration space, one for i/o space, one for 32 bit memory and one for 64 bit memory. Encoded in each is the base address and the size.

ranges:                             base address                     size
config    00000000.00000000.   00000000.00000402.00000000.     00000000.01000000.
i/o       01000000.00000000.   00000000.00000402.01000000.     00000000.01000000.
mem32  02000000.00000000.   00000000.0000041c.00000000.     00000000.80000000.
mem64  03000000.00000000.   00000000.0000041c.00000000.     00000000.80000000


So when the PCI bus goes wrong the machine may panic with a PCI Bus Error/BERR which causes the system to print out a fault address AFAR. This is the SPARC physical address that caused the error, so to decide on which bus the fault happenned match the AFAR to a segment supplied by the ranges property of a host-to-pci bridge.

The next problem is to work out which device  on that tree of buses was being accessed. So  subtract the  base of the host-to-pci bus  segment we found above to get the PCI bus physical address that is unique on this tree of PCI buses.  You then have to add the matching assigned-addresses property and the regs property then using the size from the assigned-addresses property you get a base and length to try and match.


 type address size 
assigned-addresses:  82010010. 00000000.08000000. 00000000.01000000...
               reg:  02010010. 00000000.00002000. 00000000.00800000...

sum 10 = mem32 00000000.08002000. 00000000.01000000
so this mem32 segment runs from PCI physical address 0x08002000 for length 0x01000000

It sounds easy but I have been writting code to  automate this for a couple of days now!



Comments:

Post a Comment:
Comments are closed for this entry.
About

timatworkhomeandinbetween

Search

Archives
« March 2015
MonTueWedThuFriSatSun
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
     
Today
News

No bookmarks in folder

Blogroll

No bookmarks in folder