QEMU emulates two of the three PCI buses found on real hardware because some clients seem to need both and fail with only one present, but OpenBIOS only handles a single PCI bus and initialises and puts in the device tree only one of these: the second one which is where devices are connected and also marks it bus 0. However, clients getting info from the device tree may not know about this and thinking there is only one PCI bus they erroneously use the address of the first bus to access PCI config registers for devices on the second bus which silently fails as these requests will go to the other empty bus emulated and return invalid values. Devices mapped via MMIO still appear to work but they may not be correctly initialised and some cards are not detected because of this.
Until support for multiple PCI buses is implemented add an empty node in the device tree for the uninitialised bus to let clients know about it. This is still not entirely correct as bus-range property does not match real hardware but this fixes detecting PCI devices (such as USB) under MorphOS and may also fix enabling the bus master bit needed with some network cards and allow the workarund for this to be reverted.
Signed-off-by: BALATON Zoltan balaton@eik.bme.hu --- v4: Rebased to latest master v3: See: https://mail.coreboot.org/pipermail/openbios/2017-January/009867.html
arch/ppc/qemu/init.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c index af15682..d362b0e 100644 --- a/arch/ppc/qemu/init.c +++ b/arch/ppc/qemu/init.c @@ -716,6 +716,48 @@ static void kvm_of_init(void) fword("finish-device"); }
+static void empty_pci_bus_init(void) +{ + if (machine_id == ARCH_MAC99) { + /* Add empty node for first pci bus */ + /* Remove this when pci driver is fixed to handle multiple buses */ + activate_device("/"); + fword("new-device"); + push_str("pci"); + fword("device-name"); + push_str("pci"); + fword("device-type"); + PUSH(0xf0000000); + fword("encode-int"); + PUSH(0x02000000); + fword("encode-int"); + fword("encode+"); + 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"); + PUSH(0); + fword("encode-int"); + PUSH(0); + fword("encode-int"); + fword("encode+"); + push_str("bus-range"); + fword("property"); + fword("finish-device"); + device_end(); + } +} + /* * filll ( addr bytes quad -- ) */ @@ -857,6 +899,7 @@ arch_of_init(void) feval("['] ppc-dma-sync to (dma-sync)");
#ifdef CONFIG_DRIVER_PCI + empty_pci_bus_init(); ob_pci_init(); #endif
On 20/11/16 18:04, BALATON Zoltan wrote:
QEMU emulates two of the three PCI buses found on real hardware because some clients seem to need both and fail with only one present, but OpenBIOS only handles a single PCI bus and initialises and puts in the device tree only one of these: the second one which is where devices are connected and also marks it bus 0. However, clients getting info from the device tree may not know about this and thinking there is only one PCI bus they erroneously use the address of the first bus to access PCI config registers for devices on the second bus which silently fails as these requests will go to the other empty bus emulated and return invalid values. Devices mapped via MMIO still appear to work but they may not be correctly initialised and some cards are not detected because of this.
Until support for multiple PCI buses is implemented add an empty node in the device tree for the uninitialised bus to let clients know about it. This is still not entirely correct as bus-range property does not match real hardware but this fixes detecting PCI devices (such as USB) under MorphOS and may also fix enabling the bus master bit needed with some network cards and allow the workarund for this to be reverted.
Signed-off-by: BALATON Zoltan balaton@eik.bme.hu
v4: Rebased to latest master v3: See: https://mail.coreboot.org/pipermail/openbios/2017-January/009867.html
arch/ppc/qemu/init.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c index af15682..d362b0e 100644 --- a/arch/ppc/qemu/init.c +++ b/arch/ppc/qemu/init.c @@ -716,6 +716,48 @@ static void kvm_of_init(void) fword("finish-device"); }
+static void empty_pci_bus_init(void) +{
- if (machine_id == ARCH_MAC99) {
/* Add empty node for first pci bus */
/* Remove this when pci driver is fixed to handle multiple buses */
activate_device("/");
fword("new-device");
push_str("pci");
fword("device-name");
push_str("pci");
fword("device-type");
PUSH(0xf0000000);
fword("encode-int");
PUSH(0x02000000);
fword("encode-int");
fword("encode+");
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");
PUSH(0);
fword("encode-int");
PUSH(0);
fword("encode-int");
fword("encode+");
push_str("bus-range");
fword("property");
fword("finish-device");
device_end();
- }
+}
- /*
*/
- filll ( addr bytes quad -- )
@@ -857,6 +899,7 @@ arch_of_init(void) feval("['] ppc-dma-sync to (dma-sync)");
#ifdef CONFIG_DRIVER_PCI
- empty_pci_bus_init(); ob_pci_init(); #endif
I'm still not a great fan of this patch, although now with my latest uninorth rework at least there is actually a PCI bus present at 0xf0000000 so if OSs scan the device tree and locate the bus, accesses there won't fail.
Having thought about it though, I do have a better idea: if the issue is simply that "bus-range" needs to be set to different starting value then my work on adding PCI bridge support to OpenBIOS has just about solved this.
How about changing ob_pci_init() to take a single bus_num int which is the starting bus number and then passing that down into ob_configure_pci_device()? That will allow you to set the correct bus_num for the 0xf2000000 PCI bus which should solve your problem, and also get OpenBIOS a small step closer to multiple PCI bus support.
ATB,
Mark.
On Fri, 29 Jun 2018, Mark Cave-Ayland wrote:
On 20/11/16 18:04, BALATON Zoltan wrote:
QEMU emulates two of the three PCI buses found on real hardware because some clients seem to need both and fail with only one present, but OpenBIOS only handles a single PCI bus and initialises and puts in the device tree only one of these: the second one which is where devices are connected and also marks it bus 0. However, clients getting info from the device tree may not know about this and thinking there is only one PCI bus they erroneously use the address of the first bus to access PCI config registers for devices on the second bus which silently fails as these requests will go to the other empty bus emulated and return invalid values. Devices mapped via MMIO still appear to work but they may not be correctly initialised and some cards are not detected because of this.
Until support for multiple PCI buses is implemented add an empty node in the device tree for the uninitialised bus to let clients know about it. This is still not entirely correct as bus-range property does not match real hardware but this fixes detecting PCI devices (such as USB) under MorphOS and may also fix enabling the bus master bit needed with some network cards and allow the workarund for this to be reverted.
Signed-off-by: BALATON Zoltan balaton@eik.bme.hu
v4: Rebased to latest master v3: See: https://mail.coreboot.org/pipermail/openbios/2017-January/009867.html
arch/ppc/qemu/init.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c index af15682..d362b0e 100644 --- a/arch/ppc/qemu/init.c +++ b/arch/ppc/qemu/init.c @@ -716,6 +716,48 @@ static void kvm_of_init(void) fword("finish-device"); } +static void empty_pci_bus_init(void) +{
- if (machine_id == ARCH_MAC99) {
/* Add empty node for first pci bus */
/* Remove this when pci driver is fixed to handle multiple buses
*/
activate_device("/");
fword("new-device");
push_str("pci");
fword("device-name");
push_str("pci");
fword("device-type");
PUSH(0xf0000000);
fword("encode-int");
PUSH(0x02000000);
fword("encode-int");
fword("encode+");
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");
PUSH(0);
fword("encode-int");
PUSH(0);
fword("encode-int");
fword("encode+");
push_str("bus-range");
fword("property");
fword("finish-device");
device_end();
- }
+}
- /*
*/
- filll ( addr bytes quad -- )
@@ -857,6 +899,7 @@ arch_of_init(void) feval("['] ppc-dma-sync to (dma-sync)"); #ifdef CONFIG_DRIVER_PCI
- empty_pci_bus_init(); ob_pci_init(); #endif
I'm still not a great fan of this patch, although now with my latest uninorth rework at least there is actually a PCI bus present at 0xf0000000 so if OSs scan the device tree and locate the bus, accesses there won't fail.
Does it break any of your test images or what is it that you don't like about it as a temporary measure until OpenBIOS will support multiple PCI busses correctly?
Having thought about it though, I do have a better idea: if the issue is simply that "bus-range" needs to be set to different starting value then my work on adding PCI bridge support to OpenBIOS has just about solved this.
How about changing ob_pci_init() to take a single bus_num int which is the starting bus number and then passing that down into ob_configure_pci_device()? That will allow you to set the correct bus_num for the 0xf2000000 PCI bus which should solve your problem, and also get OpenBIOS a small step closer to multiple PCI bus support.
I don't remember the details by now and don't want to debug this again but AFAIR the problem was not the bus-range but that only one PCI bus appears in the device tree while there are two buses emulated. I think MorphOS checks for up to 3 PCI buses and may not get all info from the device tree apart from addresses but may have some assumptions for other properties so it may not be possible to fix it with a device tree that does not look similar enough to a real Mac. Since only one PCI bus was present in the device tree, when trying to access config registers of bus 1 MorphOS talked to bus 0 instead which of course did not work as devices are on bus 1 and config reg accesses went to bus 0 and got ignored silently because there were no devices on that bus. The devices were still mmio mapped so some of them appeared to work when did not need initialisation but symptoms were failing to setting bus master bit for network card and not finding USB devices that are results of this mismatch between PCI buses. This is fixed by adding an empty/dummy pci bus 0 in the device tree which makes MorphOS notice there are two PCI busses and use the correct one for accessing PCI registers. So there needs to be two PCI buses in the device tree and since devices are on the second one the dummy one needs to be _before_ the second one (this is why I could not patch it from Forth or command line and need this patch).
If you can come up with any other patch to fix this (you can test with the MorphOS demo iso) then I'm fine with that but I could not find any other simple way to make this work without multiple PCI bus support in OpenBIOS but that's too much work I don't have time for. (Since the first PCI bus is empty it should not matter too much what info we have about that in device tree now as nothing should access it really.)
Regards, BALATON Zoltan
On 29/06/18 21:10, BALATON Zoltan wrote:
How about changing ob_pci_init() to take a single bus_num int which is the starting bus number and then passing that down into ob_configure_pci_device()? That will allow you to set the correct bus_num for the 0xf2000000 PCI bus which should solve your problem, and also get OpenBIOS a small step closer to multiple PCI bus support.
I don't remember the details by now and don't want to debug this again but AFAIR the problem was not the bus-range but that only one PCI bus appears in the device tree while there are two buses emulated. I think MorphOS checks for up to 3 PCI buses and may not get all info from the device tree apart from addresses but may have some assumptions for other properties so it may not be possible to fix it with a device tree that does not look similar enough to a real Mac. Since only one PCI bus was present in the device tree, when trying to access config registers of bus 1 MorphOS talked to bus 0 instead which of course did not work as devices are on bus 1 and config reg accesses went to bus 0 and got ignored silently because there were no devices on that bus. The devices were still mmio mapped so some of them appeared to work when did not need initialisation but symptoms were failing to setting bus master bit for network card and not finding USB devices that are results of this mismatch between PCI buses. This is fixed by adding an empty/dummy pci bus 0 in the device tree which makes MorphOS notice there are two PCI busses and use the correct one for accessing PCI registers. So there needs to be two PCI buses in the device tree and since devices are on the second one the dummy one needs to be _before_ the second one (this is why I could not patch it from Forth or command line and need this patch).
If you can come up with any other patch to fix this (you can test with the MorphOS demo iso) then I'm fine with that but I could not find any other simple way to make this work without multiple PCI bus support in OpenBIOS but that's too much work I don't have time for. (Since the first PCI bus is empty it should not matter too much what info we have about that in device tree now as nothing should access it really.)
I'm not asking that you implement full multiple PCI bus support for OpenBIOS, just that you try setting bus-range manually to the correct value from a real device tree to see if it makes a difference.
Unfortunately my copy of MorphOS (3.7) in my OpenBIOS test repository never seems to get past the bootloader so I don't have a way to test it myself or know what to look for to know if this has succeeded or not.
ATB,
Mark.
On Sat, 30 Jun 2018, Mark Cave-Ayland wrote:
On 29/06/18 21:10, BALATON Zoltan wrote:
How about changing ob_pci_init() to take a single bus_num int which is the starting bus number and then passing that down into ob_configure_pci_device()? That will allow you to set the correct bus_num for the 0xf2000000 PCI bus which should solve your problem, and also get OpenBIOS a small step closer to multiple PCI bus support.
I don't remember the details by now and don't want to debug this again but AFAIR the problem was not the bus-range but that only one PCI bus appears in the device tree while there are two buses emulated. I think MorphOS checks for up to 3 PCI buses and may not get all info from the device tree apart from addresses but may have some assumptions for other properties so it may not be possible to fix it with a device tree that does not look similar enough to a real Mac. Since only one PCI bus was present in the device tree, when trying to access config registers of bus 1 MorphOS talked to bus 0 instead which of course did not work as devices are on bus 1 and config reg accesses went to bus 0 and got ignored silently because there were no devices on that bus. The devices were still mmio mapped so some of them appeared to work when did not need initialisation but symptoms were failing to setting bus master bit for network card and not finding USB devices that are results of this mismatch between PCI buses. This is fixed by adding an empty/dummy pci bus 0 in the device tree which makes MorphOS notice there are two PCI busses and use the correct one for accessing PCI registers. So there needs to be two PCI buses in the device tree and since devices are on the second one the dummy one needs to be _before_ the second one (this is why I could not patch it from Forth or command line and need this patch).
If you can come up with any other patch to fix this (you can test with the MorphOS demo iso) then I'm fine with that but I could not find any other simple way to make this work without multiple PCI bus support in OpenBIOS but that's too much work I don't have time for. (Since the first PCI bus is empty it should not matter too much what info we have about that in device tree now as nothing should access it really.)
I'm not asking that you implement full multiple PCI bus support for OpenBIOS, just that you try setting bus-range manually to the correct value from a real device tree to see if it makes a difference.
Not sure what would be the correct value and where to change it. If you give me a patch I can test it.
Unfortunately my copy of MorphOS (3.7) in my OpenBIOS test repository never seems to get past the bootloader so I don't have a way to test it myself or know what to look for to know if this has succeeded or not.
It needs the target/ppc/translate.c patch I've sent to the QEMU list cc-ing you and the command line options in that patch. I'm not sure 3.7 will work, I think you'd need at least 3.8 but the most recent one is 3.10 which I'm using for testing now so maybe you should get a recent one.
Regards, BALATON Zoltan