Fabiano Rosas <farosas(a)linux.ibm.com> writes:
> Hi all,
>
> We have this bug in QEMU which indicates that we haven't been able to
> run openbios on a 7450 cpu for quite a long time:
>
> https://gitlab.com/qemu-project/qemu/-/issues/86
>
> OK:
> $ ./qemu-system-ppc -serial mon:stdio -nographic -cpu 7410
>
> >> =============================================================
> >> OpenBIOS 1.1 [Nov 1 2021 20:36]
> ...
>
> NOK:
…
[View More]> $ ./qemu-system-ppc -serial mon:stdio -nographic -cpu 7450 -d int
> Raise exception at fff08cc4 => 0000004e (00)
> QEMU: Terminated
>
> The actual issue is straightforward. There is a non-architected
> feature that QEMU has enabled by default that openbios doesn't know
> about. From the user manual:
>
> "The MPC7540 has a set of implementation-specific registers,
> exceptions, and instructions that facilitate very efficient software
> searching of the page tables in memory for when software table
> searching is enabled (HID0[STEN] = 1). This section describes those
> resources and provides three example code sequences that can be used
> in a MPC7540 system for an efficient search of the translation tables
> in software. These three code sequences can be used as handlers for
> the three exceptions requiring access to the PTEs in the page tables
> in memory in this case-instruction TLB miss, data TLB miss on load,
> and data TLB miss on store exceptions."
>
> The current state:
>
> 1) QEMU does not check HID0[STEN] and makes the feature always enabled
> by setting these cpus with the POWERPC_MMU_SOFT_74xx MMU model,
> instead of the generic POWERPC_MMU_32B.
>
> 2) openbios does not recognize the PVRs for those cpus and also does
> not have any handlers for the software TLB exceptions (vectors 0x1000,
> 0x1100, 0x1200).
>
> Some assumptions (correct me if I'm wrong please):
>
> - openbios is the only firmware we use for the following cpus: 7441,
> 7445, 7450, 7451, 7455, 7457, 7447, 7447a, 7448.
> - without openbios, we cannot have a guest running on these cpus.
>
> So to bring 7450 back to life we would need to either:
>
> a) find another firmware/guest OS code that supports the feature;
>
> b) implement the switching of the feature in QEMU and have the guest
> code enable it only when supported. That would take some fiddling with
> the MMU code to: merge POWERPC_MMU_SOFT_74xx into POWERPC_MMU_32B,
> check the HID0[STEN] bit, figure out how to switch from HW TLB miss to
> SW TLB miss on demand, block access to the TLBMISS register (and
> others) when the feature is off, and so on;
>
> c) leave the feature enabled in QEMU and implement the software TLB
> miss handlers in openbios. The UM provides sample code, so this is
> easy;
>
> d) remove support for software TLB search for the 7450 family and
> switch the cpus to the POWERPC_MMU_32B model. This is by far the
> easiest solution, but could cause problems for any (which?) guest OS
> code that actually uses the feature. All of the existing code for the
> POWERPC_MMU_SOFT_74xx MMU model would probably be removed since it
> would be dead code then;
>
> Option (c) seemed to me like a good compromise so this is a patch
> series for openbios doing that and also adding the necessary PVRs so
> we can get a working guest with these cpus without too much effort.
>
> I have also a patch for QEMU adding basic sanity check tests for the
> 7400 and 7450 families. I'll send that separately to the QEMU ml.
>
> Fabiano Rosas (2):
> ppc: Add support for MPC7450 software TLB miss interrupts
> ppc: Add PVRs for the MPC7450 family
>
> arch/ppc/qemu/init.c | 52 ++++++++++
> arch/ppc/qemu/start.S | 236 +++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 285 insertions(+), 3 deletions(-)
(Adding Mark because his email got somehow dropped from the original
message)
So with these patches in OpenBIOS we could get a bit further and call
into the Linux kernel using the same image as the one used for the
7400. However there seems to be no support for the 7450 software TLB in
the kernel. There are only handlers for the 4xx, 8xx and 603 which are
different code altogether. There's no mention of the TLBMISS and
PTEHI/LO registers in the code as well.
Do we know of any guest OS that implements the 7450 software TLB at
vectors 0x1000, 0x1100 and 0x1200? Otherwise replacing the
POWERPC_MMU_SOFT_74xx model with POWERPC_MMU_32B might be the only way
of getting an OS to run in the 7450 family.
[View Less]
Hi all,
Recap:
- QEMU enables 7450 SW TLB search by default;
- OpenBIOS does not know about SW TLB (vectors 0x1000, 0x1100, 0x1200);
- OpenBIOS does not know about 7450s PVRs.
Proposed solutions:
a) find another firmware/guest OS code that supports the feature;
b) implement the switching of the feature in QEMU and have the guest
code enable it only when supported. That would take some fiddling with
the MMU code to: merge POWERPC_MMU_SOFT_74xx into POWERPC_MMU_32B,
check the HID0[STEN] bit, …
[View More]figure out how to switch from HW TLB miss to
SW TLB miss on demand, block access to the TLBMISS register (and
others) when the feature is off, and so on;
c) leave the feature enabled in QEMU and implement the software TLB
miss handlers in openbios. The UM provides sample code, so this is
easy;
d) remove support for software TLB search for the 7450 family and
switch the cpus to the POWERPC_MMU_32B model. This is by far the
easiest solution, but could cause problems for any (which?) guest OS
code that actually uses the feature. All of the existing code for the
POWERPC_MMU_SOFT_74xx MMU model would probably be removed since it
would be dead code then;
v1:
https://lists.nongnu.org/archive/html/qemu-ppc/2021-11/msg00289.html
v2:
This series corresponds to option d) above.
- patch 1 moves all of the 7450 CPUs* into the POWERPC_MMU_32B MMU
model, which does the same as the POWERPC_MMU_SOFT_74xx minus the
software TLB handling. It also removes the instructions (tlbld, tlbli)
and SPRs (TLBMISS, PTEHI, PTELO) from the 7450s as these facilities
are only used along with the software TLB.
*- except for 7448, which is seen by QEMU as a 7400.
- patch 2 removes the instructions and SPRs just like above, but from
the e600 CPU. The e600 already uses the POWERPC_MMU_32B MMU model,
so it already has software TLB disabled.
- patch 3 removes all of the now dead code for the 74xx software
TLB. I left a note in the code with keywords to help with grep in
case people search for the feature in the future.
- patch 4 adds smoke tests for all of the 74xx CPUs. These are broken
pending the OpenBIOS patch.
For OpenBIOS:
We'd need to merge the patch 2/2 from the previous series:
https://lists.nongnu.org/archive/html/qemu-ppc/2021-11/msg00290.html
Message ID: 20211119134431.406753-3-farosas(a)linux.ibm.com
this is just for the new PVRs. There is no need to add the handlers.
Thanks!
Fabiano Rosas (4):
target/ppc: Disable software TLB for the 7450 family
target/ppc: Disable unused facilities in the e600 CPU
target/ppc: Remove the software TLB model of 7450 CPUs
tests/avocado: ppc: Add smoke tests for MPC7400 and MPC7450 families
target/ppc/cpu-qom.h | 6 +-
target/ppc/cpu.h | 4 +-
target/ppc/cpu_init.c | 57 ++++--------------
target/ppc/excp_helper.c | 29 ---------
target/ppc/helper.h | 2 -
target/ppc/mmu_common.c | 19 ------
target/ppc/mmu_helper.c | 31 ----------
target/ppc/translate.c | 26 --------
tests/avocado/ppc_74xx.py | 123 ++++++++++++++++++++++++++++++++++++++
9 files changed, 140 insertions(+), 157 deletions(-)
create mode 100644 tests/avocado/ppc_74xx.py
--
2.33.1
[View Less]
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
…
[View More]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
[View Less]
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
…
[View More]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 | 113 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 113 insertions(+)
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c
index 45cd77e..2bee848 100644
--- a/arch/ppc/qemu/init.c
+++ b/arch/ppc/qemu/init.c
@@ -716,6 +716,116 @@ 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) {
+ return;
+ }
+ fword("new-device");
+ push_str("pci");
+ fword("device-name");
+ push_str("pci");
+ fword("device-type");
+ push_str("AAPL,UniNorth");
+ fword("encode-string");
+ push_str("model");
+ fword("property");
+ push_str("uni-north");
+ fword("encode-string");
+ push_str("compatible");
+ fword("property");
+ 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");
+ PUSH(66666666);
+ fword("encode-int");
+ push_str("clock-frequency");
+ fword("property");
+ PUSH(0x800);
+ fword("encode-int");
+ push_str("UNI-N");
+ fword("encode-string");
+ fword("encode+");
+ push_str("built-in-names");
+ fword("property");
+ PUSH(0x10000);
+ fword("encode-int");
+ push_str("SLOT-A");
+ fword("encode-string");
+ fword("encode+");
+ push_str("slot-names");
+ fword("property");
+ encode_int_plus(18,
+ 0x02000000, 0, 0xf1000000, 0xf1000000, 0, 0x01000000,
+ 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");
+}
+
+static void empty_pci_bus_interrupts(void)
+{
+ phandle_t pic, dnode;
+ u32 props[8];
+
+ if (machine_id != ARCH_MAC99) {
+ return;
+ }
+ pic = dt_iterate_type(0, "open-pic");
+ dnode = find_dev("/pci@f0000000");
+ props[0] = 0x2d;
+ props[1] = 0x1;
+ set_property(dnode, "interrupts", (char *)props, 2 * sizeof(u32));
+ set_int_property(dnode, "interrupt_patent", pic);
+ props[0] = 0x8000;
+ props[1] = 0;
+ props[2] = 0;
+ props[3] = 0;
+ props[4] = pic;
+ props[5] = 0x30;
+ props[6] = 0x1;
+ set_property(dnode, "interrupt-map", (char *)props, 7 * sizeof(u32));
+ props[0] = 0xf800;
+ props[1] = 0;
+ props[2] = 0;
+ props[3] = 0;
+ set_property(dnode, "interrupt-map-mask", (char *)props, 4 * sizeof(u32));
+}
+
/*
* filll ( addr bytes quad -- )
*/
@@ -868,8 +978,11 @@ 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();
+ empty_pci_bus_interrupts();
break;
default:
ob_pci_init();
--
2.30.2
[View Less]