From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57864) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bsNQO-0005Y1-DL for qemu-devel@nongnu.org; Fri, 07 Oct 2016 01:10:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bsNQJ-0005q6-VY for qemu-devel@nongnu.org; Fri, 07 Oct 2016 01:10:23 -0400 Date: Fri, 7 Oct 2016 15:52:46 +1100 From: David Gibson Message-ID: <20161007045246.GU18490@umbus.fritz.box> References: <1475479496-16158-1-git-send-email-clg@kaod.org> <1475479496-16158-6-git-send-email-clg@kaod.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha256; protocol="application/pgp-signature"; boundary="DOQx4ubtbYINM/to" Content-Disposition: inline In-Reply-To: <1475479496-16158-6-git-send-email-clg@kaod.org> Subject: Re: [Qemu-devel] [PATCH v4 05/20] ppc/pnv: add a PnvCore object 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 --DOQx4ubtbYINM/to Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Oct 03, 2016 at 09:24:41AM +0200, C=E9dric Le Goater wrote: > This is largy inspired by sPAPRCPUCore with some simplification, no > hotplug for instance. But the differences are small and the objects > could possibly be merged. >=20 > A set of PnvCore objects is added to the PnvChip and the device > tree is populated looping on these cores. >=20 > Real HW cpu ids are now generated depending on the chip cpu model, the > chip id and a core mask. >=20 > Signed-off-by: C=E9dric Le Goater > --- >=20 > I did not introduce a single table to construct both the chip types > and the corresponding core types yet. Keeping the idea for later as > there might be other types to construct with P9 support. >=20 > Changes since v3: >=20 > - removed the usage of cpu_index > - removed the setting of the msr_mask > =20 > Changes since v2: >=20 > - added P9 support > - used error_fatal instead of error_abort when setting the chip > properties > - replaced num_cores by nr_cores > - removed gservers properties that were unused on powernv.=20 > - used a 'void *' instead of a 'PnvCore *' to hold core Objects of > potentially different size. > - qom: linked the core Objects to the chip=20 > - moved device tree creation under powernv_populate_chip() > - added a 'pir' property' for ease of use >=20 > Changes since v1: >=20 > - changed name to PnvCore > - changed PnvChip core array type to a 'PnvCore *cores' > - introduced real cpu hw ids using a core mask from the chip > - reworked powernv_create_core_node() which populates the device tree > - added missing "ibm,pa-features" property=20 > - smp_cpus representing threads, used smp_cores instead to create the > cores in the chip. > - removed the use of ppc_get_vcpu_dt_id()=20 > - added "POWER8E" and "POWER8NVL" cpu models to exercice the > PnvChipClass >=20 > hw/ppc/Makefile.objs | 2 +- > hw/ppc/pnv.c | 187 ++++++++++++++++++++++++++++++++++++++++= ++++++ > hw/ppc/pnv_core.c | 186 ++++++++++++++++++++++++++++++++++++++++= +++++ > include/hw/ppc/pnv.h | 3 + > include/hw/ppc/pnv_core.h | 48 ++++++++++++ > 5 files changed, 425 insertions(+), 1 deletion(-) > create mode 100644 hw/ppc/pnv_core.c > create mode 100644 include/hw/ppc/pnv_core.h >=20 > diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs > index 8105db7d5600..f8c7d1db9ade 100644 > --- a/hw/ppc/Makefile.objs > +++ b/hw/ppc/Makefile.objs > @@ -6,7 +6,7 @@ obj-$(CONFIG_PSERIES) +=3D spapr_hcall.o spapr_iommu.o sp= apr_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 > +obj-$(CONFIG_POWERNV) +=3D pnv.o pnv_core.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 > index 758c849702a0..2376bb222918 100644 > --- a/hw/ppc/pnv.c > +++ b/hw/ppc/pnv.c > @@ -27,6 +27,7 @@ > #include "hw/ppc/fdt.h" > #include "hw/ppc/ppc.h" > #include "hw/ppc/pnv.h" > +#include "hw/ppc/pnv_core.h" > #include "hw/loader.h" > #include "exec/address-spaces.h" > #include "qemu/cutils.h" > @@ -74,14 +75,162 @@ static void powernv_populate_memory_node(void *fdt, = int chip_id, hwaddr start, > _FDT((fdt_setprop_cell(fdt, off, "ibm,chip-id", chip_id))); > } > =20 > +static int get_cpus_node(void *fdt) > +{ > + int cpus_offset =3D fdt_path_offset(fdt, "/cpus"); > + > + if (cpus_offset < 0) { > + cpus_offset =3D fdt_add_subnode(fdt, fdt_path_offset(fdt, "/"), > + "cpus"); > + if (cpus_offset) { > + _FDT((fdt_setprop_cell(fdt, cpus_offset, "#address-cells", 0= x1))); > + _FDT((fdt_setprop_cell(fdt, cpus_offset, "#size-cells", 0x0)= )); > + } > + } > + _FDT(cpus_offset); > + return cpus_offset; > +} > + > +/* > + * The PowerNV cores (and threads) need to use real HW ids and not an > + * incremental index like it has been done on other platforms. This HW > + * id is stored in the CPU PIR, it is used to create cpu nodes in the > + * device tree, used in XSCOM to address cores and in interrupt > + * servers. > + */ > +static void powernv_create_core_node(PnvChip *chip, PnvCore *pc, void *f= dt) > +{ > + CPUState *cs =3D CPU(DEVICE(pc->threads)); > + DeviceClass *dc =3D DEVICE_GET_CLASS(cs); > + PowerPCCPU *cpu =3D POWERPC_CPU(cs); > + int smt_threads =3D ppc_get_compat_smt_threads(cpu); > + CPUPPCState *env =3D &cpu->env; > + PowerPCCPUClass *pcc =3D POWERPC_CPU_GET_CLASS(cs); > + uint32_t servers_prop[smt_threads]; > + int i; > + uint32_t segs[] =3D {cpu_to_be32(28), cpu_to_be32(40), > + 0xffffffff, 0xffffffff}; > + uint32_t tbfreq =3D PNV_TIMEBASE_FREQ; > + uint32_t cpufreq =3D 1000000000; > + uint32_t page_sizes_prop[64]; > + size_t page_sizes_prop_size; > + const uint8_t pa_features[] =3D { 24, 0, > + 0xf6, 0x3f, 0xc7, 0xc0, 0x80, 0xf0, > + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, > + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, > + 0x80, 0x00, 0x80, 0x00, 0x80, 0x00 }; > + int offset; > + char *nodename; > + int cpus_offset =3D get_cpus_node(fdt); > + > + nodename =3D g_strdup_printf("%s@%x", dc->fw_name, pc->pir); > + offset =3D fdt_add_subnode(fdt, cpus_offset, nodename); > + _FDT(offset); > + g_free(nodename); > + > + _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id", chip->chip_id))); > + > + _FDT((fdt_setprop_cell(fdt, offset, "reg", pc->pir))); > + _FDT((fdt_setprop_cell(fdt, offset, "ibm,pir", pc->pir))); > + _FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu"))); > + > + _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR]= ))); > + _FDT((fdt_setprop_cell(fdt, offset, "d-cache-block-size", > + env->dcache_line_size))); > + _FDT((fdt_setprop_cell(fdt, offset, "d-cache-line-size", > + env->dcache_line_size))); > + _FDT((fdt_setprop_cell(fdt, offset, "i-cache-block-size", > + env->icache_line_size))); > + _FDT((fdt_setprop_cell(fdt, offset, "i-cache-line-size", > + env->icache_line_size))); > + > + if (pcc->l1_dcache_size) { > + _FDT((fdt_setprop_cell(fdt, offset, "d-cache-size", > + pcc->l1_dcache_size))); > + } else { > + error_report("Warning: Unknown L1 dcache size for cpu"); > + } > + if (pcc->l1_icache_size) { > + _FDT((fdt_setprop_cell(fdt, offset, "i-cache-size", > + pcc->l1_icache_size))); > + } else { > + error_report("Warning: Unknown L1 icache size for cpu"); > + } > + > + _FDT((fdt_setprop_cell(fdt, offset, "timebase-frequency", tbfreq))); > + _FDT((fdt_setprop_cell(fdt, offset, "clock-frequency", cpufreq))); > + _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size", env->slb_nr))); > + _FDT((fdt_setprop_string(fdt, offset, "status", "okay"))); > + _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0))); > + > + if (env->spr_cb[SPR_PURR].oea_read) { > + _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0))); > + } > + > + if (env->mmu_model & POWERPC_MMU_1TSEG) { > + _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes", > + segs, sizeof(segs)))); > + } > + > + /* Advertise VMX/VSX (vector extensions) if available > + * 0 / no property =3D=3D no vector extensions > + * 1 =3D=3D VMX / Altivec available > + * 2 =3D=3D VSX available */ > + if (env->insns_flags & PPC_ALTIVEC) { > + uint32_t vmx =3D (env->insns_flags2 & PPC2_VSX) ? 2 : 1; > + > + _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx))); > + } > + > + /* Advertise DFP (Decimal Floating Point) if available > + * 0 / no property =3D=3D no DFP > + * 1 =3D=3D DFP available */ > + if (env->insns_flags2 & PPC2_DFP) { > + _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1))); > + } > + > + page_sizes_prop_size =3D ppc_create_page_sizes_prop(env, page_sizes_= prop, > + sizeof(page_sizes_prop= )); > + if (page_sizes_prop_size) { > + _FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes", > + page_sizes_prop, page_sizes_prop_size))); > + } > + > + _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", > + pa_features, sizeof(pa_features)))); > + > + if (cpu->cpu_version) { > + _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", cpu->cpu_vers= ion))); > + } > + > + /* Build interrupt servers properties */ > + for (i =3D 0; i < smt_threads; i++) { > + servers_prop[i] =3D cpu_to_be32(pc->pir + i); > + } > + _FDT((fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s", > + servers_prop, sizeof(servers_prop)))); > +} > + > static void powernv_populate_chip(PnvChip *chip, void *fdt) > { > + PnvChipClass *pcc =3D PNV_CHIP_GET_CLASS(chip); > + char *typename =3D pnv_core_typename(pcc->cpu_model); > + size_t typesize =3D object_type_get_instance_size(typename); > + int i; > + > + for (i =3D 0; i < chip->nr_cores; i++) { > + PnvCore *pnv_core =3D PNV_CORE(chip->cores + i * typesize); > + > + powernv_create_core_node(chip, pnv_core, fdt); > + } > + > /* Put all the memory in one node on chip 0 until we find a way to > * specify different ranges for each chip > */ > if (chip->chip_id =3D=3D 0) { > powernv_populate_memory_node(fdt, chip->chip_id, 0, ram_size); > } > + g_free(typename); > } > =20 > static void *powernv_create_fdt(PnvMachineState *pnv, > @@ -404,6 +553,15 @@ static void pnv_chip_realize(DeviceState *dev, Error= **errp) > { > PnvChip *chip =3D PNV_CHIP(dev); > Error *error =3D NULL; > + PnvChipClass *pcc =3D PNV_CHIP_GET_CLASS(chip); > + char *typename =3D pnv_core_typename(pcc->cpu_model); > + size_t typesize =3D object_type_get_instance_size(typename); > + int i, core_hwid; > + > + if (!object_class_by_name(typename)) { > + error_setg(errp, "Unable to find PowerNV CPU Core '%s'", typenam= e); > + return; > + } > =20 > /* Early checks on the core settings */ > pnv_chip_core_sanitize(chip, &error); > @@ -411,6 +569,35 @@ static void pnv_chip_realize(DeviceState *dev, Error= **errp) > error_propagate(errp, error); > return; > } > + > + chip->cores =3D g_malloc0(typesize * chip->nr_cores); > + > + for (i =3D 0, core_hwid =3D 0; (core_hwid < sizeof(chip->cores_mask)= * 8) > + && (i < chip->nr_cores); core_hwid++) { > + char core_name[32]; > + void *pnv_core =3D chip->cores + i * typesize; > + > + if (!(chip->cores_mask & (1ull << core_hwid))) { > + continue; > + } > + > + object_initialize(pnv_core, typesize, typename); > + snprintf(core_name, sizeof(core_name), "core[%d]", core_hwid); > + object_property_add_child(OBJECT(chip), core_name, OBJECT(pnv_co= re), > + &error_fatal); > + object_property_set_int(OBJECT(pnv_core), smp_threads, "nr-threa= ds", > + &error_fatal); > + object_property_set_int(OBJECT(pnv_core), core_hwid, > + CPU_CORE_PROP_CORE_ID, &error_fatal); > + object_property_set_int(OBJECT(pnv_core), > + pcc->core_pir(chip, core_hwid), > + "pir", &error_fatal); > + object_property_set_bool(OBJECT(pnv_core), true, "realized", > + &error_fatal); > + object_unref(OBJECT(pnv_core)); > + i++; > + } > + g_free(typename); > } > =20 > static Property pnv_chip_properties[] =3D { > diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c > new file mode 100644 > index 000000000000..d37788f142f4 > --- /dev/null > +++ b/hw/ppc/pnv_core.c > @@ -0,0 +1,186 @@ > +/* > + * QEMU PowerPC PowerNV CPU Core 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 "sysemu/sysemu.h" > +#include "qapi/error.h" > +#include "target-ppc/cpu.h" > +#include "hw/ppc/ppc.h" > +#include "hw/ppc/pnv.h" > +#include "hw/ppc/pnv_core.h" > + > +static void powernv_cpu_reset(void *opaque) > +{ > + PowerPCCPU *cpu =3D opaque; > + CPUState *cs =3D CPU(cpu); > + CPUPPCState *env =3D &cpu->env; > + int core_pir; > + int thread_index =3D 0; /* TODO: TCG supports only one thread */ > + > + cpu_reset(cs); > + > + core_pir =3D object_property_get_int(OBJECT(cpu), "core-pir", &error= _abort); Took me a while to figure out how this core-pir alias thing works, but once I did, it looks ok. I do wonder if you'll need to change to a link back to the core object at some point if there's more than just the pir you need to look up from the core. > + /* > + * The PIR of a thread is the core PIR + the thread index. We will > + * need to find a way to get the thread index when TCG supports > + * more than 1. We could use the object name ? > + */ > + env->spr[SPR_PIR] =3D core_pir + thread_index; The PIR is read-only, so could it be initialized directly in _init() rather than in the _reset() handler? > + env->spr[SPR_HIOR] =3D 0; > + /* > + * the skiboot firmware elects a primary thread to initialize the > + * system and it can be any. > + */ > + env->gpr[3] =3D POWERNV_FDT_ADDR; > + env->nip =3D 0x10; > + env->msr |=3D MSR_HVB; /* Hypervisor mode */ > +} > + > +static void powernv_cpu_init(PowerPCCPU *cpu, Error **errp) > +{ > + CPUPPCState *env =3D &cpu->env; > + > + /* Set time-base frequency to 512 MHz */ > + cpu_ppc_tb_init(env, PNV_TIMEBASE_FREQ); > + > + qemu_register_reset(powernv_cpu_reset, cpu); > + powernv_cpu_reset(cpu); I don't think you need this explicit call to the reset function - all the registered reset functions should get called after this point, but before qemu tries to start the guest. > +} > + > +static void pnv_core_realize_child(Object *child, Error **errp) > +{ > + Error *local_err =3D NULL; > + CPUState *cs =3D CPU(child); > + PowerPCCPU *cpu =3D POWERPC_CPU(cs); > + > + object_property_set_bool(child, true, "realized", &local_err); > + if (local_err) { > + error_propagate(errp, local_err); > + return; > + } > + > + powernv_cpu_init(cpu, &local_err); > + if (local_err) { > + error_propagate(errp, local_err); > + return; > + } > +} > + > +static void pnv_core_realize(DeviceState *dev, Error **errp) > +{ > + PnvCore *pc =3D PNV_CORE(OBJECT(dev)); > + CPUCore *cc =3D CPU_CORE(OBJECT(dev)); > + PnvCoreClass *pcc =3D PNV_CORE_GET_CLASS(OBJECT(dev)); > + const char *typename =3D object_class_get_name(pcc->cpu_oc); > + size_t size =3D object_type_get_instance_size(typename); > + Error *local_err =3D NULL; > + void *obj; > + int i, j; > + char name[32]; > + > + pc->threads =3D g_malloc0(size * cc->nr_threads); > + for (i =3D 0; i < cc->nr_threads; i++) { > + obj =3D pc->threads + i * size; > + > + object_initialize(obj, size, typename); > + > + snprintf(name, sizeof(name), "thread[%d]", i); > + object_property_add_child(OBJECT(pc), name, obj, &local_err); > + object_property_add_alias(obj, "core-pir", OBJECT(pc), > + "pir", &local_err); > + if (local_err) { > + goto err; > + } > + object_unref(obj); > + } > + > + for (j =3D 0; j < cc->nr_threads; j++) { > + obj =3D pc->threads + j * size; > + > + pnv_core_realize_child(obj, &local_err); > + if (local_err) { > + goto err; > + } > + } > + return; > + > +err: > + while (--i >=3D 0) { > + obj =3D pc->threads + i * size; > + object_unparent(obj); > + } > + g_free(pc->threads); > + error_propagate(errp, local_err); > +} > + > +static Property pnv_core_properties[] =3D { > + DEFINE_PROP_UINT32("pir", PnvCore, pir, 0), > + DEFINE_PROP_END_OF_LIST(), > +}; > + > +static void pnv_core_class_init(ObjectClass *oc, void *data) > +{ > + DeviceClass *dc =3D DEVICE_CLASS(oc); > + PnvCoreClass *pcc =3D PNV_CORE_CLASS(oc); > + > + dc->realize =3D pnv_core_realize; > + dc->props =3D pnv_core_properties; > + pcc->cpu_oc =3D cpu_class_by_name(TYPE_POWERPC_CPU, data); > +} > + > +static const TypeInfo pnv_core_info =3D { > + .name =3D TYPE_PNV_CORE, > + .parent =3D TYPE_CPU_CORE, > + .instance_size =3D sizeof(PnvCore), > + .class_size =3D sizeof(PnvCoreClass), > + .abstract =3D true, > +}; > + > +/* > + * Grow this list or merge with SPAPRCoreInfo which is very similar I don't think combining this with the spapr one makes sense. If nothing else I don't think we want to bind what CPU models are supported for pnv to what models are supported for PAPR. > + */ > +static const char *pnv_core_models[] =3D { > + "POWER8E", "POWER8", "POWER8NVL", "POWER9" > +}; > + > +static void pnv_core_register_types(void) > +{ > + int i ; > + > + type_register_static(&pnv_core_info); > + for (i =3D 0; i < ARRAY_SIZE(pnv_core_models); ++i) { > + TypeInfo ti =3D { > + .parent =3D TYPE_PNV_CORE, > + .instance_size =3D sizeof(PnvCore), > + .class_init =3D pnv_core_class_init, > + .class_data =3D (void *) pnv_core_models[i], > + }; > + ti.name =3D pnv_core_typename(pnv_core_models[i]); > + type_register(&ti); > + g_free((void *)ti.name); > + } > +} > + > +type_init(pnv_core_register_types) > + > +char *pnv_core_typename(const char *model) > +{ > + return g_strdup_printf(TYPE_PNV_CORE "-%s", model); > +} > diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h > index c676f800e28e..ed4a360cde3b 100644 > --- a/include/hw/ppc/pnv.h > +++ b/include/hw/ppc/pnv.h > @@ -45,6 +45,7 @@ typedef struct PnvChip { > =20 > uint32_t nr_cores; > uint64_t cores_mask; > + void *cores; > } PnvChip; > =20 > typedef struct PnvChipClass { > @@ -102,4 +103,6 @@ typedef struct PnvMachineState { > =20 > #define POWERNV_FDT_ADDR 0x01000000 > =20 > +#define PNV_TIMEBASE_FREQ 512000000ULL > + > #endif /* _PPC_PNV_H */ > diff --git a/include/hw/ppc/pnv_core.h b/include/hw/ppc/pnv_core.h > new file mode 100644 > index 000000000000..a151e281c017 > --- /dev/null > +++ b/include/hw/ppc/pnv_core.h > @@ -0,0 +1,48 @@ > +/* > + * QEMU PowerPC PowerNV CPU Core 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 . > + */ > +#ifndef _PPC_PNV_CORE_H > +#define _PPC_PNV_CORE_H > + > +#include "hw/cpu/core.h" > + > +#define TYPE_PNV_CORE "powernv-cpu-core" > +#define PNV_CORE(obj) \ > + OBJECT_CHECK(PnvCore, (obj), TYPE_PNV_CORE) > +#define PNV_CORE_CLASS(klass) \ > + OBJECT_CLASS_CHECK(PnvCoreClass, (klass), TYPE_PNV_CORE) > +#define PNV_CORE_GET_CLASS(obj) \ > + OBJECT_GET_CLASS(PnvCoreClass, (obj), TYPE_PNV_CORE) > + > +typedef struct PnvCore { > + /*< private >*/ > + CPUCore parent_obj; > + > + /*< public >*/ > + void *threads; > + uint32_t pir; > +} PnvCore; > + > +typedef struct PnvCoreClass { > + DeviceClass parent_class; > + ObjectClass *cpu_oc; > +} PnvCoreClass; > + > +extern char *pnv_core_typename(const char *model); > + > +#endif /* _PPC_PNV_CORE_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 --DOQx4ubtbYINM/to Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAEBCAAGBQJX9yobAAoJEGw4ysog2bOSgv8P/126BlIXV2Pxlz/sva6Af9Ch lHdr9jazOjqXR5mimUuR9ojZpN8qShCIffN+Bme7XTGOh+XJXDWbzpeLhStdrYy+ uE8ZMAlyG3BU1lXhZDEZfx9RLukaaoeo0pzEg2YTpe7G/fdM4id2MxGcjOisKzjH 1VIKwic4kYpTnsjxomnpcVW2Jva4jOmU2BvSnvBB6DiHQCCa+s3h9JNHoAmeF1Og NknZZvfk33g5QqMGROBbPsEwDXsxHqVX4IRy7El0W39l4DTSgXh/0Id3tcAEDhOX JERIbeULWq8oYYY7WUaaBtCBbwWQ/cfdx6C6iRXUB6D85Ye4Vhoq0CnyMA2FfDUW aDj7EQZAgX2V5WjDQ7O0xvXwvhbipduEsRi982eY5ZK39BUtr00QJp5y6nvyVWtP hGud98sKoJ2XEBc5XQuIDwDB63pi4XH4aOVH+bTgR7Z81/UkR/hecPlDtBpzjfLU ZL/gBDAvE7ho8gybmGoIcNJ7G2Ie3jQd3IPA0+TFVSVztJk1rba0qcgN1WT3H9FJ UXWg7d7XDAJD0doo5aeNmahoYG42xCm018X8gC7jzpN43TKVaLbggjsPd+vp6IdY VKil7pM1VpXCIdo8WC9cmwqmz0X/ih2byuoAPx9vyiF/qS7G1DvbamZeBStuvlId eXiAmLdn8OoltxvZ13oC =arae -----END PGP SIGNATURE----- --DOQx4ubtbYINM/to--