Skip to content

Commit

Permalink
ppc/pnv: Introduce PowerNV machines with fixed CPU models
Browse files Browse the repository at this point in the history
Make the current "powernv" machine an abstract type and derive from it
new machines with specific CPU models: power8 and power9.

The "powernv" machine is now an alias on the "powernv9" machine.

Signed-off-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <20190731141233.1340-2-clg@kaod.org>
[dwg: Adjust pnv-xscom-test to cope with this change]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
  • Loading branch information
legoater authored and dgibson committed Aug 28, 2019
1 parent f47a08d commit f30c843
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 9 deletions.
70 changes: 63 additions & 7 deletions hw/ppc/pnv.c
Expand Up @@ -605,9 +605,20 @@ static void pnv_chip_power9_pic_print_info(PnvChip *chip, Monitor *mon)
pnv_psi_pic_print_info(&chip9->psi, mon);
}

static bool pnv_match_cpu(const char *default_type, const char *cpu_type)
{
PowerPCCPUClass *ppc_default =
POWERPC_CPU_CLASS(object_class_by_name(default_type));
PowerPCCPUClass *ppc =
POWERPC_CPU_CLASS(object_class_by_name(cpu_type));

return ppc_default->pvr_match(ppc_default, ppc->pvr);
}

static void pnv_init(MachineState *machine)
{
PnvMachineState *pnv = PNV_MACHINE(machine);
MachineClass *mc = MACHINE_GET_CLASS(machine);
MemoryRegion *ram;
char *fw_filename;
long fw_size;
Expand Down Expand Up @@ -667,13 +678,23 @@ static void pnv_init(MachineState *machine)
}
}

/*
* Check compatibility of the specified CPU with the machine
* default.
*/
if (!pnv_match_cpu(mc->default_cpu_type, machine->cpu_type)) {
error_report("invalid CPU model '%s' for %s machine",
machine->cpu_type, mc->name);
exit(1);
}

/* Create the processor chips */
i = strlen(machine->cpu_type) - strlen(POWERPC_CPU_TYPE_SUFFIX);
chip_typename = g_strdup_printf(PNV_CHIP_TYPE_NAME("%.*s"),
i, machine->cpu_type);
if (!object_class_by_name(chip_typename)) {
error_report("invalid CPU model '%.*s' for %s machine",
i, machine->cpu_type, MACHINE_GET_CLASS(machine)->name);
error_report("invalid chip model '%.*s' for %s machine",
i, machine->cpu_type, mc->name);
exit(1);
}

Expand Down Expand Up @@ -1351,17 +1372,38 @@ static void pnv_machine_class_props_init(ObjectClass *oc)
NULL);
}

static void pnv_machine_class_init(ObjectClass *oc, void *data)
static void pnv_machine_power8_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
XICSFabricClass *xic = XICS_FABRIC_CLASS(oc);

mc->desc = "IBM PowerNV (Non-Virtualized) POWER8";
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");

xic->icp_get = pnv_icp_get;
xic->ics_get = pnv_ics_get;
xic->ics_resend = pnv_ics_resend;
}

static void pnv_machine_power9_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);

mc->desc = "IBM PowerNV (Non-Virtualized) POWER9";
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0");

mc->alias = "powernv";
}

static void pnv_machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc);

mc->desc = "IBM PowerNV (Non-Virtualized)";
mc->init = pnv_init;
mc->reset = pnv_reset;
mc->max_cpus = MAX_CPUS;
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power8_v2.0");
mc->block_default_type = IF_IDE; /* Pnv provides a AHCI device for
* storage */
mc->no_parallel = 1;
Expand All @@ -1371,9 +1413,6 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data)
* enough to fit the maximum initrd size at it's load address
*/
mc->default_ram_size = INITRD_LOAD_ADDR + INITRD_MAX_SIZE;
xic->icp_get = pnv_icp_get;
xic->ics_get = pnv_ics_get;
xic->ics_resend = pnv_ics_resend;
ispc->print_info = pnv_pic_print_info;

pnv_machine_class_props_init(oc);
Expand All @@ -1393,10 +1432,27 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data)
.parent = TYPE_PNV9_CHIP, \
}

#define DEFINE_PNV_MACHINE_TYPE(cpu, class_initfn) \
{ \
.name = MACHINE_TYPE_NAME(cpu), \
.parent = TYPE_PNV_MACHINE, \
.instance_size = sizeof(PnvMachineState), \
.instance_init = pnv_machine_instance_init, \
.class_init = class_initfn, \
.interfaces = (InterfaceInfo[]) { \
{ TYPE_XICS_FABRIC }, \
{ TYPE_INTERRUPT_STATS_PROVIDER }, \
{ }, \
}, \
}

static const TypeInfo types[] = {
DEFINE_PNV_MACHINE_TYPE("powernv8", pnv_machine_power8_class_init),
DEFINE_PNV_MACHINE_TYPE("powernv9", pnv_machine_power9_class_init),
{
.name = TYPE_PNV_MACHINE,
.parent = TYPE_MACHINE,
.abstract = true,
.instance_size = sizeof(PnvMachineState),
.instance_init = pnv_machine_instance_init,
.class_init = pnv_machine_class_init,
Expand Down
16 changes: 14 additions & 2 deletions tests/pnv-xscom-test.c
Expand Up @@ -77,9 +77,15 @@ static void test_xscom_cfam_id(QTestState *qts, const PnvChip *chip)
static void test_cfam_id(const void *data)
{
const PnvChip *chip = data;
const char *machine = "powernv8";
QTestState *qts;

qts = qtest_initf("-M powernv,accel=tcg -cpu %s", chip->cpu_model);
if (chip->chip_type == PNV_CHIP_POWER9) {
machine = "powernv9";
}

qts = qtest_initf("-M %s,accel=tcg -cpu %s",
machine, chip->cpu_model);
test_xscom_cfam_id(qts, chip);
qtest_quit(qts);
}
Expand Down Expand Up @@ -113,8 +119,14 @@ static void test_core(const void *data)
{
const PnvChip *chip = data;
QTestState *qts;
const char *machine = "powernv8";

if (chip->chip_type == PNV_CHIP_POWER9) {
machine = "powernv9";
}

qts = qtest_initf("-M powernv,accel=tcg -cpu %s", chip->cpu_model);
qts = qtest_initf("-M %s,accel=tcg -cpu %s",
machine, chip->cpu_model);
test_xscom_core(qts, chip);
qtest_quit(qts);
}
Expand Down

0 comments on commit f30c843

Please sign in to comment.