* [PATCH v4 01/12] ppc/vof: Make nextprop behave more like Open Firmware
2025-10-23 0:06 [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation BALATON Zoltan
@ 2025-10-23 0:06 ` BALATON Zoltan
2025-10-23 0:06 ` [PATCH v4 02/12] hw/ppc/pegasos2: Remove explicit name properties from device tree BALATON Zoltan
` (11 subsequent siblings)
12 siblings, 0 replies; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 0:06 UTC (permalink / raw)
To: qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
The FDT does not normally store name properties but reconstructs it
from path but Open Firmware specification says each node should at
least have this property. This is correctly handled in getprop but
nextprop should also return it even if not present as a property.
Explicit name properties are still allowed because they are needed
e.g. on the root node that guests expect to have specific names as
seen on real machines instead of being empty so sometimes the node
name may need to be overriden. For example on pegasos MorphOS checks
the name of "/" and expects to find bplan,Pegasos2 which is how it
identifies the machine.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Alexey Kardashevskiy <aik@ozlabs.ru>
---
hw/ppc/vof.c | 50 +++++++++++++++++++++++++++++++++-----------------
1 file changed, 33 insertions(+), 17 deletions(-)
diff --git a/hw/ppc/vof.c b/hw/ppc/vof.c
index f14efa3a7c..5ecfc68910 100644
--- a/hw/ppc/vof.c
+++ b/hw/ppc/vof.c
@@ -353,34 +353,50 @@ static uint32_t vof_nextprop(const void *fdt, uint32_t phandle,
{
int offset, nodeoff = fdt_node_offset_by_phandle(fdt, phandle);
char prev[OF_PROPNAME_LEN_MAX + 1];
- const char *tmp;
+ const char *tmp = NULL;
+ bool match = false;
if (readstr(prevaddr, prev, sizeof(prev))) {
return PROM_ERROR;
}
-
- fdt_for_each_property_offset(offset, fdt, nodeoff) {
- if (!fdt_getprop_by_offset(fdt, offset, &tmp, NULL)) {
- return 0;
+ /*
+ * "name" may or may not be present in fdt but we should still return it.
+ * Do that first and then skip it if seen later.
+ */
+ if (prev[0] == '\0') {
+ tmp = "name";
+ } else {
+ if (strcmp(prev, "name") == 0) {
+ prev[0] = '\0';
}
- if (prev[0] == '\0' || strcmp(prev, tmp) == 0) {
- if (prev[0] != '\0') {
- offset = fdt_next_property_offset(fdt, offset);
- if (offset < 0) {
- return 0;
- }
- }
+ fdt_for_each_property_offset(offset, fdt, nodeoff) {
if (!fdt_getprop_by_offset(fdt, offset, &tmp, NULL)) {
return 0;
}
-
- if (VOF_MEM_WRITE(nameaddr, tmp, strlen(tmp) + 1) != MEMTX_OK) {
- return PROM_ERROR;
+ if (strcmp(tmp, "name") == 0) {
+ continue;
+ }
+ if (match) {
+ break;
}
- return 1;
+ if (strcmp(prev, tmp) == 0) {
+ match = true;
+ continue;
+ }
+ if (prev[0] == '\0') {
+ break;
+ }
+ }
+ if (offset < 0) {
+ return 0;
}
}
-
+ if (tmp) {
+ if (VOF_MEM_WRITE(nameaddr, tmp, strlen(tmp) + 1) != MEMTX_OK) {
+ return PROM_ERROR;
+ }
+ return 1;
+ }
return 0;
}
--
2.41.3
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v4 02/12] hw/ppc/pegasos2: Remove explicit name properties from device tree
2025-10-23 0:06 [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation BALATON Zoltan
2025-10-23 0:06 ` [PATCH v4 01/12] ppc/vof: Make nextprop behave more like Open Firmware BALATON Zoltan
@ 2025-10-23 0:06 ` BALATON Zoltan
2025-10-23 4:55 ` Harsh Prateek Bora
2025-10-23 0:06 ` [PATCH v4 03/12] hw/ppc/pegasos2: Change device tree generation BALATON Zoltan
` (10 subsequent siblings)
12 siblings, 1 reply; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 0:06 UTC (permalink / raw)
To: qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
These are not needed any more now that VOF can handle it.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
hw/ppc/pegasos2.c | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index e15cf96427..73995624e5 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -662,7 +662,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
qemu_fdt_setprop_cell(fi->fdt, fi->path, "#size-cells", 1);
qemu_fdt_setprop_cell(fi->fdt, fi->path, "#address-cells", 2);
qemu_fdt_setprop_string(fi->fdt, fi->path, "device_type", "isa");
- qemu_fdt_setprop_string(fi->fdt, fi->path, "name", "isa");
/* additional devices */
g_string_printf(name, "%s/lpt@i3bc", fi->path);
@@ -677,7 +676,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
cells[2] = cpu_to_be32(8);
qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "lpt");
- qemu_fdt_setprop_string(fi->fdt, name->str, "name", "lpt");
g_string_printf(name, "%s/fdc@i3f0", fi->path);
qemu_fdt_add_subnode(fi->fdt, name->str);
@@ -691,7 +689,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
cells[2] = cpu_to_be32(8);
qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "fdc");
- qemu_fdt_setprop_string(fi->fdt, name->str, "name", "fdc");
g_string_printf(name, "%s/timer@i40", fi->path);
qemu_fdt_add_subnode(fi->fdt, name->str);
@@ -701,7 +698,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
cells[2] = cpu_to_be32(8);
qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "timer");
- qemu_fdt_setprop_string(fi->fdt, name->str, "name", "timer");
g_string_printf(name, "%s/rtc@i70", fi->path);
qemu_fdt_add_subnode(fi->fdt, name->str);
@@ -716,7 +712,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
cells[2] = cpu_to_be32(2);
qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "rtc");
- qemu_fdt_setprop_string(fi->fdt, name->str, "name", "rtc");
g_string_printf(name, "%s/keyboard@i60", fi->path);
qemu_fdt_add_subnode(fi->fdt, name->str);
@@ -729,7 +724,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
cells[2] = cpu_to_be32(5);
qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "keyboard");
- qemu_fdt_setprop_string(fi->fdt, name->str, "name", "keyboard");
g_string_printf(name, "%s/8042@i60", fi->path);
qemu_fdt_add_subnode(fi->fdt, name->str);
@@ -743,7 +737,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
cells[2] = cpu_to_be32(5);
qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "");
- qemu_fdt_setprop_string(fi->fdt, name->str, "name", "8042");
g_string_printf(name, "%s/serial@i2f8", fi->path);
qemu_fdt_add_subnode(fi->fdt, name->str);
@@ -757,7 +750,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
cells[2] = cpu_to_be32(8);
qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "serial");
- qemu_fdt_setprop_string(fi->fdt, name->str, "name", "serial");
g_string_free(name, TRUE);
}
@@ -846,7 +838,6 @@ static void add_pci_device(PCIBus *bus, PCIDevice *d, void *opaque)
j += 5;
}
qemu_fdt_setprop(fi->fdt, node->str, "reg", cells, j * sizeof(cells[0]));
- qemu_fdt_setprop_string(fi->fdt, node->str, "name", name ?: pn);
if (pci_get_byte(&d->config[PCI_INTERRUPT_PIN])) {
qemu_fdt_setprop_cell(fi->fdt, node->str, "interrupts",
pci_get_byte(&d->config[PCI_INTERRUPT_PIN]));
@@ -916,7 +907,6 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
qemu_fdt_setprop_cell(fdt, "/pci@c0000000", "#size-cells", 2);
qemu_fdt_setprop_cell(fdt, "/pci@c0000000", "#address-cells", 3);
qemu_fdt_setprop_string(fdt, "/pci@c0000000", "device_type", "pci");
- qemu_fdt_setprop_string(fdt, "/pci@c0000000", "name", "pci");
fi.path = "/pci@c0000000";
pci_bus = mv64361_get_pci_bus(pm->mv, 0);
@@ -951,7 +941,6 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
qemu_fdt_setprop_cell(fdt, "/pci@80000000", "#size-cells", 2);
qemu_fdt_setprop_cell(fdt, "/pci@80000000", "#address-cells", 3);
qemu_fdt_setprop_string(fdt, "/pci@80000000", "device_type", "pci");
- qemu_fdt_setprop_string(fdt, "/pci@80000000", "name", "pci");
fi.path = "/pci@80000000";
pci_bus = mv64361_get_pci_bus(pm->mv, 1);
@@ -959,7 +948,6 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
qemu_fdt_add_subnode(fdt, "/failsafe");
qemu_fdt_setprop_string(fdt, "/failsafe", "device_type", "serial");
- qemu_fdt_setprop_string(fdt, "/failsafe", "name", "failsafe");
qemu_fdt_add_subnode(fdt, "/rtas");
qemu_fdt_setprop_cell(fdt, "/rtas", "system-reboot", RTAS_SYSTEM_REBOOT);
@@ -989,14 +977,12 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-display-device", 0);
qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-size", 20);
qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-version", 1);
- qemu_fdt_setprop_string(fdt, "/rtas", "name", "rtas");
/* cpus */
qemu_fdt_add_subnode(fdt, "/cpus");
qemu_fdt_setprop_cell(fdt, "/cpus", "#cpus", 1);
qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 1);
qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0);
- qemu_fdt_setprop_string(fdt, "/cpus", "name", "cpus");
/* FIXME Get CPU name from CPU object */
const char *cp = "/cpus/PowerPC,G4";
@@ -1048,7 +1034,6 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
cells[1] = 0;
qemu_fdt_setprop(fdt, cp, "reg", cells, 2 * sizeof(cells[0]));
qemu_fdt_setprop_string(fdt, cp, "device_type", "cpu");
- qemu_fdt_setprop_string(fdt, cp, "name", strrchr(cp, '/') + 1);
/* memory */
qemu_fdt_add_subnode(fdt, "/memory@0");
@@ -1056,7 +1041,6 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
cells[1] = cpu_to_be32(machine->ram_size);
qemu_fdt_setprop(fdt, "/memory@0", "reg", cells, 2 * sizeof(cells[0]));
qemu_fdt_setprop_string(fdt, "/memory@0", "device_type", "memory");
- qemu_fdt_setprop_string(fdt, "/memory@0", "name", "memory");
qemu_fdt_add_subnode(fdt, "/chosen");
if (pm->initrd_addr && pm->initrd_size) {
@@ -1067,7 +1051,6 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
}
qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
machine->kernel_cmdline ?: "");
- qemu_fdt_setprop_string(fdt, "/chosen", "name", "chosen");
qemu_fdt_add_subnode(fdt, "/openprom");
qemu_fdt_setprop_string(fdt, "/openprom", "model", "Pegasos2,1.1");
--
2.41.3
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH v4 02/12] hw/ppc/pegasos2: Remove explicit name properties from device tree
2025-10-23 0:06 ` [PATCH v4 02/12] hw/ppc/pegasos2: Remove explicit name properties from device tree BALATON Zoltan
@ 2025-10-23 4:55 ` Harsh Prateek Bora
0 siblings, 0 replies; 29+ messages in thread
From: Harsh Prateek Bora @ 2025-10-23 4:55 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Markus Armbruster
On 10/23/25 05:36, BALATON Zoltan wrote:
> These are not needed any more now that VOF can handle it.
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Harsh Prateek Bora <harshp@linux.ibm.com>
> ---
> hw/ppc/pegasos2.c | 17 -----------------
> 1 file changed, 17 deletions(-)
>
> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
> index e15cf96427..73995624e5 100644
> --- a/hw/ppc/pegasos2.c
> +++ b/hw/ppc/pegasos2.c
> @@ -662,7 +662,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
> qemu_fdt_setprop_cell(fi->fdt, fi->path, "#size-cells", 1);
> qemu_fdt_setprop_cell(fi->fdt, fi->path, "#address-cells", 2);
> qemu_fdt_setprop_string(fi->fdt, fi->path, "device_type", "isa");
> - qemu_fdt_setprop_string(fi->fdt, fi->path, "name", "isa");
>
> /* additional devices */
> g_string_printf(name, "%s/lpt@i3bc", fi->path);
> @@ -677,7 +676,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
> cells[2] = cpu_to_be32(8);
> qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
> qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "lpt");
> - qemu_fdt_setprop_string(fi->fdt, name->str, "name", "lpt");
>
> g_string_printf(name, "%s/fdc@i3f0", fi->path);
> qemu_fdt_add_subnode(fi->fdt, name->str);
> @@ -691,7 +689,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
> cells[2] = cpu_to_be32(8);
> qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
> qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "fdc");
> - qemu_fdt_setprop_string(fi->fdt, name->str, "name", "fdc");
>
> g_string_printf(name, "%s/timer@i40", fi->path);
> qemu_fdt_add_subnode(fi->fdt, name->str);
> @@ -701,7 +698,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
> cells[2] = cpu_to_be32(8);
> qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
> qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "timer");
> - qemu_fdt_setprop_string(fi->fdt, name->str, "name", "timer");
>
> g_string_printf(name, "%s/rtc@i70", fi->path);
> qemu_fdt_add_subnode(fi->fdt, name->str);
> @@ -716,7 +712,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
> cells[2] = cpu_to_be32(2);
> qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
> qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "rtc");
> - qemu_fdt_setprop_string(fi->fdt, name->str, "name", "rtc");
>
> g_string_printf(name, "%s/keyboard@i60", fi->path);
> qemu_fdt_add_subnode(fi->fdt, name->str);
> @@ -729,7 +724,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
> cells[2] = cpu_to_be32(5);
> qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
> qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "keyboard");
> - qemu_fdt_setprop_string(fi->fdt, name->str, "name", "keyboard");
>
> g_string_printf(name, "%s/8042@i60", fi->path);
> qemu_fdt_add_subnode(fi->fdt, name->str);
> @@ -743,7 +737,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
> cells[2] = cpu_to_be32(5);
> qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
> qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "");
> - qemu_fdt_setprop_string(fi->fdt, name->str, "name", "8042");
>
> g_string_printf(name, "%s/serial@i2f8", fi->path);
> qemu_fdt_add_subnode(fi->fdt, name->str);
> @@ -757,7 +750,6 @@ static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
> cells[2] = cpu_to_be32(8);
> qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
> qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "serial");
> - qemu_fdt_setprop_string(fi->fdt, name->str, "name", "serial");
>
> g_string_free(name, TRUE);
> }
> @@ -846,7 +838,6 @@ static void add_pci_device(PCIBus *bus, PCIDevice *d, void *opaque)
> j += 5;
> }
> qemu_fdt_setprop(fi->fdt, node->str, "reg", cells, j * sizeof(cells[0]));
> - qemu_fdt_setprop_string(fi->fdt, node->str, "name", name ?: pn);
> if (pci_get_byte(&d->config[PCI_INTERRUPT_PIN])) {
> qemu_fdt_setprop_cell(fi->fdt, node->str, "interrupts",
> pci_get_byte(&d->config[PCI_INTERRUPT_PIN]));
> @@ -916,7 +907,6 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
> qemu_fdt_setprop_cell(fdt, "/pci@c0000000", "#size-cells", 2);
> qemu_fdt_setprop_cell(fdt, "/pci@c0000000", "#address-cells", 3);
> qemu_fdt_setprop_string(fdt, "/pci@c0000000", "device_type", "pci");
> - qemu_fdt_setprop_string(fdt, "/pci@c0000000", "name", "pci");
>
> fi.path = "/pci@c0000000";
> pci_bus = mv64361_get_pci_bus(pm->mv, 0);
> @@ -951,7 +941,6 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
> qemu_fdt_setprop_cell(fdt, "/pci@80000000", "#size-cells", 2);
> qemu_fdt_setprop_cell(fdt, "/pci@80000000", "#address-cells", 3);
> qemu_fdt_setprop_string(fdt, "/pci@80000000", "device_type", "pci");
> - qemu_fdt_setprop_string(fdt, "/pci@80000000", "name", "pci");
>
> fi.path = "/pci@80000000";
> pci_bus = mv64361_get_pci_bus(pm->mv, 1);
> @@ -959,7 +948,6 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
>
> qemu_fdt_add_subnode(fdt, "/failsafe");
> qemu_fdt_setprop_string(fdt, "/failsafe", "device_type", "serial");
> - qemu_fdt_setprop_string(fdt, "/failsafe", "name", "failsafe");
>
> qemu_fdt_add_subnode(fdt, "/rtas");
> qemu_fdt_setprop_cell(fdt, "/rtas", "system-reboot", RTAS_SYSTEM_REBOOT);
> @@ -989,14 +977,12 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
> qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-display-device", 0);
> qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-size", 20);
> qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-version", 1);
> - qemu_fdt_setprop_string(fdt, "/rtas", "name", "rtas");
>
> /* cpus */
> qemu_fdt_add_subnode(fdt, "/cpus");
> qemu_fdt_setprop_cell(fdt, "/cpus", "#cpus", 1);
> qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 1);
> qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0);
> - qemu_fdt_setprop_string(fdt, "/cpus", "name", "cpus");
>
> /* FIXME Get CPU name from CPU object */
> const char *cp = "/cpus/PowerPC,G4";
> @@ -1048,7 +1034,6 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
> cells[1] = 0;
> qemu_fdt_setprop(fdt, cp, "reg", cells, 2 * sizeof(cells[0]));
> qemu_fdt_setprop_string(fdt, cp, "device_type", "cpu");
> - qemu_fdt_setprop_string(fdt, cp, "name", strrchr(cp, '/') + 1);
>
> /* memory */
> qemu_fdt_add_subnode(fdt, "/memory@0");
> @@ -1056,7 +1041,6 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
> cells[1] = cpu_to_be32(machine->ram_size);
> qemu_fdt_setprop(fdt, "/memory@0", "reg", cells, 2 * sizeof(cells[0]));
> qemu_fdt_setprop_string(fdt, "/memory@0", "device_type", "memory");
> - qemu_fdt_setprop_string(fdt, "/memory@0", "name", "memory");
>
> qemu_fdt_add_subnode(fdt, "/chosen");
> if (pm->initrd_addr && pm->initrd_size) {
> @@ -1067,7 +1051,6 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
> }
> qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
> machine->kernel_cmdline ?: "");
> - qemu_fdt_setprop_string(fdt, "/chosen", "name", "chosen");
>
> qemu_fdt_add_subnode(fdt, "/openprom");
> qemu_fdt_setprop_string(fdt, "/openprom", "model", "Pegasos2,1.1");
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH v4 03/12] hw/ppc/pegasos2: Change device tree generation
2025-10-23 0:06 [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation BALATON Zoltan
2025-10-23 0:06 ` [PATCH v4 01/12] ppc/vof: Make nextprop behave more like Open Firmware BALATON Zoltan
2025-10-23 0:06 ` [PATCH v4 02/12] hw/ppc/pegasos2: Remove explicit name properties from device tree BALATON Zoltan
@ 2025-10-23 0:06 ` BALATON Zoltan
2025-10-23 0:06 ` [PATCH v4 04/12] hw/ppc/pegasos2: Remove fdt pointer from machine state BALATON Zoltan
` (9 subsequent siblings)
12 siblings, 0 replies; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 0:06 UTC (permalink / raw)
To: qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
We generate a flattened device tree programmatically for VOF. Change
this to load the static parts from a device tree blob and only
generate the parts that depend on run time conditions such as CPU
type, memory size and PCI devices. Moving the static parts in a dts
makes the board code simpler and more generic.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/ppc/pegasos2.c | 291 +++++++--------------------------------
pc-bios/dtb/meson.build | 1 +
pc-bios/dtb/pegasos2.dtb | Bin 0 -> 1701 bytes
pc-bios/dtb/pegasos2.dts | 167 ++++++++++++++++++++++
4 files changed, 219 insertions(+), 240 deletions(-)
create mode 100644 pc-bios/dtb/pegasos2.dtb
create mode 100644 pc-bios/dtb/pegasos2.dts
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 73995624e5..f4787397dc 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -58,16 +58,8 @@
#define BUS_FREQ_HZ 133333333
#define PCI0_CFG_ADDR 0xcf8
-#define PCI0_MEM_BASE 0xc0000000
-#define PCI0_MEM_SIZE 0x20000000
-#define PCI0_IO_BASE 0xf8000000
-#define PCI0_IO_SIZE 0x10000
-
#define PCI1_CFG_ADDR 0xc78
-#define PCI1_MEM_BASE 0x80000000
-#define PCI1_MEM_SIZE 0x40000000
#define PCI1_IO_BASE 0xfe000000
-#define PCI1_IO_SIZE 0x10000
#define TYPE_PEGASOS2_MACHINE MACHINE_TYPE_NAME("pegasos2")
OBJECT_DECLARE_TYPE(Pegasos2MachineState, MachineClass, PEGASOS2_MACHINE)
@@ -411,7 +403,11 @@ static void pegasos2_machine_reset(MachineState *machine, ResetType type)
error_report("Memory for initrd is in use");
exit(1);
}
+
fdt = build_fdt(machine, &sz);
+ if (!fdt) {
+ exit(1);
+ }
/* FIXME: VOF assumes entry is same as load address */
d[0] = cpu_to_be64(pm->kernel_entry);
d[1] = cpu_to_be64(pm->kernel_size - (pm->kernel_entry - pm->kernel_addr));
@@ -654,113 +650,12 @@ static void dt_usb(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
qemu_fdt_setprop_string(fi->fdt, fi->path, "device_type", "usb");
}
-static void dt_isa(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
-{
- GString *name = g_string_sized_new(64);
- uint32_t cells[3];
-
- qemu_fdt_setprop_cell(fi->fdt, fi->path, "#size-cells", 1);
- qemu_fdt_setprop_cell(fi->fdt, fi->path, "#address-cells", 2);
- qemu_fdt_setprop_string(fi->fdt, fi->path, "device_type", "isa");
-
- /* additional devices */
- g_string_printf(name, "%s/lpt@i3bc", fi->path);
- qemu_fdt_add_subnode(fi->fdt, name->str);
- qemu_fdt_setprop_cell(fi->fdt, name->str, "clock-frequency", 0);
- cells[0] = cpu_to_be32(7);
- cells[1] = 0;
- qemu_fdt_setprop(fi->fdt, name->str, "interrupts",
- cells, 2 * sizeof(cells[0]));
- cells[0] = cpu_to_be32(1);
- cells[1] = cpu_to_be32(0x3bc);
- cells[2] = cpu_to_be32(8);
- qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
- qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "lpt");
-
- g_string_printf(name, "%s/fdc@i3f0", fi->path);
- qemu_fdt_add_subnode(fi->fdt, name->str);
- qemu_fdt_setprop_cell(fi->fdt, name->str, "clock-frequency", 0);
- cells[0] = cpu_to_be32(6);
- cells[1] = 0;
- qemu_fdt_setprop(fi->fdt, name->str, "interrupts",
- cells, 2 * sizeof(cells[0]));
- cells[0] = cpu_to_be32(1);
- cells[1] = cpu_to_be32(0x3f0);
- cells[2] = cpu_to_be32(8);
- qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
- qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "fdc");
-
- g_string_printf(name, "%s/timer@i40", fi->path);
- qemu_fdt_add_subnode(fi->fdt, name->str);
- qemu_fdt_setprop_cell(fi->fdt, name->str, "clock-frequency", 0);
- cells[0] = cpu_to_be32(1);
- cells[1] = cpu_to_be32(0x40);
- cells[2] = cpu_to_be32(8);
- qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
- qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "timer");
-
- g_string_printf(name, "%s/rtc@i70", fi->path);
- qemu_fdt_add_subnode(fi->fdt, name->str);
- qemu_fdt_setprop_string(fi->fdt, name->str, "compatible", "ds1385-rtc");
- qemu_fdt_setprop_cell(fi->fdt, name->str, "clock-frequency", 0);
- cells[0] = cpu_to_be32(8);
- cells[1] = 0;
- qemu_fdt_setprop(fi->fdt, name->str, "interrupts",
- cells, 2 * sizeof(cells[0]));
- cells[0] = cpu_to_be32(1);
- cells[1] = cpu_to_be32(0x70);
- cells[2] = cpu_to_be32(2);
- qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
- qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "rtc");
-
- g_string_printf(name, "%s/keyboard@i60", fi->path);
- qemu_fdt_add_subnode(fi->fdt, name->str);
- cells[0] = cpu_to_be32(1);
- cells[1] = 0;
- qemu_fdt_setprop(fi->fdt, name->str, "interrupts",
- cells, 2 * sizeof(cells[0]));
- cells[0] = cpu_to_be32(1);
- cells[1] = cpu_to_be32(0x60);
- cells[2] = cpu_to_be32(5);
- qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
- qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "keyboard");
-
- g_string_printf(name, "%s/8042@i60", fi->path);
- qemu_fdt_add_subnode(fi->fdt, name->str);
- qemu_fdt_setprop_cell(fi->fdt, name->str, "#interrupt-cells", 2);
- qemu_fdt_setprop_cell(fi->fdt, name->str, "#size-cells", 0);
- qemu_fdt_setprop_cell(fi->fdt, name->str, "#address-cells", 1);
- qemu_fdt_setprop_string(fi->fdt, name->str, "interrupt-controller", "");
- qemu_fdt_setprop_cell(fi->fdt, name->str, "clock-frequency", 0);
- cells[0] = cpu_to_be32(1);
- cells[1] = cpu_to_be32(0x60);
- cells[2] = cpu_to_be32(5);
- qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
- qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "");
-
- g_string_printf(name, "%s/serial@i2f8", fi->path);
- qemu_fdt_add_subnode(fi->fdt, name->str);
- qemu_fdt_setprop_cell(fi->fdt, name->str, "clock-frequency", 0);
- cells[0] = cpu_to_be32(3);
- cells[1] = 0;
- qemu_fdt_setprop(fi->fdt, name->str, "interrupts",
- cells, 2 * sizeof(cells[0]));
- cells[0] = cpu_to_be32(1);
- cells[1] = cpu_to_be32(0x2f8);
- cells[2] = cpu_to_be32(8);
- qemu_fdt_setprop(fi->fdt, name->str, "reg", cells, 3 * sizeof(cells[0]));
- qemu_fdt_setprop_string(fi->fdt, name->str, "device_type", "serial");
-
- g_string_free(name, TRUE);
-}
-
static struct {
const char *id;
const char *name;
void (*dtf)(PCIBus *bus, PCIDevice *d, FDTInfo *fi);
} device_map[] = {
{ "pci11ab,6460", "host", NULL },
- { "pci1106,8231", "isa", dt_isa },
{ "pci1106,571", "ide", dt_ide },
{ "pci1106,3044", "firewire", NULL },
{ "pci1106,3038", "usb", dt_usb },
@@ -780,7 +675,10 @@ static void add_pci_device(PCIBus *bus, PCIDevice *d, void *opaque)
pci_get_word(&d->config[PCI_VENDOR_ID]),
pci_get_word(&d->config[PCI_DEVICE_ID]));
- if (pci_get_word(&d->config[PCI_CLASS_DEVICE]) ==
+ if (!strcmp(pn, "pci1106,8231")) {
+ return; /* ISA bridge and devices are included in dtb */
+ }
+ if (pci_get_word(&d->config[PCI_CLASS_DEVICE]) ==
PCI_CLASS_NETWORK_ETHERNET) {
name = "ethernet";
} else if (pci_get_word(&d->config[PCI_CLASS_DEVICE]) >> 8 ==
@@ -858,131 +756,9 @@ static void add_pci_device(PCIBus *bus, PCIDevice *d, void *opaque)
g_string_free(node, TRUE);
}
-static void *build_fdt(MachineState *machine, int *fdt_size)
+static void add_cpu_info(void *fdt, PowerPCCPU *cpu)
{
- Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
- PowerPCCPU *cpu = pm->cpu;
- PCIBus *pci_bus;
- FDTInfo fi;
- uint32_t cells[16];
- void *fdt = create_device_tree(fdt_size);
-
- fi.fdt = fdt;
-
- /* root node */
- qemu_fdt_setprop_string(fdt, "/", "CODEGEN,description",
- "Pegasos CHRP PowerPC System");
- qemu_fdt_setprop_string(fdt, "/", "CODEGEN,board", "Pegasos2");
- qemu_fdt_setprop_string(fdt, "/", "CODEGEN,vendor", "bplan GmbH");
- qemu_fdt_setprop_string(fdt, "/", "revision", "2B");
- qemu_fdt_setprop_string(fdt, "/", "model", "Pegasos2");
- qemu_fdt_setprop_string(fdt, "/", "device_type", "chrp");
- qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 1);
- qemu_fdt_setprop_string(fdt, "/", "name", "bplan,Pegasos2");
-
- /* pci@c0000000 */
- qemu_fdt_add_subnode(fdt, "/pci@c0000000");
- cells[0] = 0;
- cells[1] = 0;
- qemu_fdt_setprop(fdt, "/pci@c0000000", "bus-range",
- cells, 2 * sizeof(cells[0]));
- qemu_fdt_setprop_cell(fdt, "/pci@c0000000", "pci-bridge-number", 1);
- cells[0] = cpu_to_be32(PCI0_MEM_BASE);
- cells[1] = cpu_to_be32(PCI0_MEM_SIZE);
- qemu_fdt_setprop(fdt, "/pci@c0000000", "reg", cells, 2 * sizeof(cells[0]));
- cells[0] = cpu_to_be32(0x01000000);
- cells[1] = 0;
- cells[2] = 0;
- cells[3] = cpu_to_be32(PCI0_IO_BASE);
- cells[4] = 0;
- cells[5] = cpu_to_be32(PCI0_IO_SIZE);
- cells[6] = cpu_to_be32(0x02000000);
- cells[7] = 0;
- cells[8] = cpu_to_be32(PCI0_MEM_BASE);
- cells[9] = cpu_to_be32(PCI0_MEM_BASE);
- cells[10] = 0;
- cells[11] = cpu_to_be32(PCI0_MEM_SIZE);
- qemu_fdt_setprop(fdt, "/pci@c0000000", "ranges",
- cells, 12 * sizeof(cells[0]));
- qemu_fdt_setprop_cell(fdt, "/pci@c0000000", "#size-cells", 2);
- qemu_fdt_setprop_cell(fdt, "/pci@c0000000", "#address-cells", 3);
- qemu_fdt_setprop_string(fdt, "/pci@c0000000", "device_type", "pci");
-
- fi.path = "/pci@c0000000";
- pci_bus = mv64361_get_pci_bus(pm->mv, 0);
- pci_for_each_device_reverse(pci_bus, 0, add_pci_device, &fi);
-
- /* pci@80000000 */
- qemu_fdt_add_subnode(fdt, "/pci@80000000");
- cells[0] = 0;
- cells[1] = 0;
- qemu_fdt_setprop(fdt, "/pci@80000000", "bus-range",
- cells, 2 * sizeof(cells[0]));
- qemu_fdt_setprop_cell(fdt, "/pci@80000000", "pci-bridge-number", 0);
- cells[0] = cpu_to_be32(PCI1_MEM_BASE);
- cells[1] = cpu_to_be32(PCI1_MEM_SIZE);
- qemu_fdt_setprop(fdt, "/pci@80000000", "reg", cells, 2 * sizeof(cells[0]));
- qemu_fdt_setprop_cell(fdt, "/pci@80000000", "8259-interrupt-acknowledge",
- 0xf1000cb4);
- cells[0] = cpu_to_be32(0x01000000);
- cells[1] = 0;
- cells[2] = 0;
- cells[3] = cpu_to_be32(PCI1_IO_BASE);
- cells[4] = 0;
- cells[5] = cpu_to_be32(PCI1_IO_SIZE);
- cells[6] = cpu_to_be32(0x02000000);
- cells[7] = 0;
- cells[8] = cpu_to_be32(PCI1_MEM_BASE);
- cells[9] = cpu_to_be32(PCI1_MEM_BASE);
- cells[10] = 0;
- cells[11] = cpu_to_be32(PCI1_MEM_SIZE);
- qemu_fdt_setprop(fdt, "/pci@80000000", "ranges",
- cells, 12 * sizeof(cells[0]));
- qemu_fdt_setprop_cell(fdt, "/pci@80000000", "#size-cells", 2);
- qemu_fdt_setprop_cell(fdt, "/pci@80000000", "#address-cells", 3);
- qemu_fdt_setprop_string(fdt, "/pci@80000000", "device_type", "pci");
-
- fi.path = "/pci@80000000";
- pci_bus = mv64361_get_pci_bus(pm->mv, 1);
- pci_for_each_device_reverse(pci_bus, 0, add_pci_device, &fi);
-
- qemu_fdt_add_subnode(fdt, "/failsafe");
- qemu_fdt_setprop_string(fdt, "/failsafe", "device_type", "serial");
-
- qemu_fdt_add_subnode(fdt, "/rtas");
- qemu_fdt_setprop_cell(fdt, "/rtas", "system-reboot", RTAS_SYSTEM_REBOOT);
- qemu_fdt_setprop_cell(fdt, "/rtas", "hibernate", RTAS_HIBERNATE);
- qemu_fdt_setprop_cell(fdt, "/rtas", "suspend", RTAS_SUSPEND);
- qemu_fdt_setprop_cell(fdt, "/rtas", "power-off", RTAS_POWER_OFF);
- qemu_fdt_setprop_cell(fdt, "/rtas", "set-indicator", RTAS_SET_INDICATOR);
- qemu_fdt_setprop_cell(fdt, "/rtas", "display-character",
- RTAS_DISPLAY_CHARACTER);
- qemu_fdt_setprop_cell(fdt, "/rtas", "write-pci-config",
- RTAS_WRITE_PCI_CONFIG);
- qemu_fdt_setprop_cell(fdt, "/rtas", "read-pci-config",
- RTAS_READ_PCI_CONFIG);
- /* Pegasos2 firmware misspells check-exception and guests use that */
- qemu_fdt_setprop_cell(fdt, "/rtas", "check-execption",
- RTAS_CHECK_EXCEPTION);
- qemu_fdt_setprop_cell(fdt, "/rtas", "event-scan", RTAS_EVENT_SCAN);
- qemu_fdt_setprop_cell(fdt, "/rtas", "set-time-of-day",
- RTAS_SET_TIME_OF_DAY);
- qemu_fdt_setprop_cell(fdt, "/rtas", "get-time-of-day",
- RTAS_GET_TIME_OF_DAY);
- qemu_fdt_setprop_cell(fdt, "/rtas", "nvram-store", RTAS_NVRAM_STORE);
- qemu_fdt_setprop_cell(fdt, "/rtas", "nvram-fetch", RTAS_NVRAM_FETCH);
- qemu_fdt_setprop_cell(fdt, "/rtas", "restart-rtas", RTAS_RESTART_RTAS);
- qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-error-log-max", 0);
- qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-event-scan-rate", 0);
- qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-display-device", 0);
- qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-size", 20);
- qemu_fdt_setprop_cell(fdt, "/rtas", "rtas-version", 1);
-
- /* cpus */
- qemu_fdt_add_subnode(fdt, "/cpus");
- qemu_fdt_setprop_cell(fdt, "/cpus", "#cpus", 1);
- qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 1);
- qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0);
+ uint32_t cells[2];
/* FIXME Get CPU name from CPU object */
const char *cp = "/cpus/PowerPC,G4";
@@ -1034,15 +810,43 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
cells[1] = 0;
qemu_fdt_setprop(fdt, cp, "reg", cells, 2 * sizeof(cells[0]));
qemu_fdt_setprop_string(fdt, cp, "device_type", "cpu");
+}
+
+static void *load_dtb(const char *filename, int *fdt_size)
+{
+ void *fdt;
+ g_autofree char *name = qemu_find_file(QEMU_FILE_TYPE_DTB, filename);
+
+ if (!name) {
+ error_report("Could not find dtb file '%s'", filename);
+ return NULL;
+ }
+ fdt = load_device_tree(name, fdt_size);
+ if (!fdt) {
+ error_report("Could not load dtb file '%s'", name);
+ }
+ return fdt;
+}
- /* memory */
- qemu_fdt_add_subnode(fdt, "/memory@0");
+static void *build_fdt(MachineState *machine, int *fdt_size)
+{
+ Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
+ FDTInfo fi;
+ PCIBus *pci_bus;
+ uint32_t cells[2];
+ void *fdt = load_dtb("pegasos2.dtb", fdt_size);
+
+ if (!fdt) {
+ return NULL;
+ }
+ qemu_fdt_setprop_string(fdt, "/", "name", "bplan,Pegasos2");
+
+ /* Set memory size */
cells[0] = 0;
cells[1] = cpu_to_be32(machine->ram_size);
qemu_fdt_setprop(fdt, "/memory@0", "reg", cells, 2 * sizeof(cells[0]));
- qemu_fdt_setprop_string(fdt, "/memory@0", "device_type", "memory");
- qemu_fdt_add_subnode(fdt, "/chosen");
+ /* Boot parameters */
if (pm->initrd_addr && pm->initrd_size) {
qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
pm->initrd_addr + pm->initrd_size);
@@ -1052,8 +856,15 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
machine->kernel_cmdline ?: "");
- qemu_fdt_add_subnode(fdt, "/openprom");
- qemu_fdt_setprop_string(fdt, "/openprom", "model", "Pegasos2,1.1");
+ add_cpu_info(fdt, pm->cpu);
+
+ fi.fdt = fdt;
+ fi.path = "/pci@c0000000";
+ pci_bus = mv64361_get_pci_bus(pm->mv, 0);
+ pci_for_each_device_reverse(pci_bus, 0, add_pci_device, &fi);
+ fi.path = "/pci@80000000";
+ pci_bus = mv64361_get_pci_bus(pm->mv, 1);
+ pci_for_each_device_reverse(pci_bus, 0, add_pci_device, &fi);
return fdt;
}
diff --git a/pc-bios/dtb/meson.build b/pc-bios/dtb/meson.build
index 993032949f..f14648f3a4 100644
--- a/pc-bios/dtb/meson.build
+++ b/pc-bios/dtb/meson.build
@@ -1,6 +1,7 @@
dtbs = [
'bamboo.dtb',
'canyonlands.dtb',
+ 'pegasos2.dtb',
'petalogix-ml605.dtb',
'petalogix-s3adsp1800.dtb',
]
diff --git a/pc-bios/dtb/pegasos2.dtb b/pc-bios/dtb/pegasos2.dtb
new file mode 100644
index 0000000000000000000000000000000000000000..29c35216ec2d77e4083a3ef618ca185925fb5d61
GIT binary patch
literal 1701
zcmb_cyKWRQ6!nns2oQw;9TbZ~fl!Q+2&AN25u&7m6$nwJh`gS=yH;k#6WhC+r9h#h
zgAYK01`0YPJ|IXGlptz8fP#XKNGRf7&v-N0P;#X^bI!5v!;hISllwmzJMo4ww#eA{
zXMA5npGH52juw4K{Y8NfJ)@G1;d{Kqq!B-kJ|#OQFLlx;&@VNhEv&W+6`jVeEZp`A
z;WOyhn|UI#+G^Td8|oCl^pE(<sIQiKZF%i}qt?)UFpcHfgMoFBQi4e5kmW{uf}HA1
zq7VC-oxd@Uoa`8SBs<zdcED3ewHegsyi&xUL_AgKUZtF;(APaH9!0LaYfFvh&|Ynf
zaH3)FXneEeKHfMn8oxC%{|WMo=pp|z#AJcLEa;HGAK{-y_*dlBe((<XeF^z~ASWF7
z9%Aad<Pn|Ki3+FQXurbvRm8Mcf!{<-F@dijK3(CD5YxQ~<A8X&!ZqUa72ZdDp~9ac
zrXKu$wuDNoXi*L_%IVM2f>9#znxB_TRbQMd%&WutYzoInD*N%HgafDZr5q)Xo=1OP
zKP)-kq39KDZm|6TP^2KToze-{>2Z+j?JsurL&^Pp+d)!CM+@~n7SwZ`6MZW=y{JS)
zYm@(JZDV`&cbJoEA6eUP6uni}wu=HeS<OE~pKN{iu!eUkqP1Xjm~&(;w4R9>5yu9s
z<r0#_vKV?w!iF2<z)~GU!VD@_>5MJkyR)*oa(A`|S**>FHnlMEki}r7QMsc418p{A
z)nh1g&q(^7>7(R5Fg~XzG^LPZW%2hl;6)dO23XH=D@DeQaOFfWMjM{!Hc!Pi7P3wl
z$Nl%7^^8b)3!Ln*0$ZmIur@gER0>?Tcq|6Yj_`vzOm;wSa@YnL79wJf2hXL>TB^<Z
zMmeYop>Np{Mo0(7XIELQq`=}Vr~fJzZZX@n_(P3ZM>WA@v>xmKwcJ2cYsX}wv2@G8
zRu?ikU`AwZuxxSR))H44W;Wg2aUnM|-A^EH1Eap0Mj_-`H^r>1*|oS;7{~qsTcHaV
literal 0
HcmV?d00001
diff --git a/pc-bios/dtb/pegasos2.dts b/pc-bios/dtb/pegasos2.dts
new file mode 100644
index 0000000000..0ddb9e3bec
--- /dev/null
+++ b/pc-bios/dtb/pegasos2.dts
@@ -0,0 +1,167 @@
+/*
+ * QEMU Pegasos2 Device Tree Source
+ *
+ * Copyright 2025 BALATON Zoltan
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This is partial source, more info will be filled in by board code.
+ */
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ device_type = "chrp";
+ model = "Pegasos2";
+ revision = "2B";
+ CODEGEN,vendor = "bplan GmbH";
+ CODEGEN,board = "Pegasos2";
+ CODEGEN,description = "Pegasos CHRP PowerPC System";
+
+ openprom {
+ model = "Pegasos2,1.1";
+ };
+
+ chosen {
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0 0>;
+ };
+
+ cpus {
+ #size-cells = <0>;
+ #address-cells = <1>;
+ #cpus = <1>;
+ };
+
+ rtas {
+ rtas-version = <1>;
+ rtas-size = <20>;
+ rtas-display-device = <0>;
+ rtas-event-scan-rate = <0>;
+ rtas-error-log-max = <0>;
+ restart-rtas = <0>;
+ nvram-fetch = <1>;
+ nvram-store = <2>;
+ get-time-of-day = <3>;
+ set-time-of-day = <4>;
+ event-scan = <6>;
+ /* Pegasos2 firmware misspells check-exception */
+ check-execption = <7>;
+ read-pci-config = <8>;
+ write-pci-config = <9>;
+ display-character = <10>;
+ set-indicator = <11>;
+ power-off = <17>;
+ suspend = <18>;
+ hibernate = <19>;
+ system-reboot = <20>;
+ };
+
+ failsafe {
+ device_type = "serial";
+ };
+
+ pci@80000000 {
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ clock-frequency = <33333333>;
+ ranges = <0x01000000 0 0x00000000 0xfe000000 0 0x00010000
+ 0x02000000 0 0x80000000 0x80000000 0 0x40000000>;
+ 8259-interrupt-acknowledge = <0xf1000cb4>;
+ reg = <0x80000000 0x40000000>;
+ pci-bridge-number = <0>;
+ bus-range = <0 0>;
+
+ isa@c {
+ vendor-id = <0x1106>;
+ device-id = <0x8231>;
+ revision-id = <0x10>;
+ class-code = <0x60100>;
+ /* Pegasos firmware has subsystem-id and
+ subsystem-vendor-id swapped */
+ subsystem-id = <0x1af4>;
+ subsystem-vendor-id = <0x1100>;
+ reg = <0x6000 0 0 0 0>;
+ device_type = "isa";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ eisa-slots = <0>;
+ clock-frequency = <8333333>;
+ slot-names = <0>;
+
+ serial@i2f8 {
+ device_type = "serial";
+ reg = <1 0x2f8 8>;
+ interrupts = <3 0>;
+ clock-frequency = <1843200>;
+ compatible = "pnpPNP,501";
+ };
+
+ 8042@i60 {
+ device_type = "";
+ reg = <1 0x60 5>;
+ clock-frequency = <0>;
+ compatible = "chrp,8042";
+ interrupt-controller = "";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+
+ };
+
+ keyboard@i60 {
+ device_type = "keyboard";
+ reg = <1 0x60 5>;
+ interrupts = <1 0>;
+ compatible = "pnpPNP,303";
+ };
+
+ rtc@i70 {
+ device_type = "rtc";
+ reg = <1 0x70 2>;
+ interrupts = <8 0>;
+ clock-frequency = <0>;
+ compatible = "ds1385-rtc";
+ };
+
+ timer@i40 {
+ device_type = "timer";
+ reg = <1 0x40 8>;
+ clock-frequency = <0>;
+ compatible = "pnpPNP,100";
+ };
+
+ fdc@i3f0 {
+ device_type = "fdc";
+ reg = <1 0x3f0 8>;
+ interrupts = <6 0>;
+ clock-frequency = <0>;
+ compatible = "pnpPNP,700";
+ };
+
+ lpt@i3bc {
+ device_type = "lpt";
+ reg = <1 0x3bc 8>;
+ interrupts = <7 0>;
+ clock-frequency = <0>;
+ compatible = "pnpPNP,400";
+ };
+ };
+ };
+
+ pci@c0000000 {
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ clock-frequency = <66666666>;
+ ranges = <0x01000000 0 0x00000000 0xf8000000 0 0x00010000
+ 0x02000000 0 0xc0000000 0xc0000000 0 0x20000000>;
+ reg = <0xc0000000 0x20000000>;
+ pci-bridge-number = <1>;
+ bus-range = <0 0>;
+ };
+};
--
2.41.3
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v4 04/12] hw/ppc/pegasos2: Remove fdt pointer from machine state
2025-10-23 0:06 [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation BALATON Zoltan
` (2 preceding siblings ...)
2025-10-23 0:06 ` [PATCH v4 03/12] hw/ppc/pegasos2: Change device tree generation BALATON Zoltan
@ 2025-10-23 0:06 ` BALATON Zoltan
2025-10-23 0:06 ` [PATCH v4 05/12] hw/ppc/pegasos2: Rename mv field in " BALATON Zoltan
` (8 subsequent siblings)
12 siblings, 0 replies; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 0:06 UTC (permalink / raw)
To: qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
The machine class has a field for storing the fdt so we don't need our
own and can use that instead.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/ppc/pegasos2.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index f4787397dc..2ba579dddf 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -74,7 +74,6 @@ struct Pegasos2MachineState {
qemu_irq mv_pirq[PCI_NUM_PINS];
qemu_irq via_pirq[PCI_NUM_PINS];
Vof *vof;
- void *fdt_blob;
uint64_t kernel_addr;
uint64_t kernel_entry;
uint64_t kernel_size;
@@ -413,13 +412,11 @@ static void pegasos2_machine_reset(MachineState *machine, ResetType type)
d[1] = cpu_to_be64(pm->kernel_size - (pm->kernel_entry - pm->kernel_addr));
qemu_fdt_setprop(fdt, "/chosen", "qemu,boot-kernel", d, sizeof(d));
- g_free(pm->fdt_blob);
- pm->fdt_blob = fdt;
-
vof_build_dt(fdt, pm->vof);
vof_client_open_store(fdt, pm->vof, "/chosen", "stdout", "/failsafe");
/* Set machine->fdt for 'dumpdtb' QMP/HMP command */
+ g_free(machine->fdt);
machine->fdt = fdt;
pm->cpu->vhyp = PPC_VIRTUAL_HYPERVISOR(machine);
@@ -559,7 +556,7 @@ static void pegasos2_hypercall(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
} else if (env->gpr[3] == KVMPPC_H_RTAS) {
env->gpr[3] = pegasos2_rtas(cpu, pm, env->gpr[4]);
} else if (env->gpr[3] == KVMPPC_H_VOF_CLIENT) {
- int ret = vof_client_call(MACHINE(pm), pm->vof, pm->fdt_blob,
+ int ret = vof_client_call(MACHINE(pm), pm->vof, MACHINE(pm)->fdt,
env->gpr[4]);
env->gpr[3] = (ret ? H_PARAMETER : H_SUCCESS);
} else {
--
2.41.3
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v4 05/12] hw/ppc/pegasos2: Rename mv field in machine state
2025-10-23 0:06 [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation BALATON Zoltan
` (3 preceding siblings ...)
2025-10-23 0:06 ` [PATCH v4 04/12] hw/ppc/pegasos2: Remove fdt pointer from machine state BALATON Zoltan
@ 2025-10-23 0:06 ` BALATON Zoltan
2025-10-23 0:06 ` [PATCH v4 06/12] hw/ppc/pegasos2: Add south bridge pointer in the " BALATON Zoltan
` (7 subsequent siblings)
12 siblings, 0 replies; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 0:06 UTC (permalink / raw)
To: qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
Use more generic name for the field used to store the north bridge in
the machine state.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/ppc/pegasos2.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 2ba579dddf..9b89c7ecc2 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -68,7 +68,7 @@ struct Pegasos2MachineState {
MachineState parent_obj;
PowerPCCPU *cpu;
- DeviceState *mv;
+ DeviceState *nb; /* north bridge */
IRQState pci_irqs[PCI_NUM_PINS];
OrIRQState orirq[PCI_NUM_PINS];
qemu_irq mv_pirq[PCI_NUM_PINS];
@@ -166,12 +166,12 @@ static void pegasos2_init(MachineState *machine)
}
/* Marvell Discovery II system controller */
- pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
+ pm->nb = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
qdev_get_gpio_in(DEVICE(pm->cpu), PPC6xx_INPUT_INT)));
for (i = 0; i < PCI_NUM_PINS; i++) {
- pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->mv, "gpp", 12 + i);
+ pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->nb, "gpp", 12 + i);
}
- pci_bus = mv64361_get_pci_bus(pm->mv, 1);
+ pci_bus = mv64361_get_pci_bus(pm->nb, 1);
/* VIA VT8231 South Bridge (multifunction PCI device) */
via = OBJECT(pci_new_multifunction(PCI_DEVFN(12, 0), TYPE_VT8231_ISA));
@@ -190,7 +190,7 @@ static void pegasos2_init(MachineState *machine)
object_resolve_path_component(via, "rtc"),
"date");
qdev_connect_gpio_out_named(DEVICE(via), "intr", 0,
- qdev_get_gpio_in_named(pm->mv, "gpp", 31));
+ qdev_get_gpio_in_named(pm->nb, "gpp", 31));
dev = PCI_DEVICE(object_resolve_path_component(via, "ide"));
pci_ide_create_devs(dev);
@@ -208,7 +208,7 @@ static void pegasos2_init(MachineState *machine)
DeviceState *pd;
g_autofree const char *pn = g_strdup_printf("pcihost%d", h);
- pd = DEVICE(object_resolve_path_component(OBJECT(pm->mv), pn));
+ pd = DEVICE(object_resolve_path_component(OBJECT(pm->nb), pn));
assert(pd);
for (i = 0; i < PCI_NUM_PINS; i++) {
OrIRQState *ori = &pm->orirq[i];
@@ -267,7 +267,7 @@ static void pegasos2_init(MachineState *machine)
static uint32_t pegasos2_mv_reg_read(Pegasos2MachineState *pm,
uint32_t addr, uint32_t len)
{
- MemoryRegion *r = sysbus_mmio_get_region(SYS_BUS_DEVICE(pm->mv), 0);
+ MemoryRegion *r = sysbus_mmio_get_region(SYS_BUS_DEVICE(pm->nb), 0);
uint64_t val = 0xffffffffULL;
memory_region_dispatch_read(r, addr, &val, size_memop(len) | MO_LE,
MEMTXATTRS_UNSPECIFIED);
@@ -277,7 +277,7 @@ static uint32_t pegasos2_mv_reg_read(Pegasos2MachineState *pm,
static void pegasos2_mv_reg_write(Pegasos2MachineState *pm, uint32_t addr,
uint32_t len, uint32_t val)
{
- MemoryRegion *r = sysbus_mmio_get_region(SYS_BUS_DEVICE(pm->mv), 0);
+ MemoryRegion *r = sysbus_mmio_get_region(SYS_BUS_DEVICE(pm->nb), 0);
memory_region_dispatch_write(r, addr, val, size_memop(len) | MO_LE,
MEMTXATTRS_UNSPECIFIED);
}
@@ -857,10 +857,10 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
fi.fdt = fdt;
fi.path = "/pci@c0000000";
- pci_bus = mv64361_get_pci_bus(pm->mv, 0);
+ pci_bus = mv64361_get_pci_bus(pm->nb, 0);
pci_for_each_device_reverse(pci_bus, 0, add_pci_device, &fi);
fi.path = "/pci@80000000";
- pci_bus = mv64361_get_pci_bus(pm->mv, 1);
+ pci_bus = mv64361_get_pci_bus(pm->nb, 1);
pci_for_each_device_reverse(pci_bus, 0, add_pci_device, &fi);
return fdt;
--
2.41.3
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v4 06/12] hw/ppc/pegasos2: Add south bridge pointer in the machine state
2025-10-23 0:06 [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation BALATON Zoltan
` (4 preceding siblings ...)
2025-10-23 0:06 ` [PATCH v4 05/12] hw/ppc/pegasos2: Rename mv field in " BALATON Zoltan
@ 2025-10-23 0:06 ` BALATON Zoltan
2025-10-23 0:06 ` [PATCH v4 07/12] hw/ppc/pegasos2: Move PCI IRQ routing setup to a function BALATON Zoltan
` (6 subsequent siblings)
12 siblings, 0 replies; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 0:06 UTC (permalink / raw)
To: qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
Add field for the south bridge in machine state to have both north and
south bridges in it.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/ppc/pegasos2.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 9b89c7ecc2..4b63f0e175 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -69,6 +69,7 @@ struct Pegasos2MachineState {
PowerPCCPU *cpu;
DeviceState *nb; /* north bridge */
+ DeviceState *sb; /* south bridge */
IRQState pci_irqs[PCI_NUM_PINS];
OrIRQState orirq[PCI_NUM_PINS];
qemu_irq mv_pirq[PCI_NUM_PINS];
@@ -174,7 +175,8 @@ static void pegasos2_init(MachineState *machine)
pci_bus = mv64361_get_pci_bus(pm->nb, 1);
/* VIA VT8231 South Bridge (multifunction PCI device) */
- via = OBJECT(pci_new_multifunction(PCI_DEVFN(12, 0), TYPE_VT8231_ISA));
+ pm->sb = DEVICE(pci_new_multifunction(PCI_DEVFN(12, 0), TYPE_VT8231_ISA));
+ via = OBJECT(pm->sb);
/* Set properties on individual devices before realizing the south bridge */
if (machine->audiodev) {
--
2.41.3
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v4 07/12] hw/ppc/pegasos2: Move PCI IRQ routing setup to a function
2025-10-23 0:06 [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation BALATON Zoltan
` (5 preceding siblings ...)
2025-10-23 0:06 ` [PATCH v4 06/12] hw/ppc/pegasos2: Add south bridge pointer in the " BALATON Zoltan
@ 2025-10-23 0:06 ` BALATON Zoltan
2025-10-23 6:47 ` Philippe Mathieu-Daudé
2025-10-23 0:06 ` [PATCH v4 08/12] hw/ppc/pegasos2: Move hardware specific parts out of machine reset BALATON Zoltan
` (5 subsequent siblings)
12 siblings, 1 reply; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 0:06 UTC (permalink / raw)
To: qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
Collect steps of setting up PCI IRQ routing in one function.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
hw/ppc/pegasos2.c | 66 +++++++++++++++++++++++------------------------
1 file changed, 33 insertions(+), 33 deletions(-)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 4b63f0e175..2f9bd3eac5 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -107,6 +107,38 @@ static void pegasos2_pci_irq(void *opaque, int n, int level)
qemu_set_irq(pm->via_pirq[n], level);
}
+/* Set up PCI interrupt routing: lines from pci.0 and pci.1 are ORed */
+static void pegasos2_setup_pci_irq(Pegasos2MachineState *pm)
+{
+ for (int h = 0; h < 2; h++) {
+ DeviceState *pd;
+ g_autofree const char *pn = g_strdup_printf("pcihost%d", h);
+
+ pd = DEVICE(object_resolve_path_component(OBJECT(pm->nb), pn));
+ assert(pd);
+ for (int i = 0; i < PCI_NUM_PINS; i++) {
+ OrIRQState *ori = &pm->orirq[i];
+
+ if (h == 0) {
+ g_autofree const char *n = g_strdup_printf("pci-orirq[%d]", i);
+
+ object_initialize_child_with_props(OBJECT(pm), n,
+ ori, sizeof(*ori),
+ TYPE_OR_IRQ, &error_fatal,
+ "num-lines", "2", NULL);
+ qdev_realize(DEVICE(ori), NULL, &error_fatal);
+ qemu_init_irq(&pm->pci_irqs[i], pegasos2_pci_irq, pm, i);
+ qdev_connect_gpio_out(DEVICE(ori), 0, &pm->pci_irqs[i]);
+ pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->nb, "gpp", 12 + i);
+ pm->via_pirq[i] = qdev_get_gpio_in_named(pm->sb, "pirq", i);
+ }
+ qdev_connect_gpio_out(pd, i, qdev_get_gpio_in(DEVICE(ori), h));
+ }
+ }
+ qdev_connect_gpio_out_named(pm->sb, "intr", 0,
+ qdev_get_gpio_in_named(pm->nb, "gpp", 31));
+}
+
static void pegasos2_init(MachineState *machine)
{
Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
@@ -118,7 +150,6 @@ static void pegasos2_init(MachineState *machine)
I2CBus *i2c_bus;
const char *fwname = machine->firmware ?: PROM_FILENAME;
char *filename;
- int i;
ssize_t sz;
uint8_t *spd_data;
@@ -169,9 +200,6 @@ static void pegasos2_init(MachineState *machine)
/* Marvell Discovery II system controller */
pm->nb = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
qdev_get_gpio_in(DEVICE(pm->cpu), PPC6xx_INPUT_INT)));
- for (i = 0; i < PCI_NUM_PINS; i++) {
- pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->nb, "gpp", 12 + i);
- }
pci_bus = mv64361_get_pci_bus(pm->nb, 1);
/* VIA VT8231 South Bridge (multifunction PCI device) */
@@ -185,14 +213,9 @@ static void pegasos2_init(MachineState *machine)
}
pci_realize_and_unref(PCI_DEVICE(via), pci_bus, &error_abort);
- for (i = 0; i < PCI_NUM_PINS; i++) {
- pm->via_pirq[i] = qdev_get_gpio_in_named(DEVICE(via), "pirq", i);
- }
object_property_add_alias(OBJECT(machine), "rtc-time",
object_resolve_path_component(via, "rtc"),
"date");
- qdev_connect_gpio_out_named(DEVICE(via), "intr", 0,
- qdev_get_gpio_in_named(pm->nb, "gpp", 31));
dev = PCI_DEVICE(object_resolve_path_component(via, "ide"));
pci_ide_create_devs(dev);
@@ -205,30 +228,7 @@ static void pegasos2_init(MachineState *machine)
/* other PC hardware */
pci_vga_init(pci_bus);
- /* PCI interrupt routing: lines from pci.0 and pci.1 are ORed */
- for (int h = 0; h < 2; h++) {
- DeviceState *pd;
- g_autofree const char *pn = g_strdup_printf("pcihost%d", h);
-
- pd = DEVICE(object_resolve_path_component(OBJECT(pm->nb), pn));
- assert(pd);
- for (i = 0; i < PCI_NUM_PINS; i++) {
- OrIRQState *ori = &pm->orirq[i];
-
- if (h == 0) {
- g_autofree const char *n = g_strdup_printf("pci-orirq[%d]", i);
-
- object_initialize_child_with_props(OBJECT(pm), n,
- ori, sizeof(*ori),
- TYPE_OR_IRQ, &error_fatal,
- "num-lines", "2", NULL);
- qdev_realize(DEVICE(ori), NULL, &error_fatal);
- qemu_init_irq(&pm->pci_irqs[i], pegasos2_pci_irq, pm, i);
- qdev_connect_gpio_out(DEVICE(ori), 0, &pm->pci_irqs[i]);
- }
- qdev_connect_gpio_out(pd, i, qdev_get_gpio_in(DEVICE(ori), h));
- }
- }
+ pegasos2_setup_pci_irq(pm);
if (machine->kernel_filename) {
sz = load_elf(machine->kernel_filename, NULL, NULL, NULL,
--
2.41.3
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v4 08/12] hw/ppc/pegasos2: Move hardware specific parts out of machine reset
2025-10-23 0:06 [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation BALATON Zoltan
` (6 preceding siblings ...)
2025-10-23 0:06 ` [PATCH v4 07/12] hw/ppc/pegasos2: Move PCI IRQ routing setup to a function BALATON Zoltan
@ 2025-10-23 0:06 ` BALATON Zoltan
2025-10-23 6:46 ` Philippe Mathieu-Daudé
2025-10-23 0:06 ` [PATCH v4 09/12] hw/ppc/pegasos2: Introduce abstract superclass BALATON Zoltan
` (4 subsequent siblings)
12 siblings, 1 reply; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 0:06 UTC (permalink / raw)
To: qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
Move the pegasos2 specific chipset reset out from machine reset to a
separate function and move generic parts that are not pegasos2
specific from build_fdt to machine reset so now build_fdt only
contains pegasos2 specific parts and can be renamed accordingly.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
hw/ppc/pegasos2.c | 79 ++++++++++++++++++++++++-----------------------
1 file changed, 41 insertions(+), 38 deletions(-)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 2f9bd3eac5..ed3070204b 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -57,10 +57,6 @@
#define BUS_FREQ_HZ 133333333
-#define PCI0_CFG_ADDR 0xcf8
-#define PCI1_CFG_ADDR 0xc78
-#define PCI1_IO_BASE 0xfe000000
-
#define TYPE_PEGASOS2_MACHINE MACHINE_TYPE_NAME("pegasos2")
OBJECT_DECLARE_TYPE(Pegasos2MachineState, MachineClass, PEGASOS2_MACHINE)
@@ -82,7 +78,7 @@ struct Pegasos2MachineState {
uint64_t initrd_size;
};
-static void *build_fdt(MachineState *machine, int *fdt_size);
+static void *pegasos2_build_fdt(Pegasos2MachineState *pm, int *fdt_size);
static void pegasos2_cpu_reset(void *opaque)
{
@@ -284,6 +280,9 @@ static void pegasos2_mv_reg_write(Pegasos2MachineState *pm, uint32_t addr,
MEMTXATTRS_UNSPECIFIED);
}
+#define PCI0_CFG_ADDR 0xcf8
+#define PCI1_CFG_ADDR 0xc78
+
static uint32_t pegasos2_pci_config_read(Pegasos2MachineState *pm, int bus,
uint32_t addr, uint32_t len)
{
@@ -308,23 +307,12 @@ static void pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus,
static void pegasos2_superio_write(uint8_t addr, uint8_t val)
{
- cpu_physical_memory_write(PCI1_IO_BASE + 0x3f0, &addr, 1);
- cpu_physical_memory_write(PCI1_IO_BASE + 0x3f1, &val, 1);
+ cpu_physical_memory_write(0xfe0003f0, &addr, 1);
+ cpu_physical_memory_write(0xfe0003f1, &val, 1);
}
-static void pegasos2_machine_reset(MachineState *machine, ResetType type)
+static void pegasos2_chipset_reset(Pegasos2MachineState *pm)
{
- Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
- void *fdt;
- uint64_t d[2];
- int sz;
-
- qemu_devices_reset(type);
- if (!pm->vof) {
- return; /* Firmware should set up machine so nothing to do */
- }
-
- /* Otherwise, set up devices that board firmware would normally do */
pegasos2_mv_reg_write(pm, 0, 4, 0x28020ff);
pegasos2_mv_reg_write(pm, 0x278, 4, 0xa31fc);
pegasos2_mv_reg_write(pm, 0xf300, 4, 0x11ff0400);
@@ -387,6 +375,23 @@ static void pegasos2_machine_reset(MachineState *machine, ResetType type)
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 6) << 8) |
PCI_INTERRUPT_LINE, 2, 0x309);
+}
+
+static void pegasos2_machine_reset(MachineState *machine, ResetType type)
+{
+ Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
+ void *fdt;
+ uint32_t c[2];
+ uint64_t d[2];
+ int sz;
+
+ qemu_devices_reset(type);
+ if (!pm->vof) {
+ return; /* Firmware should set up machine so nothing to do */
+ }
+
+ /* Otherwise, set up devices that board firmware would normally do */
+ pegasos2_chipset_reset(pm);
/* Device tree and VOF set up */
vof_init(pm->vof, machine->ram_size, &error_fatal);
@@ -405,10 +410,25 @@ static void pegasos2_machine_reset(MachineState *machine, ResetType type)
exit(1);
}
- fdt = build_fdt(machine, &sz);
+ fdt = pegasos2_build_fdt(pm, &sz);
if (!fdt) {
exit(1);
}
+
+ /* Set memory size */
+ c[0] = 0;
+ c[1] = cpu_to_be32(machine->ram_size);
+ qemu_fdt_setprop(fdt, "/memory@0", "reg", c, sizeof(c));
+
+ /* Boot parameters */
+ if (pm->initrd_addr && pm->initrd_size) {
+ qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
+ pm->initrd_addr + pm->initrd_size);
+ qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
+ pm->initrd_addr);
+ }
+ qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
+ machine->kernel_cmdline ?: "");
/* FIXME: VOF assumes entry is same as load address */
d[0] = cpu_to_be64(pm->kernel_entry);
d[1] = cpu_to_be64(pm->kernel_size - (pm->kernel_entry - pm->kernel_addr));
@@ -827,12 +847,10 @@ static void *load_dtb(const char *filename, int *fdt_size)
return fdt;
}
-static void *build_fdt(MachineState *machine, int *fdt_size)
+static void *pegasos2_build_fdt(Pegasos2MachineState *pm, int *fdt_size)
{
- Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
FDTInfo fi;
PCIBus *pci_bus;
- uint32_t cells[2];
void *fdt = load_dtb("pegasos2.dtb", fdt_size);
if (!fdt) {
@@ -840,21 +858,6 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
}
qemu_fdt_setprop_string(fdt, "/", "name", "bplan,Pegasos2");
- /* Set memory size */
- cells[0] = 0;
- cells[1] = cpu_to_be32(machine->ram_size);
- qemu_fdt_setprop(fdt, "/memory@0", "reg", cells, 2 * sizeof(cells[0]));
-
- /* Boot parameters */
- if (pm->initrd_addr && pm->initrd_size) {
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
- pm->initrd_addr + pm->initrd_size);
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start",
- pm->initrd_addr);
- }
- qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
- machine->kernel_cmdline ?: "");
-
add_cpu_info(fdt, pm->cpu);
fi.fdt = fdt;
--
2.41.3
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH v4 08/12] hw/ppc/pegasos2: Move hardware specific parts out of machine reset
2025-10-23 0:06 ` [PATCH v4 08/12] hw/ppc/pegasos2: Move hardware specific parts out of machine reset BALATON Zoltan
@ 2025-10-23 6:46 ` Philippe Mathieu-Daudé
2025-10-23 8:45 ` Harsh Prateek Bora
2025-10-23 12:58 ` BALATON Zoltan
0 siblings, 2 replies; 29+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-10-23 6:46 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
On 23/10/25 02:06, BALATON Zoltan wrote:
> Move the pegasos2 specific chipset reset out from machine reset to a
> separate function and move generic parts that are not pegasos2
> specific from build_fdt to machine reset so now build_fdt only
> contains pegasos2 specific parts and can be renamed accordingly.
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> hw/ppc/pegasos2.c | 79 ++++++++++++++++++++++++-----------------------
> 1 file changed, 41 insertions(+), 38 deletions(-)
> -#define PCI1_IO_BASE 0xfe000000
Can't we keep such definition?
> @@ -308,23 +307,12 @@ static void pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus,
>
> static void pegasos2_superio_write(uint8_t addr, uint8_t val)
> {
> - cpu_physical_memory_write(PCI1_IO_BASE + 0x3f0, &addr, 1);
> - cpu_physical_memory_write(PCI1_IO_BASE + 0x3f1, &val, 1);
> + cpu_physical_memory_write(0xfe0003f0, &addr, 1);
> + cpu_physical_memory_write(0xfe0003f1, &val, 1);
Otherwise it is harder to notice we are accessing the MMIO mapped ISA space.
> }
Consider renaming as pegasos_superio_write() since this method becomes
common to PegasOS I and II.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 29+ messages in thread* Re: [PATCH v4 08/12] hw/ppc/pegasos2: Move hardware specific parts out of machine reset
2025-10-23 6:46 ` Philippe Mathieu-Daudé
@ 2025-10-23 8:45 ` Harsh Prateek Bora
2025-10-23 11:41 ` BALATON Zoltan
2025-10-23 12:58 ` BALATON Zoltan
1 sibling, 1 reply; 29+ messages in thread
From: Harsh Prateek Bora @ 2025-10-23 8:45 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, BALATON Zoltan, qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster
On 10/23/25 12:16, Philippe Mathieu-Daudé wrote:
> On 23/10/25 02:06, BALATON Zoltan wrote:
>> Move the pegasos2 specific chipset reset out from machine reset to a
>> separate function and move generic parts that are not pegasos2
>> specific from build_fdt to machine reset so now build_fdt only
>> contains pegasos2 specific parts and can be renamed accordingly.
>>
>> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
>> ---
>> hw/ppc/pegasos2.c | 79 ++++++++++++++++++++++++-----------------------
>> 1 file changed, 41 insertions(+), 38 deletions(-)
>
>
>> -#define PCI1_IO_BASE 0xfe000000
>
> Can't we keep such definition?
>
>> @@ -308,23 +307,12 @@ static void
>> pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus,
>> static void pegasos2_superio_write(uint8_t addr, uint8_t val)
>> {
>> - cpu_physical_memory_write(PCI1_IO_BASE + 0x3f0, &addr, 1);
>> - cpu_physical_memory_write(PCI1_IO_BASE + 0x3f1, &val, 1);
>> + cpu_physical_memory_write(0xfe0003f0, &addr, 1);
>> + cpu_physical_memory_write(0xfe0003f1, &val, 1);
>
> Otherwise it is harder to notice we are accessing the MMIO mapped ISA
> space.
>
>> }
> Consider renaming as pegasos_superio_write() since this method becomes
> common to PegasOS I and II.
Thanks Philippe for reviewing the series.
Hi BALATON,
Would you mind addressing the above (and other?) review comments or I
can queue it in the interest of time if you can send a follow-up patch
later?
Thanks
Harsh
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>
^ permalink raw reply [flat|nested] 29+ messages in thread* Re: [PATCH v4 08/12] hw/ppc/pegasos2: Move hardware specific parts out of machine reset
2025-10-23 8:45 ` Harsh Prateek Bora
@ 2025-10-23 11:41 ` BALATON Zoltan
0 siblings, 0 replies; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 11:41 UTC (permalink / raw)
To: Harsh Prateek Bora
Cc: Philippe Mathieu-Daudé, qemu-devel, qemu-ppc,
Nicholas Piggin, Markus Armbruster
[-- Attachment #1: Type: text/plain, Size: 1853 bytes --]
On Thu, 23 Oct 2025, Harsh Prateek Bora wrote:
> On 10/23/25 12:16, Philippe Mathieu-Daudé wrote:
>> On 23/10/25 02:06, BALATON Zoltan wrote:
>>> Move the pegasos2 specific chipset reset out from machine reset to a
>>> separate function and move generic parts that are not pegasos2
>>> specific from build_fdt to machine reset so now build_fdt only
>>> contains pegasos2 specific parts and can be renamed accordingly.
>>>
>>> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
>>> ---
>>> hw/ppc/pegasos2.c | 79 ++++++++++++++++++++++++-----------------------
>>> 1 file changed, 41 insertions(+), 38 deletions(-)
>>
>>
>>> -#define PCI1_IO_BASE 0xfe000000
>>
>> Can't we keep such definition?
>>
>>> @@ -308,23 +307,12 @@ static void
>>> pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus,
>>> static void pegasos2_superio_write(uint8_t addr, uint8_t val)
>>> {
>>> - cpu_physical_memory_write(PCI1_IO_BASE + 0x3f0, &addr, 1);
>>> - cpu_physical_memory_write(PCI1_IO_BASE + 0x3f1, &val, 1);
>>> + cpu_physical_memory_write(0xfe0003f0, &addr, 1);
>>> + cpu_physical_memory_write(0xfe0003f1, &val, 1);
>>
>> Otherwise it is harder to notice we are accessing the MMIO mapped ISA
>> space.
>>
>>> }
>> Consider renaming as pegasos_superio_write() since this method becomes
>> common to PegasOS I and II.
>
> Thanks Philippe for reviewing the series.
>
> Hi BALATON,
> Would you mind addressing the above (and other?) review comments or I can
> queue it in the interest of time if you can send a follow-up patch later?
I'll send another version of this series after rebasing the prep series.
We still have time until the freeze begins so I think we can wait a few
more days.
Thank you,
BALATON Zoltan
> Thanks
> Harsh
>
>>
>> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>>
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 08/12] hw/ppc/pegasos2: Move hardware specific parts out of machine reset
2025-10-23 6:46 ` Philippe Mathieu-Daudé
2025-10-23 8:45 ` Harsh Prateek Bora
@ 2025-10-23 12:58 ` BALATON Zoltan
1 sibling, 0 replies; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 12:58 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: qemu-devel, qemu-ppc, Nicholas Piggin, Markus Armbruster,
Harsh Prateek Bora
[-- Attachment #1: Type: text/plain, Size: 1946 bytes --]
On Thu, 23 Oct 2025, Philippe Mathieu-Daudé wrote:
> On 23/10/25 02:06, BALATON Zoltan wrote:
>> Move the pegasos2 specific chipset reset out from machine reset to a
>> separate function and move generic parts that are not pegasos2
>> specific from build_fdt to machine reset so now build_fdt only
>> contains pegasos2 specific parts and can be renamed accordingly.
>>
>> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
>> ---
>> hw/ppc/pegasos2.c | 79 ++++++++++++++++++++++++-----------------------
>> 1 file changed, 41 insertions(+), 38 deletions(-)
>
>
>> -#define PCI1_IO_BASE 0xfe000000
>
> Can't we keep such definition?
>
>> @@ -308,23 +307,12 @@ static void
>> pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus,
>> static void pegasos2_superio_write(uint8_t addr, uint8_t val)
>> {
>> - cpu_physical_memory_write(PCI1_IO_BASE + 0x3f0, &addr, 1);
>> - cpu_physical_memory_write(PCI1_IO_BASE + 0x3f1, &val, 1);
>> + cpu_physical_memory_write(0xfe0003f0, &addr, 1);
>> + cpu_physical_memory_write(0xfe0003f1, &val, 1);
>
> Otherwise it is harder to notice we are accessing the MMIO mapped ISA space.
It might be misleading as it's PCI1 on pegasos2 but PCI0 on pegasos1 so
the define does not clarify much either way even if I rename it to
PCI_IO_BASE. Generally I think for numbers that are only used once having
a define just obfuscates it as I then have to look up what the number is
elsewhere instead of seeing right away. I guess I'll leave it as it is now
that this version was pulled.
>> }
> Consider renaming as pegasos_superio_write() since this method becomes
> common to PegasOS I and II.
This could have removed one hunk from patch 12 and adding it here making
that patch shorter but this one longer so not much difference. Now that
these are reviewed I think it does not matter any more.
Regards,
BALATON Zoltan
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH v4 09/12] hw/ppc/pegasos2: Introduce abstract superclass
2025-10-23 0:06 [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation BALATON Zoltan
` (7 preceding siblings ...)
2025-10-23 0:06 ` [PATCH v4 08/12] hw/ppc/pegasos2: Move hardware specific parts out of machine reset BALATON Zoltan
@ 2025-10-23 0:06 ` BALATON Zoltan
2025-10-23 0:06 ` [PATCH v4 10/12] hw/ppc/pegasos2: Add bus frequency to machine state BALATON Zoltan
` (3 subsequent siblings)
12 siblings, 0 replies; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 0:06 UTC (permalink / raw)
To: qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
Rename machine state struct to PegasosMachineState as it will be used
for pegasos1 too.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/ppc/pegasos2.c | 66 ++++++++++++++++++++++++-----------------------
1 file changed, 34 insertions(+), 32 deletions(-)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index ed3070204b..f5b56c0e94 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -57,10 +57,10 @@
#define BUS_FREQ_HZ 133333333
-#define TYPE_PEGASOS2_MACHINE MACHINE_TYPE_NAME("pegasos2")
-OBJECT_DECLARE_TYPE(Pegasos2MachineState, MachineClass, PEGASOS2_MACHINE)
+#define TYPE_PEGASOS_MACHINE MACHINE_TYPE_NAME("pegasos")
+OBJECT_DECLARE_SIMPLE_TYPE(PegasosMachineState, PEGASOS_MACHINE)
-struct Pegasos2MachineState {
+struct PegasosMachineState {
MachineState parent_obj;
PowerPCCPU *cpu;
@@ -78,12 +78,12 @@ struct Pegasos2MachineState {
uint64_t initrd_size;
};
-static void *pegasos2_build_fdt(Pegasos2MachineState *pm, int *fdt_size);
+static void *pegasos2_build_fdt(PegasosMachineState *pm, int *fdt_size);
static void pegasos2_cpu_reset(void *opaque)
{
PowerPCCPU *cpu = opaque;
- Pegasos2MachineState *pm = PEGASOS2_MACHINE(current_machine);
+ PegasosMachineState *pm = PEGASOS_MACHINE(current_machine);
cpu_reset(CPU(cpu));
cpu->env.spr[SPR_HID1] = 7ULL << 28;
@@ -96,7 +96,7 @@ static void pegasos2_cpu_reset(void *opaque)
static void pegasos2_pci_irq(void *opaque, int n, int level)
{
- Pegasos2MachineState *pm = opaque;
+ PegasosMachineState *pm = opaque;
/* PCI interrupt lines are connected to both MV64361 and VT8231 */
qemu_set_irq(pm->mv_pirq[n], level);
@@ -104,7 +104,7 @@ static void pegasos2_pci_irq(void *opaque, int n, int level)
}
/* Set up PCI interrupt routing: lines from pci.0 and pci.1 are ORed */
-static void pegasos2_setup_pci_irq(Pegasos2MachineState *pm)
+static void pegasos2_setup_pci_irq(PegasosMachineState *pm)
{
for (int h = 0; h < 2; h++) {
DeviceState *pd;
@@ -137,7 +137,7 @@ static void pegasos2_setup_pci_irq(Pegasos2MachineState *pm)
static void pegasos2_init(MachineState *machine)
{
- Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
+ PegasosMachineState *pm = PEGASOS_MACHINE(machine);
CPUPPCState *env;
MemoryRegion *rom = g_new(MemoryRegion, 1);
PCIBus *pci_bus;
@@ -262,7 +262,7 @@ static void pegasos2_init(MachineState *machine)
}
}
-static uint32_t pegasos2_mv_reg_read(Pegasos2MachineState *pm,
+static uint32_t pegasos2_mv_reg_read(PegasosMachineState *pm,
uint32_t addr, uint32_t len)
{
MemoryRegion *r = sysbus_mmio_get_region(SYS_BUS_DEVICE(pm->nb), 0);
@@ -272,7 +272,7 @@ static uint32_t pegasos2_mv_reg_read(Pegasos2MachineState *pm,
return val;
}
-static void pegasos2_mv_reg_write(Pegasos2MachineState *pm, uint32_t addr,
+static void pegasos2_mv_reg_write(PegasosMachineState *pm, uint32_t addr,
uint32_t len, uint32_t val)
{
MemoryRegion *r = sysbus_mmio_get_region(SYS_BUS_DEVICE(pm->nb), 0);
@@ -283,7 +283,7 @@ static void pegasos2_mv_reg_write(Pegasos2MachineState *pm, uint32_t addr,
#define PCI0_CFG_ADDR 0xcf8
#define PCI1_CFG_ADDR 0xc78
-static uint32_t pegasos2_pci_config_read(Pegasos2MachineState *pm, int bus,
+static uint32_t pegasos2_pci_config_read(PegasosMachineState *pm, int bus,
uint32_t addr, uint32_t len)
{
hwaddr pcicfg = bus ? PCI1_CFG_ADDR : PCI0_CFG_ADDR;
@@ -296,7 +296,7 @@ static uint32_t pegasos2_pci_config_read(Pegasos2MachineState *pm, int bus,
return val;
}
-static void pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus,
+static void pegasos2_pci_config_write(PegasosMachineState *pm, int bus,
uint32_t addr, uint32_t len, uint32_t val)
{
hwaddr pcicfg = bus ? PCI1_CFG_ADDR : PCI0_CFG_ADDR;
@@ -311,7 +311,7 @@ static void pegasos2_superio_write(uint8_t addr, uint8_t val)
cpu_physical_memory_write(0xfe0003f1, &val, 1);
}
-static void pegasos2_chipset_reset(Pegasos2MachineState *pm)
+static void pegasos2_chipset_reset(PegasosMachineState *pm)
{
pegasos2_mv_reg_write(pm, 0, 4, 0x28020ff);
pegasos2_mv_reg_write(pm, 0x278, 4, 0xa31fc);
@@ -379,7 +379,7 @@ static void pegasos2_chipset_reset(Pegasos2MachineState *pm)
static void pegasos2_machine_reset(MachineState *machine, ResetType type)
{
- Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
+ PegasosMachineState *pm = PEGASOS_MACHINE(machine);
void *fdt;
uint32_t c[2];
uint64_t d[2];
@@ -463,7 +463,7 @@ enum pegasos2_rtas_tokens {
RTAS_SYSTEM_REBOOT = 20,
};
-static target_ulong pegasos2_rtas(PowerPCCPU *cpu, Pegasos2MachineState *pm,
+static target_ulong pegasos2_rtas(PowerPCCPU *cpu, PegasosMachineState *pm,
target_ulong args_real)
{
AddressSpace *as = CPU(cpu)->as;
@@ -566,7 +566,7 @@ static bool pegasos2_cpu_in_nested(PowerPCCPU *cpu)
static void pegasos2_hypercall(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
{
- Pegasos2MachineState *pm = PEGASOS2_MACHINE(vhyp);
+ PegasosMachineState *pm = PEGASOS_MACHINE(vhyp);
CPUPPCState *env = &cpu->env;
/* The TCG path should also be holding the BQL at this point */
@@ -629,24 +629,26 @@ static void pegasos2_machine_class_init(ObjectClass *oc, const void *data)
vmc->setprop = pegasos2_setprop;
}
-static const TypeInfo pegasos2_machine_info = {
- .name = TYPE_PEGASOS2_MACHINE,
- .parent = TYPE_MACHINE,
- .class_init = pegasos2_machine_class_init,
- .instance_size = sizeof(Pegasos2MachineState),
- .interfaces = (const InterfaceInfo[]) {
- { TYPE_PPC_VIRTUAL_HYPERVISOR },
- { TYPE_VOF_MACHINE_IF },
- { }
+static const TypeInfo pegasos_machine_types[] = {
+ {
+ .name = TYPE_PEGASOS_MACHINE,
+ .parent = TYPE_MACHINE,
+ .instance_size = sizeof(PegasosMachineState),
+ .abstract = true,
+ .interfaces = (const InterfaceInfo[]) {
+ { TYPE_PPC_VIRTUAL_HYPERVISOR },
+ { TYPE_VOF_MACHINE_IF },
+ { }
+ },
+ },
+ {
+ .name = MACHINE_TYPE_NAME("pegasos2"),
+ .parent = TYPE_PEGASOS_MACHINE,
+ .class_init = pegasos2_machine_class_init,
},
};
-static void pegasos2_machine_register_types(void)
-{
- type_register_static(&pegasos2_machine_info);
-}
-
-type_init(pegasos2_machine_register_types)
+DEFINE_TYPES(pegasos_machine_types)
/* FDT creation for passing to firmware */
@@ -847,7 +849,7 @@ static void *load_dtb(const char *filename, int *fdt_size)
return fdt;
}
-static void *pegasos2_build_fdt(Pegasos2MachineState *pm, int *fdt_size)
+static void *pegasos2_build_fdt(PegasosMachineState *pm, int *fdt_size)
{
FDTInfo fi;
PCIBus *pci_bus;
--
2.41.3
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v4 10/12] hw/ppc/pegasos2: Add bus frequency to machine state
2025-10-23 0:06 [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation BALATON Zoltan
` (8 preceding siblings ...)
2025-10-23 0:06 ` [PATCH v4 09/12] hw/ppc/pegasos2: Introduce abstract superclass BALATON Zoltan
@ 2025-10-23 0:06 ` BALATON Zoltan
2025-10-23 6:36 ` Philippe Mathieu-Daudé
2025-10-23 0:06 ` [PATCH v4 11/12] hw/ppc/pegasos2: Add Pegasos I emulation BALATON Zoltan
` (2 subsequent siblings)
12 siblings, 1 reply; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 0:06 UTC (permalink / raw)
To: qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
Store the bus frequency in the machine state and set it from instance
init method.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
hw/ppc/pegasos2.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index f5b56c0e94..7eaefcf9a0 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -55,8 +55,6 @@
#define H_PRIVILEGE -3 /* Caller not privileged */
#define H_PARAMETER -4 /* Parameter invalid, out-of-range or conflicting */
-#define BUS_FREQ_HZ 133333333
-
#define TYPE_PEGASOS_MACHINE MACHINE_TYPE_NAME("pegasos")
OBJECT_DECLARE_SIMPLE_TYPE(PegasosMachineState, PEGASOS_MACHINE)
@@ -66,6 +64,7 @@ struct PegasosMachineState {
PowerPCCPU *cpu;
DeviceState *nb; /* north bridge */
DeviceState *sb; /* south bridge */
+ int bus_freq_hz;
IRQState pci_irqs[PCI_NUM_PINS];
OrIRQState orirq[PCI_NUM_PINS];
qemu_irq mv_pirq[PCI_NUM_PINS];
@@ -135,7 +134,7 @@ static void pegasos2_setup_pci_irq(PegasosMachineState *pm)
qdev_get_gpio_in_named(pm->nb, "gpp", 31));
}
-static void pegasos2_init(MachineState *machine)
+static void pegasos_init(MachineState *machine)
{
PegasosMachineState *pm = PEGASOS_MACHINE(machine);
CPUPPCState *env;
@@ -158,7 +157,7 @@ static void pegasos2_init(MachineState *machine)
}
/* Set time-base frequency */
- cpu_ppc_tb_init(env, BUS_FREQ_HZ / 4);
+ cpu_ppc_tb_init(env, pm->bus_freq_hz / 4);
qemu_register_reset(pegasos2_cpu_reset, pm->cpu);
/* RAM */
@@ -610,7 +609,7 @@ static void pegasos2_machine_class_init(ObjectClass *oc, const void *data)
VofMachineIfClass *vmc = VOF_MACHINE_CLASS(oc);
mc->desc = "Genesi/bPlan Pegasos II";
- mc->init = pegasos2_init;
+ mc->init = pegasos_init;
mc->reset = pegasos2_machine_reset;
mc->block_default_type = IF_IDE;
mc->default_boot_order = "cd";
@@ -629,6 +628,13 @@ static void pegasos2_machine_class_init(ObjectClass *oc, const void *data)
vmc->setprop = pegasos2_setprop;
}
+static void pegasos2_init(Object *obj)
+{
+ PegasosMachineState *pm = PEGASOS_MACHINE(obj);
+
+ pm->bus_freq_hz = 133333333;
+}
+
static const TypeInfo pegasos_machine_types[] = {
{
.name = TYPE_PEGASOS_MACHINE,
@@ -645,6 +651,7 @@ static const TypeInfo pegasos_machine_types[] = {
.name = MACHINE_TYPE_NAME("pegasos2"),
.parent = TYPE_PEGASOS_MACHINE,
.class_init = pegasos2_machine_class_init,
+ .instance_init = pegasos2_init,
},
};
@@ -777,7 +784,7 @@ static void add_pci_device(PCIBus *bus, PCIDevice *d, void *opaque)
g_string_free(node, TRUE);
}
-static void add_cpu_info(void *fdt, PowerPCCPU *cpu)
+static void add_cpu_info(void *fdt, PowerPCCPU *cpu, int bus_freq)
{
uint32_t cells[2];
@@ -824,8 +831,8 @@ static void add_cpu_info(void *fdt, PowerPCCPU *cpu)
qemu_fdt_setprop_cell(fdt, cp, "reservation-granule-size", 4);
qemu_fdt_setprop_cell(fdt, cp, "timebase-frequency",
cpu->env.tb_env->tb_freq);
- qemu_fdt_setprop_cell(fdt, cp, "bus-frequency", BUS_FREQ_HZ);
- qemu_fdt_setprop_cell(fdt, cp, "clock-frequency", BUS_FREQ_HZ * 7.5);
+ qemu_fdt_setprop_cell(fdt, cp, "bus-frequency", bus_freq);
+ qemu_fdt_setprop_cell(fdt, cp, "clock-frequency", bus_freq * 7.5);
qemu_fdt_setprop_cell(fdt, cp, "cpu-version", cpu->env.spr[SPR_PVR]);
cells[0] = 0;
cells[1] = 0;
@@ -860,7 +867,7 @@ static void *pegasos2_build_fdt(PegasosMachineState *pm, int *fdt_size)
}
qemu_fdt_setprop_string(fdt, "/", "name", "bplan,Pegasos2");
- add_cpu_info(fdt, pm->cpu);
+ add_cpu_info(fdt, pm->cpu, pm->bus_freq_hz);
fi.fdt = fdt;
fi.path = "/pci@c0000000";
--
2.41.3
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH v4 10/12] hw/ppc/pegasos2: Add bus frequency to machine state
2025-10-23 0:06 ` [PATCH v4 10/12] hw/ppc/pegasos2: Add bus frequency to machine state BALATON Zoltan
@ 2025-10-23 6:36 ` Philippe Mathieu-Daudé
2025-10-23 11:05 ` BALATON Zoltan
0 siblings, 1 reply; 29+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-10-23 6:36 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
On 23/10/25 02:06, BALATON Zoltan wrote:
> Store the bus frequency in the machine state and set it from instance
> init method.
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> hw/ppc/pegasos2.c | 25 ++++++++++++++++---------
> 1 file changed, 16 insertions(+), 9 deletions(-)
>
> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
> index f5b56c0e94..7eaefcf9a0 100644
> --- a/hw/ppc/pegasos2.c
> +++ b/hw/ppc/pegasos2.c
> @@ -55,8 +55,6 @@
> #define H_PRIVILEGE -3 /* Caller not privileged */
> #define H_PARAMETER -4 /* Parameter invalid, out-of-range or conflicting */
>
> -#define BUS_FREQ_HZ 133333333
> -static void pegasos2_init(MachineState *machine)
> +static void pegasos_init(MachineState *machine)
> {
> PegasosMachineState *pm = PEGASOS_MACHINE(machine);
> CPUPPCState *env;
> @@ -158,7 +157,7 @@ static void pegasos2_init(MachineState *machine)
> }
>
> /* Set time-base frequency */
> - cpu_ppc_tb_init(env, BUS_FREQ_HZ / 4);
> + cpu_ppc_tb_init(env, pm->bus_freq_hz / 4);
As a future cleanup patch on top, please replace the magic '4' value ...
> -static void add_cpu_info(void *fdt, PowerPCCPU *cpu)
> +static void add_cpu_info(void *fdt, PowerPCCPU *cpu, int bus_freq)
> {
> uint32_t cells[2];
>
> @@ -824,8 +831,8 @@ static void add_cpu_info(void *fdt, PowerPCCPU *cpu)
> qemu_fdt_setprop_cell(fdt, cp, "reservation-granule-size", 4);
> qemu_fdt_setprop_cell(fdt, cp, "timebase-frequency",
> cpu->env.tb_env->tb_freq);
> - qemu_fdt_setprop_cell(fdt, cp, "bus-frequency", BUS_FREQ_HZ);
> - qemu_fdt_setprop_cell(fdt, cp, "clock-frequency", BUS_FREQ_HZ * 7.5);
> + qemu_fdt_setprop_cell(fdt, cp, "bus-frequency", bus_freq);
> + qemu_fdt_setprop_cell(fdt, cp, "clock-frequency", bus_freq * 7.5);
... and this '7.5' one by descriptive definitions.
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 29+ messages in thread* Re: [PATCH v4 10/12] hw/ppc/pegasos2: Add bus frequency to machine state
2025-10-23 6:36 ` Philippe Mathieu-Daudé
@ 2025-10-23 11:05 ` BALATON Zoltan
0 siblings, 0 replies; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 11:05 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: qemu-devel, qemu-ppc, Nicholas Piggin, Markus Armbruster,
Harsh Prateek Bora
[-- Attachment #1: Type: text/plain, Size: 2338 bytes --]
On Thu, 23 Oct 2025, Philippe Mathieu-Daudé wrote:
> On 23/10/25 02:06, BALATON Zoltan wrote:
>> Store the bus frequency in the machine state and set it from instance
>> init method.
>>
>> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
>> ---
>> hw/ppc/pegasos2.c | 25 ++++++++++++++++---------
>> 1 file changed, 16 insertions(+), 9 deletions(-)
>>
>> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
>> index f5b56c0e94..7eaefcf9a0 100644
>> --- a/hw/ppc/pegasos2.c
>> +++ b/hw/ppc/pegasos2.c
>> @@ -55,8 +55,6 @@
>> #define H_PRIVILEGE -3 /* Caller not privileged */
>> #define H_PARAMETER -4 /* Parameter invalid, out-of-range or
>> conflicting */
>> -#define BUS_FREQ_HZ 133333333
>
>
>> -static void pegasos2_init(MachineState *machine)
>> +static void pegasos_init(MachineState *machine)
>> {
>> PegasosMachineState *pm = PEGASOS_MACHINE(machine);
>> CPUPPCState *env;
>> @@ -158,7 +157,7 @@ static void pegasos2_init(MachineState *machine)
>> }
>> /* Set time-base frequency */
>> - cpu_ppc_tb_init(env, BUS_FREQ_HZ / 4);
>> + cpu_ppc_tb_init(env, pm->bus_freq_hz / 4);
>
> As a future cleanup patch on top, please replace the magic '4' value ...
>> -static void add_cpu_info(void *fdt, PowerPCCPU *cpu)
>> +static void add_cpu_info(void *fdt, PowerPCCPU *cpu, int bus_freq)
>> {
>> uint32_t cells[2];
>> @@ -824,8 +831,8 @@ static void add_cpu_info(void *fdt, PowerPCCPU *cpu)
>> qemu_fdt_setprop_cell(fdt, cp, "reservation-granule-size", 4);
>> qemu_fdt_setprop_cell(fdt, cp, "timebase-frequency",
>> cpu->env.tb_env->tb_freq);
>> - qemu_fdt_setprop_cell(fdt, cp, "bus-frequency", BUS_FREQ_HZ);
>> - qemu_fdt_setprop_cell(fdt, cp, "clock-frequency", BUS_FREQ_HZ * 7.5);
>> + qemu_fdt_setprop_cell(fdt, cp, "bus-frequency", bus_freq);
>> + qemu_fdt_setprop_cell(fdt, cp, "clock-frequency", bus_freq * 7.5);
> ... and this '7.5' one by descriptive definitions.
These are just clock multipliers. The time-base often runs at quarter of
the bus freq on PPC and I don't think we have a define for that anywhere
else. The 7.5 is a CPU clock to bus clock multiplier that should be fairly
obvious fron the above without a define.
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Thanks,
BALATON Zoltan
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH v4 11/12] hw/ppc/pegasos2: Add Pegasos I emulation
2025-10-23 0:06 [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation BALATON Zoltan
` (9 preceding siblings ...)
2025-10-23 0:06 ` [PATCH v4 10/12] hw/ppc/pegasos2: Add bus frequency to machine state BALATON Zoltan
@ 2025-10-23 0:06 ` BALATON Zoltan
2025-10-23 6:54 ` Philippe Mathieu-Daudé
2025-10-23 0:06 ` [PATCH v4 12/12] hw/ppc/pegasos2: Add VOF support for pegasos1 BALATON Zoltan
2025-10-23 11:39 ` [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation Harsh Prateek Bora
12 siblings, 1 reply; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 0:06 UTC (permalink / raw)
To: qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
The Pegasos II is a redesign of the original Pegasos (later marked I)
that replaces the north bridge and has updated firmware but otherwise
these are very similar. The Pegasos uses the same north bridge that
AmigaOne used which we already emulate so we can also easily emulate
Pegasos I.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
hw/ppc/pegasos2.c | 156 ++++++++++++++++++++++++++++++++++------------
1 file changed, 117 insertions(+), 39 deletions(-)
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 7eaefcf9a0..a11f3c99ed 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -1,5 +1,5 @@
/*
- * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator
+ * QEMU PowerPC CHRP (Genesi/bPlan Pegasos I/II) hardware System Emulator
*
* Copyright (c) 2018-2021 BALATON Zoltan
*
@@ -15,6 +15,7 @@
#include "hw/pci/pci_host.h"
#include "hw/irq.h"
#include "hw/or-irq.h"
+#include "hw/pci-host/articia.h"
#include "hw/pci-host/mv64361.h"
#include "hw/isa/vt82c686.h"
#include "hw/ide/pci.h"
@@ -55,12 +56,18 @@
#define H_PRIVILEGE -3 /* Caller not privileged */
#define H_PARAMETER -4 /* Parameter invalid, out-of-range or conflicting */
+typedef enum {
+ PEGASOS1 = 1,
+ PEGASOS2 = 2,
+} PegasosMachineType;
+
#define TYPE_PEGASOS_MACHINE MACHINE_TYPE_NAME("pegasos")
OBJECT_DECLARE_SIMPLE_TYPE(PegasosMachineState, PEGASOS_MACHINE)
struct PegasosMachineState {
MachineState parent_obj;
+ PegasosMachineType type;
PowerPCCPU *cpu;
DeviceState *nb; /* north bridge */
DeviceState *sb; /* south bridge */
@@ -79,7 +86,7 @@ struct PegasosMachineState {
static void *pegasos2_build_fdt(PegasosMachineState *pm, int *fdt_size);
-static void pegasos2_cpu_reset(void *opaque)
+static void pegasos_cpu_reset(void *opaque)
{
PowerPCCPU *cpu = opaque;
PegasosMachineState *pm = PEGASOS_MACHINE(current_machine);
@@ -89,6 +96,8 @@ static void pegasos2_cpu_reset(void *opaque)
if (pm->vof) {
cpu->env.gpr[1] = 2 * VOF_STACK_SIZE - 0x20;
cpu->env.nip = 0x100;
+ } else if (pm->type == PEGASOS1) {
+ cpu->env.nip = 0xfffc0100;
}
cpu_ppc_tb_reset(&cpu->env);
}
@@ -139,13 +148,15 @@ static void pegasos_init(MachineState *machine)
PegasosMachineState *pm = PEGASOS_MACHINE(machine);
CPUPPCState *env;
MemoryRegion *rom = g_new(MemoryRegion, 1);
- PCIBus *pci_bus;
+ PCIBus *pci_bus = NULL;
Object *via;
PCIDevice *dev;
I2CBus *i2c_bus;
const char *fwname = machine->firmware ?: PROM_FILENAME;
char *filename;
+ hwaddr prom_addr;
ssize_t sz;
+ int devfn;
uint8_t *spd_data;
/* init CPU */
@@ -158,7 +169,7 @@ static void pegasos_init(MachineState *machine)
/* Set time-base frequency */
cpu_ppc_tb_init(env, pm->bus_freq_hz / 4);
- qemu_register_reset(pegasos2_cpu_reset, pm->cpu);
+ qemu_register_reset(pegasos_cpu_reset, pm->cpu);
/* RAM */
if (machine->ram_size > 2 * GiB) {
@@ -176,12 +187,16 @@ static void pegasos_init(MachineState *machine)
if (!machine->firmware && !pm->vof) {
pm->vof = g_malloc0(sizeof(*pm->vof));
}
- memory_region_init_rom(rom, NULL, "pegasos2.rom", PROM_SIZE, &error_fatal);
- memory_region_add_subregion(get_system_memory(), PROM_ADDR, rom);
+ prom_addr = PROM_ADDR;
+ if (pm->type == PEGASOS1) {
+ prom_addr += PROM_SIZE;
+ }
+ memory_region_init_rom(rom, NULL, "rom", PROM_SIZE, &error_fatal);
+ memory_region_add_subregion(get_system_memory(), prom_addr, rom);
sz = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
ELFDATA2MSB, PPC_ELF_MACHINE, 0, 0);
if (sz <= 0) {
- sz = load_image_targphys(filename, pm->vof ? 0 : PROM_ADDR, PROM_SIZE);
+ sz = load_image_targphys(filename, pm->vof ? 0 : prom_addr, PROM_SIZE);
}
if (sz <= 0 || sz > PROM_SIZE) {
error_report("Could not load firmware '%s'", filename);
@@ -192,13 +207,37 @@ static void pegasos_init(MachineState *machine)
pm->vof->fw_size = sz;
}
- /* Marvell Discovery II system controller */
- pm->nb = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
- qdev_get_gpio_in(DEVICE(pm->cpu), PPC6xx_INPUT_INT)));
- pci_bus = mv64361_get_pci_bus(pm->nb, 1);
+ /* north bridge */
+ switch (pm->type) {
+ case PEGASOS1:
+ {
+ MemoryRegion *pci_mem, *mr;
+
+ /* Articia S */
+ pm->nb = DEVICE(sysbus_create_simple(TYPE_ARTICIA, 0xfe000000, NULL));
+ pci_mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pm->nb), 1);
+ mr = g_new(MemoryRegion, 1);
+ memory_region_init_alias(mr, OBJECT(pm->nb), "pci-mem-low", pci_mem,
+ 0, 0x1000000);
+ memory_region_add_subregion(get_system_memory(), 0xfd000000, mr);
+ mr = g_new(MemoryRegion, 1);
+ memory_region_init_alias(mr, OBJECT(pm->nb), "pci-mem-high", pci_mem,
+ 0x80000000, 0x7d000000);
+ memory_region_add_subregion(get_system_memory(), 0x80000000, mr);
+ pci_bus = PCI_BUS(qdev_get_child_bus(pm->nb, "pci.0"));
+ break;
+ }
+ case PEGASOS2:
+ /* Marvell Discovery II system controller */
+ pm->nb = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
+ qdev_get_gpio_in(DEVICE(pm->cpu), PPC6xx_INPUT_INT)));
+ pci_bus = mv64361_get_pci_bus(pm->nb, 1);
+ break;
+ }
/* VIA VT8231 South Bridge (multifunction PCI device) */
- pm->sb = DEVICE(pci_new_multifunction(PCI_DEVFN(12, 0), TYPE_VT8231_ISA));
+ devfn = PCI_DEVFN(pm->type == PEGASOS1 ? 7 : 12, 0);
+ pm->sb = DEVICE(pci_new_multifunction(devfn, TYPE_VT8231_ISA));
via = OBJECT(pm->sb);
/* Set properties on individual devices before realizing the south bridge */
@@ -223,7 +262,21 @@ static void pegasos_init(MachineState *machine)
/* other PC hardware */
pci_vga_init(pci_bus);
- pegasos2_setup_pci_irq(pm);
+ /* pci interrupt routing */
+ switch (pm->type) {
+ case PEGASOS1:
+ qdev_connect_gpio_out_named(pm->sb, "intr", 0,
+ qdev_get_gpio_in(DEVICE(pm->cpu),
+ PPC6xx_INPUT_INT));
+ for (int i = 0; i < PCI_NUM_PINS; i++) {
+ qdev_connect_gpio_out(pm->nb, i,
+ qdev_get_gpio_in_named(pm->sb, "pirq", i));
+ }
+ break;
+ case PEGASOS2:
+ pegasos2_setup_pci_irq(pm);
+ break;
+ }
if (machine->kernel_filename) {
sz = load_elf(machine->kernel_filename, NULL, NULL, NULL,
@@ -376,7 +429,7 @@ static void pegasos2_chipset_reset(PegasosMachineState *pm)
PCI_INTERRUPT_LINE, 2, 0x309);
}
-static void pegasos2_machine_reset(MachineState *machine, ResetType type)
+static void pegasos_machine_reset(MachineState *machine, ResetType type)
{
PegasosMachineState *pm = PEGASOS_MACHINE(machine);
void *fdt;
@@ -387,6 +440,9 @@ static void pegasos2_machine_reset(MachineState *machine, ResetType type)
qemu_devices_reset(type);
if (!pm->vof) {
return; /* Firmware should set up machine so nothing to do */
+ } else if (pm->type == PEGASOS1) {
+ error_report("VOF is not supported by this machine");
+ exit(1);
}
/* Otherwise, set up devices that board firmware would normally do */
@@ -558,12 +614,12 @@ static target_ulong pegasos2_rtas(PowerPCCPU *cpu, PegasosMachineState *pm,
}
}
-static bool pegasos2_cpu_in_nested(PowerPCCPU *cpu)
+static bool pegasos_cpu_in_nested(PowerPCCPU *cpu)
{
return false;
}
-static void pegasos2_hypercall(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
+static void pegasos_hypercall(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
{
PegasosMachineState *pm = PEGASOS_MACHINE(vhyp);
CPUPPCState *env = &cpu->env;
@@ -574,7 +630,7 @@ static void pegasos2_hypercall(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
if (FIELD_EX64(env->msr, MSR, PR)) {
qemu_log_mask(LOG_GUEST_ERROR, "Hypercall made with MSR[PR]=1\n");
env->gpr[3] = H_PRIVILEGE;
- } else if (env->gpr[3] == KVMPPC_H_RTAS) {
+ } else if (env->gpr[3] == KVMPPC_H_RTAS && pm->type == PEGASOS2) {
env->gpr[3] = pegasos2_rtas(cpu, pm, env->gpr[4]);
} else if (env->gpr[3] == KVMPPC_H_VOF_CLIENT) {
int ret = vof_client_call(MACHINE(pm), pm->vof, MACHINE(pm)->fdt,
@@ -596,56 +652,78 @@ static target_ulong vhyp_encode_hpt_for_kvm_pr(PPCVirtualHypervisor *vhyp)
return POWERPC_CPU(current_cpu)->env.spr[SPR_SDR1];
}
-static bool pegasos2_setprop(MachineState *ms, const char *path,
- const char *propname, void *val, int vallen)
+static bool pegasos_setprop(MachineState *ms, const char *path,
+ const char *propname, void *val, int vallen)
{
return true;
}
-static void pegasos2_machine_class_init(ObjectClass *oc, const void *data)
+static void pegasos_machine_init(MachineClass *mc)
{
- MachineClass *mc = MACHINE_CLASS(oc);
- PPCVirtualHypervisorClass *vhc = PPC_VIRTUAL_HYPERVISOR_CLASS(oc);
- VofMachineIfClass *vmc = VOF_MACHINE_CLASS(oc);
+ PPCVirtualHypervisorClass *vhc = PPC_VIRTUAL_HYPERVISOR_CLASS(mc);
+ VofMachineIfClass *vmc = VOF_MACHINE_CLASS(mc);
- mc->desc = "Genesi/bPlan Pegasos II";
mc->init = pegasos_init;
- mc->reset = pegasos2_machine_reset;
+ mc->reset = pegasos_machine_reset;
mc->block_default_type = IF_IDE;
mc->default_boot_order = "cd";
mc->default_display = "std";
- mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7457_v1.2");
- mc->default_ram_id = "pegasos2.ram";
+ mc->default_ram_id = "ram";
mc->default_ram_size = 512 * MiB;
machine_add_audiodev_property(mc);
- vhc->cpu_in_nested = pegasos2_cpu_in_nested;
- vhc->hypercall = pegasos2_hypercall;
+ vhc->cpu_in_nested = pegasos_cpu_in_nested;
+ vhc->hypercall = pegasos_hypercall;
vhc->cpu_exec_enter = vhyp_nop;
vhc->cpu_exec_exit = vhyp_nop;
vhc->encode_hpt_for_kvm_pr = vhyp_encode_hpt_for_kvm_pr;
- vmc->setprop = pegasos2_setprop;
+ vmc->setprop = pegasos_setprop;
+}
+
+static void pegasos1_init(Object *obj)
+{
+ PegasosMachineState *pm = PEGASOS_MACHINE(obj);
+
+ pm->type = PEGASOS1;
+ pm->bus_freq_hz = 33000000;
+}
+
+static void pegasos1_machine_class_init(ObjectClass *oc, const void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->desc = "Genesi/bPlan Pegasos I";
+ mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("750cxe_v3.1b");
}
static void pegasos2_init(Object *obj)
{
PegasosMachineState *pm = PEGASOS_MACHINE(obj);
+ pm->type = PEGASOS2;
pm->bus_freq_hz = 133333333;
}
+static void pegasos2_machine_class_init(ObjectClass *oc, const void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+
+ mc->desc = "Genesi/bPlan Pegasos II";
+ mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7457_v1.2");
+}
+
+DEFINE_MACHINE_EXTENDED("pegasos", MACHINE, PegasosMachineState,
+ pegasos_machine_init, true, (const InterfaceInfo[]) {
+ { TYPE_PPC_VIRTUAL_HYPERVISOR },
+ { TYPE_VOF_MACHINE_IF }, { } })
+
static const TypeInfo pegasos_machine_types[] = {
{
- .name = TYPE_PEGASOS_MACHINE,
- .parent = TYPE_MACHINE,
- .instance_size = sizeof(PegasosMachineState),
- .abstract = true,
- .interfaces = (const InterfaceInfo[]) {
- { TYPE_PPC_VIRTUAL_HYPERVISOR },
- { TYPE_VOF_MACHINE_IF },
- { }
- },
+ .name = MACHINE_TYPE_NAME("pegasos1"),
+ .parent = TYPE_PEGASOS_MACHINE,
+ .class_init = pegasos1_machine_class_init,
+ .instance_init = pegasos1_init,
},
{
.name = MACHINE_TYPE_NAME("pegasos2"),
--
2.41.3
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH v4 11/12] hw/ppc/pegasos2: Add Pegasos I emulation
2025-10-23 0:06 ` [PATCH v4 11/12] hw/ppc/pegasos2: Add Pegasos I emulation BALATON Zoltan
@ 2025-10-23 6:54 ` Philippe Mathieu-Daudé
2025-10-23 13:14 ` BALATON Zoltan
0 siblings, 1 reply; 29+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-10-23 6:54 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
On 23/10/25 02:06, BALATON Zoltan wrote:
> The Pegasos II is a redesign of the original Pegasos (later marked I)
> that replaces the north bridge and has updated firmware but otherwise
> these are very similar. The Pegasos uses the same north bridge that
> AmigaOne used which we already emulate so we can also easily emulate
> Pegasos I.
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> hw/ppc/pegasos2.c | 156 ++++++++++++++++++++++++++++++++++------------
> 1 file changed, 117 insertions(+), 39 deletions(-)
> @@ -89,6 +96,8 @@ static void pegasos2_cpu_reset(void *opaque)
> if (pm->vof) {
> cpu->env.gpr[1] = 2 * VOF_STACK_SIZE - 0x20;
> cpu->env.nip = 0x100;
> + } else if (pm->type == PEGASOS1) {
> + cpu->env.nip = 0xfffc0100;
Preferably add a comment explaining/describing this value (think
at your future you in 3 years ;) ).
> + case PEGASOS1:
> + {
> + MemoryRegion *pci_mem, *mr;
> +
> + /* Articia S */
> + pm->nb = DEVICE(sysbus_create_simple(TYPE_ARTICIA, 0xfe000000, NULL));
> + pci_mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pm->nb), 1);
> + mr = g_new(MemoryRegion, 1);
> + memory_region_init_alias(mr, OBJECT(pm->nb), "pci-mem-low", pci_mem,
> + 0, 0x1000000);
> + memory_region_add_subregion(get_system_memory(), 0xfd000000, mr);
> + mr = g_new(MemoryRegion, 1);
> + memory_region_init_alias(mr, OBJECT(pm->nb), "pci-mem-high", pci_mem,
> + 0x80000000, 0x7d000000);
> + memory_region_add_subregion(get_system_memory(), 0x80000000, mr);
Since I don't want to delay this series any further, as a future
cleanup consider passing the host MR (get_system_memory) as a link
property, and map PCI hi/lo regions in the host bridge realize.
> + pci_bus = PCI_BUS(qdev_get_child_bus(pm->nb, "pci.0"));
> + break;
> + }
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 29+ messages in thread* Re: [PATCH v4 11/12] hw/ppc/pegasos2: Add Pegasos I emulation
2025-10-23 6:54 ` Philippe Mathieu-Daudé
@ 2025-10-23 13:14 ` BALATON Zoltan
0 siblings, 0 replies; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 13:14 UTC (permalink / raw)
To: Philippe Mathieu-Daudé
Cc: qemu-devel, qemu-ppc, Nicholas Piggin, Markus Armbruster,
Harsh Prateek Bora
[-- Attachment #1: Type: text/plain, Size: 3081 bytes --]
On Thu, 23 Oct 2025, Philippe Mathieu-Daudé wrote:
> On 23/10/25 02:06, BALATON Zoltan wrote:
>> The Pegasos II is a redesign of the original Pegasos (later marked I)
>> that replaces the north bridge and has updated firmware but otherwise
>> these are very similar. The Pegasos uses the same north bridge that
>> AmigaOne used which we already emulate so we can also easily emulate
>> Pegasos I.
>>
>> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
>> ---
>> hw/ppc/pegasos2.c | 156 ++++++++++++++++++++++++++++++++++------------
>> 1 file changed, 117 insertions(+), 39 deletions(-)
>
>
>> @@ -89,6 +96,8 @@ static void pegasos2_cpu_reset(void *opaque)
>> if (pm->vof) {
>> cpu->env.gpr[1] = 2 * VOF_STACK_SIZE - 0x20;
>> cpu->env.nip = 0x100;
>> + } else if (pm->type == PEGASOS1) {
>> + cpu->env.nip = 0xfffc0100;
>
> Preferably add a comment explaining/describing this value (think
> at your future you in 3 years ;) ).
I think I can figure that out even 3 years from now :-). PPC reset vector
is 0x100 so it should point to somewhere in ROM at offset 0x100. I'm not
quite sure how real machine gets to this address (there are pins that set
initial vectors address that we don't model or maybe ROM is remapped at
startup) but it seems to be the right start address so not much I can
explain about that.
>> + case PEGASOS1:
>> + {
>> + MemoryRegion *pci_mem, *mr;
>> +
>> + /* Articia S */
>> + pm->nb = DEVICE(sysbus_create_simple(TYPE_ARTICIA, 0xfe000000,
>> NULL));
>> + pci_mem = sysbus_mmio_get_region(SYS_BUS_DEVICE(pm->nb), 1);
>> + mr = g_new(MemoryRegion, 1);
>> + memory_region_init_alias(mr, OBJECT(pm->nb), "pci-mem-low",
>> pci_mem,
>> + 0, 0x1000000);
>> + memory_region_add_subregion(get_system_memory(), 0xfd000000, mr);
>> + mr = g_new(MemoryRegion, 1);
>> + memory_region_init_alias(mr, OBJECT(pm->nb), "pci-mem-high",
>> pci_mem,
>> + 0x80000000, 0x7d000000);
>> + memory_region_add_subregion(get_system_memory(), 0x80000000, mr);
>
> Since I don't want to delay this series any further, as a future
> cleanup consider passing the host MR (get_system_memory) as a link
> property, and map PCI hi/lo regions in the host bridge realize.
I'll consider this as future clean up. These should really be controlled
by registers in the north bridge but I don't have docs on Articia S so I
don't know how this should work but these are probably the default values
that we could move to the articia model but have to check if that works
for amigaone too. I'd skip the link property though to keep it simple.
This is a simple machine and other host bridges also access system memory
currently. Until get_system_memory goes away I don't see a reason to make
it more complicated.
Regards,
BALATON Zoltan
>> + pci_bus = PCI_BUS(qdev_get_child_bus(pm->nb, "pci.0"));
>> + break;
>> + }
>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH v4 12/12] hw/ppc/pegasos2: Add VOF support for pegasos1
2025-10-23 0:06 [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation BALATON Zoltan
` (10 preceding siblings ...)
2025-10-23 0:06 ` [PATCH v4 11/12] hw/ppc/pegasos2: Add Pegasos I emulation BALATON Zoltan
@ 2025-10-23 0:06 ` BALATON Zoltan
2025-10-23 6:49 ` Philippe Mathieu-Daudé
2025-10-23 11:39 ` [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation Harsh Prateek Bora
12 siblings, 1 reply; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 0:06 UTC (permalink / raw)
To: qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
When running without firmware ROM using Virtual Open Firmware we need
to do some hardware initialisation and provide the device tree as the
machine firmware would normally do.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
MAINTAINERS | 1 +
hw/ppc/pegasos2.c | 140 +++++++++++++++++++++++++++++++++------
pc-bios/dtb/meson.build | 1 +
pc-bios/dtb/pegasos1.dtb | Bin 0 -> 857 bytes
pc-bios/dtb/pegasos1.dts | 125 ++++++++++++++++++++++++++++++++++
5 files changed, 246 insertions(+), 21 deletions(-)
create mode 100644 pc-bios/dtb/pegasos1.dtb
create mode 100644 pc-bios/dtb/pegasos1.dts
diff --git a/MAINTAINERS b/MAINTAINERS
index 36eef27b41..684d7a5b37 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1652,6 +1652,7 @@ F: hw/ppc/pegasos2.c
F: hw/pci-host/mv64361.c
F: hw/pci-host/mv643xx.h
F: include/hw/pci-host/mv64361.h
+F: pc-bios/dtb/pegasos[12].dt[sb]
amigaone
M: BALATON Zoltan <balaton@eik.bme.hu>
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index a11f3c99ed..93696ed381 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -84,6 +84,7 @@ struct PegasosMachineState {
uint64_t initrd_size;
};
+static void *pegasos1_build_fdt(PegasosMachineState *pm, int *fdt_size);
static void *pegasos2_build_fdt(PegasosMachineState *pm, int *fdt_size);
static void pegasos_cpu_reset(void *opaque)
@@ -314,6 +315,82 @@ static void pegasos_init(MachineState *machine)
}
}
+static void pegasos_superio_write(uint8_t addr, uint8_t val)
+{
+ cpu_physical_memory_write(0xfe0003f0, &addr, 1);
+ cpu_physical_memory_write(0xfe0003f1, &val, 1);
+}
+
+static void pegasos1_pci_config_write(PegasosMachineState *pm, int bus,
+ uint32_t addr, uint32_t len, uint32_t val)
+{
+ addr |= BIT(31);
+ cpu_physical_memory_write(0xfec00cf8, &addr, 4);
+ cpu_physical_memory_write(0xfee00cfc, &val, len);
+}
+
+static void pegasos1_chipset_reset(PegasosMachineState *pm)
+{
+ uint8_t elcr = 0x2e;
+ cpu_physical_memory_write(0xfe0004d1, &elcr, sizeof(elcr));
+
+ pegasos1_pci_config_write(pm, 0, PCI_COMMAND, 2, PCI_COMMAND_IO |
+ PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 0) << 8) |
+ PCI_INTERRUPT_LINE, 2, 0x9);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 0) << 8) |
+ 0x50, 1, 0x6);
+ pegasos_superio_write(0xf4, 0xbe);
+ pegasos_superio_write(0xf6, 0xef);
+ pegasos_superio_write(0xf7, 0xfc);
+ pegasos_superio_write(0xf2, 0x14);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 0) << 8) |
+ 0x51, 1, 0x3d);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 0) << 8) |
+ 0x55, 1, 0x90);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 0) << 8) |
+ 0x56, 1, 0x99);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 0) << 8) |
+ 0x57, 1, 0x90);
+
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 1) << 8) |
+ PCI_INTERRUPT_LINE, 2, 0x10e);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 1) << 8) |
+ PCI_CLASS_PROG, 1, 0xf);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 1) << 8) |
+ 0x40, 1, 0xb);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 1) << 8) |
+ 0x50, 4, 0x17171717);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 1) << 8) |
+ PCI_COMMAND, 2, 0x87);
+
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 2) << 8) |
+ PCI_INTERRUPT_LINE, 2, 0x409);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 2) << 8) |
+ PCI_COMMAND, 2, 0x7);
+
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 3) << 8) |
+ PCI_INTERRUPT_LINE, 2, 0x409);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 3) << 8) |
+ PCI_COMMAND, 2, 0x7);
+
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 4) << 8) |
+ PCI_INTERRUPT_LINE, 2, 0x9);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 4) << 8) |
+ 0x48, 4, 0x2001);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 4) << 8) |
+ 0x41, 1, 0);
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 4) << 8) |
+ 0x90, 4, 0x1000);
+
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 5) << 8) |
+ PCI_INTERRUPT_LINE, 2, 0x309);
+
+ pegasos1_pci_config_write(pm, 0, (PCI_DEVFN(7, 6) << 8) |
+ PCI_INTERRUPT_LINE, 2, 0x309);
+}
+
static uint32_t pegasos2_mv_reg_read(PegasosMachineState *pm,
uint32_t addr, uint32_t len)
{
@@ -357,12 +434,6 @@ static void pegasos2_pci_config_write(PegasosMachineState *pm, int bus,
pegasos2_mv_reg_write(pm, pcicfg + 4, len, val);
}
-static void pegasos2_superio_write(uint8_t addr, uint8_t val)
-{
- cpu_physical_memory_write(0xfe0003f0, &addr, 1);
- cpu_physical_memory_write(0xfe0003f1, &val, 1);
-}
-
static void pegasos2_chipset_reset(PegasosMachineState *pm)
{
pegasos2_mv_reg_write(pm, 0, 4, 0x28020ff);
@@ -379,10 +450,10 @@ static void pegasos2_chipset_reset(PegasosMachineState *pm)
PCI_INTERRUPT_LINE, 2, 0x9);
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
0x50, 1, 0x6);
- pegasos2_superio_write(0xf4, 0xbe);
- pegasos2_superio_write(0xf6, 0xef);
- pegasos2_superio_write(0xf7, 0xfc);
- pegasos2_superio_write(0xf2, 0x14);
+ pegasos_superio_write(0xf4, 0xbe);
+ pegasos_superio_write(0xf6, 0xef);
+ pegasos_superio_write(0xf7, 0xfc);
+ pegasos_superio_write(0xf2, 0x14);
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
0x50, 1, 0x2);
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
@@ -432,7 +503,7 @@ static void pegasos2_chipset_reset(PegasosMachineState *pm)
static void pegasos_machine_reset(MachineState *machine, ResetType type)
{
PegasosMachineState *pm = PEGASOS_MACHINE(machine);
- void *fdt;
+ void *fdt = NULL;
uint32_t c[2];
uint64_t d[2];
int sz;
@@ -440,13 +511,22 @@ static void pegasos_machine_reset(MachineState *machine, ResetType type)
qemu_devices_reset(type);
if (!pm->vof) {
return; /* Firmware should set up machine so nothing to do */
- } else if (pm->type == PEGASOS1) {
- error_report("VOF is not supported by this machine");
- exit(1);
}
/* Otherwise, set up devices that board firmware would normally do */
- pegasos2_chipset_reset(pm);
+ switch (pm->type) {
+ case PEGASOS1:
+ pegasos1_chipset_reset(pm);
+ fdt = pegasos1_build_fdt(pm, &sz);
+ break;
+ case PEGASOS2:
+ pegasos2_chipset_reset(pm);
+ fdt = pegasos2_build_fdt(pm, &sz);
+ break;
+ }
+ if (!fdt) {
+ exit(1);
+ }
/* Device tree and VOF set up */
vof_init(pm->vof, machine->ram_size, &error_fatal);
@@ -465,11 +545,6 @@ static void pegasos_machine_reset(MachineState *machine, ResetType type)
exit(1);
}
- fdt = pegasos2_build_fdt(pm, &sz);
- if (!fdt) {
- exit(1);
- }
-
/* Set memory size */
c[0] = 0;
c[1] = cpu_to_be32(machine->ram_size);
@@ -761,6 +836,8 @@ static struct {
const char *name;
void (*dtf)(PCIBus *bus, PCIDevice *d, FDTInfo *fi);
} device_map[] = {
+ { "pci10cc,660", "host", NULL },
+ { "pci10cc,661", "host", NULL },
{ "pci11ab,6460", "host", NULL },
{ "pci1106,571", "ide", dt_ide },
{ "pci1106,3044", "firewire", NULL },
@@ -846,7 +923,7 @@ static void add_pci_device(PCIBus *bus, PCIDevice *d, void *opaque)
qemu_fdt_setprop_cell(fi->fdt, node->str, "interrupts",
pci_get_byte(&d->config[PCI_INTERRUPT_PIN]));
}
- /* Pegasos2 firmware has subsystem-id amd subsystem-vendor-id swapped */
+ /* Pegasos firmware has subsystem-id and subsystem-vendor-id swapped */
qemu_fdt_setprop_cell(fi->fdt, node->str, "subsystem-vendor-id",
pci_get_word(&d->config[PCI_SUBSYSTEM_ID]));
qemu_fdt_setprop_cell(fi->fdt, node->str, "subsystem-id",
@@ -934,6 +1011,27 @@ static void *load_dtb(const char *filename, int *fdt_size)
return fdt;
}
+static void *pegasos1_build_fdt(PegasosMachineState *pm, int *fdt_size)
+{
+ FDTInfo fi;
+ PCIBus *pci_bus;
+ void *fdt = load_dtb("pegasos1.dtb", fdt_size);
+
+ if (!fdt) {
+ return NULL;
+ }
+ qemu_fdt_setprop_string(fdt, "/", "name", "bplan,Pegasos");
+
+ add_cpu_info(fdt, pm->cpu, pm->bus_freq_hz);
+
+ fi.fdt = fdt;
+ fi.path = "/pci@80000000";
+ pci_bus = PCI_BUS(qdev_get_child_bus(pm->nb, "pci.0"));
+ pci_for_each_device_reverse(pci_bus, 0, add_pci_device, &fi);
+
+ return fdt;
+}
+
static void *pegasos2_build_fdt(PegasosMachineState *pm, int *fdt_size)
{
FDTInfo fi;
diff --git a/pc-bios/dtb/meson.build b/pc-bios/dtb/meson.build
index f14648f3a4..81bdd7580e 100644
--- a/pc-bios/dtb/meson.build
+++ b/pc-bios/dtb/meson.build
@@ -1,6 +1,7 @@
dtbs = [
'bamboo.dtb',
'canyonlands.dtb',
+ 'pegasos1.dtb',
'pegasos2.dtb',
'petalogix-ml605.dtb',
'petalogix-s3adsp1800.dtb',
diff --git a/pc-bios/dtb/pegasos1.dtb b/pc-bios/dtb/pegasos1.dtb
new file mode 100644
index 0000000000000000000000000000000000000000..3b863b25288a59bcede9459ff42afad713dde741
GIT binary patch
literal 857
zcmZ8fO>Yx15OvxjK&T3w=^-c=RCQ5Ogp}S|g(^KkM8yI1P<g$Rbd_D(wKuI&2~qwB
z2PCfWU-%<P`~ZlU=k<oRBR$W&=lQVL`*U;oONjLkLWqG7Yv0*FXFOp%X25>1Ue)2P
zwH4Vq`;8bw1HZ>;t21Y#4($Qs>6oU{8xI*8@T`9T8sbOnw^Lh4-5HhX(Mm_{-ksVl
z)<#k543FN8J7aT6ZanN9FMLHMid)8#w$22?9P@Cm<{Ue{7yY!q`;sNG#%QTC<4J?o
zyrj~&#eOd+b^U#g+qE9l=58l32d?gA=i#Evk%Mn^%78T-ar4cvKZ`unPh?(rIUyvm
zp(f1s<Z@XAE#z61?+<#l1@(XbHt#{YIS+BeaUS$&_<8Hk*Y`L0=jCr^^*-L<<eHaH
z3^vr@g}yXD0>mX2*md1FhM>Vd@`{15zY&OI5A?*GZ_uJ49eCK4S?0+5L{U+Ak<mr2
z=(Ji`5~azg5RMg}8!d)!UmuPR-|SqF&Wu~p)JT`DSVmsC+*T-XG!<Q+Us3GcRd_p9
s7&S{Kj?U+#)j|w*U+pEiuE@E$trDqb+FTZtO-VSZr{qOC_eluFKX>nfX#fBK
literal 0
HcmV?d00001
diff --git a/pc-bios/dtb/pegasos1.dts b/pc-bios/dtb/pegasos1.dts
new file mode 100644
index 0000000000..e5ef9db866
--- /dev/null
+++ b/pc-bios/dtb/pegasos1.dts
@@ -0,0 +1,125 @@
+/*
+ * QEMU Pegasos1 Device Tree Source
+ *
+ * Copyright 2025 BALATON Zoltan
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This is partial source, more info will be filled in by board code.
+ */
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ device_type = "chrp";
+ model = "Pegasos";
+ revision = "1A";
+ CODEGEN,vendor = "bplan GmbH";
+ CODEGEN,board = "Pegasos";
+ CODEGEN,description = "Pegasos CHRP PowerPC System";
+
+ openprom {
+ model = "Pegasos,0.1b123";
+ };
+
+ chosen {
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0 0>;
+ };
+
+ cpus {
+ #size-cells = <0>;
+ #address-cells = <1>;
+ #cpus = <1>;
+ };
+
+ failsafe {
+ device_type = "serial";
+ };
+
+ pci@80000000 {
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ clock-frequency = <33333333>;
+ 8259-interrupt-acknowledge = <0xfef00000>;
+ reg = <0x80000000 0x7f000000>;
+ ranges = <0x01000000 0 0x00000000 0xfe000000 0 0x00800000
+ 0x02000000 0 0x80000000 0x80000000 0 0x7d000000
+ 0x02000000 0 0xfd000000 0xfd000000 0 0x01000000>;
+ bus-range = <0 0>;
+
+ isa@7 {
+ vendor-id = <0x1106>;
+ device-id = <0x8231>;
+ revision-id = <0x10>;
+ class-code = <0x60100>;
+ /* Pegasos firmware has subsystem-id and */
+ /* subsystem-vendor-id swapped */
+ subsystem-id = <0x1af4>;
+ subsystem-vendor-id = <0x1100>;
+ reg = <0x3800 0 0 0 0>;
+ device_type = "isa";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ eisa-slots = <0>;
+ clock-frequency = <8333333>;
+ slot-names = <0>;
+
+ serial@i2f8 {
+ device_type = "serial";
+ reg = <1 0x2f8 8>;
+ interrupts = <3 0>;
+ clock-frequency = <0>;
+ };
+
+ 8042@i60 {
+ device_type = "";
+ reg = <1 0x60 5>;
+ clock-frequency = <0>;
+ interrupt-controller = "";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ #interrupt-cells = <2>;
+
+ };
+
+ keyboard@i60 {
+ device_type = "keyboard";
+ reg = <1 0x60 5>;
+ interrupts = <1 0>;
+ };
+
+ rtc@i70 {
+ device_type = "rtc";
+ reg = <1 0x70 2>;
+ interrupts = <8 0>;
+ clock-frequency = <0>;
+ compatible = "ds1385-rtc";
+ };
+
+ timer@i40 {
+ device_type = "timer";
+ reg = <1 0x40 8>;
+ clock-frequency = <0>;
+ };
+
+ fdc@i3f0 {
+ device_type = "fdc";
+ reg = <1 0x3f0 8>;
+ interrupts = <6 0>;
+ clock-frequency = <0>;
+ };
+
+ lpt@i3bc {
+ device_type = "lpt";
+ reg = <1 0x3bc 8>;
+ interrupts = <7 0>;
+ clock-frequency = <0>;
+ };
+ };
+ };
+};
--
2.41.3
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH v4 12/12] hw/ppc/pegasos2: Add VOF support for pegasos1
2025-10-23 0:06 ` [PATCH v4 12/12] hw/ppc/pegasos2: Add VOF support for pegasos1 BALATON Zoltan
@ 2025-10-23 6:49 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 29+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-10-23 6:49 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc
Cc: Nicholas Piggin, Markus Armbruster, Harsh Prateek Bora
On 23/10/25 02:06, BALATON Zoltan wrote:
> When running without firmware ROM using Virtual Open Firmware we need
> to do some hardware initialisation and provide the device tree as the
> machine firmware would normally do.
>
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> ---
> MAINTAINERS | 1 +
> hw/ppc/pegasos2.c | 140 +++++++++++++++++++++++++++++++++------
> pc-bios/dtb/meson.build | 1 +
> pc-bios/dtb/pegasos1.dtb | Bin 0 -> 857 bytes
> pc-bios/dtb/pegasos1.dts | 125 ++++++++++++++++++++++++++++++++++
> 5 files changed, 246 insertions(+), 21 deletions(-)
> create mode 100644 pc-bios/dtb/pegasos1.dtb
> create mode 100644 pc-bios/dtb/pegasos1.dts
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation
2025-10-23 0:06 [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation BALATON Zoltan
` (11 preceding siblings ...)
2025-10-23 0:06 ` [PATCH v4 12/12] hw/ppc/pegasos2: Add VOF support for pegasos1 BALATON Zoltan
@ 2025-10-23 11:39 ` Harsh Prateek Bora
2025-10-23 12:07 ` BALATON Zoltan
12 siblings, 1 reply; 29+ messages in thread
From: Harsh Prateek Bora @ 2025-10-23 11:39 UTC (permalink / raw)
To: BALATON Zoltan, qemu-devel, qemu-ppc; +Cc: Nicholas Piggin, Markus Armbruster
On 10/23/25 05:36, BALATON Zoltan wrote:
> This series changes how the fdt for VOF is generated in pegasos2 by
> moving the static parts to a dtb and only generate the changing parts
> such as memory size and PCI devices programmatically. This simplifies
> the code and allows simply adding emulation of Pegasos I which has a
> different north bridge and slightly different memory map but otherwise
> very similar and can be emulated by reusing parts from the amigaone
> machine. The machine was tested with a Pegasos I ROM image and MorphOS.
>
> The first VOF patch (submitted separetely before, the reviewed v3 is
> included here) fixes handling the name property in VOF that cannot be
> represented in a dts as that always takes the path as the name and
> cannot accept an explicit name property but we need the name property
> to appear when guest queries properties which previously was worked
> around by adding it to every node.
>
> Regards,
> BALATON Zoltan
Queued.
^ permalink raw reply [flat|nested] 29+ messages in thread* Re: [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation
2025-10-23 11:39 ` [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation Harsh Prateek Bora
@ 2025-10-23 12:07 ` BALATON Zoltan
2025-10-23 12:15 ` BALATON Zoltan
0 siblings, 1 reply; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 12:07 UTC (permalink / raw)
To: Harsh Prateek Bora
Cc: qemu-devel, qemu-ppc, Nicholas Piggin, Markus Armbruster
On Thu, 23 Oct 2025, Harsh Prateek Bora wrote:
> On 10/23/25 05:36, BALATON Zoltan wrote:
>> This series changes how the fdt for VOF is generated in pegasos2 by
>> moving the static parts to a dtb and only generate the changing parts
>> such as memory size and PCI devices programmatically. This simplifies
>> the code and allows simply adding emulation of Pegasos I which has a
>> different north bridge and slightly different memory map but otherwise
>> very similar and can be emulated by reusing parts from the amigaone
>> machine. The machine was tested with a Pegasos I ROM image and MorphOS.
>>
>> The first VOF patch (submitted separetely before, the reviewed v3 is
>> included here) fixes handling the name property in VOF that cannot be
>> represented in a dts as that always takes the path as the name and
>> cannot accept an explicit name property but we need the name property
>> to appear when guest queries properties which previously was worked
>> around by adding it to every node.
>>
>> Regards,
>> BALATON Zoltan
>
> Queued.
OK. In that case I can do follow up if needed but I still plan to send
updated raven series and if time allows updated firmware for sam460ex but
the latter is unsure if I can finish before the freeze.
Regards,
BALATON Zoltan
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation
2025-10-23 12:07 ` BALATON Zoltan
@ 2025-10-23 12:15 ` BALATON Zoltan
2025-10-23 12:23 ` Harsh Prateek Bora
0 siblings, 1 reply; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 12:15 UTC (permalink / raw)
To: Harsh Prateek Bora
Cc: qemu-devel, qemu-ppc, Nicholas Piggin, Markus Armbruster
On Thu, 23 Oct 2025, BALATON Zoltan wrote:
> On Thu, 23 Oct 2025, Harsh Prateek Bora wrote:
>> On 10/23/25 05:36, BALATON Zoltan wrote:
>>> This series changes how the fdt for VOF is generated in pegasos2 by
>>> moving the static parts to a dtb and only generate the changing parts
>>> such as memory size and PCI devices programmatically. This simplifies
>>> the code and allows simply adding emulation of Pegasos I which has a
>>> different north bridge and slightly different memory map but otherwise
>>> very similar and can be emulated by reusing parts from the amigaone
>>> machine. The machine was tested with a Pegasos I ROM image and MorphOS.
>>>
>>> The first VOF patch (submitted separetely before, the reviewed v3 is
>>> included here) fixes handling the name property in VOF that cannot be
>>> represented in a dts as that always takes the path as the name and
>>> cannot accept an explicit name property but we need the name property
>>> to appear when guest queries properties which previously was worked
>>> around by adding it to every node.
>>>
>>> Regards,
>>> BALATON Zoltan
>>
>> Queued.
>
> OK. In that case I can do follow up if needed but I still plan to send
> updated raven series and if time allows updated firmware for sam460ex but the
> latter is unsure if I can finish before the freeze.
Or if you haven't sent the pull request yet (I was confused by getting
cc-d on a pull that did not go to the list, maybe was only for testing)
then I can still update this series too. I see there was some problem with
another patch from Thomas so there will be another version of that too. So
the plan is to update raven series, after that update this one to address
Philippe's comments then if there's still time I see if I can do the
sam460ex U-Boot update but you don't have to wait for that last one.
Regards,
BALATON Zoltan
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation
2025-10-23 12:15 ` BALATON Zoltan
@ 2025-10-23 12:23 ` Harsh Prateek Bora
2025-10-23 12:29 ` BALATON Zoltan
0 siblings, 1 reply; 29+ messages in thread
From: Harsh Prateek Bora @ 2025-10-23 12:23 UTC (permalink / raw)
To: BALATON Zoltan; +Cc: qemu-devel, qemu-ppc, Nicholas Piggin, Markus Armbruster
On 10/23/25 17:45, BALATON Zoltan wrote:
> On Thu, 23 Oct 2025, BALATON Zoltan wrote:
>> On Thu, 23 Oct 2025, Harsh Prateek Bora wrote:
>>> On 10/23/25 05:36, BALATON Zoltan wrote:
>>>> This series changes how the fdt for VOF is generated in pegasos2 by
>>>> moving the static parts to a dtb and only generate the changing parts
>>>> such as memory size and PCI devices programmatically. This simplifies
>>>> the code and allows simply adding emulation of Pegasos I which has a
>>>> different north bridge and slightly different memory map but otherwise
>>>> very similar and can be emulated by reusing parts from the amigaone
>>>> machine. The machine was tested with a Pegasos I ROM image and MorphOS.
>>>>
>>>> The first VOF patch (submitted separetely before, the reviewed v3 is
>>>> included here) fixes handling the name property in VOF that cannot be
>>>> represented in a dts as that always takes the path as the name and
>>>> cannot accept an explicit name property but we need the name property
>>>> to appear when guest queries properties which previously was worked
>>>> around by adding it to every node.
>>>>
>>>> Regards,
>>>> BALATON Zoltan
>>>
>>> Queued.
>>
>> OK. In that case I can do follow up if needed but I still plan to send
>> updated raven series and if time allows updated firmware for sam460ex
>> but the latter is unsure if I can finish before the freeze.
>
> Or if you haven't sent the pull request yet (I was confused by getting
> cc-d on a pull that did not go to the list, maybe was only for testing)
> then I can still update this series too. I see there was some problem
> with another patch from Thomas so there will be another version of that
> too. So the plan is to update raven series, after that update this one
> to address Philippe's comments then if there's still time I see if I can
> do the sam460ex U-Boot update but you don't have to wait for that last one.
Sure. no issues.
I have included these patches in the pull request I sent today and am
planning another pull request before soft/hard freeze, so we can include
remaining patches that gets reviewed in that. Thanks.
regards,
Harsh
>
> Regards,
> BALATON Zoltan
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH v4 00/12] Pegasos2 clean up and pegasos1 emulation
2025-10-23 12:23 ` Harsh Prateek Bora
@ 2025-10-23 12:29 ` BALATON Zoltan
0 siblings, 0 replies; 29+ messages in thread
From: BALATON Zoltan @ 2025-10-23 12:29 UTC (permalink / raw)
To: Harsh Prateek Bora
Cc: qemu-devel, qemu-ppc, Nicholas Piggin, Markus Armbruster
On Thu, 23 Oct 2025, Harsh Prateek Bora wrote:
> On 10/23/25 17:45, BALATON Zoltan wrote:
>> On Thu, 23 Oct 2025, BALATON Zoltan wrote:
>>> On Thu, 23 Oct 2025, Harsh Prateek Bora wrote:
>>>> On 10/23/25 05:36, BALATON Zoltan wrote:
>>>>> This series changes how the fdt for VOF is generated in pegasos2 by
>>>>> moving the static parts to a dtb and only generate the changing parts
>>>>> such as memory size and PCI devices programmatically. This simplifies
>>>>> the code and allows simply adding emulation of Pegasos I which has a
>>>>> different north bridge and slightly different memory map but otherwise
>>>>> very similar and can be emulated by reusing parts from the amigaone
>>>>> machine. The machine was tested with a Pegasos I ROM image and MorphOS.
>>>>>
>>>>> The first VOF patch (submitted separetely before, the reviewed v3 is
>>>>> included here) fixes handling the name property in VOF that cannot be
>>>>> represented in a dts as that always takes the path as the name and
>>>>> cannot accept an explicit name property but we need the name property
>>>>> to appear when guest queries properties which previously was worked
>>>>> around by adding it to every node.
>>>>>
>>>>> Regards,
>>>>> BALATON Zoltan
>>>>
>>>> Queued.
>>>
>>> OK. In that case I can do follow up if needed but I still plan to send
>>> updated raven series and if time allows updated firmware for sam460ex but
>>> the latter is unsure if I can finish before the freeze.
>>
>> Or if you haven't sent the pull request yet (I was confused by getting cc-d
>> on a pull that did not go to the list, maybe was only for testing) then I
>> can still update this series too. I see there was some problem with another
>> patch from Thomas so there will be another version of that too. So the plan
>> is to update raven series, after that update this one to address Philippe's
>> comments then if there's still time I see if I can do the sam460ex U-Boot
>> update but you don't have to wait for that last one.
>
> Sure. no issues.
> I have included these patches in the pull request I sent today and am
> planning another pull request before soft/hard freeze, so we can include
> remaining patches that gets reviewed in that. Thanks.
OK, so the pull did go to the list. I'm OK with this series as it is, the
remaining changes were minor and could be done as follow up (or later).
I'll then concentrate on the raven series and see if I'll have time for
sam460ex. Thank you for stepping in and taking care of it.
Regards,
BALATON Zoltan
^ permalink raw reply [flat|nested] 29+ messages in thread