Patchwork pci: fix bridge IO/BASE

login
register
mail settings
Submitter Blue Swirl
Date March 4, 2012, 1:33 p.m.
Message ID <CAAu8pHuP5hwZ_g4dc9wvdGvpswUEwLaqmKMyqquEJR3EhLRsQQ@mail.gmail.com>
Download mbox | patch
Permalink /patch/144511/
State New
Headers show

Comments

Blue Swirl - March 4, 2012, 1:33 p.m.
On Sun, Mar 4, 2012 at 13:22, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Sun, Mar 04, 2012 at 02:41:33PM +0200, Avi Kivity wrote:
>> On 03/04/2012 02:38 PM, Blue Swirl wrote:
>> > >>
>> > >> This unassigned memory exception is triggered because CMD646 IDE I/O
>> > >> registers are not accessible:
>> > >>
>> > >> (qemu) info pci
>> > >>   Bus  0, device   5, function 0:
>> > >>     IDE controller: PCI device 1095:0646
>> > >>       IRQ 1.
>> > >>       BAR0: I/O at 0xffffffffffffffff [0x0006].
>> > >>       BAR1: I/O at 0xffffffffffffffff [0x0002].
>> > >>       BAR2: I/O at 0xffffffffffffffff [0x0006].
>> > >>       BAR3: I/O at 0xffffffffffffffff [0x0002].
>> > >>       BAR4: I/O at 0xffffffffffffffff [0x000e].
>> > >>       id ""
>> > >
>> > > The BARs are not initialized, so they aren't accessible.
>> > >
>> > > But perhaps the dump was not taken at the point of failure, can you
>> > > provide a relevant dump if so?
>> >
>> > No, this is after failure.
>>
>> I don't see why the guest expects the BARs to work then.
>
> I don't belive it does - it probably got hang before
> initializing BARs.

This is later, the crash happens when IDE driver is accessing CMD646
registers after the PCI device is configured.

I changed OpenBIOS to disable any bridges with no devices, but that
didn't help. It looks like this is not related to bridges, I disabled
the secondary bridges with this patch and still there is the crash.

>
>> --
>> error compiling committee.c: too many arguments to function
Michael S. Tsirkin - March 4, 2012, 2:08 p.m.
On Sun, Mar 04, 2012 at 01:33:42PM +0000, Blue Swirl wrote:
> On Sun, Mar 4, 2012 at 13:22, Michael S. Tsirkin <mst@redhat.com> wrote:
> > On Sun, Mar 04, 2012 at 02:41:33PM +0200, Avi Kivity wrote:
> >> On 03/04/2012 02:38 PM, Blue Swirl wrote:
> >> > >>
> >> > >> This unassigned memory exception is triggered because CMD646 IDE I/O
> >> > >> registers are not accessible:
> >> > >>
> >> > >> (qemu) info pci
> >> > >>   Bus  0, device   5, function 0:
> >> > >>     IDE controller: PCI device 1095:0646
> >> > >>       IRQ 1.
> >> > >>       BAR0: I/O at 0xffffffffffffffff [0x0006].
> >> > >>       BAR1: I/O at 0xffffffffffffffff [0x0002].
> >> > >>       BAR2: I/O at 0xffffffffffffffff [0x0006].
> >> > >>       BAR3: I/O at 0xffffffffffffffff [0x0002].
> >> > >>       BAR4: I/O at 0xffffffffffffffff [0x000e].
> >> > >>       id ""
> >> > >
> >> > > The BARs are not initialized, so they aren't accessible.
> >> > >
> >> > > But perhaps the dump was not taken at the point of failure, can you
> >> > > provide a relevant dump if so?
> >> >
> >> > No, this is after failure.
> >>
> >> I don't see why the guest expects the BARs to work then.
> >
> > I don't belive it does - it probably got hang before
> > initializing BARs.
> 
> This is later, the crash happens when IDE driver is accessing CMD646
> registers after the PCI device is configured.
> 
> I changed OpenBIOS to disable any bridges with no devices, but that
> didn't help. It looks like this is not related to bridges, I disabled
> the secondary bridges with this patch and still there is the crash.

It seems to have to do with the host bridge.
It's unusual to have host bridge present itself
as a pci to pci bridge but there it is.

> diff --git a/hw/apb_pci.c b/hw/apb_pci.c
> index 1d25da8..ed9dc68 100644
> --- a/hw/apb_pci.c
> +++ b/hw/apb_pci.c
> @@ -256,11 +256,13 @@ static const MemoryRegionOps pci_ioport_ops = {
>      .endianness = DEVICE_NATIVE_ENDIAN,
>  };
> 
> +#if 0
>  /* The APB host has an IRQ line for each IRQ line of each slot.  */
>  static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
>  {
>      return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
>  }
> +#endif
> 
>  static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
>  {
> @@ -322,8 +324,10 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
>      SysBusDevice *s;
>      APBState *d;
>      unsigned int i;
> +#if 0
>      PCIDevice *pci_dev;
>      PCIBridge *br;
> +#endif
> 
>      /* Ultrasparc PBM main bus */
>      dev = qdev_create(NULL, "pbm");
> @@ -352,6 +356,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
> 
>      pci_create_simple(d->bus, 0, "pbm-pci");
> 
> +#if 0
>      /* APB secondary busses */
>      pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 0), true,
>                                     "pbm-bridge");
> @@ -368,7 +373,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
>                         pci_apb_map_irq);
>      qdev_init_nofail(&pci_dev->qdev);
>      *bus3 = pci_bridge_get_sec_bus(br);
> -
> +#endif
>      return d->bus;
>  }
> 
> >
> >> --
> >> error compiling committee.c: too many arguments to function
Blue Swirl - March 4, 2012, 2:26 p.m.
On Sun, Mar 4, 2012 at 14:08, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Sun, Mar 04, 2012 at 01:33:42PM +0000, Blue Swirl wrote:
>> On Sun, Mar 4, 2012 at 13:22, Michael S. Tsirkin <mst@redhat.com> wrote:
>> > On Sun, Mar 04, 2012 at 02:41:33PM +0200, Avi Kivity wrote:
>> >> On 03/04/2012 02:38 PM, Blue Swirl wrote:
>> >> > >>
>> >> > >> This unassigned memory exception is triggered because CMD646 IDE I/O
>> >> > >> registers are not accessible:
>> >> > >>
>> >> > >> (qemu) info pci
>> >> > >>   Bus  0, device   5, function 0:
>> >> > >>     IDE controller: PCI device 1095:0646
>> >> > >>       IRQ 1.
>> >> > >>       BAR0: I/O at 0xffffffffffffffff [0x0006].
>> >> > >>       BAR1: I/O at 0xffffffffffffffff [0x0002].
>> >> > >>       BAR2: I/O at 0xffffffffffffffff [0x0006].
>> >> > >>       BAR3: I/O at 0xffffffffffffffff [0x0002].
>> >> > >>       BAR4: I/O at 0xffffffffffffffff [0x000e].
>> >> > >>       id ""
>> >> > >
>> >> > > The BARs are not initialized, so they aren't accessible.
>> >> > >
>> >> > > But perhaps the dump was not taken at the point of failure, can you
>> >> > > provide a relevant dump if so?
>> >> >
>> >> > No, this is after failure.
>> >>
>> >> I don't see why the guest expects the BARs to work then.
>> >
>> > I don't belive it does - it probably got hang before
>> > initializing BARs.
>>
>> This is later, the crash happens when IDE driver is accessing CMD646
>> registers after the PCI device is configured.
>>
>> I changed OpenBIOS to disable any bridges with no devices, but that
>> didn't help. It looks like this is not related to bridges, I disabled
>> the secondary bridges with this patch and still there is the crash.
>
> It seems to have to do with the host bridge.
> It's unusual to have host bridge present itself
> as a pci to pci bridge but there it is.

It looks like the I/O base calculations in OpenBIOS are confused by
host bridge, after that all BARs are wrong. OpenBIOS also thinks that
the host bridge is a device and attempts to configure six BARs instead
of two.

>> diff --git a/hw/apb_pci.c b/hw/apb_pci.c
>> index 1d25da8..ed9dc68 100644
>> --- a/hw/apb_pci.c
>> +++ b/hw/apb_pci.c
>> @@ -256,11 +256,13 @@ static const MemoryRegionOps pci_ioport_ops = {
>>      .endianness = DEVICE_NATIVE_ENDIAN,
>>  };
>>
>> +#if 0
>>  /* The APB host has an IRQ line for each IRQ line of each slot.  */
>>  static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
>>  {
>>      return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
>>  }
>> +#endif
>>
>>  static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
>>  {
>> @@ -322,8 +324,10 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
>>      SysBusDevice *s;
>>      APBState *d;
>>      unsigned int i;
>> +#if 0
>>      PCIDevice *pci_dev;
>>      PCIBridge *br;
>> +#endif
>>
>>      /* Ultrasparc PBM main bus */
>>      dev = qdev_create(NULL, "pbm");
>> @@ -352,6 +356,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
>>
>>      pci_create_simple(d->bus, 0, "pbm-pci");
>>
>> +#if 0
>>      /* APB secondary busses */
>>      pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 0), true,
>>                                     "pbm-bridge");
>> @@ -368,7 +373,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base,
>>                         pci_apb_map_irq);
>>      qdev_init_nofail(&pci_dev->qdev);
>>      *bus3 = pci_bridge_get_sec_bus(br);
>> -
>> +#endif
>>      return d->bus;
>>  }
>>
>> >
>> >> --
>> >> error compiling committee.c: too many arguments to function

Patch

diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index 1d25da8..ed9dc68 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -256,11 +256,13 @@  static const MemoryRegionOps pci_ioport_ops = {
     .endianness = DEVICE_NATIVE_ENDIAN,
 };

+#if 0
 /* The APB host has an IRQ line for each IRQ line of each slot.  */
 static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
 {
     return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
 }
+#endif

 static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
 {
@@ -322,8 +324,10 @@  PCIBus *pci_apb_init(target_phys_addr_t special_base,
     SysBusDevice *s;
     APBState *d;
     unsigned int i;
+#if 0
     PCIDevice *pci_dev;
     PCIBridge *br;
+#endif

     /* Ultrasparc PBM main bus */
     dev = qdev_create(NULL, "pbm");
@@ -352,6 +356,7 @@  PCIBus *pci_apb_init(target_phys_addr_t special_base,

     pci_create_simple(d->bus, 0, "pbm-pci");

+#if 0
     /* APB secondary busses */
     pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 0), true,
                                    "pbm-bridge");
@@ -368,7 +373,7 @@  PCIBus *pci_apb_init(target_phys_addr_t special_base,
                        pci_apb_map_irq);
     qdev_init_nofail(&pci_dev->qdev);
     *bus3 = pci_bridge_get_sec_bus(br);
-
+#endif
     return d->bus;
 }