QEMU mac99 emulates two of the three PCI buses found on real PowerMac3,1 but OpenBIOS currently only handles a single PCI bus and inits and puts info in the device tree of the second PCI bus only (which is where devices are connected). However, some clients (e.g. MorphOS) may have hardcoded assumptions and erroneously use the address of the first bus to access PCI config registers for devices on the second bus if the first bus is missing from the device tree, which silently fails as these requests will go to the other empty bus emulated and return invalid values as the device they address are not present there.
As a result devices mapped via MMIO still appear to work but they may not be correctly initialised and some cards are not detected because of this. One such case might be enabling bus master bit for network cards which the OS should do but OpenBIOS has workaround for it now. Once both PCI buses appear in device tree those workarounds may not be needed any more.
Until proper support for multiple PCI buses is implemented add an empty node in the device tree for the first bus on QEMU mac99 to let OSes know about it. This fixes detecting PCI devices (such as USB) under MorphOS and allows it to boot.
Signed-off-by: BALATON Zoltan balaton@eik.bme.hu --- arch/ppc/qemu/init.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+)
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c index 45cd77e..b1c2197 100644 --- a/arch/ppc/qemu/init.c +++ b/arch/ppc/qemu/init.c @@ -716,6 +716,59 @@ static void kvm_of_init(void) fword("finish-device"); }
+static void encode_int_plus(int n, ...) +{ + int i; + ucell v; + va_list ap; + + va_start(ap, n); + for (i = 0; i < n; i++) { + v = va_arg(ap, ucell); + PUSH(v); + fword("encode-int"); + if (i > 0) { + fword("encode+"); + } + } + va_end(ap); +} + +static void empty_pci_bus_init(void) +{ + if (machine_id == ARCH_MAC99) { + fword("new-device"); + push_str("pci"); + fword("device-name"); + push_str("pci"); + fword("device-type"); + encode_int_plus(2, 0xf0000000, 0x02000000); + push_str("reg"); + fword("property"); + PUSH(3); + fword("encode-int"); + push_str("#address-cells"); + fword("property"); + PUSH(2); + fword("encode-int"); + push_str("#size-cells"); + fword("property"); + PUSH(1); + fword("encode-int"); + push_str("#interrupt-cells"); + fword("property"); + encode_int_plus(12, + 0x01000000, 0, 0, 0xf0000000, 0, 0x00800000, + 0x02000000, 0, 0x90000000, 0x90000000, 0, 0x10000000); + push_str("ranges"); + fword("property"); + encode_int_plus(2, 0, 0); + push_str("bus-range"); + fword("property"); + fword("finish-device"); + } +} + /* * filll ( addr bytes quad -- ) */ @@ -868,6 +921,8 @@ arch_of_init(void) case ARCH_MAC99_U3: /* The NewWorld NVRAM is not located in the MacIO device */ macio_nvram_init("/", 0); + /* We only handle 1 PCI bus but MorphOS needs info for both to boot */ + empty_pci_bus_init(); ob_pci_init(); ob_unin_init(); break;