Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
npiggin authored and danielhb committed Jul 7, 2023
1 parent 9cdfd1b commit 934676c
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 13 deletions.
5 changes: 0 additions & 5 deletions docs/system/ppc/powernv.rst
Expand Up @@ -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
------------------------------

Expand Down
12 changes: 12 additions & 0 deletions hw/ppc/pnv.c
Expand Up @@ -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...,
Expand Down
13 changes: 5 additions & 8 deletions hw/ppc/pnv_core.c
Expand Up @@ -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);

Expand All @@ -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 */
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit 934676c

Please sign in to comment.