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(a)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;
--
2.21.4