ppc/pnv: SMT support for powernv
Set the TIR default value with the SMT thread index, and place some standard limits on SMT configurations. Now powernv is able to boot skiboot and Linux with a SMT topology, including booting a KVM guest. There are several SPRs and other features (e.g., broadcast msgsnd) that are not implemented, but not used by OPAL or Linux and can be added incrementally. Reviewed-by: Cédric Le Goater <clg@kaod.org> Tested-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Message-ID: <20230705120631.27670-4-npiggin@gmail.com> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
This commit is contained in:
parent
9cdfd1b9f7
commit
934676c7b7
@ -195,11 +195,6 @@ Use a MTD drive to add a PNOR to the machine, and get a NVRAM :
|
||||
|
||||
-drive file=./witherspoon.pnor,format=raw,if=mtd
|
||||
|
||||
CAVEATS
|
||||
-------
|
||||
|
||||
* No support for multiple HW threads (SMT=1). Same as pseries.
|
||||
|
||||
Maintainer contact information
|
||||
------------------------------
|
||||
|
||||
|
12
hw/ppc/pnv.c
12
hw/ppc/pnv.c
@ -887,6 +887,18 @@ static void pnv_init(MachineState *machine)
|
||||
|
||||
pnv->num_chips =
|
||||
machine->smp.max_cpus / (machine->smp.cores * machine->smp.threads);
|
||||
|
||||
if (machine->smp.threads > 8) {
|
||||
error_report("Cannot support more than 8 threads/core "
|
||||
"on a powernv machine");
|
||||
exit(1);
|
||||
}
|
||||
if (!is_power_of_2(machine->smp.threads)) {
|
||||
error_report("Cannot support %d threads/core on a powernv"
|
||||
"machine because it must be a power of 2",
|
||||
machine->smp.threads);
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
* TODO: should we decide on how many chips we can create based
|
||||
* on #cores and Venice vs. Murano vs. Naples chip type etc...,
|
||||
|
@ -218,12 +218,13 @@ static const MemoryRegionOps pnv_core_power10_xscom_ops = {
|
||||
.endianness = DEVICE_BIG_ENDIAN,
|
||||
};
|
||||
|
||||
static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp)
|
||||
static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp,
|
||||
int thread_index)
|
||||
{
|
||||
CPUPPCState *env = &cpu->env;
|
||||
int core_pir;
|
||||
int thread_index = 0; /* TODO: TCG supports only one thread */
|
||||
ppc_spr_t *pir = &env->spr_cb[SPR_PIR];
|
||||
ppc_spr_t *tir = &env->spr_cb[SPR_TIR];
|
||||
Error *local_err = NULL;
|
||||
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(pc->chip);
|
||||
|
||||
@ -239,11 +240,7 @@ static void pnv_core_cpu_realize(PnvCore *pc, PowerPCCPU *cpu, Error **errp)
|
||||
|
||||
core_pir = object_property_get_uint(OBJECT(pc), "pir", &error_abort);
|
||||
|
||||
/*
|
||||
* 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 ?
|
||||
*/
|
||||
tir->default_value = thread_index;
|
||||
pir->default_value = core_pir + thread_index;
|
||||
|
||||
/* Set time-base frequency to 512 MHz */
|
||||
@ -292,7 +289,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp)
|
||||
}
|
||||
|
||||
for (j = 0; j < cc->nr_threads; j++) {
|
||||
pnv_core_cpu_realize(pc, pc->threads[j], &local_err);
|
||||
pnv_core_cpu_realize(pc, pc->threads[j], &local_err, j);
|
||||
if (local_err) {
|
||||
goto err;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user