From nobody Sun May 19 00:47:38 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=eik.bme.hu ARC-Seal: i=1; a=rsa-sha256; t=1622997500; cv=none; d=zohomail.com; s=zohoarc; b=iw8RtU4VTKkub9qLmHw2MCgpprpIedt8RmLIWDXESqPR1rSmsI3vSwLUzadfKjBLfpVc5AmKACleKuEV280XR9SRB8GNfJOZJ9JqYuo3L/rBiGVSu/Qr52sgIn/O5iaG0/k1g2/NRa3UR7bj98BHsabcIajfy1eDjG1+G2NQIQQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1622997500; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=xaZZrXZE/2jPTSP9qLv40t+WyFMZ03Q2m9TaXOO9D9A=; b=a7J7LNBp7MZ19U8Sq7RrgaLD+bjJoqkKmySddZCuRhNfDg0GXN/tkTnyF7hFHvCurIeUTPrItfN85A7AjFGzu95/RupqqREKbOZNwpWnb2dVESfgxSHFu/AZ5Wm0mcbFkCx+fuB86db2fpc6PCQ8ugg827YvQNSz3x/Dy8GR99w= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1622997500549359.00023854656195; Sun, 6 Jun 2021 09:38:20 -0700 (PDT) Received: from localhost ([::1]:35640 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lpvn1-0001KB-1w for importer@patchew.org; Sun, 06 Jun 2021 12:38:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33192) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpvlY-000724-Jm; Sun, 06 Jun 2021 12:36:48 -0400 Received: from zero.eik.bme.hu ([152.66.115.2]:58755) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpvlV-0004Rh-Rt; Sun, 06 Jun 2021 12:36:47 -0400 Received: from zero.eik.bme.hu (blah.eik.bme.hu [152.66.115.182]) by localhost (Postfix) with SMTP id C7494746FDC; Sun, 6 Jun 2021 18:36:40 +0200 (CEST) Received: by zero.eik.bme.hu (Postfix, from userid 432) id A69CA74634B; Sun, 6 Jun 2021 18:36:40 +0200 (CEST) Message-Id: <16763926cad112e259e66c24864cdacbc83b6983.1622994395.git.balaton@eik.bme.hu> In-Reply-To: References: From: BALATON Zoltan Subject: [RFC PATCH 1/5] Misc VOF fixes Date: Sun, 06 Jun 2021 17:46:35 +0200 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org X-Spam-Probability: 8% Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=152.66.115.2; envelope-from=balaton@eik.bme.hu; helo=zero.eik.bme.hu X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: BALATON Zoltan --- hw/ppc/vof.c | 11 +++++++---- pc-bios/vof.bin | Bin 3784 -> 3784 bytes pc-bios/vof/entry.S | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/hw/ppc/vof.c b/hw/ppc/vof.c index a283b7d251..ac95be9666 100644 --- a/hw/ppc/vof.c +++ b/hw/ppc/vof.c @@ -144,12 +144,15 @@ static uint32_t vof_finddevice(const void *fdt, uint3= 2_t nodeaddr) char fullnode[VOF_MAX_PATH]; uint32_t ret =3D -1; int offset; + gchar *p; =20 if (readstr(nodeaddr, fullnode, sizeof(fullnode))) { return (uint32_t) ret; } =20 - offset =3D fdt_path_offset(fdt, fullnode); + p =3D g_ascii_strdown(fullnode, -1); + offset =3D fdt_path_offset(fdt, p); + g_free(p); if (offset >=3D 0) { ret =3D fdt_get_phandle(fdt, offset); } @@ -160,14 +163,14 @@ static uint32_t vof_finddevice(const void *fdt, uint3= 2_t nodeaddr) static const void *getprop(const void *fdt, int nodeoff, const char *propn= ame, int *proplen, bool *write0) { - const char *unit, *prop; + const char *unit, *prop =3D fdt_getprop(fdt, nodeoff, propname, prople= n); =20 /* * The "name" property is not actually stored as a property in the FDT, * we emulate it by returning a pointer to the node's name and adjust * proplen to include only the name but not the unit. */ - if (strcmp(propname, "name") =3D=3D 0) { + if (!prop && strcmp(propname, "name") =3D=3D 0) { prop =3D fdt_get_name(fdt, nodeoff, proplen); if (!prop) { *proplen =3D 0; @@ -193,7 +196,7 @@ static const void *getprop(const void *fdt, int nodeoff= , const char *propname, if (write0) { *write0 =3D false; } - return fdt_getprop(fdt, nodeoff, propname, proplen); + return prop; } =20 static uint32_t vof_getprop(const void *fdt, uint32_t nodeph, uint32_t pna= me, diff --git a/pc-bios/vof.bin b/pc-bios/vof.bin index 7e4c3742deae3c1904f4b2bf03ef72576b12d532..1ec670be82134adcb5ae128732a= ff6e371281360 100755 GIT binary patch delta 14 VcmX>hdqQ@D4kKgpW?jbFyZ|U11hoJF delta 14 VcmX>hdqQ@D4kP31&AN=3DUc>yYn1swnY diff --git a/pc-bios/vof/entry.S b/pc-bios/vof/entry.S index 569688714c..f8066775ec 100644 --- a/pc-bios/vof/entry.S +++ b/pc-bios/vof/entry.S @@ -30,7 +30,7 @@ ENTRY(_prom_entry) bl prom_entry nop mtlr %r31 - ld %r31,104(%r1) + lwz %r31,104(%r1) addi %r1,%r1,112 blr =20 --=20 2.21.4 From nobody Sun May 19 00:47:38 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=eik.bme.hu ARC-Seal: i=1; a=rsa-sha256; t=1622997505; cv=none; d=zohomail.com; s=zohoarc; b=jISs2Y0fW0NDcBkFzyg4RxWnCYHJpBbp64OGEeCzdFefnLwogeTpaYR71YovbdvJo/J7rqS4dRXusnMyns/NJFBkn+LpmH3v2Z8OuvfBeLIcg7lE+1wI73KVqykCiJatVreMZBXih00nI/3di/c4UpM972X0WtDf0HC85XAee/I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1622997505; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=gdW0gi+apv22uvEILtxOMRYLRlOAzrXFxtNVLI5RapM=; b=NlDhoA1Gf+Lx+U/rvJyw+ZgHT3we1mR0XxcClmZ9ewixxKdPsreyIbUlx1FI3NEPkIk/2yy3W9wIVqUJATWGtzQdLXaslhh8+JZ4zJ/tRtpjgeO0RAt07FtYbSXXOhCZF5Ym7JnwrO+USaxtSpKpIdxIJRwIbJEKWo07raWR2no= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1622997505400627.4259047916554; Sun, 6 Jun 2021 09:38:25 -0700 (PDT) Received: from localhost ([::1]:35710 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lpvn6-0001NM-4b for importer@patchew.org; Sun, 06 Jun 2021 12:38:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33222) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpvlZ-00072X-MH; Sun, 06 Jun 2021 12:36:49 -0400 Received: from zero.eik.bme.hu ([2001:738:2001:2001::2001]:34467) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpvlV-0004Rg-Rt; Sun, 06 Jun 2021 12:36:49 -0400 Received: from zero.eik.bme.hu (blah.eik.bme.hu [152.66.115.182]) by localhost (Postfix) with SMTP id 2CF03746FEB; Sun, 6 Jun 2021 18:36:41 +0200 (CEST) Received: by zero.eik.bme.hu (Postfix, from userid 432) id AA588746358; Sun, 6 Jun 2021 18:36:40 +0200 (CEST) Message-Id: <7ef9d2058fab88cc83c54e0482eeae8e275f0069.1622994395.git.balaton@eik.bme.hu> In-Reply-To: References: From: BALATON Zoltan Subject: [RFC PATCH 2/5] ppc/pegasos2: Introduce Pegasos2MachineState structure Date: Sun, 06 Jun 2021 17:46:35 +0200 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org X-Spam-Probability: 8% Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2001:738:2001:2001::2001; envelope-from=balaton@eik.bme.hu; helo=zero.eik.bme.hu X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Add own machine state structure which will be used to store state needed for firmware emulation. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- 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 @@ =20 #define BUS_FREQ_HZ 133333333 =20 +#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 =3D opaque; @@ -51,9 +60,9 @@ static void pegasos2_cpu_reset(void *opaque) =20 static void pegasos2_init(MachineState *machine) { - PowerPCCPU *cpu =3D NULL; + Pegasos2MachineState *pm =3D PEGASOS2_MACHINE(machine); + CPUPPCState *env; MemoryRegion *rom =3D 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; =20 /* init CPU */ - cpu =3D POWERPC_CPU(cpu_create(machine->cpu_type)); - if (PPC_INPUT(&cpu->env) !=3D PPC_FLAGS_INPUT_6xx) { + pm->cpu =3D POWERPC_CPU(cpu_create(machine->cpu_type)); + env =3D &pm->cpu->env; + if (PPC_INPUT(env) !=3D PPC_FLAGS_INPUT_6xx) { error_report("Incompatible CPU, only 6xx bus supported"); exit(1); } =20 /* 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); =20 /* RAM */ memory_region_add_subregion(get_system_memory(), 0, machine->ram); @@ -96,16 +106,16 @@ static void pegasos2_init(MachineState *machine) g_free(filename); =20 /* Marvell Discovery II system controller */ - mv =3D DEVICE(sysbus_create_simple(TYPE_MV64361, -1, - ((qemu_irq *)cpu->env.irq_inputs)[PPC6xx_INPUT_INT= ])); - pci_bus =3D mv64361_get_pci_bus(mv, 1); + pm->mv =3D DEVICE(sysbus_create_simple(TYPE_MV64361, -1, + ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_IN= T])); + pci_bus =3D mv64361_get_pci_bus(pm->mv, 1); =20 /* VIA VT8231 South Bridge (multifunction PCI device) */ /* VT8231 function 0: PCI-to-ISA Bridge */ dev =3D pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0), tru= e, 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)); =20 /* VT8231 function 1: IDE Controller */ dev =3D 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); } =20 -static void pegasos2_machine(MachineClass *mc) +static void pegasos2_machine_class_init(ObjectClass *oc, void *data) { + MachineClass *mc =3D MACHINE_CLASS(oc); + mc->desc =3D "Genesi/bPlan Pegasos II"; mc->init =3D pegasos2_init; mc->block_default_type =3D IF_IDE; @@ -141,4 +153,16 @@ static void pegasos2_machine(MachineClass *mc) mc->default_ram_size =3D 512 * MiB; } =20 -DEFINE_MACHINE("pegasos2", pegasos2_machine) +static const TypeInfo pegasos2_machine_info =3D { + .name =3D TYPE_PEGASOS2_MACHINE, + .parent =3D TYPE_MACHINE, + .class_init =3D pegasos2_machine_class_init, + .instance_size =3D sizeof(Pegasos2MachineState), +}; + +static void pegasos2_machine_register_types(void) +{ + type_register_static(&pegasos2_machine_info); +} + +type_init(pegasos2_machine_register_types) --=20 2.21.4 From nobody Sun May 19 00:47:38 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=eik.bme.hu ARC-Seal: i=1; a=rsa-sha256; t=1622997516; cv=none; d=zohomail.com; s=zohoarc; b=XLksuNGB/Q46rijACiGnnZ1L928NlEQuqink0RfpaP4p8KAU1MmJ+LewhwlI2MW94UxSJ0WK7HQngoEv6QIdaFWY/7zqRprElBbB63GQdVqZPnYrTIdzQVwnT9ay5vqMQAWInv4eZptXyNtBTT6atCnrumkbl8OxWa/0gQY7oIY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1622997516; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Ks0sIIFW897CyetW4+3Z+EjEl7Rp7+WVSlPMwHwS044=; b=JCamtwHOX+wDRuAUE2SqAIQEnXtfjhDuGjE66SGrEULaQxtCpyh2KuoADtu0+D+CqNnYUJyhBQslrEUxgI/9NCvs7B8JzpNS+FTByagDA6jgrU4Awbs0xBzX5WbH9iFAF7XGQBeBpCWNMuZEQbqH/piHciW0qMy7Brhpw1JxSWE= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1622997516250435.37438743449945; Sun, 6 Jun 2021 09:38:36 -0700 (PDT) Received: from localhost ([::1]:36426 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lpvnG-0001qA-S6 for importer@patchew.org; Sun, 06 Jun 2021 12:38:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33244) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpvlb-00075g-5o; Sun, 06 Jun 2021 12:36:51 -0400 Received: from zero.eik.bme.hu ([152.66.115.2]:18998) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpvlZ-0004Up-I9; Sun, 06 Jun 2021 12:36:50 -0400 Received: from zero.eik.bme.hu (blah.eik.bme.hu [152.66.115.182]) by localhost (Postfix) with SMTP id 275CD7456E3; Sun, 6 Jun 2021 18:36:41 +0200 (CEST) Received: by zero.eik.bme.hu (Postfix, from userid 432) id ADA4674639A; Sun, 6 Jun 2021 18:36:40 +0200 (CEST) Message-Id: <72781d9157bf771bbf1c777f77ba95ae6d214094.1622994395.git.balaton@eik.bme.hu> In-Reply-To: References: From: BALATON Zoltan Subject: [RFC PATCH 3/5] target/ppc: Allow virtual hypervisor on CPU without HV Date: Sun, 06 Jun 2021 17:46:35 +0200 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org X-Spam-Probability: 8% Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=152.66.115.2; envelope-from=balaton@eik.bme.hu; helo=zero.eik.bme.hu X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" 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 --- 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 =3D 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 =3D SDR_64_HTABORG | SDR_64_HTABSIZE; --=20 2.21.4 From nobody Sun May 19 00:47:38 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=eik.bme.hu ARC-Seal: i=1; a=rsa-sha256; t=1622997800; cv=none; d=zohomail.com; s=zohoarc; b=RQYk9zyt4rJ3DKmCSjp3UHmZRJ+0Oi+lQCncAowHSXCSNoKeUDNBp8s4v+Kc1ivvuvKVk56jNZh8Bj4qoeI6r+ZTXLG1I+SW3k+Rq7VlYFN+ZDj4F6eUCb1xzq6n3aYa911Aqx2O4u17uN3xoDY0mR75PzMd9weN/16Qoh/ctSs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1622997800; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=8cx6R2si9XMhdeexTt/ftiqIQ8UCtK4AyJMUe1oX4oY=; b=n2AMzoVtgQ0OyiFMR5h94WmNEn96AHIZo2hbi1SB9H5/28ityDqsgoMl9drVpbH53WGAQ9Kp4V55sQ19kFOf1PVce9rhz6QbkVLoaaKMhFIruEFXYXA+6CYwsXoKK9yR1VJQnfEeWxz+3DmuTYyDJyiDu0piTIDANd+kh0CTKmg= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1622997800003334.781051689597; Sun, 6 Jun 2021 09:43:20 -0700 (PDT) Received: from localhost ([::1]:45908 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lpvrq-00006N-Un for importer@patchew.org; Sun, 06 Jun 2021 12:43:18 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33246) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpvlc-0007C5-RH; Sun, 06 Jun 2021 12:36:52 -0400 Received: from zero.eik.bme.hu ([2001:738:2001:2001::2001]:38292) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpvlV-0004Re-QP; Sun, 06 Jun 2021 12:36:52 -0400 Received: from zero.eik.bme.hu (blah.eik.bme.hu [152.66.115.182]) by localhost (Postfix) with SMTP id 0A33A746FE0; Sun, 6 Jun 2021 18:36:41 +0200 (CEST) Received: by zero.eik.bme.hu (Postfix, from userid 432) id B13C674645F; Sun, 6 Jun 2021 18:36:40 +0200 (CEST) Message-Id: <53e3f069ab536bc2d0c6b3e39418bc85357631ad.1622994395.git.balaton@eik.bme.hu> In-Reply-To: References: From: BALATON Zoltan Subject: [RFC PATCH 4/5] ppc/pegasos2: Use Virtual Open Firmware as firmware replacement Date: Sun, 06 Jun 2021 17:46:35 +0200 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org X-Spam-Probability: 10% Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2001:738:2001:2001::2001; envelope-from=balaton@eik.bme.hu; helo=zero.eik.bme.hu X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" 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 imlements 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 --- hw/ppc/Kconfig | 1 + hw/ppc/pegasos2.c | 622 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 621 insertions(+), 2 deletions(-) diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig index b895720b28..0eb48128fe 100644 --- a/hw/ppc/Kconfig +++ b/hw/ppc/Kconfig @@ -75,6 +75,7 @@ config PEGASOS2 select VT82C686 select IDE_VIA select SMBUS_EEPROM + select VOF # This should come with VT82C686 select ACPI_X86 =20 diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index 07971175c9..91e5fa8fbe 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -34,13 +34,36 @@ #include "trace.h" #include "qemu/datadir.h" #include "sysemu/device_tree.h" +#include "hw/ppc/vof.h" =20 -#define PROM_FILENAME "pegasos2.rom" +#include + +#define PROM_FILENAME "vof.bin" #define PROM_ADDR 0xfff00000 #define PROM_SIZE 0x80000 =20 +#define KVMPPC_HCALL_BASE 0xf000 +#define KVMPPC_H_VOF_CLIENT (KVMPPC_HCALL_BASE + 0x5) + +/* Copied from SLOF, and 4K is definitely not enough for GRUB */ +#define OF_STACK_SIZE 0x8000 + +#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 =20 +#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) =20 @@ -48,14 +71,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; }; =20 +static void *build_fdt(MachineState *machine, int *fdt_size); + static void pegasos2_cpu_reset(void *opaque) { PowerPCCPU *cpu =3D opaque; + Pegasos2MachineState *pm =3D PEGASOS2_MACHINE(current_machine); =20 cpu_reset(CPU(cpu)); cpu->env.spr[SPR_HID1] =3D 7ULL << 28; + if (pm->vof) { + cpu->env.gpr[1] =3D 2 * OF_STACK_SIZE - 0x20; + cpu->env.nip =3D 0x100; + } } =20 static void pegasos2_init(MachineState *machine) @@ -92,18 +127,24 @@ static void pegasos2_init(MachineState *machine) error_report("Could not find firmware '%s'", fwname); exit(1); } + if (!machine->firmware && !pm->vof) { + pm->vof =3D g_malloc0(sizeof(*pm->vof)); + } memory_region_init_rom(rom, NULL, "pegasos2.rom", PROM_SIZE, &error_fa= tal); memory_region_add_subregion(get_system_memory(), PROM_ADDR, rom); sz =3D load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (sz <=3D 0) { - sz =3D load_image_targphys(filename, PROM_ADDR, PROM_SIZE); + sz =3D load_image_targphys(filename, pm->vof ? 0 : PROM_ADDR, PROM= _SIZE); } if (sz <=3D 0 || sz > PROM_SIZE) { error_report("Could not load firmware '%s'", filename); exit(1); } g_free(filename); + if (pm->vof) { + pm->vof->fw_size =3D sz; + } =20 /* Marvell Discovery II system controller */ pm->mv =3D DEVICE(sysbus_create_simple(TYPE_MV64361, -1, @@ -137,20 +178,179 @@ static void pegasos2_init(MachineState *machine) =20 /* other PC hardware */ pci_vga_init(pci_bus); + + if (machine->kernel_filename) { + sz =3D load_elf(machine->kernel_filename, NULL, NULL, NULL, + &pm->kernel_entry, &pm->kernel_addr, NULL, NULL, 1, + PPC_ELF_MACHINE, 0, 0); + if (sz <=3D 0) { + error_report("Could not load kernel '%s'", + machine->kernel_filename); + exit(1); + } + pm->kernel_size =3D 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 =3D (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 =3D PEGASOS2_MACHINE(machine); + AddressSpace *as =3D 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, OF_STACK_SIZE, OF_STACK_SIZE) =3D=3D -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) =3D=3D -1)= { + error_report("Memory for kernel is in use"); + exit(1); + } + fdt =3D build_fdt(machine, &sz); + /* FIXME: VOF assumes entry is same as load address */ + d[0] =3D cpu_to_be64(pm->kernel_entry); + d[1] =3D 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 =3D fdt; + + vof_build_dt(fdt, pm->vof); + vof_client_open_store(fdt, pm->vof, "/chosen", "stdout", "/failsafe"); + pm->cpu->vhyp =3D PPC_VIRTUAL_HYPERVISOR(machine); +} + +static void pegasos2_hypercall(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) +{ + Pegasos2MachineState *pm =3D PEGASOS2_MACHINE(vhyp); + CPUPPCState *env =3D &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]=3D1\n"= ); + env->gpr[3] =3D H_PRIVILEGE; + } else if (env->gpr[3] =3D=3D KVMPPC_H_VOF_CLIENT) { + int ret =3D vof_client_call(MACHINE(pm), pm->vof, pm->fdt_blob, + env->gpr[4]); + env->gpr[3] =3D (ret ? H_PARAMETER : H_SUCCESS); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "Unsupported hypercall " TARGET_FMT= _lx + "\n", env->gpr[3]); + env->gpr[3] =3D -1; + } +} + +static void vhyp_nop(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) +{ } =20 static void pegasos2_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc =3D MACHINE_CLASS(oc); + PPCVirtualHypervisorClass *vhc =3D PPC_VIRTUAL_HYPERVISOR_CLASS(oc); =20 mc->desc =3D "Genesi/bPlan Pegasos II"; mc->init =3D pegasos2_init; + mc->reset =3D pegasos2_machine_reset; mc->block_default_type =3D IF_IDE; mc->default_boot_order =3D "cd"; mc->default_display =3D "std"; mc->default_cpu_type =3D POWERPC_CPU_TYPE_NAME("7400_v2.9"); mc->default_ram_id =3D "pegasos2.ram"; mc->default_ram_size =3D 512 * MiB; + + vhc->hypercall =3D pegasos2_hypercall; + vhc->cpu_exec_enter =3D vhyp_nop; + vhc->cpu_exec_exit =3D vhyp_nop; } =20 static const TypeInfo pegasos2_machine_info =3D { @@ -158,6 +358,10 @@ static const TypeInfo pegasos2_machine_info =3D { .parent =3D TYPE_MACHINE, .class_init =3D pegasos2_machine_class_init, .instance_size =3D sizeof(Pegasos2MachineState), + .interfaces =3D (InterfaceInfo[]) { + { TYPE_PPC_VIRTUAL_HYPERVISOR }, + { } + }, }; =20 static void pegasos2_machine_register_types(void) @@ -166,3 +370,417 @@ static void pegasos2_machine_register_types(void) } =20 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 =3D 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] =3D cpu_to_be32(7); + cells[1] =3D 0; + qemu_fdt_setprop(fi->fdt, name->str, "interrupts", + cells, 2 * sizeof(cells[0])); + cells[0] =3D cpu_to_be32(1); + cells[1] =3D cpu_to_be32(0x3bc); + cells[2] =3D 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] =3D cpu_to_be32(6); + cells[1] =3D 0; + qemu_fdt_setprop(fi->fdt, name->str, "interrupts", + cells, 2 * sizeof(cells[0])); + cells[0] =3D cpu_to_be32(1); + cells[1] =3D cpu_to_be32(0x3f0); + cells[2] =3D 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] =3D cpu_to_be32(1); + cells[1] =3D cpu_to_be32(0x40); + cells[2] =3D 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] =3D cpu_to_be32(8); + cells[1] =3D 0; + qemu_fdt_setprop(fi->fdt, name->str, "interrupts", + cells, 2 * sizeof(cells[0])); + cells[0] =3D cpu_to_be32(1); + cells[1] =3D cpu_to_be32(0x70); + cells[2] =3D 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] =3D cpu_to_be32(1); + cells[1] =3D 0; + qemu_fdt_setprop(fi->fdt, name->str, "interrupts", + cells, 2 * sizeof(cells[0])); + cells[0] =3D cpu_to_be32(1); + cells[1] =3D cpu_to_be32(0x60); + cells[2] =3D 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] =3D cpu_to_be32(1); + cells[1] =3D cpu_to_be32(0x60); + cells[2] =3D 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] =3D cpu_to_be32(3); + cells[1] =3D 0; + qemu_fdt_setprop(fi->fdt, name->str, "interrupts", + cells, 2 * sizeof(cells[0])); + cells[0] =3D cpu_to_be32(1); + cells[1] =3D cpu_to_be32(0x2f8); + cells[2] =3D 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[] =3D { + { "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 =3D opaque; + GString *node =3D g_string_new(NULL); + uint32_t cells[(PCI_NUM_REGIONS + 1) * 5]; + int i, j; + const char *name =3D NULL; + g_autofree const gchar *pn =3D g_strdup_printf("pci%x,%x", + pci_get_word(&d->config[PCI_VENDOR_ID= ]), + pci_get_word(&d->config[PCI_DEVICE_ID= ])); + + for (i =3D 0; device_map[i].id; i++) { + if (!strcmp(pn, device_map[i].id)) { + name =3D 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 =3D { fi->fdt, node->str }; + device_map[i].dtf(bus, d, &cfi); + } + cells[0] =3D cpu_to_be32(d->devfn << 8); + cells[1] =3D 0; + cells[2] =3D 0; + cells[3] =3D 0; + cells[4] =3D 0; + j =3D 5; + for (i =3D 0; i < PCI_NUM_REGIONS; i++) { + if (!d->io_regions[i].size) { + continue; + } + cells[j] =3D 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] |=3D cpu_to_be32(1 << 24); + } else { + cells[j] |=3D cpu_to_be32(2 << 24); + if (d->io_regions[i].type & PCI_BASE_ADDRESS_MEM_PREFETCH) { + cells[j] |=3D cpu_to_be32(4 << 28); + } + } + cells[j + 1] =3D 0; + cells[j + 2] =3D 0; + cells[j + 3] =3D cpu_to_be32(d->io_regions[i].size >> 32); + cells[j + 4] =3D cpu_to_be32(d->io_regions[i].size); + j +=3D 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] =3D 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] && 0= xff); + 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 =3D PEGASOS2_MACHINE(machine); + PowerPCCPU *cpu =3D pm->cpu; + PCIBus *pci_bus; + FDTInfo fi; + uint32_t cells[16]; + void *fdt =3D create_device_tree(fdt_size); + + fi.fdt =3D 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] =3D 0; + cells[1] =3D 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] =3D cpu_to_be32(PCI0_MEM_BASE); + cells[1] =3D cpu_to_be32(PCI0_MEM_SIZE); + qemu_fdt_setprop(fdt, "/pci@c0000000", "reg", cells, 2 * sizeof(cells[= 0])); + cells[0] =3D cpu_to_be32(0x01000000); + cells[1] =3D 0; + cells[2] =3D 0; + cells[3] =3D cpu_to_be32(PCI0_IO_BASE); + cells[4] =3D 0; + cells[5] =3D cpu_to_be32(PCI0_IO_SIZE); + cells[6] =3D cpu_to_be32(0x02000000); + cells[7] =3D 0; + cells[8] =3D cpu_to_be32(PCI0_MEM_BASE); + cells[9] =3D cpu_to_be32(PCI0_MEM_BASE); + cells[10] =3D 0; + cells[11] =3D 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 =3D "/pci@c0000000"; + pci_bus =3D 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] =3D 0; + cells[1] =3D 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] =3D cpu_to_be32(PCI1_MEM_BASE); + cells[1] =3D 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-acknowledg= e", + 0xf1000cb4); + cells[0] =3D cpu_to_be32(0x01000000); + cells[1] =3D 0; + cells[2] =3D 0; + cells[3] =3D cpu_to_be32(PCI1_IO_BASE); + cells[4] =3D 0; + cells[5] =3D cpu_to_be32(PCI1_IO_SIZE); + cells[6] =3D cpu_to_be32(0x02000000); + cells[7] =3D 0; + cells[8] =3D cpu_to_be32(PCI1_MEM_BASE); + cells[9] =3D cpu_to_be32(PCI1_MEM_BASE); + cells[10] =3D 0; + cells[11] =3D 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 =3D "/pci@80000000"; + pci_bus =3D 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"); + + 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); + 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 =3D "/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] =3D 0; + cells[1] =3D 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] =3D 0; + cells[1] =3D 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; +} --=20 2.21.4 From nobody Sun May 19 00:47:38 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=eik.bme.hu ARC-Seal: i=1; a=rsa-sha256; t=1622997664; cv=none; d=zohomail.com; s=zohoarc; b=TIv1ZXd2WRYNYjWe0Hx78hNyb/wFruZGlO0QhAFeY44uU6B+3FXDMW4612aYw1Sih7Dyt/jtnqwHdQH6TYJACQBMRQJJZhwAyORUbofffEnhK//KfBiM+/vkufrfUmONvGhoQfBnmUQNZZOgS7Hb3HS/+tLBlqtsgf+cPckuAOU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1622997664; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=7lWHmO/czgB8xsyPtmBIp8izMqTTI0RBTXyC/k2CRnQ=; b=a3VVP+KNJ6VLKBxdqOFXF3lBGpIBVK6BnbNraqszbSa8+zjMoxj08KtdgMn2j1d6dc8Xb9tuULbQU3LgrMRyWPj88gH80zFIEWbpOQut+dV5zBAX3O8QwT60tZwSPEaevF6kjNx8LGKAuZnZtB6mM8sZ0BPS7D+bbqZ/Iky2mMY= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1622997664502322.52656446365665; Sun, 6 Jun 2021 09:41:04 -0700 (PDT) Received: from localhost ([::1]:41756 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lpvpf-0005d7-2Y for importer@patchew.org; Sun, 06 Jun 2021 12:41:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:33226) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpvlZ-00072j-V8; Sun, 06 Jun 2021 12:36:49 -0400 Received: from zero.eik.bme.hu ([152.66.115.2]:56224) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lpvlV-0004Ri-Ry; Sun, 06 Jun 2021 12:36:49 -0400 Received: from zero.eik.bme.hu (blah.eik.bme.hu [152.66.115.182]) by localhost (Postfix) with SMTP id F0EF9746FDE; Sun, 6 Jun 2021 18:36:40 +0200 (CEST) Received: by zero.eik.bme.hu (Postfix, from userid 432) id B45B8746FCF; Sun, 6 Jun 2021 18:36:40 +0200 (CEST) Message-Id: In-Reply-To: References: From: BALATON Zoltan Subject: [RFC PATCH 5/5] ppc/pegasos2: Implement some RTAS functions with VOF Date: Sun, 06 Jun 2021 17:46:35 +0200 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org X-Spam-Probability: 10% Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=152.66.115.2; envelope-from=balaton@eik.bme.hu; helo=zero.eik.bme.hu X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexey Kardashevskiy , David Gibson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" 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 --- default-configs/devices/ppc-softmmu.mak | 2 +- hw/ppc/pegasos2.c | 108 ++++++++++++++++++++++++ 2 files changed, 109 insertions(+), 1 deletion(-) diff --git a/default-configs/devices/ppc-softmmu.mak b/default-configs/devi= ces/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=3Dy CONFIG_MAC_OLDWORLD=3Dy CONFIG_MAC_NEWWORLD=3Dy =20 -CONFIG_PEGASOS2=3Dn +CONFIG_PEGASOS2=3Dy =20 # For PReP CONFIG_PREP=3Dy diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index 91e5fa8fbe..cb2be27394 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -43,6 +43,7 @@ #define PROM_SIZE 0x80000 =20 #define KVMPPC_HCALL_BASE 0xf000 +#define KVMPPC_H_RTAS (KVMPPC_HCALL_BASE + 0x0) #define KVMPPC_H_VOF_CLIENT (KVMPPC_HCALL_BASE + 0x5) =20 /* Copied from SLOF, and 4K is definitely not enough for GRUB */ @@ -198,6 +199,30 @@ static void pegasos2_init(MachineState *machine) } } =20 +static uint32_t pegasos2_pci_config_read(AddressSpace *as, int bus, + uint32_t addr, uint32_t len) +{ + hwaddr pcicfg =3D (bus ? 0xf1000c78 : 0xf1000cf8); + uint32_t val =3D 0xffffffff; + + stl_le_phys(as, pcicfg, addr | BIT(31)); + switch (len) { + case 4: + val =3D ldl_le_phys(as, pcicfg + 4); + break; + case 2: + val =3D lduw_le_phys(as, pcicfg + 4); + break; + case 1: + val =3D 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) { @@ -307,6 +332,87 @@ static void pegasos2_machine_reset(MachineState *machi= ne) pm->cpu->vhyp =3D PPC_VIRTUAL_HYPERVISOR(machine); } =20 +enum pegasos2_rtas_tokens { + RTAS_RESTART_RTAS =3D 0, + RTAS_NVRAM_FETCH =3D 1, + RTAS_NVRAM_STORE =3D 2, + RTAS_GET_TIME_OF_DAY =3D 3, + RTAS_SET_TIME_OF_DAY =3D 4, + RTAS_EVENT_SCAN =3D 6, + RTAS_CHECK_EXCEPTION =3D 7, + RTAS_READ_PCI_CONFIG =3D 8, + RTAS_WRITE_PCI_CONFIG =3D 9, + RTAS_DISPLAY_CHARACTER =3D 10, + RTAS_SET_INDICATOR =3D 11, + RTAS_POWER_OFF =3D 17, + RTAS_SUSPEND =3D 18, + RTAS_HIBERNATE =3D 19, + RTAS_SYSTEM_REBOOT =3D 20, +}; + +static target_ulong pegasos2_rtas(PowerPCCPU *cpu, Pegasos2MachineState *p= m, + target_ulong args_real) +{ + AddressSpace *as =3D CPU(cpu)->as; + uint32_t token =3D ldl_be_phys(as, args_real); + uint32_t nargs =3D ldl_be_phys(as, args_real + 4); + uint32_t nrets =3D ldl_be_phys(as, args_real + 8); + uint32_t args =3D args_real + 12; + uint32_t rets =3D 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 !=3D 2 || nrets !=3D 2) { + stl_be_phys(as, rets, -1); + return H_PARAMETER; + } + addr =3D ldl_be_phys(as, args); + len =3D ldl_be_phys(as, args + 4); + val =3D 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 !=3D 3 || nrets !=3D 1) { + stl_be_phys(as, rets, -1); + return H_PARAMETER; + } + addr =3D ldl_be_phys(as, args); + len =3D ldl_be_phys(as, args + 4); + val =3D 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 !=3D 1 || nrets !=3D 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=3D%u, rets= =3D%u)\n", + token, nargs, nrets); + stl_be_phys(as, rets, 0); + return H_SUCCESS; + } +} + static void pegasos2_hypercall(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) { Pegasos2MachineState *pm =3D PEGASOS2_MACHINE(vhyp); @@ -318,6 +424,8 @@ static void pegasos2_hypercall(PPCVirtualHypervisor *vh= yp, PowerPCCPU *cpu) if (msr_pr) { qemu_log_mask(LOG_GUEST_ERROR, "Hypercall made with MSR[PR]=3D1\n"= ); env->gpr[3] =3D H_PRIVILEGE; + } else if (env->gpr[3] =3D=3D KVMPPC_H_RTAS) { + env->gpr[3] =3D pegasos2_rtas(cpu, pm, env->gpr[4]); } else if (env->gpr[3] =3D=3D KVMPPC_H_VOF_CLIENT) { int ret =3D vof_client_call(MACHINE(pm), pm->vof, pm->fdt_blob, env->gpr[4]); --=20 2.21.4