[OpenBIOS] [PATCH] pci: fix setup of 64-bit BARs

Mark Cave-Ayland mark.cave-ayland at ilande.co.uk
Tue Mar 14 22:35:15 CET 2017


On 11/03/17 14:38, Mark Cave-Ayland wrote:

> The current PCI implementation is designed for a 32-bit PCI bus. When
> a 64-bit BAR is encountered during PCI bus enumeration, currently we
> treat the MSB BAR the same as a standard 32-bit BAR, attempting to guess
> its size by setting to 0xffffffff and reading back the response which
> returns back an invalid size of 0 and fails.
> 
> This has the effect of setting the MSB BAR to 0xffffffff meaning that
> 64-bit BARs are mapped at the top of PCI memory in the wrong location.
> 
> Handle this case by ignoring the MSB BAR when we detect a 64-bit BAR
> leaving it at its default value of zero. This solves the issue by
> ensuring that all 64-bit BARs are mapped within 32-bit PCI space which
> is fine for the PPC/SPARC64 machines we care about.
> 
> Most noticeably this solves the issue of virtio modern devices (which
> use 64-bit BARs under QEMU) causing a kernel panic upon startup on
> qemu-system-sparc64 because they are mapped at the wrong address by OpenBIOS.
> 
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at ilande.co.uk>
> ---
>  drivers/pci.c |   12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci.c b/drivers/pci.c
> index c998280..2e09d0a 100644
> --- a/drivers/pci.c
> +++ b/drivers/pci.c
> @@ -1202,9 +1202,9 @@ ob_pci_configure(pci_addr addr, pci_config_t *config, int num_regs, int rom_bar,
>                   unsigned long *mem_base, unsigned long *io_base)
>  
>  {
> -        uint32_t omask;
> +        uint32_t omask, mask;
>          uint16_t cmd;
> -        int reg;
> +        int reg, flags, space_code;
>          pci_addr config_addr;
>  
>          ob_pci_configure_irq(addr, config);
> @@ -1216,6 +1216,14 @@ ob_pci_configure(pci_addr addr, pci_config_t *config, int num_regs, int rom_bar,
>                  ob_pci_configure_bar(addr, config, reg, config_addr,
>                                       &omask, mem_base,
>                                       io_base);
> +
> +                /* Ignore 64-bit BAR MSBs (always map in 32-bit space) */
> +                pci_decode_pci_addr(config->assigned[reg],
> +                                    &flags, &space_code, &mask);
> +
> +                if (space_code == MEMORY_SPACE_64) {
> +                    reg++;
> +                }
>          }
>  
>          if (rom_bar) {
> 

No further comments, so pushed to git master.


ATB,

Mark.




More information about the OpenBIOS mailing list