From: Harsh Prateek Bora <harshpb@linux.ibm.com>
To: qemu-devel@nongnu.org
Cc: "BALATON Zoltan" <balaton@eik.bme.hu>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>
Subject: [PULL 23/32] hw/ppc/pegasos2: Add Pegasos I emulation
Date: Thu, 23 Oct 2025 17:46:42 +0530 [thread overview]
Message-ID: <20251023121653.3686015-24-harshpb@linux.ibm.com> (raw)
In-Reply-To: <20251023121653.3686015-1-harshpb@linux.ibm.com>
From: BALATON Zoltan <balaton@eik.bme.hu>
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>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Link: https://lore.kernel.org/qemu-devel/8f5bd07553b41d83a54f9df0bb93b76b22dea5c5.1761176219.git.balaton@eik.bme.hu
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
---
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.43.5
next prev parent reply other threads:[~2025-10-23 12:42 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-23 12:16 [PULL RESEND 00/32] ppc-for-10.2 queue Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 01/32] ppc/spapr: remove deprecated machine pseries-3.0 Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 02/32] hw/ppc/spapr: Remove SpaprMachineClass::nr_xirqs field Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 03/32] ppc/spapr: remove deprecated machine pseries-3.1 Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 04/32] hw/ppc/spapr: Inline spapr_dtb_needed() Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 05/32] hw/ppc/spapr: Inline few SPAPR_IRQ_* uses Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 06/32] target/ppc/kvm: Remove kvmppc_get_host_serial() as unused Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 07/32] target/ppc/kvm: Remove kvmppc_get_host_model() " Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 08/32] ppc/spapr: remove deprecated machine pseries-4.0 Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 09/32] hw/ppc/spapr: Remove SpaprMachineClass::phb_placement callback Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 10/32] ppc/spapr: remove deprecated machine pseries-4.1 Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 11/32] ppc/spapr: remove deprecated machine pseries-4.2 Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 12/32] ppc/amigaone: Free allocated struct Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 13/32] ppc/vof: Make nextprop behave more like Open Firmware Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 14/32] hw/ppc/pegasos2: Remove explicit name properties from device tree Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 15/32] hw/ppc/pegasos2: Change device tree generation Harsh Prateek Bora
2025-10-27 13:14 ` Peter Maydell
2025-10-30 9:06 ` Harsh Prateek Bora
2025-10-30 10:18 ` BALATON Zoltan
2025-10-23 12:16 ` [PULL 16/32] hw/ppc/pegasos2: Remove fdt pointer from machine state Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 17/32] hw/ppc/pegasos2: Rename mv field in " Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 18/32] hw/ppc/pegasos2: Add south bridge pointer in the " Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 19/32] hw/ppc/pegasos2: Move PCI IRQ routing setup to a function Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 20/32] hw/ppc/pegasos2: Move hardware specific parts out of machine reset Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 21/32] hw/ppc/pegasos2: Introduce abstract superclass Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 22/32] hw/ppc/pegasos2: Add bus frequency to machine state Harsh Prateek Bora
2025-10-23 12:16 ` Harsh Prateek Bora [this message]
2025-10-23 12:16 ` [PULL 24/32] hw/ppc/pegasos2: Add VOF support for pegasos1 Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 25/32] hw/ppc: Implement fadump register command Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 26/32] hw/ppc: Trigger Fadump boot if fadump is registered Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 27/32] hw/ppc: Preserve memory regions registered for fadump Harsh Prateek Bora
2025-10-27 13:06 ` Peter Maydell
2025-10-23 12:16 ` [PULL 28/32] hw/ppc: Implement saving CPU state in Fadump Harsh Prateek Bora
2025-10-27 13:03 ` Peter Maydell
2025-10-23 12:16 ` [PULL 29/32] hw/ppc: Pass dump-sizes property for fadump in device tree Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 30/32] hw/ppc: Enable fadump for PSeries Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 31/32] tests/functional: Add test for fadump in PSeries Harsh Prateek Bora
2025-10-23 12:16 ` [PULL 32/32] MAINTAINERS: Add entry for FADump (pSeries) Harsh Prateek Bora
2025-10-23 19:33 ` [PULL RESEND 00/32] ppc-for-10.2 queue Richard Henderson
-- strict thread matches above, loose matches on Subject: below --
2025-10-23 11:43 [PULL " Harsh Prateek Bora
2025-10-23 11:44 ` [PULL 23/32] hw/ppc/pegasos2: Add Pegasos I emulation Harsh Prateek Bora
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251023121653.3686015-24-harshpb@linux.ibm.com \
--to=harshpb@linux.ibm.com \
--cc=balaton@eik.bme.hu \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).