Date: Thu, 14 Sep 1995 23:05:49 -0700 From: jordan@pongo.West.Sun.COM (Jordan Brown) Subject: Item #287: PCI Supp: Supply examples to clarify PCI address handling P1275 Openboot Working Group Proposal -- Proposal #:287 Ver 1.0 Title: Supply examples to clarify PCI address handling Author: Jordan Brown Date: 14 September 1995 Ed/Tech: Technical Synopsis: Gives examples of typical "reg" and "assigned-address" values Doc & Version: PCI binding 1.5 Problem: While our developer group appears to be slowly understanding the underlying models and intent of the PCI binding's treatment of "reg" and "assigned-addresses", we are both concerned that we do not yet fully understand the binding and that future readers (including people writing FCode for devices we will have to support!) will encounter some of the same misunderstandings we've been through. Proposal: At the end of the document, add a section: Examples In the following examples: xxxx represents the bus, device, function numbers as appropriate hhhhhhhh represents the high 32 bits of a PCI absolute address llllllll represents the low 32 bits of a PCI absolute address A simple function, with a single 256-byte non-prefetchable memory range and no expansion ROM: Base address 0x10 ??????00 ... after writing ffffffff ffffff00 Base address 0x14 00000000 ... after writing ffffffff 00000000 (same for 0x18, 0x1c, 0x20, 0x24, and 0x30) reg: phys_hi phys_mid phys_lo size_hi size_lo 00xxxx00 00000000 00000000 00000000 00000000 02xxxx10 00000000 00000000 00000000 00000100 assigned-addresses: 82xxxx10 00000000 llllll00 00000000 00000100 with the resulting base registers: 0x10 llllll00 A simple VGA, with no relocatable regions and a 4K non-Fcode expansion ROM: Base address 0x10 00000000 ... after writing ffffffff 00000000 (same for 0x14, 0x18, 0x1c, 0x20, and 0x24) Expansion ROM address 0x30 ?????000 ... after writing ffffffff fffff000 reg: phys_hi phys_mid phys_lo size_hi size_lo 00xxxx00 00000000 00000000 00000000 00000000 02xxxx30 00000000 00000000 00000000 00001000 81xxxx00 00000000 000003b0 00000000 0000000c 81xxxx00 00000000 000003c0 00000000 00000020 82xxxx00 00000000 000a0000 00000000 00020000 assigned-addresses: 82xxxx30 00000000 lllll000 00000000 00001000 with the resulting base registers: 0x30 lllll000 A function with 256 bytes of registers mappable as both memory and I/O space, without FCode: Base address 0x10 ??????00 ... after writing ffffffff ffffff00 Base address 0x14 ??????01 ... after writing ffffffff ffffff01 Base address 0x18 00000000 ... after writing ffffffff 00000000 (same for 0x1c, 0x20, 0x24, and 0x30) reg: phys_hi phys_mid phys_lo size_hi size_lo 00xxxx00 00000000 00000000 00000000 00000000 02xxxx10 00000000 00000000 00000000 00000100 01xxxx14 00000000 00000000 00000000 00000100 assigned-addresses: 82xxxx10 00000000 llllll00 00000000 00000100 81xxxx14 00000000 llllll00 00000000 00000100 with the resulting base registers: 0x10 llllll00 a memory address 0x14 llllll01 an I/O address The same function, with 4K of FCode that reveals that the first 32 bytes of the registers are unused and the second 32 bytes are used only for diagnostic purposes: Base address 0x10 ??????00 ... after writing ffffffff ffffff00 Base address 0x14 ??????01 ... after writing ffffffff ffffff01 Base address 0x18 00000000 ... after writing ffffffff 00000000 (same for 0x1c, 0x20, and 0x24) Expansion ROM 0x30 ?????000 ... after writing ffffffff fffff000 reg: phys_hi phys_mid phys_lo size_hi size_lo 00xxxx00 00000000 00000000 00000000 00000000 02xxxx10 00000000 00000040 00000000 000000c0 alternate-reg: 00000000 00000000 00000000 00000000 00000000 01xxxx14 00000000 00000040 00000000 000000c0 *1 02xxxx10 00000000 00000020 00000000 00000020 *2 01xxxx14 00000000 00000020 00000000 00000020 *3 Notes: *1 Secondary access to operational registers *2 Primary access to diagnostic registers *3 Secondary access to diagnostic registers assigned-addresses: 81xxxx14 00000000 llllll00 00000000 00000100 82xxxx10 00000000 llllll00 00000000 00000100 (Note that this platform appears to allocate I/O space first, yielding an assigned-addresses property in a different order from the reg property.) with the resulting base registers: 0x10 llllll00 a memory address 0x14 llllll01 an I/O address Example procedures to determine the physical address of a particular register: Problem: Given the last device described above, determine the physical address associated with the 3rd byte of its operational registers. 1. Extract the second physaddr,size pair from the reg property. (We know to use the second pair because the first pair is the Configuration Space entry and the device documentation tells us that the second pair is the operational registers.) 2. Note that the "n" bit is zero, indicating a relocatable region. Note that the rrrrrrrr field is 0x10. 3. Search the assigned-addresses property for an entry with an rrrrrrrr field of 0x10. Find the second entry. 4. Add the phys_mid,phys_lo value from the assigned-addresses entry to the phys_mid,phys_lo value (0x40) from the reg entry. This yields the physical base of the device's operational registers. 5. Add this value to the desired register offset, 3. This yields the physical address of the desired register. Problem: Given the VGA device described above, determine the physical address associated with the sequencer index register (address 3c4 in the documentation). (Of course, we could "just know" that the answer is 3c4, but let's do it according to the book.) 1. Extract the fourth physaddr,size pair from the reg property. (We know to use the fourth pair because the first pair is the Configuration Space entry, the second pair is the ROM, the third pair is the monochrome I/O range, the fourth pair is the color I/O range, and the fifth pair is the video memory.) 2. Note that the "n" bit is one, indicating a non-relocatable region. 3. Add the phys_mid,phys_lo values from this reg pair to the desired register offset, 4. This yields the physical address of the sequencer index register. [ P1275 Item #287 -- Received: Thu Sep 14 23:08:59 PDT 1995 ]