From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46634) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgkO2-00064j-SM for qemu-devel@nongnu.org; Sun, 04 Sep 2016 23:15:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bgkNx-0001eD-Uk for qemu-devel@nongnu.org; Sun, 04 Sep 2016 23:15:53 -0400 Date: Mon, 5 Sep 2016 12:48:19 +1000 From: David Gibson Message-ID: <20160905024819.GE2587@voom.fritz.box> References: <1472661255-20160-1-git-send-email-clg@kaod.org> <1472661255-20160-2-git-send-email-clg@kaod.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="KuLpqunXa7jZSBt+" Content-Disposition: inline In-Reply-To: <1472661255-20160-2-git-send-email-clg@kaod.org> Subject: Re: [Qemu-devel] [PATCH v2 1/7] 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, Alexander Graf --KuLpqunXa7jZSBt+ Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Wed, Aug 31, 2016 at 06:34:09PM +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 (also) > - 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 > --- >=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 | 244 ++++++++++++++++++++++++++++++++= ++++++ > include/hw/ppc/pnv.h | 37 ++++++ > 4 files changed, 284 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-so= ftmmu.mak > index c4be59f638ed..516a6e25aba3 100644 > --- a/default-configs/ppc64-softmmu.mak > +++ b/default-configs/ppc64-softmmu.mak > @@ -40,6 +40,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_even= ts.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_rng= =2Eo > 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..70413e3c5740 > --- /dev/null > +++ b/hw/ppc/pnv.c > @@ -0,0 +1,244 @@ > +/* > + * QEMU PowerPC PowerNV model > + * > + * Copyright (c) 2004-2007 Fabrice Bellard > + * Copyright (c) 2007 Jocelyn Mayer > + * Copyright (c) 2010 David Gibson, IBM Corporation. > + * Copyright (c) 2014-2016 BenH, IBM Corporation. > + * > + * Permission is hereby granted, free of charge, to any person obtaining= a copy > + * of this software and associated documentation files (the "Software"),= to deal > + * in the Software without restriction, including without limitation the= rights > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or = sell > + * copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be includ= ed in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRE= SS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILI= TY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHA= LL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR = OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISI= NG FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING= S IN > + * THE SOFTWARE. > + * > + */ > +#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_ADDR 0x01000000 > +#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 > + > +static void powernv_populate_memory_node(void *fdt, int chip_id, hwaddr = 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@"TARGET_FMT_lx, 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))); > +} > + > + > +/* > + * 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 int powernv_populate_memory(void *fdt) > +{ > + int chip_id =3D 0; > + hwaddr chip_ramsize =3D ram_size; > + hwaddr chip_start =3D 0; > + > + /* Only one chip for the moment */ > + powernv_populate_memory_node(fdt, chip_id, chip_start, chip_ramsize); > + > + return 0; > +} > + > +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 g_strdup_printf(UUID_FMT, qemu_uuid[0], qemu_uuid[1], > + qemu_uuid[2], qemu_uuid[3], qemu_uuid[4], > + qemu_uuid[5], qemu_uuid[6], qemu_uuid[7], > + qemu_uuid[8], qemu_uuid[9], qemu_uuid[10], > + qemu_uuid[11], qemu_uuid[12], qemu_uuid[13], > + qemu_uuid[14], qemu_uuid[15]); > + _FDT((fdt_setprop_string(fdt, 0, "vm,uuid", 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->initrd= _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)))); > + } > + > + /* Memory */ > + powernv_populate_memory(fdt); > + > + return fdt; > +} > + > +static void ppc_powernv_reset(void) > +{ > + MachineState *machine =3D MACHINE(qdev_get_machine()); > + PnvMachineState *pnv =3D POWERNV_MACHINE(machine); > + void *fdt; > + > + pnv->fdt_addr =3D FDT_ADDR; Not sure there's any point to pnv->fdt_addr, since it will always have the value FDT_ADDR. Only worth changing if you're doing a respin for other reasons though. > + > + qemu_devices_reset(); > + > + fdt =3D powernv_create_fdt(pnv, machine->kernel_cmdline); > + > + cpu_physical_memory_write(pnv->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_SI= ZE); > + 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_fi= lename); > + exit(1); > + } > + > + /* load initrd */ > + if (machine->initrd_filename) { > + pnv->initrd_base =3D INITRD_LOAD_ADDR; > + pnv->initrd_size =3D load_image_targphys(machine->initrd_filenam= e, > + pnv->initrd_base, 0x10000000); /* 128M= B 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 for > + * 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..31a57ed7f465 > --- /dev/null > +++ b/include/hw/ppc/pnv.h > @@ -0,0 +1,37 @@ > +/* > + * QEMU 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; > + hwaddr fdt_addr; > +} PnvMachineState; > + > +#endif /* _PPC_PNV_H */ --=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 --KuLpqunXa7jZSBt+ Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIcBAEBAgAGBQJXzNzyAAoJEGw4ysog2bOSwnUP/RD/oUsQUCcRzH56E0uUrC7p ARA1HZarkhRWK8Pe1AyezTZGVdbeHIW0RSmIHPrQ5kgKbGAcucTDz/5KLyXssTXC 5qvrU+1UZD64Ve7epDYGpCkIsv6T844ev38aSMRZTcbugUUyIpN4JMesjek/TTFZ CdBozGjc1mzet7aFIKgrocewSudbL6pA3P1Ra+bGddnbrfgtGmyXG0mBti2SH6MT DlyFi8Y8BU9J1ykeQeu12+fuefm4VXI0mndTjoFpmW96SKXnqBufvgZyznC+Xiq4 SADoNuv3RDyJW3CJLLm7EaEnZqAiTqI+EGwj9sAqVwcowXNz9c2WP4vxTZQZlKK4 ttndflAYTDxooHsIDezsngifkUM0LWzm5LdLrUSASv4eVGr8mhDNHpq08rd/1jtY dCIVgXW0cH0YCEIfNLfrFAX7H5HUIWMjn1vPTjzvpuApxDFKNLM7B/3RuRCwB29/ XIggB6Pe/6WRqF/w6KakiGSi82TVn5nnzFN0bDJy+y8jC1HABiQZ38Xyhw1Fz5Bj PGaH0s3ENpJSxTagQZTT5h2v/1zU5R2jikTjlbwv7hxrdDET1vB1nkP/BE1Oz2bP eBm/+QUEF/4h758+CNv41/mTjMzKK9Xj6H6jrkSH1J9Pm4IaEomLw0VieXzOJidz qzv37+tOoynag1gsXVuY =oT8z -----END PGP SIGNATURE----- --KuLpqunXa7jZSBt+--