A change in QEMU on how PCI bridges are setup revealed a bug in OpenBIOS PCI setup. On Sparc64, the BARs just happened to get somewhat correct values by accident before the commit but not after the change.
Don't use arch->io_base for PCI I/O port BARs.
Fix Sparc64 PCI memory base.
Signed-off-by: Blue Swirl blauwirbel@gmail.com ---
I removed the bridge setup code, it's not really valid for Sparc64 APB bridges anyway and currently no devices exist behind the bridges (but that's where they really should be).
Tested Sparc64 and PPC.
--- arch/sparc64/openbios.c | 2 +- drivers/pci.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/arch/sparc64/openbios.c b/arch/sparc64/openbios.c index ac709fe..ab32a8f 100644 --- a/arch/sparc64/openbios.c +++ b/arch/sparc64/openbios.c @@ -64,7 +64,7 @@ static const struct hwdef hwdefs[] = { .cfg_base = APB_SPECIAL_BASE, .cfg_len = 0x2000000, .host_mem_base = APB_MEM_BASE, - .pci_mem_base = 0, + .pci_mem_base = 0x100000, /* avoid VGA at 0xa0000 */ .mem_len = 0x10000000, .io_base = APB_SPECIAL_BASE + 0x2000000ULL, // PCI Bus I/O space .io_len = 0x10000, diff --git a/drivers/pci.c b/drivers/pci.c index f8c6414..e270a73 100644 --- a/drivers/pci.c +++ b/drivers/pci.c @@ -931,6 +931,7 @@ static void ob_pci_configure_bar(pci_addr addr, pci_config_t *config,
if ((*p_omask & 0x0000000f) == 0x4) { /* 64 bits memory mapping */ + PCI_DPRINTF("Skipping 64 bit BARs for %s\n", config->path); return; }
@@ -966,11 +967,17 @@ static void ob_pci_configure_bar(pci_addr addr, pci_config_t *config, size = min_align; reloc = (reloc + size -1) & ~(size - 1); if (*io_base == base) { + PCI_DPRINTF("changing io_base from 0x%lx to 0x%x\n", + *io_base, reloc + size); *io_base = reloc + size; - reloc -= arch->io_base; } else { + PCI_DPRINTF("changing mem_base from 0x%lx to 0x%x\n", + *mem_base, reloc + size); *mem_base = reloc + size; } + PCI_DPRINTF("Configuring BARs for %s: reloc 0x%x omask 0x%x " + "io_base 0x%lx mem_base 0x%lx size 0x%x\n", + config->path, reloc, *p_omask, *io_base, *mem_base, size); pci_config_write32(addr, config_addr, reloc | *p_omask); config->assigned[reg] = reloc | *p_omask; } @@ -1260,7 +1267,7 @@ int ob_pci_init(void) mem_base = arch->pci_mem_base; /* I/O ports under 0x400 are used by devices mapped at fixed location. */ - io_base = arch->io_base + 0x400; + io_base = 0x400;
bus = 0;