@@ -1501,6 +1501,8 @@ F: include/hw/ppc/fdt.h
F: hw/ppc/fdt.c
F: include/hw/ppc/pef.h
F: hw/ppc/pef.c
+F: include/hw/ppc/ppc_core.h
+F: hw/ppc/ppc_core.c
F: pc-bios/slof.bin
F: docs/system/ppc/pseries.rst
F: docs/specs/ppc-spapr-*
@@ -14,33 +14,6 @@
#include "qapi/error.h"
#include "qapi/visitor.h"
-static void core_prop_get_core_id(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
-{
- CPUCore *core = CPU_CORE(obj);
- int64_t value = core->core_id;
-
- visit_type_int(v, name, &value, errp);
-}
-
-static void core_prop_set_core_id(Object *obj, Visitor *v, const char *name,
- void *opaque, Error **errp)
-{
- CPUCore *core = CPU_CORE(obj);
- int64_t value;
-
- if (!visit_type_int(v, name, &value, errp)) {
- return;
- }
-
- if (value < 0) {
- error_setg(errp, "Invalid core id %"PRId64, value);
- return;
- }
-
- core->core_id = value;
-}
-
static void core_prop_get_nr_threads(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
@@ -82,8 +55,6 @@ static void cpu_core_class_init(ObjectClass *oc, void *data)
DeviceClass *dc = DEVICE_CLASS(oc);
set_bit(DEVICE_CATEGORY_CPU, dc->categories);
- object_class_property_add(oc, "core-id", "int", core_prop_get_core_id,
- core_prop_set_core_id, NULL, NULL);
object_class_property_add(oc, "nr-threads", "int", core_prop_get_nr_threads,
core_prop_set_nr_threads, NULL, NULL);
}
@@ -2,6 +2,7 @@ ppc_ss = ss.source_set()
ppc_ss.add(files(
'ppc.c',
'ppc_booke.c',
+ 'ppc_core.c',
))
ppc_ss.add(when: 'CONFIG_FDT_PPC', if_true: [files(
'fdt.c',
@@ -1224,7 +1224,7 @@ static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error **errp)
/* Map the ICP registers for each thread */
for (i = 0; i < chip->nr_cores; i++) {
PnvCore *pnv_core = chip->cores[i];
- int core_hwid = CPU_CORE(pnv_core)->core_id;
+ int core_hwid = POWERPC_CORE(pnv_core)->core_id;
for (j = 0; j < CPU_CORE(pnv_core)->nr_threads; j++) {
uint32_t pir = pcc->core_pir(chip, core_hwid) + j;
@@ -1443,7 +1443,7 @@ static void pnv_chip_quad_realize_one(PnvChip *chip, PnvQuad *eq,
const char *type)
{
char eq_name[32];
- int core_id = CPU_CORE(pnv_core)->core_id;
+ int core_id = POWERPC_CORE(pnv_core)->core_id;
snprintf(eq_name, sizeof(eq_name), "eq[%d]", core_id);
object_initialize_child_with_props(OBJECT(chip), eq_name, eq,
@@ -1983,7 +1983,7 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp)
chip->cores[i] = pnv_core;
object_property_set_int(OBJECT(pnv_core), "nr-threads",
chip->nr_threads, &error_fatal);
- object_property_set_int(OBJECT(pnv_core), CPU_CORE_PROP_CORE_ID,
+ object_property_set_int(OBJECT(pnv_core), POWERPC_CORE_PROP_CORE_ID,
core_hwid, &error_fatal);
object_property_set_int(OBJECT(pnv_core), "pir",
pcc->core_pir(chip, core_hwid), &error_fatal);
@@ -267,6 +267,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
PnvCore *pc = PNV_CORE(OBJECT(dev));
PnvCoreClass *pcc = PNV_CORE_GET_CLASS(pc);
CPUCore *cc = CPU_CORE(OBJECT(dev));
+ PowerPCCore *ppc = POWERPC_CORE(cc);
const char *typename = pnv_core_cpu_typename(pc);
Error *local_err = NULL;
void *obj;
@@ -299,7 +300,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
}
}
- snprintf(name, sizeof(name), "xscom-core.%d", cc->core_id);
+ snprintf(name, sizeof(name), "xscom-core.%d", ppc->core_id);
pnv_xscom_region_init(&pc->xscom_regs, OBJECT(dev), pcc->xscom_ops,
pc, name, pcc->xscom_size);
@@ -392,7 +393,7 @@ static void pnv_core_class_init(ObjectClass *oc, void *data)
static const TypeInfo pnv_core_infos[] = {
{
.name = TYPE_PNV_CORE,
- .parent = TYPE_CPU_CORE,
+ .parent = TYPE_POWERPC_CORE,
.instance_size = sizeof(PnvCore),
.class_size = sizeof(PnvCoreClass),
.class_init = pnv_core_class_init,
new file mode 100644
@@ -0,0 +1,79 @@
+/*
+ * Common PPC CPU core abstraction
+ *
+ * Copyright (c) 2023 Intel Corporation
+ * Author: Zhao Liu <zhao1.liu@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/ppc/ppc_core.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+
+static void powerpc_core_prop_get_core_id(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ PowerPCCore *core = POWERPC_CORE(obj);
+ int64_t value = core->core_id;
+
+ visit_type_int(v, name, &value, errp);
+}
+
+static void powerpc_core_prop_set_core_id(Object *obj, Visitor *v,
+ const char *name, void *opaque,
+ Error **errp)
+{
+ PowerPCCore *core = POWERPC_CORE(obj);
+ int64_t value;
+
+ if (!visit_type_int(v, name, &value, errp)) {
+ return;
+ }
+
+ if (value < 0) {
+ error_setg(errp, "Invalid core id %"PRId64, value);
+ return;
+ }
+
+ core->core_id = value;
+}
+
+static void powerpc_core_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ object_class_property_add(oc, "core-id", "int",
+ powerpc_core_prop_get_core_id,
+ powerpc_core_prop_set_core_id,
+ NULL, NULL);
+}
+
+static const TypeInfo powerpc_core_type_info = {
+ .name = TYPE_POWERPC_CORE,
+ .parent = TYPE_CPU_CORE,
+ .abstract = true,
+ .class_init = powerpc_core_class_init,
+ .instance_size = sizeof(PowerPCCore),
+};
+
+static void powerpc_core_register_types(void)
+{
+ type_register_static(&powerpc_core_type_info);
+}
+
+type_init(powerpc_core_register_types)
@@ -2713,7 +2713,7 @@ static void spapr_init_cpus(SpaprMachineState *spapr)
object_property_set_int(core, "nr-threads", nr_threads,
&error_fatal);
- object_property_set_int(core, CPU_CORE_PROP_CORE_ID, core_id,
+ object_property_set_int(core, POWERPC_CORE_PROP_CORE_ID, core_id,
&error_fatal);
qdev_realize(DEVICE(core), NULL, &error_fatal);
@@ -3889,7 +3889,8 @@ static void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
MachineState *ms = MACHINE(hotplug_dev);
SpaprMachineClass *smc = SPAPR_MACHINE_GET_CLASS(ms);
CPUCore *cc = CPU_CORE(dev);
- CPUArchId *core_slot = spapr_find_cpu_slot(ms, cc->core_id, NULL);
+ PowerPCCore *ppc = POWERPC_CORE(cc);
+ CPUArchId *core_slot = spapr_find_cpu_slot(ms, ppc->core_id, NULL);
if (smc->pre_2_10_has_unused_icps) {
SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
@@ -3915,10 +3916,11 @@ void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev,
int index;
SpaprDrc *drc;
CPUCore *cc = CPU_CORE(dev);
+ PowerPCCore *ppc = POWERPC_CORE(cc);
- if (!spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index)) {
+ if (!spapr_find_cpu_slot(MACHINE(hotplug_dev), ppc->core_id, &index)) {
error_setg(errp, "Unable to find CPU core with core-id: %d",
- cc->core_id);
+ ppc->core_id);
return;
}
if (index == 0) {
@@ -3927,7 +3929,7 @@ void spapr_core_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev,
}
drc = spapr_drc_by_id(TYPE_SPAPR_DRC_CPU,
- spapr_vcpu_id(spapr, cc->core_id));
+ spapr_vcpu_id(spapr, ppc->core_id));
g_assert(drc);
if (!spapr_drc_unplug_requested(drc)) {
@@ -3985,6 +3987,7 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev)
SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(mc);
SpaprCpuCore *core = SPAPR_CPU_CORE(OBJECT(dev));
CPUCore *cc = CPU_CORE(dev);
+ PowerPCCore *ppc = POWERPC_CORE(cc);
CPUState *cs;
SpaprDrc *drc;
CPUArchId *core_slot;
@@ -3992,11 +3995,11 @@ static void spapr_core_plug(HotplugHandler *hotplug_dev, DeviceState *dev)
bool hotplugged = spapr_drc_hotplugged(dev);
int i;
- core_slot = spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index);
+ core_slot = spapr_find_cpu_slot(MACHINE(hotplug_dev), ppc->core_id, &index);
g_assert(core_slot); /* Already checked in spapr_core_pre_plug() */
drc = spapr_drc_by_id(TYPE_SPAPR_DRC_CPU,
- spapr_vcpu_id(spapr, cc->core_id));
+ spapr_vcpu_id(spapr, ppc->core_id));
g_assert(drc || !mc->has_hotpluggable_cpus);
@@ -4047,6 +4050,7 @@ static void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
MachineState *machine = MACHINE(OBJECT(hotplug_dev));
MachineClass *mc = MACHINE_GET_CLASS(hotplug_dev);
CPUCore *cc = CPU_CORE(dev);
+ PowerPCCore *ppc = POWERPC_CORE(cc);
const char *base_core_type = spapr_get_cpu_core_type(machine->cpu_type);
const char *type = object_get_typename(OBJECT(dev));
CPUArchId *core_slot;
@@ -4063,8 +4067,8 @@ static void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
}
- if (cc->core_id % smp_threads) {
- error_setg(errp, "invalid core id %d", cc->core_id);
+ if (ppc->core_id % smp_threads) {
+ error_setg(errp, "invalid core id %d", ppc->core_id);
return;
}
@@ -4080,14 +4084,14 @@ static void spapr_core_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
}
- core_slot = spapr_find_cpu_slot(MACHINE(hotplug_dev), cc->core_id, &index);
+ core_slot = spapr_find_cpu_slot(MACHINE(hotplug_dev), ppc->core_id, &index);
if (!core_slot) {
- error_setg(errp, "core id %d out of range", cc->core_id);
+ error_setg(errp, "core id %d out of range", ppc->core_id);
return;
}
if (core_slot->cpu) {
- error_setg(errp, "core %d already populated", cc->core_id);
+ error_setg(errp, "core %d already populated", ppc->core_id);
return;
}
@@ -292,7 +292,7 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
static PowerPCCPU *spapr_create_vcpu(SpaprCpuCore *sc, int i, Error **errp)
{
SpaprCpuCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(sc);
- CPUCore *cc = CPU_CORE(sc);
+ PowerPCCore *ppc = POWERPC_CORE(sc);
g_autoptr(Object) obj = NULL;
g_autofree char *id = NULL;
CPUState *cs;
@@ -307,7 +307,7 @@ static PowerPCCPU *spapr_create_vcpu(SpaprCpuCore *sc, int i, Error **errp)
* and the rest are explicitly started up by the guest using an RTAS call.
*/
cs->start_powered_off = true;
- cs->cpu_index = cc->core_id + i;
+ cs->cpu_index = ppc->core_id + i;
if (!spapr_set_vcpu_id(cpu, cs->cpu_index, errp)) {
return NULL;
}
@@ -381,7 +381,7 @@ static void spapr_cpu_core_class_init(ObjectClass *oc, void *data)
static const TypeInfo spapr_cpu_core_type_infos[] = {
{
.name = TYPE_SPAPR_CPU_CORE,
- .parent = TYPE_CPU_CORE,
+ .parent = TYPE_POWERPC_CORE,
.abstract = true,
.instance_size = sizeof(SpaprCpuCore),
.class_size = sizeof(SpaprCpuCoreClass),
@@ -21,13 +21,7 @@ struct CPUCore {
DeviceState parent_obj;
/*< public >*/
- int core_id;
int nr_threads;
};
-/* Note: topology field names need to be kept in sync with
- * 'CpuInstanceProperties' */
-
-#define CPU_CORE_PROP_CORE_ID "core-id"
-
#endif
@@ -20,9 +20,9 @@
#ifndef PPC_PNV_CORE_H
#define PPC_PNV_CORE_H
-#include "hw/cpu/core.h"
#include "target/ppc/cpu.h"
#include "hw/ppc/pnv.h"
+#include "hw/ppc/ppc_core.h"
#include "qom/object.h"
#define TYPE_PNV_CORE "powernv-cpu-core"
@@ -31,7 +31,7 @@ OBJECT_DECLARE_TYPE(PnvCore, PnvCoreClass,
struct PnvCore {
/*< private >*/
- CPUCore parent_obj;
+ PowerPCCore parent_obj;
/*< public >*/
PowerPCCPU **threads;
@@ -43,8 +43,10 @@ struct PnvCore {
};
struct PnvCoreClass {
- DeviceClass parent_class;
+ /*< private >*/
+ PowerPCCoreClass parent_class;
+ /*< public >*/
const MemoryRegionOps *xscom_ops;
uint64_t xscom_size;
};
new file mode 100644
@@ -0,0 +1,57 @@
+/*
+ * Common PPC CPU core abstraction header
+ *
+ * Copyright (c) 2023 Intel Corporation
+ * Author: Zhao Liu <zhao1.liu@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef HW_PPC_CORE_H
+#define HW_PPC_CORE_H
+
+#include "hw/cpu/core.h"
+#include "hw/qdev-core.h"
+#include "qom/object.h"
+
+#define TYPE_POWERPC_CORE "powerpc-core"
+
+OBJECT_DECLARE_TYPE(PowerPCCore, PowerPCCoreClass, POWERPC_CORE)
+
+struct PowerPCCoreClass {
+ /*< private >*/
+ CPUCoreClass parent_class;
+
+ /*< public >*/
+};
+
+struct PowerPCCore {
+ /*< private >*/
+ CPUCore parent_obj;
+
+ /*< public >*/
+ /*
+ * The system-wide id for core, not the sub core-id within the
+ * parent container (which is above the core level).
+ */
+ int core_id;
+};
+
+/*
+ * Note: topology field names need to be kept in sync with
+ * 'CpuInstanceProperties'
+ */
+#define POWERPC_CORE_PROP_CORE_ID "core-id"
+
+#endif /* HW_PPC_CORE_H */
@@ -9,7 +9,7 @@
#ifndef HW_SPAPR_CPU_CORE_H
#define HW_SPAPR_CPU_CORE_H
-#include "hw/cpu/core.h"
+#include "hw/ppc/ppc_core.h"
#include "hw/qdev-core.h"
#include "target/ppc/cpu-qom.h"
#include "target/ppc/cpu.h"
@@ -23,7 +23,7 @@ OBJECT_DECLARE_TYPE(SpaprCpuCore, SpaprCpuCoreClass,
struct SpaprCpuCore {
/*< private >*/
- CPUCore parent_obj;
+ PowerPCCore parent_obj;
/*< public >*/
PowerPCCPU **threads;
@@ -32,7 +32,10 @@ struct SpaprCpuCore {
};
struct SpaprCpuCoreClass {
- DeviceClass parent_class;
+ /*< private >*/
+ PowerPCCoreClass parent_class;
+
+ /*< public >*/
const char *cpu_type;
};