Thank you again for your detailed email Lazslo. I tried your tricks and unfortunately, no luck. But I did find something out. Our internal specifications lied. The bus we're looking for is not 1 butrather 0xFE. And if I look at the boot logs the PCI registers I need are definitely being initialized and writtento properly during boot-up on PCI bus 0xFE. Is it a possibility that the "pci" command or the UEFI PCI Bus Driver has a bug in it to where it's notrecognizing 0xFE ? Some people I know are suggesting the following approach to read PCI registers (the 0xCF8 approach):PCI - OSDev Wiki
| | | | | | | | | PCI - OSDev WikiContents 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 | 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. ramanishubharam...@gmail.com shubharam...@yahoo.com On Friday, September 25, 2015 11:25 AM, Laszlo Ersek <ler...@redhat.com> 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 edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel