On 11/14/14 14:31, Gabriel Somlo wrote:
> On Fri, Nov 14, 2014 at 10:26:55AM +0100, Laszlo Ersek wrote:
>> One question.
>>
>> On 11/14/14 04:01, Gabriel L. Somlo wrote:
>>> +
>>> +  Status = EFI_SUCCESS;
>>> +
>>> +  if (PciHdr->Device.InterruptPin != 0) {
>>
>> so here InterruptPin >= 1
> 
> Same as in SeaBIOS pci_bios_init_device() under "/* map the interrupt */":
> 
>   if (pin != 0)
>       pci_config_writeb(bdf, PCI_INTERRUPT_LINE, pci_slot_get_irq(pci, pin));
> 
> 
>>> +
>>> +    DevPathNode = DevicePathFromHandle (Handle);
>>> +    ASSERT (DevPathNode != NULL);
>>> +
>>> +    //
>>> +    // Compute index into PciHostIrqs[] table by walking
>>> +    // the device path and adding up all device numbers
>>> +    //
>>> +    Status = EFI_NOT_FOUND;
>>> +    Idx = PciHdr->Device.InterruptPin - 1;
>>
>> Hence Idx >= 0 (in the mathematical sense -- I'm just saying there's no
>> unsigned underflow)
> 
> So here it gets a bit fuzzy, because piix_pci_slot_get_irq uses
> "slot_addend", and mch_pci_slot_get_irq uses "pin_addend", so I had to
> massage them both a bit before I could factor out what's common and
> what differs :) But let's roll with piix_pci_slot_get_irq():
> 
> static int piix_pci_slot_get_irq(struct pci_device *pci, int pin)
> {
>     int slot_addend = 0;
> 
>     while (pci->parent != NULL) {
>         slot_addend += pci_bdf_to_dev(pci->bdf);
>         pci = pci->parent;
>     }
>     slot_addend += pci_bdf_to_dev(pci->bdf) - 1;
>     return pci_irqs[(pin - 1 + slot_addend) & 3];
> }
> 
>  
>>> +    RootSlot = 0; // Suppress gcc uninitialized use warning
>>> +    while (!IsDevicePathEnd (DevPathNode)) {
>>> +      if (DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH &&
>>> +          DevicePathSubType (DevPathNode) == HW_PCI_DP) {
>>> +
>>> +        Idx += ((PCI_DEVICE_PATH *)DevPathNode)->Device;
>>
>> Assume the loop body is entered precisely once, and that the addend here
>> on the right side is zero.
> 
> pin == 1.
> slot_addend == 0 after the while loop (since parent == NULL).
> pci_bdf_to_dev(pci->bdf) might be 0, so slot_addend might become -1.
> 
> We then return pci_irqs[( 1 - 1 + (-1) ) & 3].
> 
>> That means Idx may equal zero after this increment is done.
>>
>>> +
>>> +        //
>>> +        // Unlike SeaBIOS, which starts climbing from the leaf device
>>> +        // up toward the root, we traverse the device path starting at
>>> +        // the root moving toward the leaf node.
>>> +        // The slot number of the top-level parent bridge is needed for
>>> +        // Q35 cases with more than 24 slots on the root bus.
>>> +        //
>>> +        if (Status != EFI_SUCCESS) {
>>> +          RootSlot = ((PCI_DEVICE_PATH *)DevPathNode)->Device;
>>> +          Status = EFI_SUCCESS;
>>> +        }
>>> +      }
>>> +
>>> +      DevPathNode = NextDevicePathNode (DevPathNode);
>>> +    }
>>> +    if (EFI_ERROR (Status)) {
>>> +      return Status;
>>> +    }
>>
>> since we ran the loop body more than zero times (in this case, exactly
>> once), we don't return here.
>>
>>> +
>>> +    //
>>> +    // Final PciHostIrqs[] index calculation depends on the platform
>>> +    // and should match SeaBIOS src/fw/pciinit.c *_pci_slot_get_irq()
>>> +    //
>>> +    switch (mHostBridgeDevId) {
>>> +      case INTEL_82441_DEVICE_ID:
>>> +        Idx -= 1;
>>
>> whoops, Idx becomes MAX_UINTN.
> 
> Which is the same as (-1) above. We then go %= 4 (a.k.a &= 3), and
> pull an irq value from the table :)
> 
>> Now where is my thought process wrong? You might want to add an assert
>> somewhere.
> 
> I don't think your thought process is wrong. I think I'm being exactly
> as right (or as wrong) as SeaBIOS under all cases, which is what I was
> aiming for :)

Sounds fair enough.

Reviewed-by: Laszlo Ersek <ler...@redhat.com>

Thanks!
Laszlo

> 
>> *Awesome* job, otherwise. Thank you very much!
> 
> And thank *you* (again) for all the help navigating the edk2/OvmfPkg
> environment !
> 
> --Gabriel
> 


------------------------------------------------------------------------------
Comprehensive Server Monitoring with Site24x7.
Monitor 10 servers for $9/Month.
Get alerted through email, SMS, voice calls or mobile push notifications.
Take corrective actions from your mobile device.
http://pubads.g.doubleclick.net/gampad/clk?id=154624111&iu=/4140/ostg.clktrk
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to