On 09/26/15 02:49, Shubha Ramani wrote: > Thank you again for your detailed email Lazslo.
The fun never stops; last time you wrote "Lazlo" and I mentioned that my first name was L-A-S-Z-L-O. I also recommended that you try copy & paste. I can see the attempt here (you added an "S" indeed), but that's still not copy & paste, because the order of S and Z is in reverse. Sigh. I guess I should change my name. > I tried your tricks and > unfortunately, no luck. > But I did find something out. Our internal specifications lied. Who would have thought. :) > The bus > we're looking for is not 1 but > rather 0xFE. And if I look at the boot logs the PCI registers I need are > definitely being initialized and written > to properly during boot-up on PCI bus 0xFE. What boot logs? Are they logged by some proprietary code, or by the PCI bus driver of edk2? > Is it a possibility that the "pci" command or the UEFI PCI Bus Driver > has a bug in it to where it's not > recognizing 0xFE ? The PCI bus driver recursively enumerates root bridges for which your root bridge driver produces PciRootBridgeIo protocol instances, and which PciRootBridgeIo instances the BDS policy tells the PCI bus driver to connect. That's all I can say. Did you try the "dh" command from my previous email? If there's only one PciRootBridgeIo protocol instance in the system, (and bus 0xFE is not on that (after enumeration)), then it's probably an issue with your PCI host bridge / root bridge driver. > Some people I know are suggesting the following approach to read PCI > registers (the 0xCF8 approach): > PCI - OSDev Wiki <http://wiki.osdev.org/PCI> Sure, you can do that very easily in edk2 too, with the appropriate PciLib library instance; see again (2) in http://thread.gmane.org/gmane.comp.bios.edk2.devel/2491/focus=2492 But that is not the pedantic UEFI driver / app way -- direct PciLib use is appropriate for code that is shipped with the platform (ie. where you have ingrained knowledge about platform specifics -- DXE drivers, PEIMs, etc), but UEFI modules (drivers and apps) are supposed to be independent of the platform (like if PCI config space is memory mapped vs. accessible through ioports 0xCF8/0xCFC), so in UEFI driver & app modules you should use PciIo protocol instances. (I don't claim that we comply with the above 100% in OvmfPkg.) Thanks Laszlo > > > > > > > > > > > PCI - OSDev Wiki <http://wiki.osdev.org/PCI> > Contents 1 The PCI Bus 2 Configuration Space 2.1 Configuration Space > Access Mechanism #1 2.2 Configuration Space Access Mechanism #2 2.3 > Memory Mapped PCI Configuration Space Access > View on wiki.osdev.org <http://wiki.osdev.org/PCI> > > Preview by Yahoo > > > > uint16_t pciConfigReadWord (uint8_t bus, uint8_t slot, > uint8_t func, uint8_t offset) > { > uint32_t address; > uint32_t lbus = (uint32_t)bus; > uint32_t lslot = (uint32_t)slot; > uint32_t lfunc = (uint32_t)func; > uint16_t tmp = 0; > > /* create configuration address as per Figure 1 */ > address = (uint32_t)((lbus << 16) | (lslot << 11) | > (lfunc << 8) | (offset & 0xfc) | ((uint32_t)0x80000000)); > > /* write out the address */ > sysOutLong (0xCF8, address); > /* read in the data */ > /* (offset & 2) * 8) = 0 will choose the first word of the 32 bits > register */ > tmp = (uint16_t)((sysInLong (0xCFC) >> ((offset & 2) * 8)) & 0xffff); > return (tmp); > } > > > Thanks, > > Shubha > > * > Shubha D. Ramani > [email protected] <mailto:[email protected]> > [email protected] <mailto:[email protected]>* > > > > On Friday, September 25, 2015 11:25 AM, Laszlo Ersek <[email protected]> > wrote: > > > On 09/25/15 00:59, Shubha Ramani wrote: >> Hello Laszlo. >> >> All I see from the driver debug messages are the following type(just a >> snippet printed). I assume the format is [B|F|D] and I'm not >> seeing any with 01 for the B. So the PCI Bus Driver is not seeing Bus 1 >> it seems. Is my interpretation correct ? >> >> PciBus: Discovered PCI @ [00|00|00] >> >> PciBus: Discovered PCI @ [00|00|01] >> >> PciBus: Discovered PCI @ [00|00|04] >> >> PciBus: Discovered PCI @ [00|00|05] >> >> PciBus: Discovered PCI @ [00|00|06] >> >> PciBus: Discovered PCI @ [00|00|07] >> >> PciBus: Discovered PCI @ [00|01|04] >> >> PciBus: Discovered PCI @ [00|01|05] >> >> PciBus: Discovered PCI @ [00|01|06] >> >> PciBus: Discovered PCI @ [00|01|07] >> >> PciBus: Discovered PCI @ [00|02|04] >> >> PciBus: Discovered PCI @ [00|02|05] >> >> PciBus: Discovered PCI @ [00|02|06] >> >> PciBus: Discovered PCI @ [00|02|07] >> >> PciBus: Discovered PCI @ [00|05|00] >> >> PciBus: Discovered PCI @ [00|05|02] >> >> PciBus: Discovered PCI @ [00|05|03] >> >> PciBus: Discovered PCI @ [00|05|04] >> >> blah >> blah >> blah > > I think I've had the same idea as Bill described in his email. Here's > what I thought: > > Your bus numbers can originate from two places. Your buses are either > (a) secondary / subordinate buses, or (b) separate root buses. > > Secondary / subordinate buses live behind PCI bridges, and are > recursively traversed / enumerated by the PCI bus driver, during which > the PCI bus numbers are assigned. > > Separate root buses are associated with PciRootBridgeIo protocol > instances. The PCI host bridge / root bridge driver produces those > protocol instances, one for each separate root bus. The way the PCI host > bridge / root bridge driver determines how many root buses there are, > and what bus number ranges those get, is platform specific (and I > presume this is what can be exposed to the runtime OS too with the ACPI > tables that Bill mentioned). > > The PCI Bus driver binds and recursively enumerates *individual* > PciRootBridgeIo protocol instances. During enumeration, if I recall > correctly, the host bridge protocol is consulted for the range of > possible bus numbers for that root bridge, from which range the bus > numbers will be assigned to the root bus itself, and any subordinate > buses too, beyond bridges rooted (recursively) in the same one root bus. > > Now, you don't seem to have a bridge plugged into the "first" PCI root > bus. Namely, that would be listed by the PCI Bus driver, and you'd see > the bridge as well in the PCI Bus driver's debug log. Since you don't > see that, we can conclude that the special device on bus 1 either > doesn't exist, *or* that it belongs to a separate root bus. (Represented > by another PciRootBridgeIo protocol instance.) > > Then the question becomes: if you have another root bus, then why > doesn't the PCI Bus driver enumerate it? See above -- as I explained > (and I hope I recall this correctly), the PCI bus driver binds > *individual* root buses. According to the UEFI driver model, it won't > look for separate root buses that it "could" bind. > > Therefore this is ultimately in the hands of platform BDS. Platform BDS > is where the top-level gBS->ConnectController() calls are issued. > Therefore, *if* indeed you have a separate root bus, and the special > device exists on that root bus, then my take is that it is not > enumerated because your platform BDS does not connect that > PciRootBridgeIo protocol instance, despite the PCI host bridge / root > bridge driver having produced that protocol instance. > > (The PCI host bridge / root bridge driver does not follow the UEFI > driver model usually -- it doesn't need another handle to bind, in order > to produce new (child) handles. Instead it produces brand new handles > with root bridge io protocol instances on them out of thin air, in its > entry point function, using platform-specific knowledge.) > > You can verify if you have multiple root buses with the following UEFI > shell command: > > dh -d -v -p PciRootBridgeIo > > If multiple handle numbers are printed, you can try to connect each > (with "all suitable drivers", including the PCI Bus driver), with the > following command: > > connect HANDLE_NUMBER > > For handles that the PCI Bus driver did not previously bind, you'll see > the enumeration log appear, and hopefully the special device too will > show up. > > If it does, then you can investigate two solutions: > - modify your platform BDS to connect the "other" root bus automatically, > - modify your UEFI_APPLICATION module to locate all PciRootBridgeIo > protocol instances, and connect them all (or connect just the "right > one") before you start looking for the special PCI device. > > ... Sorry I think the above is quite inaccurate or ad-hoc in some > places; it's been a hard week. My memories about > OvmfPkg/PciHostBridgeDxe are somewhat vague at this point. I do remember > that when I implemented OVMF support for QEMU's multiple root buses (PXB > device), I had to modify our platform BDS to connect those extra root > buses as well. > > Summary: try to find out if you have additional handles with > PciRootBridgeIo on them (see the dh command above), and if so, connect > them too, in the shell, in the platform BDS, or in your application. The > PCI Bus driver should then do the enumeration / bus number assignment. > > > Laszlo > > _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

