[OpenBIOS] [PATCH] pci: fix BAR setup

Artyom Tarasenko atar4qemu at gmail.com
Sun Apr 28 18:28:50 CEST 2013


On Sat, Apr 20, 2013 at 1:05 PM, Blue Swirl <blauwirbel at gmail.com> wrote:
> On Fri, Apr 19, 2013 at 9:10 PM, Artyom Tarasenko <atar4qemu at gmail.com> wrote:
>> On Mon, May 14, 2012 at 8:58 PM, Blue Swirl <blauwirbel at gmail.com> wrote:
>>> On Mon, May 14, 2012 at 1:49 PM, Mark Cave-Ayland
>>> <mark.cave-ayland at ilande.co.uk> wrote:
>>>> On 14/05/12 14:28, Artyom Tarasenko wrote:
>>>>
>>>>>>> It's to avoid VGA legacy mapping at 0xa0000. If I change
>>>>>>> hwdefs.pci.pci_mem_base in arch/sparc64/openbios.c to 0, OpenBIOS will
>>>>>>> crash during VGA init. Previously this worked because the PCI devices
>>>>>>> were mapped somewhat randomly and by chance, VGA legacy low mem area
>>>>>>> was avoided.
>>>>>>>
>>>>>>> I think the correct fix is to make QEMU VGA device disable the legacy
>>>>>>> mapping unless explicitly enabled. Alternatively the child base
>>>>>>> arithmetic could be fixed in OpenBIOS like proposed by Jakub.
>>>>>>
>>>>>>
>>>>>>
>>>>>> Did a patch ever come out of this discussion in the end?
>>>>>>
>>>>>
>>>>> No. :-) Feel free to fix it, unless Blue prefers fixing it himself...
>>>>
>>>>
>>>> I'm not sure I'm confident enough with PCI to do this, and I'm also not sure
>>>> what Blue's recommended fix actually is? Is it to increase parent_base by
>>>> 0x1000 or set child_base to zero?
>>>
>>> The best solution is to fix VGA (assuming my analysis was right) and
>>> set child_base to zero.
>>
>> Blue, do you know whether the QOMification improved the situation with
>> the legacy VGA low mem area?
>
> I don't think it had any effect, but PCI bridging code was fixed recently.
>
> There are still some problems, if I move most devices behind the first
> bridge with this patch, Sparc64 does not boot anymore:
> diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
> index 0d29620..8bf7230 100644
> --- a/hw/sparc64/sun4u.c
> +++ b/hw/sparc64/sun4u.c
> @@ -813,7 +813,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
>      M48t59State *nvram;
>      unsigned int i;
>      uint64_t initrd_addr, initrd_size, kernel_addr, kernel_size, kernel_entry;
> -    PCIBus *pci_bus, *pci_bus2, *pci_bus3;
> +    PCIBus *pci_bus2, *pci_bus3;
>      ISABus *isa_bus;
>      qemu_irq *ivec_irqs, *pbm_irqs;
>      DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
> @@ -829,12 +829,11 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
>      prom_init(hwdef->prom_addr, bios_name);
>
>      ivec_irqs = qemu_allocate_irqs(cpu_set_ivec_irq, cpu, IVEC_MAX);
> -    pci_bus = pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, ivec_irqs,
> &pci_bus2,
> -                           &pci_bus3, &pbm_irqs);
> -    pci_vga_init(pci_bus);
> +    pci_apb_init(APB_SPECIAL_BASE, APB_MEM_BASE, ivec_irqs, &pci_bus2,
> +                 &pci_bus3, &pbm_irqs);
> +    pci_vga_init(pci_bus2);
>
> -    // XXX Should be pci_bus3
> -    isa_bus = pci_ebus_init(pci_bus, -1, pbm_irqs);
> +    isa_bus = pci_ebus_init(pci_bus2, -1, pbm_irqs);
>
>      i = 0;
>      if (hwdef->console_serial_base) {
> @@ -859,7 +858,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
>
>      ide_drive_get(hd, MAX_IDE_BUS);
>
> -    pci_cmd646_ide_init(pci_bus, hd, 1);
> +    pci_cmd646_ide_init(pci_bus2, hd, 1);
>
>      isa_create_simple(isa_bus, "i8042");
>      for(i = 0; i < MAX_FD; i++) {
>
> Also ethernet is using the main PCI bus instead of the bridged version:
> (qemu) info pci
>   Bus  0, device   0, function 0:
>     Host bridge: PCI device 108e:a000
>       id ""
>   Bus  0, device   1, function 0:
>     PCI bridge: PCI device 108e:5000
>       BUS 0.
>       secondary bus 1.
>       subordinate bus 255.
>       IO range [0x0000, 0x0fff]
>       memory range [0x00000000, 0x000fffff]
>       prefetchable memory range [0x00000000, 0x000fffff]
>       id ""
>   Bus  1, device   0, function 0:
>     VGA controller: PCI device 1234:1111
>       BAR0: 32 bit prefetchable memory at 0x01000000 [0x01ffffff].
>       BAR2: 32 bit memory at 0x02000000 [0x02000fff].
>       BAR6: 32 bit memory at 0x02010000 [0x0201ffff].
>       id ""
>   Bus  1, device   1, function 0:
>     Bridge: PCI device 108e:1000
>       BAR0: 32 bit memory at 0xffffffffffffffff [0x00fffffe].
>       BAR1: 32 bit memory at 0xffffffffffffffff [0x007ffffe].
>       id ""
>   Bus  1, device   2, function 0:
>     IDE controller: PCI device 1095:0646
>       IRQ 0.
>       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 ""
>   Bus  0, device   1, function 1:
>     PCI bridge: PCI device 108e:5000
>       BUS 0.
>       secondary bus 0.
>       subordinate bus 0.
>       IO range [0x0000, 0x0fff]
>       memory range [0x00000000, 0x000fffff]
>       prefetchable memory range [0x00000000, 0x000fffff]
>       id ""
>   Bus  0, device   2, function 0:
> ^ should be bus 1.

But in your patch above you didn't touch the Ethernet, only cmd646 and
vga, or am I missing something?

Another question - is VGA legacy low mem area turned on by the PCI
feature called "DOS Compatibility" in the PBM and APB docs?
Both PBM and APB docs say that they don't have "DOS Compatibility" feature.
Maybe it's possible to tell the VGA card, that we don't need the low mem area?

>
>     Ethernet controller: PCI device 10ec:8029
>       IRQ 0.
>       BAR0: I/O at 0xffffffffffffffff [0x00fe].
>       BAR6: 32 bit memory at 0xffffffffffffffff [0x0003fffe].
>       id ""
>
>>



--
Regards,
Artyom Tarasenko

linux/sparc and solaris/sparc under qemu blog:
http://tyom.blogspot.com/search/label/qemu



More information about the OpenBIOS mailing list