On Mon, Aug 09, 2010 at 06:19:14PM -0500, David Young wrote: > Attached is a preview of information that I supply to instances of > pci(4), ppb(4), and cbb(4) through their device properties. The > information will help them manage PCI address spaces and to program > their address windows correctly, so that I can retire rbus and > PCI_ADDR_FIXUP, whose heuristics are incomplete. > > Currently, I derive the information by scanning PCI Configuration Space. > The system BIOS---be it OpenFirmware, ACPI, or something else---may > supply similar information.
Here is a new snapshot of the PCI information that I'm reading out of PCI Configuration Space. This time the format is slightly different, and the property list includes the I/O-space reservations and the legacy VGA regions. I've had a look at the document on the IEEE 1275 (sp?) bindings that Eduardo Horvath mentioned, and there appears to be a very good fit between the OpenFirmware format and my property-list format. I'm looking for volunteers to parse ACPI and OpenFirmware information into this format. Let me describe the format: PCI functions including bridges have in their device_properties() a "pci-resources" key. Properties for device `pci0': <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>device-driver</key> <string>pci</string> <key>device-unit</key> <integer>0x0</integer> <key>pci-resources</key> Under that key is a dictionary with "io" and "memory" keys, corresponding to PCI I/O and memory-mapped I/O space: <dict> <key>io</key> ... <key>memory</key> ... Under each of those keys is a dictionary containing one key, "bios-reservations", and under that key an array of dictionaries: ... <key>io</key> <dict> <key>bios-reservations</key> <array> <dict> ... </dict> ... Each dictionary in the array describes one I/O or memory range reserved by this PCI function or, in the case of a bridge, reserved by this function or one of its subordinate functions. The dictionary identifies the function corresponding with the range with "bus"/"device"/"function" keys, <dict> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0x1</integer> <key>function</key> <integer>0x0</integer> ... it tells the starting address and width of the range, <key>address</key> <integer>0xa000</integer> <key>size</key> <integer>0x1000</integer> it tells the type of reservation---i.e., whether the range was reserved by a bus-bridge window ("window"), a Base Address Register ("bar"), or the PCI Command & Status Register's VGA-enable bit ("vga-enable"), <key>type</key> <string>window</string> and it tells the PCI Configuration Space registers that encode the reservation using an array at "regs"---VGA enables, 64-bit BARs and bus-bridge windows to encode a reservation using two registers; all other reservations use one register, <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x1c</integer> <key>val</key> <integer>0xa0a0</integer> </dict> </array> </dict> If the kernel reclaims and re-assigns the I/O or memory space used by a PCI subtree, it can put all of the BIOS assignments back by using the "regs" array. Every register is encoded with a Configuration Space offset, a value, and a mask---the register is restored by pci_conf_write(..., ofs, pci_conf_read(..., ofs) & ~mask | val & mask), <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x1c</integer> <key>val</key> <integer>0xa0a0</integer> </dict> </array> </dict> Dave -- David Young OJC Technologies [email protected] Urbana, IL * (217) 344-0444 x24
Properties for device `pci0': <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>device-driver</key> <string>pci</string> <key>device-unit</key> <integer>0x0</integer> <key>pci-resources</key> <dict> <key>io</key> <dict> <key>bios-reservations</key> <array> <dict> <key>address</key> <integer>0xa000</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0x1</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x1c</integer> <key>val</key> <integer>0xa0a0</integer> </dict> </array> <key>size</key> <integer>0x1000</integer> <key>type</key> <string>window</string> </dict> <dict> <key>address</key> <integer>0x3b0</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0x1</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0x1</integer> <key>offset</key> <integer>0x4</integer> <key>val</key> <integer>0x22200007</integer> </dict> <dict> <key>mask</key> <integer>0x80000</integer> <key>offset</key> <integer>0x3c</integer> <key>val</key> <integer>0x80000</integer> </dict> </array> <key>size</key> <integer>0xc</integer> <key>type</key> <string>vga-enable</string> </dict> <dict> <key>address</key> <integer>0x3c0</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0x1</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0x1</integer> <key>offset</key> <integer>0x4</integer> <key>val</key> <integer>0x22200007</integer> </dict> <dict> <key>mask</key> <integer>0x80000</integer> <key>offset</key> <integer>0x3c</integer> <key>val</key> <integer>0x80000</integer> </dict> </array> <key>size</key> <integer>0x20</integer> <key>type</key> <string>vga-enable</string> </dict> <dict> <key>address</key> <integer>0x1100</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0x7</integer> <key>function</key> <integer>0x1</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x20</integer> <key>val</key> <integer>0x1101</integer> </dict> </array> <key>size</key> <integer>0x10</integer> <key>type</key> <string>bar</string> </dict> <dict> <key>address</key> <integer>0x3000</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0x7</integer> <key>function</key> <integer>0x2</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x20</integer> <key>val</key> <integer>0x3001</integer> </dict> </array> <key>size</key> <integer>0x20</integer> <key>type</key> <string>bar</string> </dict> <dict> <key>address</key> <integer>0x0</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0xa</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x2c</integer> <key>val</key> <integer>0x1</integer> </dict> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x30</integer> <key>val</key> <integer>0x1</integer> </dict> </array> <key>size</key> <integer>0x4</integer> <key>type</key> <string>window</string> </dict> <dict> <key>address</key> <integer>0x0</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0xa</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x34</integer> <key>val</key> <integer>0x1</integer> </dict> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x38</integer> <key>val</key> <integer>0x1</integer> </dict> </array> <key>size</key> <integer>0x4</integer> <key>type</key> <string>window</string> </dict> <dict> <key>address</key> <integer>0x3100</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0xd</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x10</integer> <key>val</key> <integer>0x3101</integer> </dict> </array> <key>size</key> <integer>0x100</integer> <key>type</key> <string>bar</string> </dict> <dict> <key>address</key> <integer>0x3200</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0xd</integer> <key>function</key> <integer>0x1</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x10</integer> <key>val</key> <integer>0x3201</integer> </dict> </array> <key>size</key> <integer>0x100</integer> <key>type</key> <string>bar</string> </dict> </array> <key>size</key> <integer>0xb000</integer> <key>start</key> <integer>0x0</integer> </dict> <key>memory</key> <dict> <key>bios-reservations</key> <array> <dict> <key>address</key> <integer>0x20000000</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0x0</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x10</integer> <key>val</key> <integer>0x20000008</integer> </dict> </array> <key>size</key> <integer>0x2000000</integer> <key>type</key> <string>bar</string> </dict> <dict> <key>address</key> <integer>0x40000000</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0x1</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x20</integer> <key>val</key> <integer>0x47004000</integer> </dict> </array> <key>size</key> <integer>0x7100000</integer> <key>type</key> <string>window</string> </dict> <dict> <key>address</key> <integer>0x48000000</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0x1</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x24</integer> <key>val</key> <integer>0x4f004800</integer> </dict> </array> <key>size</key> <integer>0x7100000</integer> <key>type</key> <string>window</string> </dict> <dict> <key>address</key> <integer>0xa0000</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0x1</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0x2</integer> <key>offset</key> <integer>0x4</integer> <key>val</key> <integer>0x22200007</integer> </dict> <dict> <key>mask</key> <integer>0x80000</integer> <key>offset</key> <integer>0x3c</integer> <key>val</key> <integer>0x80000</integer> </dict> </array> <key>size</key> <integer>0x20000</integer> <key>type</key> <string>vga-enable</string> </dict> <dict> <key>address</key> <integer>0x7800000</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0xa</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x10</integer> <key>val</key> <integer>0x7800000</integer> </dict> </array> <key>size</key> <integer>0x1000</integer> <key>type</key> <string>bar</string> </dict> <dict> <key>address</key> <integer>0x22000000</integer> <key>bus</key> <integer>0x0</integer> <key>device</key> <integer>0xd</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x14</integer> <key>val</key> <integer>0x22000000</integer> </dict> </array> <key>size</key> <integer>0x2000</integer> <key>type</key> <string>bar</string> </dict> <dict> <key>address</key> <integer>0x40000000</integer> <key>bus</key> <integer>0x1</integer> <key>device</key> <integer>0x0</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x10</integer> <key>val</key> <integer>0x40000000</integer> </dict> </array> <key>size</key> <integer>0x800000</integer> <key>type</key> <string>bar</string> </dict> <dict> <key>address</key> <integer>0x40800000</integer> <key>bus</key> <integer>0x1</integer> <key>device</key> <integer>0x0</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x14</integer> <key>val</key> <integer>0x40800000</integer> </dict> </array> <key>size</key> <integer>0x20000</integer> <key>type</key> <string>bar</string> </dict> <dict> <key>address</key> <integer>0x41000000</integer> <key>bus</key> <integer>0x1</integer> <key>device</key> <integer>0x0</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x18</integer> <key>val</key> <integer>0x41000000</integer> </dict> </array> <key>size</key> <integer>0x800000</integer> <key>type</key> <string>bar</string> </dict> <dict> <key>address</key> <integer>0x7810000</integer> <key>bus</key> <integer>0x2</integer> <key>device</key> <integer>0x0</integer> <key>function</key> <integer>0x0</integer> <key>regs</key> <array> <dict> <key>mask</key> <integer>0xffffffff</integer> <key>offset</key> <integer>0x10</integer> <key>val</key> <integer>0x7810000</integer> </dict> </array> <key>size</key> <integer>0x10000</integer> <key>type</key> <string>bar</string> </dict> </array> <key>size</key> <integer>0x4f060000</integer> <key>start</key> <integer>0xa0000</integer> </dict> </dict> </dict> </plist>
