qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 2/4] target/ppc: Allow virtual hypervisor on CPU without HV
  2021-06-27 16:27 [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF BALATON Zoltan
@ 2021-06-27 16:27 ` BALATON Zoltan
  2021-07-08  2:48   ` David Gibson
  2021-06-27 16:27 ` [PATCH 1/4] ppc/pegasos2: Introduce Pegasos2MachineState structure BALATON Zoltan
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: BALATON Zoltan @ 2021-06-27 16:27 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Alexey Kardashevskiy, David Gibson

Change the assert in ppc_store_sdr1() to allow vhyp to be set on CPUs
without HV bit. This allows using the vhyp interface for firmware
emulation on pegasos2.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
 target/ppc/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/cpu.c b/target/ppc/cpu.c
index 19d67b5b07..a29299882a 100644
--- a/target/ppc/cpu.c
+++ b/target/ppc/cpu.c
@@ -72,7 +72,7 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
 {
     PowerPCCPU *cpu = env_archcpu(env);
     qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value);
-    assert(!cpu->vhyp);
+    assert(!cpu->env.has_hv_mode || !cpu->vhyp);
 #if defined(TARGET_PPC64)
     if (mmu_is_64bit(env->mmu_model)) {
         target_ulong sdr_mask = SDR_64_HTABORG | SDR_64_HTABSIZE;
-- 
2.21.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/4] ppc/pegasos2: Use Virtual Open Firmware as firmware replacement
  2021-06-27 16:27 [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF BALATON Zoltan
                   ` (2 preceding siblings ...)
  2021-06-27 16:27 ` [PATCH 4/4] ppc/pegasos2: Implement some RTAS functions with VOF BALATON Zoltan
@ 2021-06-27 16:27 ` BALATON Zoltan
  2021-07-01 11:35 ` [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF BALATON Zoltan
  2021-07-08  4:37 ` David Gibson
  5 siblings, 0 replies; 12+ messages in thread
From: BALATON Zoltan @ 2021-06-27 16:27 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Alexey Kardashevskiy, David Gibson

The pegasos2 board comes with an Open Firmware compliant ROM based on
SmartFirmware but it has some changes that are not open source
therefore the ROM binary cannot be included in QEMU. Guests running on
the board however depend on services provided by the firmware. The
Virtual Open Firmware recently added to QEMU implements a minimal set
of these services to allow some guests to boot without the original
firmware. This patch adds VOF as the default firmware for pegasos2
which allows booting Linux and MorphOS via -kernel option while a ROM
image can still be used with -bios for guests that don't run with VOF.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
 hw/ppc/Kconfig    |   1 +
 hw/ppc/pegasos2.c | 602 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 601 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index 67630f80e1..7fcafec60a 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -76,6 +76,7 @@ config PEGASOS2
     select VT82C686
     select IDE_VIA
     select SMBUS_EEPROM
+    select VOF
 # This should come with VT82C686
     select ACPI_X86
 
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 07971175c9..f1741a4512 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -34,13 +34,33 @@
 #include "trace.h"
 #include "qemu/datadir.h"
 #include "sysemu/device_tree.h"
+#include "hw/ppc/vof.h"
 
-#define PROM_FILENAME "pegasos2.rom"
+#include <libfdt.h>
+
+#define PROM_FILENAME "vof.bin"
 #define PROM_ADDR     0xfff00000
 #define PROM_SIZE     0x80000
 
+#define KVMPPC_HCALL_BASE    0xf000
+#define KVMPPC_H_VOF_CLIENT  (KVMPPC_HCALL_BASE + 0x5)
+
+#define H_SUCCESS     0
+#define H_PRIVILEGE  -3  /* Caller not privileged */
+#define H_PARAMETER  -4  /* Parameter invalid, out-of-range or conflicting */
+
 #define BUS_FREQ_HZ 133333333
 
+#define PCI0_MEM_BASE 0xc0000000
+#define PCI0_MEM_SIZE 0x20000000
+#define PCI0_IO_BASE  0xf8000000
+#define PCI0_IO_SIZE  0x10000
+
+#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)
 
@@ -48,14 +68,26 @@ struct Pegasos2MachineState {
     MachineState parent_obj;
     PowerPCCPU *cpu;
     DeviceState *mv;
+    Vof *vof;
+    void *fdt_blob;
+    uint64_t kernel_addr;
+    uint64_t kernel_entry;
+    uint64_t kernel_size;
 };
 
+static void *build_fdt(MachineState *machine, int *fdt_size);
+
 static void pegasos2_cpu_reset(void *opaque)
 {
     PowerPCCPU *cpu = opaque;
+    Pegasos2MachineState *pm = PEGASOS2_MACHINE(current_machine);
 
     cpu_reset(CPU(cpu));
     cpu->env.spr[SPR_HID1] = 7ULL << 28;
+    if (pm->vof) {
+        cpu->env.gpr[1] = 2 * VOF_STACK_SIZE - 0x20;
+        cpu->env.nip = 0x100;
+    }
 }
 
 static void pegasos2_init(MachineState *machine)
@@ -92,18 +124,24 @@ static void pegasos2_init(MachineState *machine)
         error_report("Could not find firmware '%s'", fwname);
         exit(1);
     }
+    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);
     sz = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1,
                   PPC_ELF_MACHINE, 0, 0);
     if (sz <= 0) {
-        sz = load_image_targphys(filename, 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);
         exit(1);
     }
     g_free(filename);
+    if (pm->vof) {
+        pm->vof->fw_size = sz;
+    }
 
     /* Marvell Discovery II system controller */
     pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
@@ -137,20 +175,185 @@ static void pegasos2_init(MachineState *machine)
 
     /* other PC hardware */
     pci_vga_init(pci_bus);
+
+    if (machine->kernel_filename) {
+        sz = load_elf(machine->kernel_filename, NULL, NULL, NULL,
+                      &pm->kernel_entry, &pm->kernel_addr, NULL, NULL, 1,
+                      PPC_ELF_MACHINE, 0, 0);
+        if (sz <= 0) {
+            error_report("Could not load kernel '%s'",
+                         machine->kernel_filename);
+            exit(1);
+        }
+        pm->kernel_size = sz;
+        if (!pm->vof) {
+            warn_report("Option -kernel may be ineffective with -bios.");
+        }
+    }
+    if (machine->kernel_cmdline && !pm->vof) {
+        warn_report("Option -append may be ineffective with -bios.");
+    }
+}
+
+static void pegasos2_pci_config_write(AddressSpace *as, int bus, uint32_t addr,
+                                      uint32_t len, uint32_t val)
+{
+    hwaddr pcicfg = (bus ? 0xf1000c78 : 0xf1000cf8);
+
+    stl_le_phys(as, pcicfg, addr | BIT(31));
+    switch (len) {
+    case 4:
+        stl_le_phys(as, pcicfg + 4, val);
+        break;
+    case 2:
+        stw_le_phys(as, pcicfg + 4, val);
+        break;
+    case 1:
+        stb_phys(as, pcicfg + 4, val);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid length\n", __func__);
+        break;
+    }
+}
+
+static void pegasos2_machine_reset(MachineState *machine)
+{
+    Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
+    AddressSpace *as = CPU(pm->cpu)->as;
+    void *fdt;
+    uint64_t d[2];
+    int sz;
+
+    qemu_devices_reset();
+    if (!pm->vof) {
+        return; /* Firmware should set up machine so nothing to do */
+    }
+
+    /* Otherwise, set up devices that board firmware would normally do */
+    stl_le_phys(as, 0xf1000000, 0x28020ff);
+    stl_le_phys(as, 0xf1000278, 0xa31fc);
+    stl_le_phys(as, 0xf100f300, 0x11ff0400);
+    stl_le_phys(as, 0xf100f10c, 0x80000000);
+    stl_le_phys(as, 0xf100001c, 0x8000000);
+    pegasos2_pci_config_write(as, 0, PCI_COMMAND, 2, PCI_COMMAND_IO |
+                              PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+    pegasos2_pci_config_write(as, 1, PCI_COMMAND, 2, PCI_COMMAND_IO |
+                              PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 0) << 8) |
+                              PCI_INTERRUPT_LINE, 2, 0x9);
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 0) << 8) |
+                              0x50, 1, 0x2);
+
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 1) << 8) |
+                              PCI_INTERRUPT_LINE, 2, 0x109);
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 1) << 8) |
+                              PCI_CLASS_PROG, 1, 0xf);
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 1) << 8) |
+                              0x40, 1, 0xb);
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 1) << 8) |
+                              0x50, 4, 0x17171717);
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 1) << 8) |
+                              PCI_COMMAND, 2, 0x87);
+
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 2) << 8) |
+                              PCI_INTERRUPT_LINE, 2, 0x409);
+
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 3) << 8) |
+                              PCI_INTERRUPT_LINE, 2, 0x409);
+
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 4) << 8) |
+                              PCI_INTERRUPT_LINE, 2, 0x9);
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 4) << 8) |
+                              0x48, 4, 0xf00);
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 4) << 8) |
+                              0x40, 4, 0x558020);
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 4) << 8) |
+                              0x90, 4, 0xd00);
+
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 5) << 8) |
+                              PCI_INTERRUPT_LINE, 2, 0x309);
+
+    pegasos2_pci_config_write(as, 1, (PCI_DEVFN(12, 6) << 8) |
+                              PCI_INTERRUPT_LINE, 2, 0x309);
+
+    /* Device tree and VOF set up */
+    vof_init(pm->vof, machine->ram_size, &error_fatal);
+    if (vof_claim(pm->vof, 0, VOF_STACK_SIZE, VOF_STACK_SIZE) == -1) {
+        error_report("Memory allocation for stack failed");
+        exit(1);
+    }
+    if (pm->kernel_size &&
+        vof_claim(pm->vof, pm->kernel_addr, pm->kernel_size, 0) == -1) {
+        error_report("Memory for kernel is in use");
+        exit(1);
+    }
+    fdt = build_fdt(machine, &sz);
+    /* 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));
+    qemu_fdt_setprop(fdt, "/chosen", "qemu,boot-kernel", d, sizeof(d));
+
+    qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
+    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");
+    pm->cpu->vhyp = PPC_VIRTUAL_HYPERVISOR(machine);
+}
+
+static void pegasos2_hypercall(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
+{
+    Pegasos2MachineState *pm = PEGASOS2_MACHINE(vhyp);
+    CPUPPCState *env = &cpu->env;
+
+    /* The TCG path should also be holding the BQL at this point */
+    g_assert(qemu_mutex_iothread_locked());
+
+    if (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_VOF_CLIENT) {
+        int ret = vof_client_call(MACHINE(pm), pm->vof, pm->fdt_blob,
+                                  env->gpr[4]);
+        env->gpr[3] = (ret ? H_PARAMETER : H_SUCCESS);
+    } else {
+        qemu_log_mask(LOG_GUEST_ERROR, "Unsupported hypercall " TARGET_FMT_lx
+                      "\n", env->gpr[3]);
+        env->gpr[3] = -1;
+    }
+}
+
+static void vhyp_nop(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
+{
+}
+
+static target_ulong vhyp_encode_hpt_for_kvm_pr(PPCVirtualHypervisor *vhyp)
+{
+    return POWERPC_CPU(current_cpu)->env.spr[SPR_SDR1];
 }
 
 static void pegasos2_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
+    PPCVirtualHypervisorClass *vhc = PPC_VIRTUAL_HYPERVISOR_CLASS(oc);
 
     mc->desc = "Genesi/bPlan Pegasos II";
     mc->init = pegasos2_init;
+    mc->reset = pegasos2_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("7400_v2.9");
     mc->default_ram_id = "pegasos2.ram";
     mc->default_ram_size = 512 * MiB;
+
+    vhc->hypercall = pegasos2_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;
 }
 
 static const TypeInfo pegasos2_machine_info = {
@@ -158,6 +361,10 @@ static const TypeInfo pegasos2_machine_info = {
     .parent        = TYPE_MACHINE,
     .class_init    = pegasos2_machine_class_init,
     .instance_size = sizeof(Pegasos2MachineState),
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_PPC_VIRTUAL_HYPERVISOR },
+        { }
+    },
 };
 
 static void pegasos2_machine_register_types(void)
@@ -166,3 +373,394 @@ static void pegasos2_machine_register_types(void)
 }
 
 type_init(pegasos2_machine_register_types)
+
+/* FDT creation for passing to firmware */
+
+typedef struct {
+    void *fdt;
+    const char *path;
+} FDTInfo;
+
+/* We do everything in reverse order so it comes out right in the tree */
+
+static void dt_ide(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
+{
+    qemu_fdt_setprop_string(fi->fdt, fi->path, "device_type", "spi");
+}
+
+static void dt_usb(PCIBus *bus, PCIDevice *d, FDTInfo *fi)
+{
+    qemu_fdt_setprop_cell(fi->fdt, fi->path, "#size-cells", 0);
+    qemu_fdt_setprop_cell(fi->fdt, fi->path, "#address-cells", 1);
+    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");
+    qemu_fdt_setprop_string(fi->fdt, fi->path, "name", "isa");
+
+    /* addional 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");
+    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);
+    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");
+    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);
+    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");
+    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);
+    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");
+    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);
+    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");
+    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);
+    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", "");
+    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);
+    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");
+    qemu_fdt_setprop_string(fi->fdt, name->str, "name", "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 },
+    { "pci1106,8235", "other", NULL },
+    { "pci1106,3058", "sound", NULL },
+    { NULL, NULL }
+};
+
+static void add_pci_device(PCIBus *bus, PCIDevice *d, void *opaque)
+{
+    FDTInfo *fi = opaque;
+    GString *node = g_string_new(NULL);
+    uint32_t cells[(PCI_NUM_REGIONS + 1) * 5];
+    int i, j;
+    const char *name = NULL;
+    g_autofree const gchar *pn = g_strdup_printf("pci%x,%x",
+                                     pci_get_word(&d->config[PCI_VENDOR_ID]),
+                                     pci_get_word(&d->config[PCI_DEVICE_ID]));
+
+    for (i = 0; device_map[i].id; i++) {
+        if (!strcmp(pn, device_map[i].id)) {
+            name = device_map[i].name;
+            break;
+        }
+    }
+    g_string_printf(node, "%s/%s@%x", fi->path, (name ?: pn),
+                    PCI_SLOT(d->devfn));
+    if (PCI_FUNC(d->devfn)) {
+        g_string_append_printf(node, ",%x", PCI_FUNC(d->devfn));
+    }
+
+    qemu_fdt_add_subnode(fi->fdt, node->str);
+    if (device_map[i].dtf) {
+        FDTInfo cfi = { fi->fdt, node->str };
+        device_map[i].dtf(bus, d, &cfi);
+    }
+    cells[0] = cpu_to_be32(d->devfn << 8);
+    cells[1] = 0;
+    cells[2] = 0;
+    cells[3] = 0;
+    cells[4] = 0;
+    j = 5;
+    for (i = 0; i < PCI_NUM_REGIONS; i++) {
+        if (!d->io_regions[i].size) {
+            continue;
+        }
+        cells[j] = cpu_to_be32(d->devfn << 8 | (PCI_BASE_ADDRESS_0 + i * 4));
+        if (d->io_regions[i].type & PCI_BASE_ADDRESS_SPACE_IO) {
+            cells[j] |= cpu_to_be32(1 << 24);
+        } else {
+            cells[j] |= cpu_to_be32(2 << 24);
+            if (d->io_regions[i].type & PCI_BASE_ADDRESS_MEM_PREFETCH) {
+                cells[j] |= cpu_to_be32(4 << 28);
+            }
+        }
+        cells[j + 1] = 0;
+        cells[j + 2] = 0;
+        cells[j + 3] = cpu_to_be32(d->io_regions[i].size >> 32);
+        cells[j + 4] = cpu_to_be32(d->io_regions[i].size);
+        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]));
+    }
+    /* Pegasos2 firmware has subsystem-id amd 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",
+                          pci_get_word(&d->config[PCI_SUBSYSTEM_VENDOR_ID]));
+    cells[0] = pci_get_long(&d->config[PCI_CLASS_REVISION]);
+    qemu_fdt_setprop_cell(fi->fdt, node->str, "class-code", cells[0] >> 8);
+    qemu_fdt_setprop_cell(fi->fdt, node->str, "revision-id", cells[0] && 0xff);
+    qemu_fdt_setprop_cell(fi->fdt, node->str, "device-id",
+                          pci_get_word(&d->config[PCI_DEVICE_ID]));
+    qemu_fdt_setprop_cell(fi->fdt, node->str, "vendor-id",
+                          pci_get_word(&d->config[PCI_VENDOR_ID]));
+
+    g_string_free(node, TRUE);
+}
+
+static void *build_fdt(MachineState *machine, int *fdt_size)
+{
+    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");
+    qemu_fdt_setprop_string(fdt, "/pci@c0000000", "name", "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");
+    qemu_fdt_setprop_string(fdt, "/pci@80000000", "name", "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_setprop_string(fdt, "/failsafe", "name", "failsafe");
+
+    /* 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";
+    qemu_fdt_add_subnode(fdt, cp);
+    qemu_fdt_setprop_cell(fdt, cp, "l2cr", 0);
+    qemu_fdt_setprop_cell(fdt, cp, "d-cache-size", 0x8000);
+    qemu_fdt_setprop_cell(fdt, cp, "d-cache-block-size",
+                          cpu->env.dcache_line_size);
+    qemu_fdt_setprop_cell(fdt, cp, "d-cache-line-size",
+                          cpu->env.dcache_line_size);
+    qemu_fdt_setprop_cell(fdt, cp, "i-cache-size", 0x8000);
+    qemu_fdt_setprop_cell(fdt, cp, "i-cache-block-size",
+                          cpu->env.icache_line_size);
+    qemu_fdt_setprop_cell(fdt, cp, "i-cache-line-size",
+                          cpu->env.icache_line_size);
+    if (cpu->env.id_tlbs) {
+        qemu_fdt_setprop_cell(fdt, cp, "i-tlb-sets", cpu->env.nb_ways);
+        qemu_fdt_setprop_cell(fdt, cp, "i-tlb-size", cpu->env.tlb_per_way);
+        qemu_fdt_setprop_cell(fdt, cp, "d-tlb-sets", cpu->env.nb_ways);
+        qemu_fdt_setprop_cell(fdt, cp, "d-tlb-size", cpu->env.tlb_per_way);
+        qemu_fdt_setprop_string(fdt, cp, "tlb-split", "");
+    }
+    qemu_fdt_setprop_cell(fdt, cp, "tlb-sets", cpu->env.nb_ways);
+    qemu_fdt_setprop_cell(fdt, cp, "tlb-size", cpu->env.nb_tlb);
+    qemu_fdt_setprop_string(fdt, cp, "state", "running");
+    if (cpu->env.insns_flags & PPC_ALTIVEC) {
+        qemu_fdt_setprop_string(fdt, cp, "altivec", "");
+        qemu_fdt_setprop_string(fdt, cp, "data-streams", "");
+    }
+    /*
+     * FIXME What flags do data-streams, external-control and
+     * performance-monitor depend on?
+     */
+    qemu_fdt_setprop_string(fdt, cp, "external-control", "");
+    if (cpu->env.insns_flags & PPC_FLOAT_FSQRT) {
+        qemu_fdt_setprop_string(fdt, cp, "general-purpose", "");
+    }
+    qemu_fdt_setprop_string(fdt, cp, "performance-monitor", "");
+    if (cpu->env.insns_flags & PPC_FLOAT_FRES) {
+        qemu_fdt_setprop_string(fdt, cp, "graphics", "");
+    }
+    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, "cpu-version", cpu->env.spr[SPR_PVR]);
+    cells[0] = 0;
+    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");
+    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_setprop_string(fdt, "/memory@0", "name", "memory");
+
+    qemu_fdt_add_subnode(fdt, "/chosen");
+    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");
+
+    return fdt;
+}
-- 
2.21.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/4] ppc/pegasos2: Implement some RTAS functions with VOF
  2021-06-27 16:27 [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF BALATON Zoltan
  2021-06-27 16:27 ` [PATCH 2/4] target/ppc: Allow virtual hypervisor on CPU without HV BALATON Zoltan
  2021-06-27 16:27 ` [PATCH 1/4] ppc/pegasos2: Introduce Pegasos2MachineState structure BALATON Zoltan
@ 2021-06-27 16:27 ` BALATON Zoltan
  2021-07-08  4:37   ` David Gibson
  2021-06-27 16:27 ` [PATCH 3/4] ppc/pegasos2: Use Virtual Open Firmware as firmware replacement BALATON Zoltan
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: BALATON Zoltan @ 2021-06-27 16:27 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Alexey Kardashevskiy, David Gibson

Linux uses RTAS functions to access PCI devices so we need to provide
these with VOF. Implement some of the most important functions to
allow booting Linux with VOF. With this the board is now usable
without a binary ROM image and we can enable it by default as other
boards.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
---
 default-configs/devices/ppc-softmmu.mak |   2 +-
 hw/ppc/pegasos2.c                       | 131 ++++++++++++++++++++++++
 2 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/default-configs/devices/ppc-softmmu.mak b/default-configs/devices/ppc-softmmu.mak
index c2d41198cd..4535993d8d 100644
--- a/default-configs/devices/ppc-softmmu.mak
+++ b/default-configs/devices/ppc-softmmu.mak
@@ -14,7 +14,7 @@ CONFIG_SAM460EX=y
 CONFIG_MAC_OLDWORLD=y
 CONFIG_MAC_NEWWORLD=y
 
-CONFIG_PEGASOS2=n
+CONFIG_PEGASOS2=y
 
 # For PReP
 CONFIG_PREP=y
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index f1741a4512..d482806edd 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -43,6 +43,7 @@
 #define PROM_SIZE     0x80000
 
 #define KVMPPC_HCALL_BASE    0xf000
+#define KVMPPC_H_RTAS        (KVMPPC_HCALL_BASE + 0x0)
 #define KVMPPC_H_VOF_CLIENT  (KVMPPC_HCALL_BASE + 0x5)
 
 #define H_SUCCESS     0
@@ -195,6 +196,30 @@ static void pegasos2_init(MachineState *machine)
     }
 }
 
+static uint32_t pegasos2_pci_config_read(AddressSpace *as, int bus,
+                                         uint32_t addr, uint32_t len)
+{
+    hwaddr pcicfg = (bus ? 0xf1000c78 : 0xf1000cf8);
+    uint32_t val = 0xffffffff;
+
+    stl_le_phys(as, pcicfg, addr | BIT(31));
+    switch (len) {
+    case 4:
+        val = ldl_le_phys(as, pcicfg + 4);
+        break;
+    case 2:
+        val = lduw_le_phys(as, pcicfg + 4);
+        break;
+    case 1:
+        val = ldub_phys(as, pcicfg + 4);
+        break;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid length\n", __func__);
+        break;
+    }
+    return val;
+}
+
 static void pegasos2_pci_config_write(AddressSpace *as, int bus, uint32_t addr,
                                       uint32_t len, uint32_t val)
 {
@@ -304,6 +329,87 @@ static void pegasos2_machine_reset(MachineState *machine)
     pm->cpu->vhyp = PPC_VIRTUAL_HYPERVISOR(machine);
 }
 
+enum pegasos2_rtas_tokens {
+    RTAS_RESTART_RTAS = 0,
+    RTAS_NVRAM_FETCH = 1,
+    RTAS_NVRAM_STORE = 2,
+    RTAS_GET_TIME_OF_DAY = 3,
+    RTAS_SET_TIME_OF_DAY = 4,
+    RTAS_EVENT_SCAN = 6,
+    RTAS_CHECK_EXCEPTION = 7,
+    RTAS_READ_PCI_CONFIG = 8,
+    RTAS_WRITE_PCI_CONFIG = 9,
+    RTAS_DISPLAY_CHARACTER = 10,
+    RTAS_SET_INDICATOR = 11,
+    RTAS_POWER_OFF = 17,
+    RTAS_SUSPEND = 18,
+    RTAS_HIBERNATE = 19,
+    RTAS_SYSTEM_REBOOT = 20,
+};
+
+static target_ulong pegasos2_rtas(PowerPCCPU *cpu, Pegasos2MachineState *pm,
+                                  target_ulong args_real)
+{
+    AddressSpace *as = CPU(cpu)->as;
+    uint32_t token = ldl_be_phys(as, args_real);
+    uint32_t nargs = ldl_be_phys(as, args_real + 4);
+    uint32_t nrets = ldl_be_phys(as, args_real + 8);
+    uint32_t args = args_real + 12;
+    uint32_t rets = args_real + 12 + nargs * 4;
+
+    if (nrets < 1) {
+        qemu_log_mask(LOG_GUEST_ERROR, "Too few return values in RTAS call\n");
+        return H_PARAMETER;
+    }
+    switch (token) {
+    case RTAS_READ_PCI_CONFIG:
+    {
+        uint32_t addr, len, val;
+
+        if (nargs != 2 || nrets != 2) {
+            stl_be_phys(as, rets, -1);
+            return H_PARAMETER;
+        }
+        addr = ldl_be_phys(as, args);
+        len = ldl_be_phys(as, args + 4);
+        val = pegasos2_pci_config_read(as, !(addr >> 24),
+                                       addr & 0x0fffffff, len);
+        stl_be_phys(as, rets, 0);
+        stl_be_phys(as, rets + 4, val);
+        return H_SUCCESS;
+    }
+    case RTAS_WRITE_PCI_CONFIG:
+    {
+        uint32_t addr, len, val;
+
+        if (nargs != 3 || nrets != 1) {
+            stl_be_phys(as, rets, -1);
+            return H_PARAMETER;
+        }
+        addr = ldl_be_phys(as, args);
+        len = ldl_be_phys(as, args + 4);
+        val = ldl_be_phys(as, args + 8);
+        pegasos2_pci_config_write(as, !(addr >> 24),
+                                  addr & 0x0fffffff, len, val);
+        stl_be_phys(as, rets, 0);
+        return H_SUCCESS;
+    }
+    case RTAS_DISPLAY_CHARACTER:
+        if (nargs != 1 || nrets != 1) {
+            stl_be_phys(as, rets, -1);
+            return H_PARAMETER;
+        }
+        qemu_log_mask(LOG_UNIMP, "%c", ldl_be_phys(as, args));
+        stl_be_phys(as, rets, 0);
+        return H_SUCCESS;
+    default:
+        qemu_log_mask(LOG_UNIMP, "Unknown RTAS token %u (args=%u, rets=%u)\n",
+                      token, nargs, nrets);
+        stl_be_phys(as, rets, 0);
+        return H_SUCCESS;
+    }
+}
+
 static void pegasos2_hypercall(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
 {
     Pegasos2MachineState *pm = PEGASOS2_MACHINE(vhyp);
@@ -315,6 +421,8 @@ static void pegasos2_hypercall(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu)
     if (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) {
+        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,
                                   env->gpr[4]);
@@ -687,6 +795,29 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
     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", 20);
+    qemu_fdt_setprop_cell(fdt, "/rtas", "hibernate", 19);
+    qemu_fdt_setprop_cell(fdt, "/rtas", "suspend", 18);
+    qemu_fdt_setprop_cell(fdt, "/rtas", "power-off", 17);
+    qemu_fdt_setprop_cell(fdt, "/rtas", "set-indicator", 11);
+    qemu_fdt_setprop_cell(fdt, "/rtas", "display-character", 10);
+    qemu_fdt_setprop_cell(fdt, "/rtas", "write-pci-config", 9);
+    qemu_fdt_setprop_cell(fdt, "/rtas", "read-pci-config", 8);
+    /* Pegasos2 firmware misspells check-exception and guests use that */
+    qemu_fdt_setprop_cell(fdt, "/rtas", "check-execption", 7);
+    qemu_fdt_setprop_cell(fdt, "/rtas", "event-scan", 6);
+    qemu_fdt_setprop_cell(fdt, "/rtas", "set-time-of-day", 4);
+    qemu_fdt_setprop_cell(fdt, "/rtas", "get-time-of-day", 3);
+    qemu_fdt_setprop_cell(fdt, "/rtas", "nvram-store", 2);
+    qemu_fdt_setprop_cell(fdt, "/rtas", "nvram-fetch", 1);
+    qemu_fdt_setprop_cell(fdt, "/rtas", "restart-rtas", 0);
+    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);
-- 
2.21.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 1/4] ppc/pegasos2: Introduce Pegasos2MachineState structure
  2021-06-27 16:27 [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF BALATON Zoltan
  2021-06-27 16:27 ` [PATCH 2/4] target/ppc: Allow virtual hypervisor on CPU without HV BALATON Zoltan
@ 2021-06-27 16:27 ` BALATON Zoltan
  2021-07-08  2:47   ` David Gibson
  2021-06-27 16:27 ` [PATCH 4/4] ppc/pegasos2: Implement some RTAS functions with VOF BALATON Zoltan
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 12+ messages in thread
From: BALATON Zoltan @ 2021-06-27 16:27 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Alexey Kardashevskiy, David Gibson

Add own machine state structure which will be used to store state
needed for firmware emulation.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
 hw/ppc/pegasos2.c | 50 +++++++++++++++++++++++++++++++++++------------
 1 file changed, 37 insertions(+), 13 deletions(-)

diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index 0bfd0928aa..07971175c9 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -1,7 +1,7 @@
 /*
  * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator
  *
- * Copyright (c) 2018-2020 BALATON Zoltan
+ * Copyright (c) 2018-2021 BALATON Zoltan
  *
  * This work is licensed under the GNU GPL license version 2 or later.
  *
@@ -41,6 +41,15 @@
 
 #define BUS_FREQ_HZ 133333333
 
+#define TYPE_PEGASOS2_MACHINE  MACHINE_TYPE_NAME("pegasos2")
+OBJECT_DECLARE_TYPE(Pegasos2MachineState, MachineClass, PEGASOS2_MACHINE)
+
+struct Pegasos2MachineState {
+    MachineState parent_obj;
+    PowerPCCPU *cpu;
+    DeviceState *mv;
+};
+
 static void pegasos2_cpu_reset(void *opaque)
 {
     PowerPCCPU *cpu = opaque;
@@ -51,9 +60,9 @@ static void pegasos2_cpu_reset(void *opaque)
 
 static void pegasos2_init(MachineState *machine)
 {
-    PowerPCCPU *cpu = NULL;
+    Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
+    CPUPPCState *env;
     MemoryRegion *rom = g_new(MemoryRegion, 1);
-    DeviceState *mv;
     PCIBus *pci_bus;
     PCIDevice *dev;
     I2CBus *i2c_bus;
@@ -63,15 +72,16 @@ static void pegasos2_init(MachineState *machine)
     uint8_t *spd_data;
 
     /* init CPU */
-    cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
-    if (PPC_INPUT(&cpu->env) != PPC_FLAGS_INPUT_6xx) {
+    pm->cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
+    env = &pm->cpu->env;
+    if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
         error_report("Incompatible CPU, only 6xx bus supported");
         exit(1);
     }
 
     /* Set time-base frequency */
-    cpu_ppc_tb_init(&cpu->env, BUS_FREQ_HZ / 4);
-    qemu_register_reset(pegasos2_cpu_reset, cpu);
+    cpu_ppc_tb_init(env, BUS_FREQ_HZ / 4);
+    qemu_register_reset(pegasos2_cpu_reset, pm->cpu);
 
     /* RAM */
     memory_region_add_subregion(get_system_memory(), 0, machine->ram);
@@ -96,16 +106,16 @@ static void pegasos2_init(MachineState *machine)
     g_free(filename);
 
     /* Marvell Discovery II system controller */
-    mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
-                        ((qemu_irq *)cpu->env.irq_inputs)[PPC6xx_INPUT_INT]));
-    pci_bus = mv64361_get_pci_bus(mv, 1);
+    pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
+                             ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]));
+    pci_bus = mv64361_get_pci_bus(pm->mv, 1);
 
     /* VIA VT8231 South Bridge (multifunction PCI device) */
     /* VT8231 function 0: PCI-to-ISA Bridge */
     dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true,
                                           TYPE_VT8231_ISA);
     qdev_connect_gpio_out(DEVICE(dev), 0,
-                          qdev_get_gpio_in_named(mv, "gpp", 31));
+                          qdev_get_gpio_in_named(pm->mv, "gpp", 31));
 
     /* VT8231 function 1: IDE Controller */
     dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), "via-ide");
@@ -129,8 +139,10 @@ static void pegasos2_init(MachineState *machine)
     pci_vga_init(pci_bus);
 }
 
-static void pegasos2_machine(MachineClass *mc)
+static void pegasos2_machine_class_init(ObjectClass *oc, void *data)
 {
+    MachineClass *mc = MACHINE_CLASS(oc);
+
     mc->desc = "Genesi/bPlan Pegasos II";
     mc->init = pegasos2_init;
     mc->block_default_type = IF_IDE;
@@ -141,4 +153,16 @@ static void pegasos2_machine(MachineClass *mc)
     mc->default_ram_size = 512 * MiB;
 }
 
-DEFINE_MACHINE("pegasos2", pegasos2_machine)
+static const TypeInfo pegasos2_machine_info = {
+    .name          = TYPE_PEGASOS2_MACHINE,
+    .parent        = TYPE_MACHINE,
+    .class_init    = pegasos2_machine_class_init,
+    .instance_size = sizeof(Pegasos2MachineState),
+};
+
+static void pegasos2_machine_register_types(void)
+{
+    type_register_static(&pegasos2_machine_info);
+}
+
+type_init(pegasos2_machine_register_types)
-- 
2.21.4



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF
@ 2021-06-27 16:27 BALATON Zoltan
  2021-06-27 16:27 ` [PATCH 2/4] target/ppc: Allow virtual hypervisor on CPU without HV BALATON Zoltan
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: BALATON Zoltan @ 2021-06-27 16:27 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: Alexey Kardashevskiy, David Gibson

Based-on: <20210625055155.2252896-1-aik@ozlabs.ru>
^ That is v22 of Alexey's VOF patch

With this series on top of VOF v22 I can now boot Linux and MorphOS on
pegasos2 without a firmware blob so I hope this is enough to get this
board in 6.1 and also have it enabled so people can start using it
eventually (a lot of people don't compile their QEMU but rely on
binaries from distros and other sources). Provided that VOF will also
be merged by then. This gives VOF another use case that may help it
getting merged at last.

Further info and example command lines can be found at
https://osdn.net/projects/qmiga/wiki/SubprojectPegasos2

Regards,
BALATON Zoltan

BALATON Zoltan (4):
  ppc/pegasos2: Introduce Pegasos2MachineState structure
  target/ppc: Allow virtual hypervisor on CPU without HV
  ppc/pegasos2: Use Virtual Open Firmware as firmware replacement
  ppc/pegasos2: Implement some RTAS functions with VOF

 default-configs/devices/ppc-softmmu.mak |   2 +-
 hw/ppc/Kconfig                          |   1 +
 hw/ppc/pegasos2.c                       | 783 +++++++++++++++++++++++-
 target/ppc/cpu.c                        |   2 +-
 4 files changed, 771 insertions(+), 17 deletions(-)

-- 
2.21.4



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF
  2021-06-27 16:27 [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF BALATON Zoltan
                   ` (3 preceding siblings ...)
  2021-06-27 16:27 ` [PATCH 3/4] ppc/pegasos2: Use Virtual Open Firmware as firmware replacement BALATON Zoltan
@ 2021-07-01 11:35 ` BALATON Zoltan
  2021-07-05 19:17   ` Philippe Mathieu-Daudé
  2021-07-08  4:37 ` David Gibson
  5 siblings, 1 reply; 12+ messages in thread
From: BALATON Zoltan @ 2021-07-01 11:35 UTC (permalink / raw)
  To: qemu-devel, qemu-ppc; +Cc: David Gibson

On Sun, 27 Jun 2021, BALATON Zoltan wrote:
> Based-on: <20210625055155.2252896-1-aik@ozlabs.ru>
> ^ That is v22 of Alexey's VOF patch
>
> With this series on top of VOF v22 I can now boot Linux and MorphOS on
> pegasos2 without a firmware blob so I hope this is enough to get this
> board in 6.1 and also have it enabled so people can start using it
> eventually (a lot of people don't compile their QEMU but rely on
> binaries from distros and other sources). Provided that VOF will also
> be merged by then. This gives VOF another use case that may help it
> getting merged at last.
>
> Further info and example command lines can be found at
> https://osdn.net/projects/qmiga/wiki/SubprojectPegasos2

Ping? Freeze is coming and this would be the second release pegasos2 
misses (after it missed 6.0) if this is not in the next pull request so 
that's why I'm pushing.

Regards,
BALATON Zoltan


> BALATON Zoltan (4):
>  ppc/pegasos2: Introduce Pegasos2MachineState structure
>  target/ppc: Allow virtual hypervisor on CPU without HV
>  ppc/pegasos2: Use Virtual Open Firmware as firmware replacement
>  ppc/pegasos2: Implement some RTAS functions with VOF
>
> default-configs/devices/ppc-softmmu.mak |   2 +-
> hw/ppc/Kconfig                          |   1 +
> hw/ppc/pegasos2.c                       | 783 +++++++++++++++++++++++-
> target/ppc/cpu.c                        |   2 +-
> 4 files changed, 771 insertions(+), 17 deletions(-)
>
>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF
  2021-07-01 11:35 ` [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF BALATON Zoltan
@ 2021-07-05 19:17   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 12+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-07-05 19:17 UTC (permalink / raw)
  To: BALATON Zoltan, qemu-devel, qemu-ppc, Alexey Kardashevskiy
  Cc: Greg Kurz, Laurent Vivier, David Gibson

On 7/1/21 1:35 PM, BALATON Zoltan wrote:
> On Sun, 27 Jun 2021, BALATON Zoltan wrote:
>> Based-on: <20210625055155.2252896-1-aik@ozlabs.ru>
>> ^ That is v22 of Alexey's VOF patch
>>
>> With this series on top of VOF v22 I can now boot Linux and MorphOS on
>> pegasos2 without a firmware blob so I hope this is enough to get this
>> board in 6.1 and also have it enabled so people can start using it
>> eventually (a lot of people don't compile their QEMU but rely on
>> binaries from distros and other sources). Provided that VOF will also
>> be merged by then. This gives VOF another use case that may help it
>> getting merged at last.
>>
>> Further info and example command lines can be found at
>> https://osdn.net/projects/qmiga/wiki/SubprojectPegasos2
> 
> Ping? Freeze is coming and this would be the second release pegasos2
> misses (after it missed 6.0) if this is not in the next pull request so
> that's why I'm pushing.

I'm not sure who can help, I was expecting Alexey would review
your series. Cc'ing Laurent and Greg in case, to help you...

>> BALATON Zoltan (4):
>>  ppc/pegasos2: Introduce Pegasos2MachineState structure
>>  target/ppc: Allow virtual hypervisor on CPU without HV
>>  ppc/pegasos2: Use Virtual Open Firmware as firmware replacement
>>  ppc/pegasos2: Implement some RTAS functions with VOF
>>
>> default-configs/devices/ppc-softmmu.mak |   2 +-
>> hw/ppc/Kconfig                          |   1 +
>> hw/ppc/pegasos2.c                       | 783 +++++++++++++++++++++++-
>> target/ppc/cpu.c                        |   2 +-
>> 4 files changed, 771 insertions(+), 17 deletions(-)
>>
>>
> 



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/4] ppc/pegasos2: Introduce Pegasos2MachineState structure
  2021-06-27 16:27 ` [PATCH 1/4] ppc/pegasos2: Introduce Pegasos2MachineState structure BALATON Zoltan
@ 2021-07-08  2:47   ` David Gibson
  0 siblings, 0 replies; 12+ messages in thread
From: David Gibson @ 2021-07-08  2:47 UTC (permalink / raw)
  To: BALATON Zoltan; +Cc: Alexey Kardashevskiy, qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 4902 bytes --]

On Sun, Jun 27, 2021 at 06:27:13PM +0200, BALATON Zoltan wrote:
> Add own machine state structure which will be used to store state
> needed for firmware emulation.
> 
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

Applied to ppc-for-6.1.

> ---
>  hw/ppc/pegasos2.c | 50 +++++++++++++++++++++++++++++++++++------------
>  1 file changed, 37 insertions(+), 13 deletions(-)
> 
> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
> index 0bfd0928aa..07971175c9 100644
> --- a/hw/ppc/pegasos2.c
> +++ b/hw/ppc/pegasos2.c
> @@ -1,7 +1,7 @@
>  /*
>   * QEMU PowerPC CHRP (Genesi/bPlan Pegasos II) hardware System Emulator
>   *
> - * Copyright (c) 2018-2020 BALATON Zoltan
> + * Copyright (c) 2018-2021 BALATON Zoltan
>   *
>   * This work is licensed under the GNU GPL license version 2 or later.
>   *
> @@ -41,6 +41,15 @@
>  
>  #define BUS_FREQ_HZ 133333333
>  
> +#define TYPE_PEGASOS2_MACHINE  MACHINE_TYPE_NAME("pegasos2")
> +OBJECT_DECLARE_TYPE(Pegasos2MachineState, MachineClass, PEGASOS2_MACHINE)
> +
> +struct Pegasos2MachineState {
> +    MachineState parent_obj;
> +    PowerPCCPU *cpu;
> +    DeviceState *mv;
> +};
> +
>  static void pegasos2_cpu_reset(void *opaque)
>  {
>      PowerPCCPU *cpu = opaque;
> @@ -51,9 +60,9 @@ static void pegasos2_cpu_reset(void *opaque)
>  
>  static void pegasos2_init(MachineState *machine)
>  {
> -    PowerPCCPU *cpu = NULL;
> +    Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
> +    CPUPPCState *env;
>      MemoryRegion *rom = g_new(MemoryRegion, 1);
> -    DeviceState *mv;
>      PCIBus *pci_bus;
>      PCIDevice *dev;
>      I2CBus *i2c_bus;
> @@ -63,15 +72,16 @@ static void pegasos2_init(MachineState *machine)
>      uint8_t *spd_data;
>  
>      /* init CPU */
> -    cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
> -    if (PPC_INPUT(&cpu->env) != PPC_FLAGS_INPUT_6xx) {
> +    pm->cpu = POWERPC_CPU(cpu_create(machine->cpu_type));
> +    env = &pm->cpu->env;
> +    if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
>          error_report("Incompatible CPU, only 6xx bus supported");
>          exit(1);
>      }
>  
>      /* Set time-base frequency */
> -    cpu_ppc_tb_init(&cpu->env, BUS_FREQ_HZ / 4);
> -    qemu_register_reset(pegasos2_cpu_reset, cpu);
> +    cpu_ppc_tb_init(env, BUS_FREQ_HZ / 4);
> +    qemu_register_reset(pegasos2_cpu_reset, pm->cpu);
>  
>      /* RAM */
>      memory_region_add_subregion(get_system_memory(), 0, machine->ram);
> @@ -96,16 +106,16 @@ static void pegasos2_init(MachineState *machine)
>      g_free(filename);
>  
>      /* Marvell Discovery II system controller */
> -    mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
> -                        ((qemu_irq *)cpu->env.irq_inputs)[PPC6xx_INPUT_INT]));
> -    pci_bus = mv64361_get_pci_bus(mv, 1);
> +    pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
> +                             ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]));
> +    pci_bus = mv64361_get_pci_bus(pm->mv, 1);
>  
>      /* VIA VT8231 South Bridge (multifunction PCI device) */
>      /* VT8231 function 0: PCI-to-ISA Bridge */
>      dev = pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), true,
>                                            TYPE_VT8231_ISA);
>      qdev_connect_gpio_out(DEVICE(dev), 0,
> -                          qdev_get_gpio_in_named(mv, "gpp", 31));
> +                          qdev_get_gpio_in_named(pm->mv, "gpp", 31));
>  
>      /* VT8231 function 1: IDE Controller */
>      dev = pci_create_simple(pci_bus, PCI_DEVFN(12, 1), "via-ide");
> @@ -129,8 +139,10 @@ static void pegasos2_init(MachineState *machine)
>      pci_vga_init(pci_bus);
>  }
>  
> -static void pegasos2_machine(MachineClass *mc)
> +static void pegasos2_machine_class_init(ObjectClass *oc, void *data)
>  {
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +
>      mc->desc = "Genesi/bPlan Pegasos II";
>      mc->init = pegasos2_init;
>      mc->block_default_type = IF_IDE;
> @@ -141,4 +153,16 @@ static void pegasos2_machine(MachineClass *mc)
>      mc->default_ram_size = 512 * MiB;
>  }
>  
> -DEFINE_MACHINE("pegasos2", pegasos2_machine)
> +static const TypeInfo pegasos2_machine_info = {
> +    .name          = TYPE_PEGASOS2_MACHINE,
> +    .parent        = TYPE_MACHINE,
> +    .class_init    = pegasos2_machine_class_init,
> +    .instance_size = sizeof(Pegasos2MachineState),
> +};
> +
> +static void pegasos2_machine_register_types(void)
> +{
> +    type_register_static(&pegasos2_machine_info);
> +}
> +
> +type_init(pegasos2_machine_register_types)

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/4] target/ppc: Allow virtual hypervisor on CPU without HV
  2021-06-27 16:27 ` [PATCH 2/4] target/ppc: Allow virtual hypervisor on CPU without HV BALATON Zoltan
@ 2021-07-08  2:48   ` David Gibson
  0 siblings, 0 replies; 12+ messages in thread
From: David Gibson @ 2021-07-08  2:48 UTC (permalink / raw)
  To: BALATON Zoltan; +Cc: Alexey Kardashevskiy, qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1219 bytes --]

On Sun, Jun 27, 2021 at 06:27:13PM +0200, BALATON Zoltan wrote:
> Change the assert in ppc_store_sdr1() to allow vhyp to be set on CPUs
> without HV bit. This allows using the vhyp interface for firmware
> emulation on pegasos2.
> 
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>

Kind of a hack, but a simple one, so applied to ppc-for-6.1.

> ---
>  target/ppc/cpu.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target/ppc/cpu.c b/target/ppc/cpu.c
> index 19d67b5b07..a29299882a 100644
> --- a/target/ppc/cpu.c
> +++ b/target/ppc/cpu.c
> @@ -72,7 +72,7 @@ void ppc_store_sdr1(CPUPPCState *env, target_ulong value)
>  {
>      PowerPCCPU *cpu = env_archcpu(env);
>      qemu_log_mask(CPU_LOG_MMU, "%s: " TARGET_FMT_lx "\n", __func__, value);
> -    assert(!cpu->vhyp);
> +    assert(!cpu->env.has_hv_mode || !cpu->vhyp);
>  #if defined(TARGET_PPC64)
>      if (mmu_is_64bit(env->mmu_model)) {
>          target_ulong sdr_mask = SDR_64_HTABORG | SDR_64_HTABSIZE;

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/4] ppc/pegasos2: Implement some RTAS functions with VOF
  2021-06-27 16:27 ` [PATCH 4/4] ppc/pegasos2: Implement some RTAS functions with VOF BALATON Zoltan
@ 2021-07-08  4:37   ` David Gibson
  2021-07-08 22:25     ` BALATON Zoltan
  0 siblings, 1 reply; 12+ messages in thread
From: David Gibson @ 2021-07-08  4:37 UTC (permalink / raw)
  To: BALATON Zoltan; +Cc: Alexey Kardashevskiy, qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 2370 bytes --]

On Sun, Jun 27, 2021 at 06:27:13PM +0200, BALATON Zoltan wrote:
> Linux uses RTAS functions to access PCI devices so we need to provide
> these with VOF. Implement some of the most important functions to
> allow booting Linux with VOF. With this the board is now usable
> without a binary ROM image and we can enable it by default as other
> boards.
> 
> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>

Applied, but...

> @@ -687,6 +795,29 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
>      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", 20);
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "hibernate", 19);
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "suspend", 18);
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "power-off", 17);
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "set-indicator", 11);
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "display-character", 10);
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "write-pci-config", 9);
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "read-pci-config", 8);
> +    /* Pegasos2 firmware misspells check-exception and guests use that */
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "check-execption", 7);
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "event-scan", 6);
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "set-time-of-day", 4);
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "get-time-of-day", 3);
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "nvram-store", 2);
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "nvram-fetch", 1);
> +    qemu_fdt_setprop_cell(fdt, "/rtas", "restart-rtas", 0);
> +    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);

..you really want to be using your symbolic names here as well.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF
  2021-06-27 16:27 [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF BALATON Zoltan
                   ` (4 preceding siblings ...)
  2021-07-01 11:35 ` [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF BALATON Zoltan
@ 2021-07-08  4:37 ` David Gibson
  5 siblings, 0 replies; 12+ messages in thread
From: David Gibson @ 2021-07-08  4:37 UTC (permalink / raw)
  To: BALATON Zoltan; +Cc: Alexey Kardashevskiy, qemu-ppc, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1577 bytes --]

On Sun, Jun 27, 2021 at 06:27:13PM +0200, BALATON Zoltan wrote:
> Based-on: <20210625055155.2252896-1-aik@ozlabs.ru>
> ^ That is v22 of Alexey's VOF patch
> 
> With this series on top of VOF v22 I can now boot Linux and MorphOS on
> pegasos2 without a firmware blob so I hope this is enough to get this
> board in 6.1 and also have it enabled so people can start using it
> eventually (a lot of people don't compile their QEMU but rely on
> binaries from distros and other sources). Provided that VOF will also
> be merged by then. This gives VOF another use case that may help it
> getting merged at last.
> 
> Further info and example command lines can be found at
> https://osdn.net/projects/qmiga/wiki/SubprojectPegasos2

Applied to ppc-for-6.1, thanks.

> 
> Regards,
> BALATON Zoltan
> 
> BALATON Zoltan (4):
>   ppc/pegasos2: Introduce Pegasos2MachineState structure
>   target/ppc: Allow virtual hypervisor on CPU without HV
>   ppc/pegasos2: Use Virtual Open Firmware as firmware replacement
>   ppc/pegasos2: Implement some RTAS functions with VOF
> 
>  default-configs/devices/ppc-softmmu.mak |   2 +-
>  hw/ppc/Kconfig                          |   1 +
>  hw/ppc/pegasos2.c                       | 783 +++++++++++++++++++++++-
>  target/ppc/cpu.c                        |   2 +-
>  4 files changed, 771 insertions(+), 17 deletions(-)
> 

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/4] ppc/pegasos2: Implement some RTAS functions with VOF
  2021-07-08  4:37   ` David Gibson
@ 2021-07-08 22:25     ` BALATON Zoltan
  0 siblings, 0 replies; 12+ messages in thread
From: BALATON Zoltan @ 2021-07-08 22:25 UTC (permalink / raw)
  To: David Gibson; +Cc: Alexey Kardashevskiy, qemu-ppc, qemu-devel

On Thu, 8 Jul 2021, David Gibson wrote:
> On Sun, Jun 27, 2021 at 06:27:13PM +0200, BALATON Zoltan wrote:
>> Linux uses RTAS functions to access PCI devices so we need to provide
>> these with VOF. Implement some of the most important functions to
>> allow booting Linux with VOF. With this the board is now usable
>> without a binary ROM image and we can enable it by default as other
>> boards.
>>
>> Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
>
> Applied, but...
>
>> @@ -687,6 +795,29 @@ static void *build_fdt(MachineState *machine, int *fdt_size)
>>      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", 20);
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "hibernate", 19);
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "suspend", 18);
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "power-off", 17);
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "set-indicator", 11);
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "display-character", 10);
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "write-pci-config", 9);
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "read-pci-config", 8);
>> +    /* Pegasos2 firmware misspells check-exception and guests use that */
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "check-execption", 7);
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "event-scan", 6);
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "set-time-of-day", 4);
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "get-time-of-day", 3);
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "nvram-store", 2);
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "nvram-fetch", 1);
>> +    qemu_fdt_setprop_cell(fdt, "/rtas", "restart-rtas", 0);
>> +    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);
>
> ..you really want to be using your symbolic names here as well.

Sent a v2 for this patch that you can replace this with.

Regards,
BALATON Zoltan


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-07-08 22:26 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-27 16:27 [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF BALATON Zoltan
2021-06-27 16:27 ` [PATCH 2/4] target/ppc: Allow virtual hypervisor on CPU without HV BALATON Zoltan
2021-07-08  2:48   ` David Gibson
2021-06-27 16:27 ` [PATCH 1/4] ppc/pegasos2: Introduce Pegasos2MachineState structure BALATON Zoltan
2021-07-08  2:47   ` David Gibson
2021-06-27 16:27 ` [PATCH 4/4] ppc/pegasos2: Implement some RTAS functions with VOF BALATON Zoltan
2021-07-08  4:37   ` David Gibson
2021-07-08 22:25     ` BALATON Zoltan
2021-06-27 16:27 ` [PATCH 3/4] ppc/pegasos2: Use Virtual Open Firmware as firmware replacement BALATON Zoltan
2021-07-01 11:35 ` [PATCH 0/4] ppc/Pegasos2: Firmware replacement using VOF BALATON Zoltan
2021-07-05 19:17   ` Philippe Mathieu-Daudé
2021-07-08  4:37 ` David Gibson

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).