The PCI Bus under Open Firmware
Practically everything on a PowerMac except the processor and the RAM is a device which is connected to the processor through the PCI bus, which maps the device's registers to memory through a somewhat convoluted process. At least from an Open Firmware point of view.
If you look at an OF device node for a PCI Bus, you will see that it has
the #address-cells
property set to 3, and the #size-cells
property
set to 2. The reg
property of a node is a series of addr/size
pairs, so a PCI child node's reg
property will have entries which are
5 cells in size.
Note that this is not a main memory address -- it is an OF PCI bus
address. To get an actual memory address, you have to take the bus
specifier (the first cell of the PCI address), and find the matching entry
in the assigned-addresses
property (bus, device, function, and
register fields must match). assigned-addresses
has the same format
as reg
, except that the PCI address indicates that this is NOT a
relocatable address, so the low cell (or two cells for a 64-bit Memory
Space address) are an actual physical memory address.
Then you just have to map the physical address to get a virtual address
that you can use to access it from the processor. I'm currently calling
the map-in
method of the root node ("/") of the OF device tree.
However, PearPC won't open the root node, so presumably there are other
ways to do this. It looks like the Linux kernel goes up through the
device tree until it finds a pci bridge node (device-type
= "pci"),
and then looks up the address in the ranges
property. But...that
still leaves you with a physical address. Grr. How do you get from a
physical to a virtual address?