hw/ppc: Fix build error with CONFIG_POWERNV disabled
Currently when CONFIG_POWERNV is not enabled, the build fails, such as
with --without-default-devices:
$ ./configure --without-default-devices
$ make
[281/283] Linking target qemu-system-ppc64
FAILED: qemu-system-ppc64
cc -m64 @qemu-system-ppc64.rsp
/usr/bin/ld: libqemu-ppc64-softmmu.a.p/target_ppc_misc_helper.c.o: in function `helper_load_sprd':
.../target/ppc/misc_helper.c:335:(.text+0xcdc): undefined reference to `pnv_chip_find_core'
/usr/bin/ld: libqemu-ppc64-softmmu.a.p/target_ppc_misc_helper.c.o: in function `helper_store_sprd':
.../target/ppc/misc_helper.c:375:(.text+0xdf4): undefined reference to `pnv_chip_find_core'
collect2: error: ld returned 1 exit status
...
This is since target/ppc/misc_helper.c references PowerNV specific
'pnv_chip_find_core' call.
Split the PowerNV specific SPRD code out of the generic PowerPC code, by
moving the SPRD code to pnv.c
Fixes: 9808ce6d5c ("target/ppc: Big-core scratch register fix")
Cc: Philippe Mathieu-Daudé <philmd@linaro.org>
Reported-by: Thomas Huth <thuth@redhat.com>
Suggested-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Acked-by: Cédric Le Goater <clg@redhat.com>
Message-ID: <20250820122516.949766-2-adityag@linux.ibm.com>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
This commit is contained in:
parent
1f82ca7234
commit
46d03bb23d
3 changed files with 96 additions and 53 deletions
86
hw/ppc/pnv.c
86
hw/ppc/pnv.c
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/datadir.h"
|
||||
#include "qemu/log.h"
|
||||
#include "qemu/units.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qapi/error.h"
|
||||
|
|
@ -1794,12 +1795,83 @@ static void pnv_chip_power9_pec_realize(PnvChip *chip, Error **errp)
|
|||
}
|
||||
}
|
||||
|
||||
static uint64_t pnv_handle_sprd_load(CPUPPCState *env)
|
||||
{
|
||||
PowerPCCPU *cpu = env_archcpu(env);
|
||||
PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
|
||||
uint64_t sprc = env->spr[SPR_POWER_SPRC];
|
||||
|
||||
if (pc->big_core) {
|
||||
pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
|
||||
}
|
||||
|
||||
switch (sprc & 0x3e0) {
|
||||
case 0: /* SCRATCH0-3 */
|
||||
case 1: /* SCRATCH4-7 */
|
||||
return pc->scratch[(sprc >> 3) & 0x7];
|
||||
|
||||
case 0x1e0: /* core thread state */
|
||||
if (env->excp_model == POWERPC_EXCP_POWER9) {
|
||||
/*
|
||||
* Only implement for POWER9 because skiboot uses it to check
|
||||
* big-core mode. Other bits are unimplemented so we would
|
||||
* prefer to get unimplemented message on POWER10 if it were
|
||||
* used anywhere.
|
||||
*/
|
||||
if (pc->big_core) {
|
||||
return PPC_BIT(63);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* fallthru */
|
||||
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "mfSPRD: Unimplemented SPRC:0x"
|
||||
TARGET_FMT_lx"\n", sprc);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pnv_handle_sprd_store(CPUPPCState *env, uint64_t val)
|
||||
{
|
||||
PowerPCCPU *cpu = env_archcpu(env);
|
||||
uint64_t sprc = env->spr[SPR_POWER_SPRC];
|
||||
PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
|
||||
int nr;
|
||||
|
||||
if (pc->big_core) {
|
||||
pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
|
||||
}
|
||||
|
||||
switch (sprc & 0x3e0) {
|
||||
case 0: /* SCRATCH0-3 */
|
||||
case 1: /* SCRATCH4-7 */
|
||||
/*
|
||||
* Log stores to SCRATCH, because some firmware uses these for
|
||||
* debugging and logging, but they would normally be read by the BMC,
|
||||
* which is not implemented in QEMU yet. This gives a way to get at the
|
||||
* information. Could also dump these upon checkstop.
|
||||
*/
|
||||
nr = (sprc >> 3) & 0x7;
|
||||
pc->scratch[nr] = val;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "mtSPRD: Unimplemented SPRC:0x"
|
||||
TARGET_FMT_lx"\n", sprc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
|
||||
Pnv9Chip *chip9 = PNV9_CHIP(dev);
|
||||
PnvChip *chip = PNV_CHIP(dev);
|
||||
Pnv9Psi *psi9 = &chip9->psi;
|
||||
PowerPCCPU *cpu;
|
||||
PowerPCCPUClass *cpu_class;
|
||||
Error *local_err = NULL;
|
||||
int i;
|
||||
|
||||
|
|
@ -1827,6 +1899,12 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Set handlers for Special registers, such as SPRD */
|
||||
cpu = chip->cores[0]->threads[0];
|
||||
cpu_class = POWERPC_CPU_GET_CLASS(cpu);
|
||||
cpu_class->load_sprd = pnv_handle_sprd_load;
|
||||
cpu_class->store_sprd = pnv_handle_sprd_store;
|
||||
|
||||
/* XIVE interrupt controller (POWER9) */
|
||||
object_property_set_int(OBJECT(&chip9->xive), "ic-bar",
|
||||
PNV9_XIVE_IC_BASE(chip), &error_fatal);
|
||||
|
|
@ -2078,6 +2156,8 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
|
|||
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
|
||||
PnvChip *chip = PNV_CHIP(dev);
|
||||
Pnv10Chip *chip10 = PNV10_CHIP(dev);
|
||||
PowerPCCPU *cpu;
|
||||
PowerPCCPUClass *cpu_class;
|
||||
Error *local_err = NULL;
|
||||
int i;
|
||||
|
||||
|
|
@ -2105,6 +2185,12 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Set handlers for Special registers, such as SPRD */
|
||||
cpu = chip->cores[0]->threads[0];
|
||||
cpu_class = POWERPC_CPU_GET_CLASS(cpu);
|
||||
cpu_class->load_sprd = pnv_handle_sprd_load;
|
||||
cpu_class->store_sprd = pnv_handle_sprd_store;
|
||||
|
||||
/* XIVE2 interrupt controller (POWER10) */
|
||||
object_property_set_int(OBJECT(&chip10->xive), "ic-bar",
|
||||
PNV10_XIVE2_IC_BASE(chip), &error_fatal);
|
||||
|
|
|
|||
|
|
@ -1522,6 +1522,10 @@ struct PowerPCCPUClass {
|
|||
void (*init_proc)(CPUPPCState *env);
|
||||
int (*check_pow)(CPUPPCState *env);
|
||||
int (*check_attn)(CPUPPCState *env);
|
||||
|
||||
/* Handlers to be set by the machine initialising the chips */
|
||||
uint64_t (*load_sprd)(CPUPPCState *env);
|
||||
void (*store_sprd)(CPUPPCState *env, uint64_t val);
|
||||
};
|
||||
|
||||
static inline bool ppc_cpu_core_single_threaded(CPUState *cs)
|
||||
|
|
|
|||
|
|
@ -328,69 +328,22 @@ target_ulong helper_load_sprd(CPUPPCState *env)
|
|||
* accessed by powernv machines.
|
||||
*/
|
||||
PowerPCCPU *cpu = env_archcpu(env);
|
||||
PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
|
||||
target_ulong sprc = env->spr[SPR_POWER_SPRC];
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||
|
||||
if (pc->big_core) {
|
||||
pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
|
||||
if (pcc->load_sprd) {
|
||||
return pcc->load_sprd(env);
|
||||
}
|
||||
|
||||
switch (sprc & 0x3e0) {
|
||||
case 0: /* SCRATCH0-3 */
|
||||
case 1: /* SCRATCH4-7 */
|
||||
return pc->scratch[(sprc >> 3) & 0x7];
|
||||
|
||||
case 0x1e0: /* core thread state */
|
||||
if (env->excp_model == POWERPC_EXCP_POWER9) {
|
||||
/*
|
||||
* Only implement for POWER9 because skiboot uses it to check
|
||||
* big-core mode. Other bits are unimplemented so we would
|
||||
* prefer to get unimplemented message on POWER10 if it were
|
||||
* used anywhere.
|
||||
*/
|
||||
if (pc->big_core) {
|
||||
return PPC_BIT(63);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* fallthru */
|
||||
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "mfSPRD: Unimplemented SPRC:0x"
|
||||
TARGET_FMT_lx"\n", sprc);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void helper_store_sprd(CPUPPCState *env, target_ulong val)
|
||||
{
|
||||
target_ulong sprc = env->spr[SPR_POWER_SPRC];
|
||||
PowerPCCPU *cpu = env_archcpu(env);
|
||||
PnvCore *pc = pnv_cpu_state(cpu)->pnv_core;
|
||||
int nr;
|
||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||
|
||||
if (pc->big_core) {
|
||||
pc = pnv_chip_find_core(pc->chip, CPU_CORE(pc)->core_id & ~0x1);
|
||||
}
|
||||
|
||||
switch (sprc & 0x3e0) {
|
||||
case 0: /* SCRATCH0-3 */
|
||||
case 1: /* SCRATCH4-7 */
|
||||
/*
|
||||
* Log stores to SCRATCH, because some firmware uses these for
|
||||
* debugging and logging, but they would normally be read by the BMC,
|
||||
* which is not implemented in QEMU yet. This gives a way to get at the
|
||||
* information. Could also dump these upon checkstop.
|
||||
*/
|
||||
nr = (sprc >> 3) & 0x7;
|
||||
pc->scratch[nr] = val;
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "mtSPRD: Unimplemented SPRC:0x"
|
||||
TARGET_FMT_lx"\n", sprc);
|
||||
break;
|
||||
if (pcc->store_sprd) {
|
||||
return pcc->store_sprd(env, val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue