From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44708) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bsMpo-0005ZM-Ui for qemu-devel@nongnu.org; Fri, 07 Oct 2016 00:32:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bsMpm-0007k7-Mo for qemu-devel@nongnu.org; Fri, 07 Oct 2016 00:32:36 -0400 Date: Fri, 7 Oct 2016 15:16:45 +1100 From: David Gibson Message-ID: <20161007041645.GQ18490@umbus.fritz.box> References: <1475479496-16158-1-git-send-email-clg@kaod.org> <1475479496-16158-2-git-send-email-clg@kaod.org> <20161007041448.GP18490@umbus.fritz.box> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="U/5EjKfnYgGK6hcj" Content-Disposition: inline In-Reply-To: <20161007041448.GP18490@umbus.fritz.box> Subject: Re: [Qemu-devel] [PATCH v4 01/20] ppc/pnv: add skeleton PowerNV platform List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: =?iso-8859-1?Q?C=E9dric?= Le Goater Cc: qemu-ppc@nongnu.org, Benjamin Herrenschmidt , qemu-devel@nongnu.org --U/5EjKfnYgGK6hcj Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Oct 07, 2016 at 03:14:48PM +1100, David Gibson wrote: > On Mon, Oct 03, 2016 at 09:24:37AM +0200, C=E9dric Le Goater wrote: > > From: Benjamin Herrenschmidt > >=20 > > The goal is to emulate a PowerNV system at the level of the skiboot > > firmware, which loads the OS and provides some runtime services. Power > > Systems have a lower firmware (HostBoot) that does low level system > > initialization, like DRAM training. This is beyond the scope of what > > qemu will address in a PowerNV guest. > >=20 > > No devices yet, not even an interrupt controller. Just to get started, > > some RAM to load the skiboot firmware, the kernel and initrd. The > > device tree is fully created in the machine reset op. > >=20 > > Signed-off-by: Benjamin Herrenschmidt > > [clg: - updated for qemu-2.7 > > - replaced fprintf by error_report > > - used a common definition of _FDT macro > > - removed VMStateDescription as migration is not yet supported > > - added IBM Copyright statements > > - reworked kernel_filename handling > > - merged PnvSystem and sPowerNVMachineState > > - removed PHANDLE_XICP > > - added ppc_create_page_sizes_prop helper > > - removed nmi support > > - removed kvm support > > - updated powernv machine to version 2.8 > > - removed chips and cpus, They will be provided in another patches > > - added a machine reset routine to initialize the device tree (al= so) > > - french has a squelette and english a skeleton. > > - improved commit log. > > - reworked prototypes parameters > > - added a check on the ram size (thanks to Michael Ellerman) > > - fixed chip-id cell > > - changed MAX_CPUS to 2048 > > - simplified memory node creation to one node only > > - removed machine version > > - rewrote the device tree creation with the fdt "rw" routines > > - s/sPowerNVMachineState/PnvMachineState/ > > - etc.] > > Signed-off-by: C=E9dric Le Goater > > --- > > Changes since v3: > >=20 > > - fixed printf format for hwaddr > > - used fdt_pack() before writing the tree in memory=20 > > - removed the requirement on having a kernel loaded as running with > > just a firmware is fine. We will need to discuss the inclusion of > > the file skiboot.lid under qemu. >=20 > Yes, this isn't terribly useful without it. The normal procedure for > new roms is this: >=20 > 1. Get the upstream git tree for the ROM mirrored to qemu.org > 2. Add a git submodule under roms/ referencing the git mirror on > qemu.org > 3. Add a pre-built ROM binary to pc-bios/ > 4. Add a brief description of the ROM, including upstream git URL > to pc-bios/README >=20 > Steps 2, 3 & 4 can (and usually should) be a single commit. >=20 > This code is looking close enough, that having a usable rom image is > probably the last thing stopping merge, at least of these initial > patches. >=20 > Probably best to get underway with the rom inclusion ASAP. Sorry, forgot to add, with the exception of the ROM question, and the one tiny code nit: Reviewed-by: David Gibson >=20 > > Changes since v2: > >=20 > > - some more copyright header cleanups > > - remove fdt_addr field from PnvMachineState > >=20 > > Changes since v1: > >=20 > > - changed MAX_CPUS to 2048 > > - simplified memory node creation to one node only > > - removed machine version=20 > > - rewrote the device tree creation with the fdt "rw" routines > > - s/sPowerNVMachineState/PnvMachineState/ > > - block_default_type is back to IF_IDE because of the AHCI device > >=20 > > default-configs/ppc64-softmmu.mak | 1 + > > hw/ppc/Makefile.objs | 2 + > > hw/ppc/pnv.c | 223 ++++++++++++++++++++++++++++++= ++++++++ > > include/hw/ppc/pnv.h | 38 +++++++ > > 4 files changed, 264 insertions(+) > > create mode 100644 hw/ppc/pnv.c > > create mode 100644 include/hw/ppc/pnv.h > >=20 > > diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-= softmmu.mak > > index db5a4d6f5eea..67a9bcaa67fa 100644 > > --- a/default-configs/ppc64-softmmu.mak > > +++ b/default-configs/ppc64-softmmu.mak > > @@ -39,6 +39,7 @@ CONFIG_I8259=3Dy > > CONFIG_XILINX=3Dy > > CONFIG_XILINX_ETHLITE=3Dy > > CONFIG_PSERIES=3Dy > > +CONFIG_POWERNV=3Dy > > CONFIG_PREP=3Dy > > CONFIG_MAC=3Dy > > CONFIG_E500=3Dy > > diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs > > index 99a0d4e581bf..8105db7d5600 100644 > > --- a/hw/ppc/Makefile.objs > > +++ b/hw/ppc/Makefile.objs > > @@ -5,6 +5,8 @@ obj-$(CONFIG_PSERIES) +=3D spapr.o spapr_vio.o spapr_ev= ents.o > > obj-$(CONFIG_PSERIES) +=3D spapr_hcall.o spapr_iommu.o spapr_rtas.o > > obj-$(CONFIG_PSERIES) +=3D spapr_pci.o spapr_rtc.o spapr_drc.o spapr_r= ng.o > > obj-$(CONFIG_PSERIES) +=3D spapr_cpu_core.o > > +# IBM PowerNV > > +obj-$(CONFIG_POWERNV) +=3D pnv.o > > ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy) > > obj-y +=3D spapr_pci_vfio.o > > endif > > diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c > > new file mode 100644 > > index 000000000000..02fc4826baa4 > > --- /dev/null > > +++ b/hw/ppc/pnv.c > > @@ -0,0 +1,223 @@ > > +/* > > + * QEMU PowerPC PowerNV machine model > > + * > > + * Copyright (c) 2016, IBM Corporation. > > + * > > + * This library is free software; you can redistribute it and/or > > + * modify it under the terms of the GNU Lesser General Public > > + * License as published by the Free Software Foundation; either > > + * version 2 of the License, or (at your option) any later version. > > + * > > + * This library is distributed in the hope that it will be useful, > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + * Lesser General Public License for more details. > > + * > > + * You should have received a copy of the GNU Lesser General Public > > + * License along with this library; if not, see . > > + */ > > + > > +#include "qemu/osdep.h" > > +#include "qapi/error.h" > > +#include "sysemu/sysemu.h" > > +#include "sysemu/numa.h" > > +#include "hw/hw.h" > > +#include "target-ppc/cpu.h" > > +#include "qemu/log.h" > > +#include "hw/ppc/fdt.h" > > +#include "hw/ppc/ppc.h" > > +#include "hw/ppc/pnv.h" > > +#include "hw/loader.h" > > +#include "exec/address-spaces.h" > > +#include "qemu/cutils.h" > > + > > +#include > > + > > +#define FDT_MAX_SIZE 0x00100000 > > + > > +#define FW_FILE_NAME "skiboot.lid" > > +#define FW_LOAD_ADDR 0x0 > > +#define FW_MAX_SIZE 0x00400000 > > + > > +#define KERNEL_LOAD_ADDR 0x20000000 > > +#define INITRD_LOAD_ADDR 0x40000000 > > + > > +/* > > + * On Power Systems E880, the max cpus (threads) should be : > > + * 4 * 4 sockets * 12 cores * 8 threads =3D 1536 > > + * Let's make it 2^11 > > + */ > > +#define MAX_CPUS 2048 > > + > > +/* > > + * Memory nodes are created by hostboot, one for each range of memory > > + * that has a different "affinity". In practice, it means one range > > + * per chip. > > + */ > > +static void powernv_populate_memory_node(void *fdt, int chip_id, hwadd= r start, > > + hwaddr size) > > +{ > > + char *mem_name; > > + uint64_t mem_reg_property[2]; > > + int off; > > + > > + mem_reg_property[0] =3D cpu_to_be64(start); > > + mem_reg_property[1] =3D cpu_to_be64(size); > > + > > + mem_name =3D g_strdup_printf("memory@%"HWADDR_PRIx, start); > > + off =3D fdt_add_subnode(fdt, 0, mem_name); > > + g_free(mem_name); > > + > > + _FDT((fdt_setprop_string(fdt, off, "device_type", "memory"))); > > + _FDT((fdt_setprop(fdt, off, "reg", mem_reg_property, > > + sizeof(mem_reg_property)))); > > + _FDT((fdt_setprop_cell(fdt, off, "ibm,chip-id", chip_id))); > > +} > > + > > +static void *powernv_create_fdt(PnvMachineState *pnv, > > + const char *kernel_cmdline) > > +{ > > + void *fdt; > > + char *buf; > > + const char plat_compat[] =3D "qemu,powernv\0ibm,powernv"; > > + int off; > > + > > + fdt =3D g_malloc0(FDT_MAX_SIZE); > > + _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE))); > > + > > + /* Root node */ > > + _FDT((fdt_setprop_cell(fdt, 0, "#address-cells", 0x2))); > > + _FDT((fdt_setprop_cell(fdt, 0, "#size-cells", 0x2))); > > + _FDT((fdt_setprop_string(fdt, 0, "model", > > + "IBM PowerNV (emulated by qemu)"))); > > + _FDT((fdt_setprop(fdt, 0, "compatible", plat_compat, > > + sizeof(plat_compat)))); > > + > > + buf =3D qemu_uuid_unparse_strdup(&qemu_uuid); > > + _FDT((fdt_setprop_string(fdt, 0, "vm,uuid", buf))); > > + if (qemu_uuid_set) { > > + _FDT((fdt_property_string(fdt, "system-id", buf))); > > + } > > + g_free(buf); > > + > > + off =3D fdt_add_subnode(fdt, 0, "chosen"); > > + if (kernel_cmdline) { > > + _FDT((fdt_setprop_string(fdt, off, "bootargs", kernel_cmdline)= )); > > + } > > + > > + if (pnv->initrd_size) { > > + uint32_t start_prop =3D cpu_to_be32(pnv->initrd_base); > > + uint32_t end_prop =3D cpu_to_be32(pnv->initrd_base + pnv->init= rd_size); > > + > > + _FDT((fdt_setprop(fdt, off, "linux,initrd-start", > > + &start_prop, sizeof(start_prop)))); > > + _FDT((fdt_setprop(fdt, off, "linux,initrd-end", > > + &end_prop, sizeof(end_prop)))); > > + } > > + > > + /* Put all the memory in one node on chip 0 until we find a way to > > + * specify different ranges for each chip > > + */ > > + powernv_populate_memory_node(fdt, 0, 0, ram_size); >=20 > machine->ram_size is preferred over the ram_size global these days. > Doesn't matter that much, since this will be reworked for multiple > chips at some point anyway. >=20 > > + > > + return fdt; > > +} > > + > > +static void ppc_powernv_reset(void) > > +{ > > + MachineState *machine =3D MACHINE(qdev_get_machine()); > > + PnvMachineState *pnv =3D POWERNV_MACHINE(machine); > > + void *fdt; > > + > > + qemu_devices_reset(); > > + > > + fdt =3D powernv_create_fdt(pnv, machine->kernel_cmdline); > > + > > + /* Pack resulting tree */ > > + _FDT((fdt_pack(fdt))); > > + > > + cpu_physical_memory_write(POWERNV_FDT_ADDR, fdt, fdt_totalsize(fdt= )); > > +} > > + > > +static void ppc_powernv_init(MachineState *machine) > > +{ > > + PnvMachineState *pnv =3D POWERNV_MACHINE(machine); > > + ram_addr_t ram_size =3D machine->ram_size; > > + MemoryRegion *ram; > > + char *fw_filename; > > + long fw_size; > > + long kernel_size; > > + > > + /* allocate RAM */ > > + if (ram_size < (1 * G_BYTE)) { > > + error_report("Warning: skiboot may not work with < 1GB of RAM"= ); > > + } > > + > > + ram =3D g_new(MemoryRegion, 1); > > + memory_region_allocate_system_memory(ram, NULL, "ppc_powernv.ram", > > + ram_size); > > + memory_region_add_subregion(get_system_memory(), 0, ram); > > + > > + /* load skiboot firmware */ > > + if (bios_name =3D=3D NULL) { > > + bios_name =3D FW_FILE_NAME; > > + } > > + > > + fw_filename =3D qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); > > + > > + fw_size =3D load_image_targphys(fw_filename, FW_LOAD_ADDR, FW_MAX_= SIZE); > > + if (fw_size < 0) { > > + hw_error("qemu: could not load OPAL '%s'\n", fw_filename); > > + exit(1); > > + } > > + g_free(fw_filename); > > + > > + /* load kernel */ > > + kernel_size =3D load_image_targphys(machine->kernel_filename, > > + KERNEL_LOAD_ADDR, 0x2000000); > > + if (kernel_size < 0) { > > + hw_error("qemu: could not load kernel'%s'\n", machine->kernel_= filename); > > + exit(1); > > + } > > + > > + /* load initrd */ > > + if (machine->initrd_filename) { > > + pnv->initrd_base =3D INITRD_LOAD_ADDR; > > + pnv->initrd_size =3D load_image_targphys(machine->initrd_filen= ame, > > + pnv->initrd_base, 0x10000000); /* 12= 8MB max */ > > + if (pnv->initrd_size < 0) { > > + error_report("qemu: could not load initial ram disk '%s'", > > + machine->initrd_filename); > > + exit(1); > > + } > > + } > > +} > > + > > +static void powernv_machine_class_init(ObjectClass *oc, void *data) > > +{ > > + MachineClass *mc =3D MACHINE_CLASS(oc); > > + > > + mc->desc =3D "IBM PowerNV (Non-Virtualized)"; > > + mc->init =3D ppc_powernv_init; > > + mc->reset =3D ppc_powernv_reset; > > + mc->max_cpus =3D MAX_CPUS; > > + mc->block_default_type =3D IF_IDE; /* Pnv provides a AHCI device f= or > > + * storage */ > > + mc->no_parallel =3D 1; > > + mc->default_boot_order =3D NULL; > > + mc->default_ram_size =3D 1 * G_BYTE; > > +} > > + > > +static const TypeInfo powernv_machine_info =3D { > > + .name =3D TYPE_POWERNV_MACHINE, > > + .parent =3D TYPE_MACHINE, > > + .instance_size =3D sizeof(PnvMachineState), > > + .class_init =3D powernv_machine_class_init, > > +}; > > + > > +static void powernv_machine_register_types(void) > > +{ > > + type_register_static(&powernv_machine_info); > > +} > > + > > +type_init(powernv_machine_register_types) > > diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h > > new file mode 100644 > > index 000000000000..c8a73bc74267 > > --- /dev/null > > +++ b/include/hw/ppc/pnv.h > > @@ -0,0 +1,38 @@ > > +/* > > + * QEMU PowerPC PowerNV various definitions > > + * > > + * Copyright (c) 2014-2016 BenH, IBM Corporation. > > + * > > + * This library is free software; you can redistribute it and/or > > + * modify it under the terms of the GNU Lesser General Public > > + * License as published by the Free Software Foundation; either > > + * version 2 of the License, or (at your option) any later version. > > + * > > + * This library is distributed in the hope that it will be useful, > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + * Lesser General Public License for more details. > > + * > > + * You should have received a copy of the GNU Lesser General Public > > + * License along with this library; if not, see . > > + */ > > +#ifndef _PPC_PNV_H > > +#define _PPC_PNV_H > > + > > +#include "hw/boards.h" > > + > > +#define TYPE_POWERNV_MACHINE MACHINE_TYPE_NAME("powernv") > > +#define POWERNV_MACHINE(obj) \ > > + OBJECT_CHECK(PnvMachineState, (obj), TYPE_POWERNV_MACHINE) > > + > > +typedef struct PnvMachineState { > > + /*< private >*/ > > + MachineState parent_obj; > > + > > + uint32_t initrd_base; > > + long initrd_size; > > +} PnvMachineState; > > + > > +#define POWERNV_FDT_ADDR 0x01000000 > > + > > +#endif /* _PPC_PNV_H */ >=20 --=20 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 --U/5EjKfnYgGK6hcj Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCAAGBQJX9yGtAAoJEGw4ysog2bOSCjoP/RzONa3SHBcpqECOIQlqWeJC 3ROmLpjlvLY9fc6eGn+kVWt8LHCJEWx2UT9npVlmMXHz16jtXASREQ+uc5RYX7ET U0PfGzxBcaWzC6qofg4O1btwg94/M9NYyVfrom6dJ6LN/kx6FhN0liOh5OifVIXO fUks3I01KhAo3EZiYKdn7T5kPFbQM6T6sPAksbG3KbjPhHRXjVhWFXSpS1Ni02ja kvZ6/5SUi3Dzr9d0UKdZvRiMq9kcn47DeozseMjdEMpyxjkFsfVQx93IkVJE5lqa UaMAUHjVJ8pgZ8LpNNazS4unGU8LyB098dN8WbSnU+w89Q3fNwOfEPrExqO6SgSx c+1wwBcr8RblZumpwsDAw+sXDqELf+V3S+w0GLC06dweaQ6EUaWbtjI+L4ABeaKK Xd2C2/pDxbsZozWY3OCSUhKaBBRm1YD7NvSJIxYf3ddVGGo6TJQ6NAKVJkAgKKqn mxZmXnTqJJcujovuMTZmYlkcbMlVQexTfJaWsg7S+QMJuMy2xM2Lskr2JhNHIYtd a3TNA2ME44Axgr8yQmNjHp+/uACrxNjcjiTOjhtpqbcd2xos4NyzW/QeZkcdMmbm HJ3ScqCRc4tcazpK8EybqWnhE5nx05eC9NPdi2zu50eH06VxtWjLekHviEBJmhp/ GrXcxUpWkGDs4jLQregA =F/+Y -----END PGP SIGNATURE----- --U/5EjKfnYgGK6hcj--