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

Reply via email to