* [PULL 00/27] ppc-for-20250928 queue
@ 2025-09-28 19:26 Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 01/27] ppc/pnv: Introduce Pnv11Chip Harsh Prateek Bora
` (27 more replies)
0 siblings, 28 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel
The following changes since commit d6dfd8d40cebebc3378d379cd28879e0345fbf91:
Merge tag 'pull-target-arm-20250926' of https://gitlab.com/pm215/qemu into staging (2025-09-26 13:27:01 -0700)
are available in the Git repository at:
https://gitlab.com/harshpb/qemu.git tags/pull-ppc-for-20250928-20250929
for you to fetch changes up to 6c51df580d2a64b4e1ef7bdbffeb3615ffe25d43:
target/ppc: use MAKE_64BIT_MASK for mcrfs exception clear mask (2025-09-28 23:50:36 +0530)
----------------------------------------------------------------
ppc queue for 20250928
* Support for PowerNV11 and PPE42 CPU/Machines.
* Deprecation of Power8E and Power8NVL
* Decodetree patches for some floating-point instructions
* Minor bug fixes, improvements in ppc/spapr/xive/xics.
Qemu CI: https://gitlab.com/harshpb/qemu/-/pipelines/2068351418
----------------------------------------------------------------
Aditya Gupta (10):
ppc/pnv: Introduce Pnv11Chip
ppc/pnv: Introduce Power11 PowerNV machine
ppc/pnv: Add PnvChipClass handler to get reference to interrupt controller
ppc/pnv: Add XIVE2 controller to Power11
ppc/pnv: Add PHB5 PCIe Host bridge to Power11
ppc/pnv: Add ChipTOD model for Power11
tests/powernv: Switch to buildroot images instead of op-build
tests/powernv: Add PowerNV test for Power11
target/ppc: Introduce macro for deprecating PowerPC CPUs
target/ppc: Deprecate Power8E and Power8NVL
Chinmay Rath (4):
target/ppc: Move floating-point rounding and conversion instructions to decodetree.
target/ppc: Move floating-point compare instructions to decodetree.
target/ppc: Move floating-point move instructions to decodetree.
target/ppc: Move remaining floating-point move instructions to decodetree.
Denis Sergeev (1):
target/ppc: use MAKE_64BIT_MASK for mcrfs exception clear mask
Fabian Vogt (1):
hw/intc/xics: Add missing call to register vmstate_icp_server
Gautam Menghani (1):
ppc/xive2: Fix integer overflow warning in xive2_redistribute()
Glenn Miles (9):
target/ppc: IBM PPE42 general regs and flags
target/ppc: Add IBM PPE42 family of processors
target/ppc: IBM PPE42 exception flags and regs
target/ppc: Add IBM PPE42 exception model
target/ppc: Support for IBM PPE42 MMU
target/ppc: Add IBM PPE42 special instructions
hw/ppc: Support for an IBM PPE42 CPU decrementer
hw/ppc: Add a test machine for the IBM PPE42 CPU
tests/functional: Add test for IBM PPE42 instructions
Harsh Prateek Bora (1):
ppc/spapr: init lrdr-capapcity phys with ram size if maxmem not provided
MAINTAINERS | 7 +
docs/about/deprecated.rst | 9 +
docs/system/ppc/powernv.rst | 9 +-
include/hw/ppc/pnv.h | 38 ++
include/hw/ppc/pnv_chip.h | 8 +
include/hw/ppc/pnv_chiptod.h | 2 +
include/hw/ppc/pnv_xscom.h | 49 +++
include/hw/ppc/ppc.h | 1 +
target/ppc/cpu-models.h | 4 +
target/ppc/cpu.h | 76 +++-
target/ppc/helper.h | 38 +-
target/ppc/insn32.decode | 106 +++++-
hw/intc/pnv_xive2.c | 4 +-
hw/intc/xics.c | 2 +
hw/intc/xive2.c | 45 ++-
hw/ppc/pnv.c | 560 ++++++++++++++++++++++++++++++
hw/ppc/pnv_chiptod.c | 59 ++++
hw/ppc/pnv_core.c | 17 +
hw/ppc/ppc_booke.c | 7 +-
hw/ppc/ppe42_machine.c | 101 ++++++
hw/ppc/spapr.c | 11 +-
target/ppc/cpu-models.c | 27 +-
target/ppc/cpu_init.c | 251 +++++++++++---
target/ppc/excp_helper.c | 163 +++++++++
target/ppc/fpu_helper.c | 38 +-
target/ppc/helper_regs.c | 45 ++-
target/ppc/tcg-excp_helper.c | 12 +
target/ppc/translate.c | 35 +-
target/ppc/translate/fp-impl.c.inc | 291 ++++++----------
target/ppc/translate/fp-ops.c.inc | 30 --
target/ppc/translate/ppe-impl.c.inc | 609 +++++++++++++++++++++++++++++++++
hw/ppc/Kconfig | 5 +
hw/ppc/meson.build | 2 +
tests/functional/ppc/meson.build | 1 +
tests/functional/ppc/test_ppe42.py | 79 +++++
tests/functional/ppc64/test_powernv.py | 34 +-
36 files changed, 2407 insertions(+), 368 deletions(-)
create mode 100644 hw/ppc/ppe42_machine.c
create mode 100644 target/ppc/translate/ppe-impl.c.inc
create mode 100644 tests/functional/ppc/test_ppe42.py
^ permalink raw reply [flat|nested] 33+ messages in thread
* [PULL 01/27] ppc/pnv: Introduce Pnv11Chip
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 02/27] ppc/pnv: Introduce Power11 PowerNV machine Harsh Prateek Bora
` (26 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Aditya Gupta, Cédric Le Goater, Amit Machhiwal
From: Aditya Gupta <adityag@linux.ibm.com>
Implement Pnv11Chip, currently without chiptod, xive and phb.
Chiptod, XIVE, PHB are implemented in later patches.
Since Power11 core is same as Power10, the implementation of Pnv11Chip
is a duplicate of corresponding Pnv10Chip.
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Tested-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925173049.891406-2-adityag@linux.ibm.com
Message-ID: <20250925173049.891406-2-adityag@linux.ibm.com>
---
include/hw/ppc/pnv.h | 20 +++
include/hw/ppc/pnv_chip.h | 7 +
include/hw/ppc/pnv_xscom.h | 49 ++++++
hw/ppc/pnv.c | 325 +++++++++++++++++++++++++++++++++++++
hw/ppc/pnv_core.c | 17 ++
5 files changed, 418 insertions(+)
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index d8fca079f2..f0002627bc 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -33,6 +33,7 @@ typedef struct PnvChip PnvChip;
typedef struct Pnv8Chip Pnv8Chip;
typedef struct Pnv9Chip Pnv9Chip;
typedef struct Pnv10Chip Pnv10Chip;
+typedef struct Pnv10Chip Pnv11Chip;
#define PNV_CHIP_TYPE_SUFFIX "-" TYPE_PNV_CHIP
#define PNV_CHIP_TYPE_NAME(cpu_model) cpu_model PNV_CHIP_TYPE_SUFFIX
@@ -57,6 +58,10 @@ DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER9,
DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER10,
TYPE_PNV_CHIP_POWER10)
+#define TYPE_PNV_CHIP_POWER11 PNV_CHIP_TYPE_NAME("power11_v2.0")
+DECLARE_INSTANCE_CHECKER(PnvChip, PNV_CHIP_POWER11,
+ TYPE_PNV_CHIP_POWER11)
+
PnvCore *pnv_chip_find_core(PnvChip *chip, uint32_t core_id);
PowerPCCPU *pnv_chip_find_cpu(PnvChip *chip, uint32_t pir);
@@ -252,4 +257,19 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
#define PNV10_HOMER_BASE(chip) \
(0x300ffd800000ll + ((uint64_t)(chip)->chip_id) * PNV_HOMER_SIZE)
+/* Power11 */
+#define PNV11_XSCOM_SIZE PNV10_XSCOM_SIZE
+#define PNV11_XSCOM_BASE(chip) PNV10_XSCOM_BASE(chip)
+
+#define PNV11_LPCM_SIZE PNV10_LPCM_SIZE
+#define PNV11_LPCM_BASE(chip) PNV10_LPCM_BASE(chip)
+
+#define PNV11_PSIHB_ESB_SIZE PNV10_PSIHB_ESB_SIZE
+#define PNV11_PSIHB_ESB_BASE(chip) PNV10_PSIHB_ESB_BASE(chip)
+
+#define PNV11_PSIHB_SIZE PNV10_PSIHB_SIZE
+#define PNV11_PSIHB_BASE(chip) PNV10_PSIHB_BASE(chip)
+
+#define PNV11_OCC_SENSOR_BASE(chip) PNV10_OCC_SENSOR_BASE(chip)
+
#endif /* PPC_PNV_H */
diff --git a/include/hw/ppc/pnv_chip.h b/include/hw/ppc/pnv_chip.h
index 24ce37a9c8..6bd930f8b4 100644
--- a/include/hw/ppc/pnv_chip.h
+++ b/include/hw/ppc/pnv_chip.h
@@ -141,6 +141,13 @@ struct Pnv10Chip {
#define PNV10_PIR2CHIP(pir) (((pir) >> 8) & 0x7f)
#define PNV10_PIR2THREAD(pir) (((pir) & 0x7f))
+#define TYPE_PNV11_CHIP "pnv11-chip"
+DECLARE_INSTANCE_CHECKER(Pnv11Chip, PNV11_CHIP,
+ TYPE_PNV11_CHIP)
+
+/* Power11 core is same as Power10 */
+typedef struct Pnv10Chip Pnv11Chip;
+
struct PnvChipClass {
/*< private >*/
SysBusDeviceClass parent_class;
diff --git a/include/hw/ppc/pnv_xscom.h b/include/hw/ppc/pnv_xscom.h
index b14549db70..610b075a27 100644
--- a/include/hw/ppc/pnv_xscom.h
+++ b/include/hw/ppc/pnv_xscom.h
@@ -207,6 +207,55 @@ struct PnvXScomInterfaceClass {
#define PNV10_XSCOM_PIB_SPIC_BASE 0xc0000
#define PNV10_XSCOM_PIB_SPIC_SIZE 0x20
+/*
+ * Power11 core is same as Power10
+ */
+#define PNV11_XSCOM_EC_BASE(core) PNV10_XSCOM_EC_BASE(core)
+
+#define PNV11_XSCOM_ADU_BASE PNV10_XSCOM_ADU_BASE
+#define PNV11_XSCOM_ADU_SIZE PNV10_XSCOM_ADU_SIZE
+
+#define PNV11_XSCOM_QME_BASE(core) PNV10_XSCOM_QME_BASE(core)
+
+#define PNV11_XSCOM_EQ_BASE(core) PNV10_XSCOM_EQ_BASE(core)
+
+#define PNV11_XSCOM_PSIHB_BASE PNV10_XSCOM_PSIHB_BASE
+#define PNV11_XSCOM_PSIHB_SIZE PNV10_XSCOM_PSIHB_SIZE
+
+#define PNV11_XSCOM_I2CM_BASE PNV10_XSCOM_I2CM_BASE
+#define PNV11_XSCOM_I2CM_SIZE PNV10_XSCOM_I2CM_SIZE
+
+#define PNV11_XSCOM_CHIPTOD_BASE PNV10_XSCOM_CHIPTOD_BASE
+#define PNV11_XSCOM_CHIPTOD_SIZE PNV10_XSCOM_CHIPTOD_SIZE
+
+#define PNV11_XSCOM_OCC_BASE PNV10_XSCOM_OCC_BASE
+#define PNV11_XSCOM_OCC_SIZE PNV10_XSCOM_OCC_SIZE
+
+#define PNV11_XSCOM_SBE_CTRL_BASE PNV10_XSCOM_SBE_CTRL_BASE
+#define PNV11_XSCOM_SBE_CTRL_SIZE PNV10_XSCOM_SBE_CTRL_SIZE
+
+#define PNV11_XSCOM_SBE_MBOX_BASE PNV10_XSCOM_SBE_MBOX_BASE
+#define PNV11_XSCOM_SBE_MBOX_SIZE PNV10_XSCOM_SBE_MBOX_SIZE
+
+#define PNV11_XSCOM_PBA_BASE PNV10_XSCOM_PBA_BASE
+#define PNV11_XSCOM_PBA_SIZE PNV10_XSCOM_PBA_SIZE
+
+#define PNV11_XSCOM_XIVE2_BASE PNV10_XSCOM_XIVE2_BASE
+#define PNV11_XSCOM_XIVE2_SIZE PNV10_XSCOM_XIVE2_SIZE
+
+#define PNV11_XSCOM_N1_CHIPLET_CTRL_REGS_BASE \
+ PNV10_XSCOM_N1_CHIPLET_CTRL_REGS_BASE
+#define PNV11_XSCOM_CHIPLET_CTRL_REGS_SIZE PNV10_XSCOM_CHIPLET_CTRL_REGS_SIZE
+
+#define PNV11_XSCOM_N1_PB_SCOM_EQ_BASE PNV10_XSCOM_N1_PB_SCOM_EQ_BASE
+#define PNV11_XSCOM_N1_PB_SCOM_EQ_SIZE PNV10_XSCOM_N1_PB_SCOM_EQ_SIZE
+
+#define PNV11_XSCOM_N1_PB_SCOM_ES_BASE PNV10_XSCOM_N1_PB_SCOM_ES_BASE
+#define PNV11_XSCOM_N1_PB_SCOM_ES_SIZE PNV10_XSCOM_N1_PB_SCOM_ES_SIZE
+
+#define PNV11_XSCOM_PIB_SPIC_BASE PNV10_XSCOM_PIB_SPIC_BASE
+#define PNV11_XSCOM_PIB_SPIC_SIZE PNV10_XSCOM_PIB_SPIC_SIZE
+
void pnv_xscom_init(PnvChip *chip, uint64_t size, hwaddr addr);
int pnv_dt_xscom(PnvChip *chip, void *fdt, int root_offset,
uint64_t xscom_base, uint64_t xscom_size,
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 9c74f46091..77136091bb 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -491,6 +491,37 @@ static void pnv_chip_power10_dt_populate(PnvChip *chip, void *fdt)
pnv_dt_lpc(chip, fdt, 0, PNV10_LPCM_BASE(chip), PNV10_LPCM_SIZE);
}
+static void pnv_chip_power11_dt_populate(PnvChip *chip, void *fdt)
+{
+ static const char compat[] = "ibm,power11-xscom\0ibm,xscom";
+ int i;
+
+ pnv_dt_xscom(chip, fdt, 0,
+ cpu_to_be64(PNV11_XSCOM_BASE(chip)),
+ cpu_to_be64(PNV11_XSCOM_SIZE),
+ compat, sizeof(compat));
+
+ for (i = 0; i < chip->nr_cores; i++) {
+ PnvCore *pnv_core = chip->cores[i];
+ int offset;
+
+ offset = pnv_dt_core(chip, pnv_core, fdt);
+
+ _FDT((fdt_setprop(fdt, offset, "ibm,pa-features",
+ pa_features_31, sizeof(pa_features_31))));
+
+ if (pnv_core->big_core) {
+ i++; /* Big-core groups two QEMU cores */
+ }
+ }
+
+ if (chip->ram_size) {
+ pnv_dt_memory(fdt, chip->chip_id, chip->ram_start, chip->ram_size);
+ }
+
+ pnv_dt_lpc(chip, fdt, 0, PNV11_LPCM_BASE(chip), PNV11_LPCM_SIZE);
+}
+
static void pnv_dt_rtc(ISADevice *d, void *fdt, int lpc_off)
{
uint32_t io_base = d->ioport_id;
@@ -823,6 +854,26 @@ static ISABus *pnv_chip_power10_isa_create(PnvChip *chip, Error **errp)
return pnv_lpc_isa_create(&chip10->lpc, false, errp);
}
+static ISABus *pnv_chip_power11_isa_create(PnvChip *chip, Error **errp)
+{
+ Pnv11Chip *chip11 = PNV11_CHIP(chip);
+ qemu_irq irq;
+
+ irq = qdev_get_gpio_in(DEVICE(&chip11->psi), PSIHB9_IRQ_LPCHC);
+ qdev_connect_gpio_out_named(DEVICE(&chip11->lpc), "LPCHC", 0, irq);
+
+ irq = qdev_get_gpio_in(DEVICE(&chip11->psi), PSIHB9_IRQ_LPC_SIRQ0);
+ qdev_connect_gpio_out_named(DEVICE(&chip11->lpc), "SERIRQ", 0, irq);
+ irq = qdev_get_gpio_in(DEVICE(&chip11->psi), PSIHB9_IRQ_LPC_SIRQ1);
+ qdev_connect_gpio_out_named(DEVICE(&chip11->lpc), "SERIRQ", 1, irq);
+ irq = qdev_get_gpio_in(DEVICE(&chip11->psi), PSIHB9_IRQ_LPC_SIRQ2);
+ qdev_connect_gpio_out_named(DEVICE(&chip11->lpc), "SERIRQ", 2, irq);
+ irq = qdev_get_gpio_in(DEVICE(&chip11->psi), PSIHB9_IRQ_LPC_SIRQ3);
+ qdev_connect_gpio_out_named(DEVICE(&chip11->lpc), "SERIRQ", 3, irq);
+
+ return pnv_lpc_isa_create(&chip11->lpc, false, errp);
+}
+
static ISABus *pnv_isa_create(PnvChip *chip, Error **errp)
{
return PNV_CHIP_GET_CLASS(chip)->isa_create(chip, errp);
@@ -886,6 +937,12 @@ static uint64_t pnv_chip_power10_xscom_core_base(PnvChip *chip,
return PNV10_XSCOM_EC_BASE(core_id);
}
+static uint64_t pnv_chip_power11_xscom_core_base(PnvChip *chip,
+ uint32_t core_id)
+{
+ return PNV11_XSCOM_EC_BASE(core_id);
+}
+
static bool pnv_match_cpu(const char *default_type, const char *cpu_type)
{
PowerPCCPUClass *ppc_default =
@@ -915,6 +972,13 @@ static void pnv_chip_power10_pic_print_info(PnvChip *chip, GString *buf)
pnv_chip_power9_pic_print_info_child, buf);
}
+static void pnv_chip_power11_pic_print_info(PnvChip *chip, GString *buf)
+{
+ Pnv11Chip *chip11 = PNV11_CHIP(chip);
+
+ pnv_psi_pic_print_info(&chip11->psi, buf);
+}
+
/* Always give the first 1GB to chip 0 else we won't boot */
static uint64_t pnv_chip_get_ram_size(PnvMachineState *pnv, int chip_id)
{
@@ -1452,6 +1516,8 @@ static void pnv_chip_power10_intc_print_info(PnvChip *chip, PowerPCCPU *cpu,
#define POWER10_CORE_MASK (0xffffffffffffffull)
+#define POWER11_CORE_MASK (0xffffffffffffffull)
+
static void pnv_chip_power8_instance_init(Object *obj)
{
Pnv8Chip *chip8 = PNV8_CHIP(obj);
@@ -2350,6 +2416,219 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
}
}
+static void pnv_chip_power11_instance_init(Object *obj)
+{
+ Pnv11Chip *chip11 = PNV11_CHIP(obj);
+ PnvChipClass *pcc = PNV_CHIP_GET_CLASS(obj);
+ int i;
+
+ object_initialize_child(obj, "adu", &chip11->adu, TYPE_PNV_ADU);
+
+ /*
+ * Use Power10 device models for PSI/LPC/OCC/SBE/HOMER as corresponding
+ * device models for Power11 are same
+ */
+ object_initialize_child(obj, "psi", &chip11->psi, TYPE_PNV10_PSI);
+ object_initialize_child(obj, "lpc", &chip11->lpc, TYPE_PNV10_LPC);
+ object_initialize_child(obj, "occ", &chip11->occ, TYPE_PNV10_OCC);
+ object_initialize_child(obj, "sbe", &chip11->sbe, TYPE_PNV10_SBE);
+ object_initialize_child(obj, "homer", &chip11->homer, TYPE_PNV10_HOMER);
+ object_initialize_child(obj, "n1-chiplet", &chip11->n1_chiplet,
+ TYPE_PNV_N1_CHIPLET);
+
+ for (i = 0; i < pcc->i2c_num_engines; i++) {
+ object_initialize_child(obj, "i2c[*]", &chip11->i2c[i], TYPE_PNV_I2C);
+ }
+
+ for (i = 0; i < PNV10_CHIP_MAX_PIB_SPIC; i++) {
+ object_initialize_child(obj, "pib_spic[*]", &chip11->pib_spic[i],
+ TYPE_PNV_SPI);
+ }
+}
+
+static void pnv_chip_power11_quad_realize(Pnv11Chip *chip11, Error **errp)
+{
+ PnvChip *chip = PNV_CHIP(chip11);
+ int i;
+
+ chip11->nr_quads = DIV_ROUND_UP(chip->nr_cores, 4);
+ chip11->quads = g_new0(PnvQuad, chip11->nr_quads);
+
+ for (i = 0; i < chip11->nr_quads; i++) {
+ PnvQuad *eq = &chip11->quads[i];
+
+ pnv_chip_quad_realize_one(chip, eq, chip->cores[i * 4],
+ PNV_QUAD_TYPE_NAME("power11"));
+
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_EQ_BASE(eq->quad_id),
+ &eq->xscom_regs);
+
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_QME_BASE(eq->quad_id),
+ &eq->xscom_qme_regs);
+ }
+}
+
+static void pnv_chip_power11_realize(DeviceState *dev, Error **errp)
+{
+ PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
+ PnvChip *chip = PNV_CHIP(dev);
+ Pnv11Chip *chip11 = PNV11_CHIP(dev);
+ PowerPCCPU *cpu;
+ PowerPCCPUClass *cpu_class;
+ Error *local_err = NULL;
+ int i;
+
+ /* XSCOM bridge is first */
+ pnv_xscom_init(chip, PNV11_XSCOM_SIZE, PNV11_XSCOM_BASE(chip));
+
+ pcc->parent_realize(dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ 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;
+
+ /* ADU */
+ object_property_set_link(OBJECT(&chip11->adu), "lpc", OBJECT(&chip11->lpc),
+ &error_abort);
+ if (!qdev_realize(DEVICE(&chip11->adu), NULL, errp)) {
+ return;
+ }
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_ADU_BASE,
+ &chip11->adu.xscom_regs);
+
+ pnv_chip_power11_quad_realize(chip11, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /* WIP: XIVE added in future patch */
+
+ /* Processor Service Interface (PSI) Host Bridge */
+ object_property_set_int(OBJECT(&chip11->psi), "bar",
+ PNV11_PSIHB_BASE(chip), &error_fatal);
+ /* PSI can be configured to use 64k ESB pages on Power11 */
+ object_property_set_int(OBJECT(&chip11->psi), "shift", XIVE_ESB_64K,
+ &error_fatal);
+ if (!qdev_realize(DEVICE(&chip11->psi), NULL, errp)) {
+ return;
+ }
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_PSIHB_BASE,
+ &PNV_PSI(&chip11->psi)->xscom_regs);
+
+ /* LPC */
+ if (!qdev_realize(DEVICE(&chip11->lpc), NULL, errp)) {
+ return;
+ }
+ memory_region_add_subregion(get_system_memory(), PNV11_LPCM_BASE(chip),
+ &chip11->lpc.xscom_regs);
+
+ chip->fw_mr = &chip11->lpc.isa_fw;
+ chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
+ (uint64_t) PNV11_LPCM_BASE(chip));
+
+ /* HOMER (must be created before OCC) */
+ object_property_set_link(OBJECT(&chip11->homer), "chip", OBJECT(chip),
+ &error_abort);
+ if (!qdev_realize(DEVICE(&chip11->homer), NULL, errp)) {
+ return;
+ }
+ /* Homer Xscom region */
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_PBA_BASE,
+ &chip11->homer.pba_regs);
+ /* Homer RAM region */
+ memory_region_add_subregion(get_system_memory(), chip11->homer.base,
+ &chip11->homer.mem);
+
+ /* Create the simplified OCC model */
+ object_property_set_link(OBJECT(&chip11->occ), "homer",
+ OBJECT(&chip11->homer), &error_abort);
+ if (!qdev_realize(DEVICE(&chip11->occ), NULL, errp)) {
+ return;
+ }
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_OCC_BASE,
+ &chip11->occ.xscom_regs);
+ qdev_connect_gpio_out(DEVICE(&chip11->occ), 0, qdev_get_gpio_in(
+ DEVICE(&chip11->psi), PSIHB9_IRQ_OCC));
+
+ /* OCC SRAM model */
+ memory_region_add_subregion(get_system_memory(),
+ PNV11_OCC_SENSOR_BASE(chip),
+ &chip11->occ.sram_regs);
+
+ /* SBE */
+ if (!qdev_realize(DEVICE(&chip11->sbe), NULL, errp)) {
+ return;
+ }
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_SBE_CTRL_BASE,
+ &chip11->sbe.xscom_ctrl_regs);
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_SBE_MBOX_BASE,
+ &chip11->sbe.xscom_mbox_regs);
+ qdev_connect_gpio_out(DEVICE(&chip11->sbe), 0, qdev_get_gpio_in(
+ DEVICE(&chip11->psi), PSIHB9_IRQ_PSU));
+
+ /* N1 chiplet */
+ if (!qdev_realize(DEVICE(&chip11->n1_chiplet), NULL, errp)) {
+ return;
+ }
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_N1_CHIPLET_CTRL_REGS_BASE,
+ &chip11->n1_chiplet.nest_pervasive.xscom_ctrl_regs_mr);
+
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_N1_PB_SCOM_EQ_BASE,
+ &chip11->n1_chiplet.xscom_pb_eq_mr);
+
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_N1_PB_SCOM_ES_BASE,
+ &chip11->n1_chiplet.xscom_pb_es_mr);
+
+ /* WIP: PHB added in future patch */
+
+ /*
+ * I2C
+ */
+ for (i = 0; i < pcc->i2c_num_engines; i++) {
+ Object *obj = OBJECT(&chip11->i2c[i]);
+
+ object_property_set_int(obj, "engine", i + 1, &error_fatal);
+ object_property_set_int(obj, "num-busses",
+ pcc->i2c_ports_per_engine[i],
+ &error_fatal);
+ object_property_set_link(obj, "chip", OBJECT(chip), &error_abort);
+ if (!qdev_realize(DEVICE(obj), NULL, errp)) {
+ return;
+ }
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_I2CM_BASE +
+ (chip11->i2c[i].engine - 1) *
+ PNV11_XSCOM_I2CM_SIZE,
+ &chip11->i2c[i].xscom_regs);
+ qdev_connect_gpio_out(DEVICE(&chip11->i2c[i]), 0,
+ qdev_get_gpio_in(DEVICE(&chip11->psi),
+ PSIHB9_IRQ_SBE_I2C));
+ }
+ /* PIB SPI Controller */
+ for (i = 0; i < PNV10_CHIP_MAX_PIB_SPIC; i++) {
+ object_property_set_int(OBJECT(&chip11->pib_spic[i]), "spic_num",
+ i, &error_fatal);
+ /* pib_spic[2] connected to 25csm04 which implements 1 byte transfer */
+ object_property_set_int(OBJECT(&chip11->pib_spic[i]), "transfer_len",
+ (i == 2) ? 1 : 4, &error_fatal);
+ object_property_set_int(OBJECT(&chip11->pib_spic[i]), "chip-id",
+ chip->chip_id, &error_fatal);
+ if (!sysbus_realize(SYS_BUS_DEVICE(OBJECT
+ (&chip11->pib_spic[i])), errp)) {
+ return;
+ }
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_PIB_SPIC_BASE +
+ i * PNV11_XSCOM_PIB_SPIC_SIZE,
+ &chip11->pib_spic[i].xscom_spic_regs);
+ }
+}
+
static void pnv_rainier_i2c_init(PnvMachineState *pnv)
{
int i;
@@ -2415,6 +2694,34 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, const void *data)
&k->parent_realize);
}
+static uint32_t pnv_chip_power11_xscom_pcba(PnvChip *chip, uint64_t addr)
+{
+ addr &= (PNV11_XSCOM_SIZE - 1);
+ return addr >> 3;
+}
+
+static void pnv_chip_power11_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PnvChipClass *k = PNV_CHIP_CLASS(klass);
+ static const int i2c_ports_per_engine[PNV10_CHIP_MAX_I2C] = {14, 14, 2, 16};
+
+ k->chip_cfam_id = 0x220da04980000000ull; /* P11 DD2.0 (with NX) */
+ k->cores_mask = POWER11_CORE_MASK;
+ k->get_pir_tir = pnv_get_pir_tir_p10;
+ k->isa_create = pnv_chip_power11_isa_create;
+ k->dt_populate = pnv_chip_power11_dt_populate;
+ k->pic_print_info = pnv_chip_power11_pic_print_info;
+ k->xscom_core_base = pnv_chip_power11_xscom_core_base;
+ k->xscom_pcba = pnv_chip_power11_xscom_pcba;
+ dc->desc = "PowerNV Chip Power11";
+ k->i2c_num_engines = PNV10_CHIP_MAX_I2C;
+ k->i2c_ports_per_engine = i2c_ports_per_engine;
+
+ device_class_set_parent_realize(dc, pnv_chip_power11_realize,
+ &k->parent_realize);
+}
+
static void pnv_chip_core_sanitize(PnvMachineState *pnv, PnvChip *chip,
Error **errp)
{
@@ -3033,6 +3340,13 @@ static void pnv_machine_class_init(ObjectClass *oc, const void *data)
.parent = TYPE_PNV10_CHIP, \
}
+#define DEFINE_PNV11_CHIP_TYPE(type, class_initfn) \
+ { \
+ .name = type, \
+ .class_init = class_initfn, \
+ .parent = TYPE_PNV11_CHIP, \
+ }
+
static const TypeInfo types[] = {
{
.name = MACHINE_TYPE_NAME("powernv10-rainier"),
@@ -3088,6 +3402,17 @@ static const TypeInfo types[] = {
.abstract = true,
},
+ /*
+ * P11 chip and variants
+ */
+ {
+ .name = TYPE_PNV11_CHIP,
+ .parent = TYPE_PNV_CHIP,
+ .instance_init = pnv_chip_power11_instance_init,
+ .instance_size = sizeof(Pnv11Chip),
+ },
+ DEFINE_PNV11_CHIP_TYPE(TYPE_PNV_CHIP_POWER11, pnv_chip_power11_class_init),
+
/*
* P10 chip and variants
*/
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 08c20224b9..fb2dfc7ba2 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -473,6 +473,11 @@ static void pnv_core_power10_class_init(ObjectClass *oc, const void *data)
pcc->xscom_size = PNV10_XSCOM_EC_SIZE;
}
+static void pnv_core_power11_class_init(ObjectClass *oc, const void *data)
+{
+ pnv_core_power10_class_init(oc, data);
+}
+
static void pnv_core_class_init(ObjectClass *oc, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
@@ -504,6 +509,7 @@ static const TypeInfo pnv_core_infos[] = {
DEFINE_PNV_CORE_TYPE(power8, "power8nvl_v1.0"),
DEFINE_PNV_CORE_TYPE(power9, "power9_v2.2"),
DEFINE_PNV_CORE_TYPE(power10, "power10_v2.0"),
+ DEFINE_PNV_CORE_TYPE(power11, "power11_v2.0"),
};
DEFINE_TYPES(pnv_core_infos)
@@ -725,6 +731,12 @@ static void pnv_quad_power10_class_init(ObjectClass *oc, const void *data)
pqc->xscom_qme_size = PNV10_XSCOM_QME_SIZE;
}
+static void pnv_quad_power11_class_init(ObjectClass *oc, const void *data)
+{
+ /* Power11 quad is similar to Power10 quad */
+ pnv_quad_power10_class_init(oc, data);
+}
+
static void pnv_quad_class_init(ObjectClass *oc, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
@@ -752,6 +764,11 @@ static const TypeInfo pnv_quad_infos[] = {
.name = PNV_QUAD_TYPE_NAME("power10"),
.class_init = pnv_quad_power10_class_init,
},
+ {
+ .parent = TYPE_PNV_QUAD,
+ .name = PNV_QUAD_TYPE_NAME("power11"),
+ .class_init = pnv_quad_power11_class_init,
+ },
};
DEFINE_TYPES(pnv_quad_infos);
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 02/27] ppc/pnv: Introduce Power11 PowerNV machine
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 01/27] ppc/pnv: Introduce Pnv11Chip Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 03/27] ppc/pnv: Add PnvChipClass handler to get reference to interrupt controller Harsh Prateek Bora
` (25 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Aditya Gupta, Cédric Le Goater, Amit Machhiwal
From: Aditya Gupta <adityag@linux.ibm.com>
The Powernv11 machine doesn't have XIVE & PHBs as of now
XIVE2 interface and PHB5 added in later patches to Powernv11 machine
Also add mention of Power11 to powernv documentation
Note: A difference from P10's and P11's machine_class_init is, in P11
different number of PHBs cannot be used on the command line, ie. the
following line does NOT exist in pnv_machine_power11_class_init, which
existed in case of Power10:
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_PNV_PHB);
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Tested-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925173049.891406-3-adityag@linux.ibm.com
Message-ID: <20250925173049.891406-3-adityag@linux.ibm.com>
---
docs/system/ppc/powernv.rst | 9 +++++----
hw/ppc/pnv.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/docs/system/ppc/powernv.rst b/docs/system/ppc/powernv.rst
index f3ec2cc69c..5154794cc8 100644
--- a/docs/system/ppc/powernv.rst
+++ b/docs/system/ppc/powernv.rst
@@ -1,5 +1,5 @@
-PowerNV family boards (``powernv8``, ``powernv9``, ``powernv10``)
-==================================================================
+PowerNV family boards (``powernv8``, ``powernv9``, ``powernv10``, ``powernv11``)
+================================================================================
PowerNV (as Non-Virtualized) is the "bare metal" platform using the
OPAL firmware. It runs Linux on IBM and OpenPOWER systems and it can
@@ -15,11 +15,12 @@ beyond the scope of what QEMU addresses today.
Supported devices
-----------------
- * Multi processor support for POWER8, POWER8NVL and POWER9.
+ * Multi processor support for POWER8, POWER8NVL, POWER9, Power10 and Power11.
* XSCOM, serial communication sideband bus to configure chiplets.
* Simple LPC Controller.
* Processor Service Interface (PSI) Controller.
- * Interrupt Controller, XICS (POWER8) and XIVE (POWER9) and XIVE2 (Power10).
+ * Interrupt Controller, XICS (POWER8) and XIVE (POWER9) and XIVE2 (Power10 &
+ Power11).
* POWER8 PHB3 PCIe Host bridge and POWER9 PHB4 PCIe Host bridge.
* Simple OCC is an on-chip micro-controller used for power management tasks.
* iBT device to handle BMC communication, with the internal BMC simulator
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 77136091bb..423954ba7e 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -3235,6 +3235,35 @@ static void pnv_machine_p10_rainier_class_init(ObjectClass *oc,
pmc->i2c_init = pnv_rainier_i2c_init;
}
+static void pnv_machine_power11_class_init(ObjectClass *oc, const void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+ PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc);
+ static const char compat[] = "qemu,powernv11\0ibm,powernv";
+
+ pmc->compat = compat;
+ pmc->compat_size = sizeof(compat);
+ pmc->max_smt_threads = 4;
+ pmc->has_lpar_per_thread = true;
+ pmc->quirk_tb_big_core = true;
+ pmc->dt_power_mgt = pnv_dt_power_mgt;
+
+ mc->desc = "IBM PowerNV (Non-Virtualized) Power11";
+ mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power11_v2.0");
+
+ object_class_property_add_bool(oc, "big-core",
+ pnv_machine_get_big_core,
+ pnv_machine_set_big_core);
+ object_class_property_set_description(oc, "big-core",
+ "Use big-core (aka fused-core) mode");
+
+ object_class_property_add_bool(oc, "lpar-per-core",
+ pnv_machine_get_lpar_per_core,
+ pnv_machine_set_lpar_per_core);
+ object_class_property_set_description(oc, "lpar-per-core",
+ "Use 1 LPAR per core mode");
+}
+
static void pnv_cpu_do_nmi_on_cpu(CPUState *cs, run_on_cpu_data arg)
{
CPUPPCState *env = cpu_env(cs);
@@ -3348,6 +3377,11 @@ static void pnv_machine_class_init(ObjectClass *oc, const void *data)
}
static const TypeInfo types[] = {
+ {
+ .name = MACHINE_TYPE_NAME("powernv11"),
+ .parent = TYPE_PNV_MACHINE,
+ .class_init = pnv_machine_power11_class_init,
+ },
{
.name = MACHINE_TYPE_NAME("powernv10-rainier"),
.parent = MACHINE_TYPE_NAME("powernv10"),
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 03/27] ppc/pnv: Add PnvChipClass handler to get reference to interrupt controller
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 01/27] ppc/pnv: Introduce Pnv11Chip Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 02/27] ppc/pnv: Introduce Power11 PowerNV machine Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 04/27] ppc/pnv: Add XIVE2 controller to Power11 Harsh Prateek Bora
` (24 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Aditya Gupta, Cédric Le Goater, Amit Machhiwal
From: Aditya Gupta <adityag@linux.ibm.com>
Existing code in XIVE2 assumes the chip to be a Power10 Chip.
Instead add a handler to get reference to the interrupt controller (XIVE)
for a given Power Chip.
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925173049.891406-4-adityag@linux.ibm.com
Message-ID: <20250925173049.891406-4-adityag@linux.ibm.com>
---
include/hw/ppc/pnv_chip.h | 1 +
hw/intc/pnv_xive2.c | 4 ++--
hw/ppc/pnv.c | 12 ++++++++++++
3 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/include/hw/ppc/pnv_chip.h b/include/hw/ppc/pnv_chip.h
index 6bd930f8b4..a5b8c49680 100644
--- a/include/hw/ppc/pnv_chip.h
+++ b/include/hw/ppc/pnv_chip.h
@@ -170,6 +170,7 @@ struct PnvChipClass {
void (*intc_reset)(PnvChip *chip, PowerPCCPU *cpu);
void (*intc_destroy)(PnvChip *chip, PowerPCCPU *cpu);
void (*intc_print_info)(PnvChip *chip, PowerPCCPU *cpu, GString *buf);
+ void* (*intc_get)(PnvChip *chip);
ISABus *(*isa_create)(PnvChip *chip, Error **errp);
void (*dt_populate)(PnvChip *chip, void *fdt);
void (*pic_print_info)(PnvChip *chip, GString *buf);
diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c
index e019cad5c1..0663baab54 100644
--- a/hw/intc/pnv_xive2.c
+++ b/hw/intc/pnv_xive2.c
@@ -110,8 +110,8 @@ static PnvXive2 *pnv_xive2_get_remote(uint32_t vsd_type, hwaddr fwd_addr)
int i;
for (i = 0; i < pnv->num_chips; i++) {
- Pnv10Chip *chip10 = PNV10_CHIP(pnv->chips[i]);
- PnvXive2 *xive = &chip10->xive;
+ PnvChipClass *k = PNV_CHIP_GET_CLASS(pnv->chips[i]);
+ PnvXive2 *xive = PNV_XIVE2(k->intc_get(pnv->chips[i]));
/*
* Is this the XIVE matching the forwarded VSD address is for this
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 423954ba7e..a4fdf59207 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -1486,6 +1486,16 @@ static void pnv_chip_power10_intc_print_info(PnvChip *chip, PowerPCCPU *cpu,
xive_tctx_pic_print_info(XIVE_TCTX(pnv_cpu_state(cpu)->intc), buf);
}
+static void *pnv_chip_power10_intc_get(PnvChip *chip)
+{
+ return &PNV10_CHIP(chip)->xive;
+}
+
+static void *pnv_chip_power11_intc_get(PnvChip *chip)
+{
+ return &PNV11_CHIP(chip)->xive;
+}
+
/*
* Allowed core identifiers on a POWER8 Processor Chip :
*
@@ -2680,6 +2690,7 @@ static void pnv_chip_power10_class_init(ObjectClass *klass, const void *data)
k->intc_reset = pnv_chip_power10_intc_reset;
k->intc_destroy = pnv_chip_power10_intc_destroy;
k->intc_print_info = pnv_chip_power10_intc_print_info;
+ k->intc_get = pnv_chip_power10_intc_get;
k->isa_create = pnv_chip_power10_isa_create;
k->dt_populate = pnv_chip_power10_dt_populate;
k->pic_print_info = pnv_chip_power10_pic_print_info;
@@ -2709,6 +2720,7 @@ static void pnv_chip_power11_class_init(ObjectClass *klass, const void *data)
k->chip_cfam_id = 0x220da04980000000ull; /* P11 DD2.0 (with NX) */
k->cores_mask = POWER11_CORE_MASK;
k->get_pir_tir = pnv_get_pir_tir_p10;
+ k->intc_get = pnv_chip_power11_intc_get;
k->isa_create = pnv_chip_power11_isa_create;
k->dt_populate = pnv_chip_power11_dt_populate;
k->pic_print_info = pnv_chip_power11_pic_print_info;
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 04/27] ppc/pnv: Add XIVE2 controller to Power11
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (2 preceding siblings ...)
2025-09-28 19:26 ` [PULL 03/27] ppc/pnv: Add PnvChipClass handler to get reference to interrupt controller Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 05/27] ppc/pnv: Add PHB5 PCIe Host bridge " Harsh Prateek Bora
` (23 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Aditya Gupta, Cédric Le Goater, Amit Machhiwal
From: Aditya Gupta <adityag@linux.ibm.com>
Add a XIVE2 controller to Power11 chip and machine.
The controller has the same logic as Power10.
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Tested-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925173049.891406-5-adityag@linux.ibm.com
Message-ID: <20250925173049.891406-5-adityag@linux.ibm.com>
---
include/hw/ppc/pnv.h | 18 +++++++
hw/ppc/pnv.c | 121 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 138 insertions(+), 1 deletion(-)
diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h
index f0002627bc..cbdddfc73c 100644
--- a/include/hw/ppc/pnv.h
+++ b/include/hw/ppc/pnv.h
@@ -270,6 +270,24 @@ void pnv_bmc_set_pnor(IPMIBmc *bmc, PnvPnor *pnor);
#define PNV11_PSIHB_SIZE PNV10_PSIHB_SIZE
#define PNV11_PSIHB_BASE(chip) PNV10_PSIHB_BASE(chip)
+#define PNV11_XIVE2_IC_SIZE PNV10_XIVE2_IC_SIZE
+#define PNV11_XIVE2_IC_BASE(chip) PNV10_XIVE2_IC_BASE(chip)
+
+#define PNV11_XIVE2_TM_SIZE PNV10_XIVE2_TM_SIZE
+#define PNV11_XIVE2_TM_BASE(chip) PNV10_XIVE2_TM_BASE(chip)
+
+#define PNV11_XIVE2_NVC_SIZE PNV10_XIVE2_NVC_SIZE
+#define PNV11_XIVE2_NVC_BASE(chip) PNV10_XIVE2_NVC_BASE(chip)
+
+#define PNV11_XIVE2_NVPG_SIZE PNV10_XIVE2_NVPG_SIZE
+#define PNV11_XIVE2_NVPG_BASE(chip) PNV10_XIVE2_NVPG_BASE(chip)
+
+#define PNV11_XIVE2_ESB_SIZE PNV10_XIVE2_ESB_SIZE
+#define PNV11_XIVE2_ESB_BASE(chip) PNV10_XIVE2_ESB_BASE(chip)
+
+#define PNV11_XIVE2_END_SIZE PNV10_XIVE2_END_SIZE
+#define PNV11_XIVE2_END_BASE(chip) PNV10_XIVE2_END_BASE(chip)
+
#define PNV11_OCC_SENSOR_BASE(chip) PNV10_OCC_SENSOR_BASE(chip)
#endif /* PPC_PNV_H */
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index a4fdf59207..8097d3c09a 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -976,6 +976,7 @@ static void pnv_chip_power11_pic_print_info(PnvChip *chip, GString *buf)
{
Pnv11Chip *chip11 = PNV11_CHIP(chip);
+ pnv_xive2_pic_print_info(&chip11->xive, buf);
pnv_psi_pic_print_info(&chip11->psi, buf);
}
@@ -1491,6 +1492,50 @@ static void *pnv_chip_power10_intc_get(PnvChip *chip)
return &PNV10_CHIP(chip)->xive;
}
+static void pnv_chip_power11_intc_create(PnvChip *chip, PowerPCCPU *cpu,
+ Error **errp)
+{
+ Pnv11Chip *chip11 = PNV11_CHIP(chip);
+ Error *local_err = NULL;
+ Object *obj;
+ PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
+
+ /*
+ * The core creates its interrupt presenter but the XIVE2 interrupt
+ * controller object is initialized afterwards. Hopefully, it's
+ * only used at runtime.
+ */
+ obj = xive_tctx_create(OBJECT(cpu), XIVE_PRESENTER(&chip11->xive),
+ &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ pnv_cpu->intc = obj;
+}
+
+static void pnv_chip_power11_intc_reset(PnvChip *chip, PowerPCCPU *cpu)
+{
+ PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
+
+ xive_tctx_reset(XIVE_TCTX(pnv_cpu->intc));
+}
+
+static void pnv_chip_power11_intc_destroy(PnvChip *chip, PowerPCCPU *cpu)
+{
+ PnvCPUState *pnv_cpu = pnv_cpu_state(cpu);
+
+ xive_tctx_destroy(XIVE_TCTX(pnv_cpu->intc));
+ pnv_cpu->intc = NULL;
+}
+
+static void pnv_chip_power11_intc_print_info(PnvChip *chip, PowerPCCPU *cpu,
+ GString *buf)
+{
+ xive_tctx_pic_print_info(XIVE_TCTX(pnv_cpu_state(cpu)->intc), buf);
+}
+
static void *pnv_chip_power11_intc_get(PnvChip *chip)
{
return &PNV11_CHIP(chip)->xive;
@@ -2443,6 +2488,10 @@ static void pnv_chip_power11_instance_init(Object *obj)
object_initialize_child(obj, "occ", &chip11->occ, TYPE_PNV10_OCC);
object_initialize_child(obj, "sbe", &chip11->sbe, TYPE_PNV10_SBE);
object_initialize_child(obj, "homer", &chip11->homer, TYPE_PNV10_HOMER);
+
+ object_initialize_child(obj, "xive", &chip11->xive, TYPE_PNV_XIVE2);
+ object_property_add_alias(obj, "xive-fabric", OBJECT(&chip11->xive),
+ "xive-fabric");
object_initialize_child(obj, "n1-chiplet", &chip11->n1_chiplet,
TYPE_PNV_N1_CHIPLET);
@@ -2518,7 +2567,26 @@ static void pnv_chip_power11_realize(DeviceState *dev, Error **errp)
return;
}
- /* WIP: XIVE added in future patch */
+ /* XIVE2 interrupt controller */
+ object_property_set_int(OBJECT(&chip11->xive), "ic-bar",
+ PNV11_XIVE2_IC_BASE(chip), &error_fatal);
+ object_property_set_int(OBJECT(&chip11->xive), "esb-bar",
+ PNV11_XIVE2_ESB_BASE(chip), &error_fatal);
+ object_property_set_int(OBJECT(&chip11->xive), "end-bar",
+ PNV11_XIVE2_END_BASE(chip), &error_fatal);
+ object_property_set_int(OBJECT(&chip11->xive), "nvpg-bar",
+ PNV11_XIVE2_NVPG_BASE(chip), &error_fatal);
+ object_property_set_int(OBJECT(&chip11->xive), "nvc-bar",
+ PNV11_XIVE2_NVC_BASE(chip), &error_fatal);
+ object_property_set_int(OBJECT(&chip11->xive), "tm-bar",
+ PNV11_XIVE2_TM_BASE(chip), &error_fatal);
+ object_property_set_link(OBJECT(&chip11->xive), "chip", OBJECT(chip),
+ &error_abort);
+ if (!sysbus_realize(SYS_BUS_DEVICE(&chip11->xive), errp)) {
+ return;
+ }
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_XIVE2_BASE,
+ &chip11->xive.xscom_regs);
/* Processor Service Interface (PSI) Host Bridge */
object_property_set_int(OBJECT(&chip11->psi), "bar",
@@ -2720,6 +2788,10 @@ static void pnv_chip_power11_class_init(ObjectClass *klass, const void *data)
k->chip_cfam_id = 0x220da04980000000ull; /* P11 DD2.0 (with NX) */
k->cores_mask = POWER11_CORE_MASK;
k->get_pir_tir = pnv_get_pir_tir_p10;
+ k->intc_create = pnv_chip_power11_intc_create;
+ k->intc_reset = pnv_chip_power11_intc_reset;
+ k->intc_destroy = pnv_chip_power11_intc_destroy;
+ k->intc_print_info = pnv_chip_power11_intc_print_info;
k->intc_get = pnv_chip_power11_intc_get;
k->isa_create = pnv_chip_power11_isa_create;
k->dt_populate = pnv_chip_power11_dt_populate;
@@ -3073,6 +3145,45 @@ static int pnv10_xive_broadcast(XiveFabric *xfb,
return 0;
}
+static bool pnv11_xive_match_nvt(XiveFabric *xfb, uint8_t format,
+ uint8_t nvt_blk, uint32_t nvt_idx,
+ bool crowd, bool cam_ignore, uint8_t priority,
+ uint32_t logic_serv,
+ XiveTCTXMatch *match)
+{
+ PnvMachineState *pnv = PNV_MACHINE(xfb);
+ int i;
+
+ for (i = 0; i < pnv->num_chips; i++) {
+ Pnv11Chip *chip11 = PNV11_CHIP(pnv->chips[i]);
+ XivePresenter *xptr = XIVE_PRESENTER(&chip11->xive);
+ XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
+
+ xpc->match_nvt(xptr, format, nvt_blk, nvt_idx, crowd,
+ cam_ignore, priority, logic_serv, match);
+ }
+
+ return !!match->count;
+}
+
+static int pnv11_xive_broadcast(XiveFabric *xfb,
+ uint8_t nvt_blk, uint32_t nvt_idx,
+ bool crowd, bool cam_ignore,
+ uint8_t priority)
+{
+ PnvMachineState *pnv = PNV_MACHINE(xfb);
+ int i;
+
+ for (i = 0; i < pnv->num_chips; i++) {
+ Pnv11Chip *chip11 = PNV11_CHIP(pnv->chips[i]);
+ XivePresenter *xptr = XIVE_PRESENTER(&chip11->xive);
+ XivePresenterClass *xpc = XIVE_PRESENTER_GET_CLASS(xptr);
+
+ xpc->broadcast(xptr, nvt_blk, nvt_idx, crowd, cam_ignore, priority);
+ }
+ return 0;
+}
+
static bool pnv_machine_get_big_core(Object *obj, Error **errp)
{
PnvMachineState *pnv = PNV_MACHINE(obj);
@@ -3251,6 +3362,7 @@ static void pnv_machine_power11_class_init(ObjectClass *oc, const void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc);
+ XiveFabricClass *xfc = XIVE_FABRIC_CLASS(oc);
static const char compat[] = "qemu,powernv11\0ibm,powernv";
pmc->compat = compat;
@@ -3260,6 +3372,9 @@ static void pnv_machine_power11_class_init(ObjectClass *oc, const void *data)
pmc->quirk_tb_big_core = true;
pmc->dt_power_mgt = pnv_dt_power_mgt;
+ xfc->match_nvt = pnv11_xive_match_nvt;
+ xfc->broadcast = pnv11_xive_broadcast;
+
mc->desc = "IBM PowerNV (Non-Virtualized) Power11";
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power11_v2.0");
@@ -3393,6 +3508,10 @@ static const TypeInfo types[] = {
.name = MACHINE_TYPE_NAME("powernv11"),
.parent = TYPE_PNV_MACHINE,
.class_init = pnv_machine_power11_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_XIVE_FABRIC },
+ { },
+ },
},
{
.name = MACHINE_TYPE_NAME("powernv10-rainier"),
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 05/27] ppc/pnv: Add PHB5 PCIe Host bridge to Power11
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (3 preceding siblings ...)
2025-09-28 19:26 ` [PULL 04/27] ppc/pnv: Add XIVE2 controller to Power11 Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 06/27] ppc/pnv: Add ChipTOD model for Power11 Harsh Prateek Bora
` (22 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Aditya Gupta, Cédric Le Goater, Amit Machhiwal
From: Aditya Gupta <adityag@linux.ibm.com>
Power11 also uses PHB5, same as Power10.
Add Power11 PHBs with similar code as the corresponding Power10 implementation.
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Tested-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925173049.891406-6-adityag@linux.ibm.com
Message-ID: <20250925173049.891406-6-adityag@linux.ibm.com>
---
hw/ppc/pnv.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 56 insertions(+), 1 deletion(-)
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 8097d3c09a..2b4df6076c 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -978,6 +978,8 @@ static void pnv_chip_power11_pic_print_info(PnvChip *chip, GString *buf)
pnv_xive2_pic_print_info(&chip11->xive, buf);
pnv_psi_pic_print_info(&chip11->psi, buf);
+ object_child_foreach_recursive(OBJECT(chip),
+ pnv_chip_power9_pic_print_info_child, buf);
}
/* Always give the first 1GB to chip 0 else we won't boot */
@@ -2473,6 +2475,7 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
static void pnv_chip_power11_instance_init(Object *obj)
{
+ PnvChip *chip = PNV_CHIP(obj);
Pnv11Chip *chip11 = PNV11_CHIP(obj);
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(obj);
int i;
@@ -2495,6 +2498,13 @@ static void pnv_chip_power11_instance_init(Object *obj)
object_initialize_child(obj, "n1-chiplet", &chip11->n1_chiplet,
TYPE_PNV_N1_CHIPLET);
+ chip->num_pecs = pcc->num_pecs;
+
+ for (i = 0; i < chip->num_pecs; i++) {
+ object_initialize_child(obj, "pec[*]", &chip11->pecs[i],
+ TYPE_PNV_PHB5_PEC);
+ }
+
for (i = 0; i < pcc->i2c_num_engines; i++) {
object_initialize_child(obj, "i2c[*]", &chip11->i2c[i], TYPE_PNV_I2C);
}
@@ -2527,6 +2537,38 @@ static void pnv_chip_power11_quad_realize(Pnv11Chip *chip11, Error **errp)
}
}
+static void pnv_chip_power11_phb_realize(PnvChip *chip, Error **errp)
+{
+ Pnv11Chip *chip11 = PNV11_CHIP(chip);
+ int i;
+
+ for (i = 0; i < chip->num_pecs; i++) {
+ PnvPhb4PecState *pec = &chip11->pecs[i];
+ PnvPhb4PecClass *pecc = PNV_PHB4_PEC_GET_CLASS(pec);
+ uint32_t pec_cplt_base;
+ uint32_t pec_nest_base;
+ uint32_t pec_pci_base;
+
+ object_property_set_int(OBJECT(pec), "index", i, &error_fatal);
+ object_property_set_int(OBJECT(pec), "chip-id", chip->chip_id,
+ &error_fatal);
+ object_property_set_link(OBJECT(pec), "chip", OBJECT(chip),
+ &error_fatal);
+ if (!qdev_realize(DEVICE(pec), NULL, errp)) {
+ return;
+ }
+
+ pec_cplt_base = pecc->xscom_cplt_base(pec);
+ pec_nest_base = pecc->xscom_nest_base(pec);
+ pec_pci_base = pecc->xscom_pci_base(pec);
+
+ pnv_xscom_add_subregion(chip, pec_cplt_base,
+ &pec->nest_pervasive.xscom_ctrl_regs_mr);
+ pnv_xscom_add_subregion(chip, pec_nest_base, &pec->nest_regs_mr);
+ pnv_xscom_add_subregion(chip, pec_pci_base, &pec->pci_regs_mr);
+ }
+}
+
static void pnv_chip_power11_realize(DeviceState *dev, Error **errp)
{
PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev);
@@ -2664,7 +2706,12 @@ static void pnv_chip_power11_realize(DeviceState *dev, Error **errp)
pnv_xscom_add_subregion(chip, PNV11_XSCOM_N1_PB_SCOM_ES_BASE,
&chip11->n1_chiplet.xscom_pb_es_mr);
- /* WIP: PHB added in future patch */
+ /* PHBs */
+ pnv_chip_power11_phb_realize(chip, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
/*
* I2C
@@ -2799,6 +2846,7 @@ static void pnv_chip_power11_class_init(ObjectClass *klass, const void *data)
k->xscom_core_base = pnv_chip_power11_xscom_core_base;
k->xscom_pcba = pnv_chip_power11_xscom_pcba;
dc->desc = "PowerNV Chip Power11";
+ k->num_pecs = PNV10_CHIP_MAX_PEC;
k->i2c_num_engines = PNV10_CHIP_MAX_I2C;
k->i2c_ports_per_engine = i2c_ports_per_engine;
@@ -3365,6 +3413,13 @@ static void pnv_machine_power11_class_init(ObjectClass *oc, const void *data)
XiveFabricClass *xfc = XIVE_FABRIC_CLASS(oc);
static const char compat[] = "qemu,powernv11\0ibm,powernv";
+ static GlobalProperty phb_compat[] = {
+ { TYPE_PNV_PHB, "version", "5" },
+ { TYPE_PNV_PHB_ROOT_PORT, "version", "5" },
+ };
+
+ compat_props_add(mc->compat_props, phb_compat, G_N_ELEMENTS(phb_compat));
+
pmc->compat = compat;
pmc->compat_size = sizeof(compat);
pmc->max_smt_threads = 4;
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 06/27] ppc/pnv: Add ChipTOD model for Power11
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (4 preceding siblings ...)
2025-09-28 19:26 ` [PULL 05/27] ppc/pnv: Add PHB5 PCIe Host bridge " Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 07/27] tests/powernv: Switch to buildroot images instead of op-build Harsh Prateek Bora
` (21 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Aditya Gupta, Cédric Le Goater, Amit Machhiwal
From: Aditya Gupta <adityag@linux.ibm.com>
Introduce Power11 ChipTod. The code has been copied from Power10 ChipTod
code as the Power11 core is same as Power10 core.
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Tested-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925173049.891406-7-adityag@linux.ibm.com
Message-ID: <20250925173049.891406-7-adityag@linux.ibm.com>
---
include/hw/ppc/pnv_chiptod.h | 2 ++
hw/ppc/pnv.c | 15 +++++++++
hw/ppc/pnv_chiptod.c | 59 ++++++++++++++++++++++++++++++++++++
3 files changed, 76 insertions(+)
diff --git a/include/hw/ppc/pnv_chiptod.h b/include/hw/ppc/pnv_chiptod.h
index fde569bcbf..466b06560a 100644
--- a/include/hw/ppc/pnv_chiptod.h
+++ b/include/hw/ppc/pnv_chiptod.h
@@ -17,6 +17,8 @@ OBJECT_DECLARE_TYPE(PnvChipTOD, PnvChipTODClass, PNV_CHIPTOD)
DECLARE_INSTANCE_CHECKER(PnvChipTOD, PNV9_CHIPTOD, TYPE_PNV9_CHIPTOD)
#define TYPE_PNV10_CHIPTOD TYPE_PNV_CHIPTOD "-POWER10"
DECLARE_INSTANCE_CHECKER(PnvChipTOD, PNV10_CHIPTOD, TYPE_PNV10_CHIPTOD)
+#define TYPE_PNV11_CHIPTOD TYPE_PNV_CHIPTOD "-POWER11"
+DECLARE_INSTANCE_CHECKER(PnvChipTOD, PNV11_CHIPTOD, TYPE_PNV11_CHIPTOD)
enum tod_state {
tod_error = 0,
diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c
index 2b4df6076c..f0469cdb8b 100644
--- a/hw/ppc/pnv.c
+++ b/hw/ppc/pnv.c
@@ -2495,6 +2495,8 @@ static void pnv_chip_power11_instance_init(Object *obj)
object_initialize_child(obj, "xive", &chip11->xive, TYPE_PNV_XIVE2);
object_property_add_alias(obj, "xive-fabric", OBJECT(&chip11->xive),
"xive-fabric");
+ object_initialize_child(obj, "chiptod", &chip11->chiptod,
+ TYPE_PNV11_CHIPTOD);
object_initialize_child(obj, "n1-chiplet", &chip11->n1_chiplet,
TYPE_PNV_N1_CHIPLET);
@@ -2653,6 +2655,19 @@ static void pnv_chip_power11_realize(DeviceState *dev, Error **errp)
chip->dt_isa_nodename = g_strdup_printf("/lpcm-opb@%" PRIx64 "/lpc@0",
(uint64_t) PNV11_LPCM_BASE(chip));
+ /* ChipTOD */
+ object_property_set_bool(OBJECT(&chip11->chiptod), "primary",
+ chip->chip_id == 0, &error_abort);
+ object_property_set_bool(OBJECT(&chip11->chiptod), "secondary",
+ chip->chip_id == 1, &error_abort);
+ object_property_set_link(OBJECT(&chip11->chiptod), "chip", OBJECT(chip),
+ &error_abort);
+ if (!qdev_realize(DEVICE(&chip11->chiptod), NULL, errp)) {
+ return;
+ }
+ pnv_xscom_add_subregion(chip, PNV11_XSCOM_CHIPTOD_BASE,
+ &chip11->chiptod.xscom_regs);
+
/* HOMER (must be created before OCC) */
object_property_set_link(OBJECT(&chip11->homer), "chip", OBJECT(chip),
&error_abort);
diff --git a/hw/ppc/pnv_chiptod.c b/hw/ppc/pnv_chiptod.c
index b9e9c7ba3d..f887a18cde 100644
--- a/hw/ppc/pnv_chiptod.c
+++ b/hw/ppc/pnv_chiptod.c
@@ -210,6 +210,22 @@ static void chiptod_power10_broadcast_ttype(PnvChipTOD *sender,
}
}
+static void chiptod_power11_broadcast_ttype(PnvChipTOD *sender,
+ uint32_t trigger)
+{
+ PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine());
+ int i;
+
+ for (i = 0; i < pnv->num_chips; i++) {
+ Pnv11Chip *chip11 = PNV11_CHIP(pnv->chips[i]);
+ PnvChipTOD *chiptod = &chip11->chiptod;
+
+ if (chiptod != sender) {
+ chiptod_receive_ttype(chiptod, trigger);
+ }
+ }
+}
+
static PnvCore *pnv_chip_get_core_by_xscom_base(PnvChip *chip,
uint32_t xscom_base)
{
@@ -283,6 +299,12 @@ static PnvCore *chiptod_power10_tx_ttype_target(PnvChipTOD *chiptod,
}
}
+static PnvCore *chiptod_power11_tx_ttype_target(PnvChipTOD *chiptod,
+ uint64_t val)
+{
+ return chiptod_power10_tx_ttype_target(chiptod, val);
+}
+
static void pnv_chiptod_xscom_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
@@ -520,6 +542,42 @@ static const TypeInfo pnv_chiptod_power10_type_info = {
}
};
+static int pnv_chiptod_power11_dt_xscom(PnvXScomInterface *dev, void *fdt,
+ int xscom_offset)
+{
+ const char compat[] = "ibm,power-chiptod\0ibm,power11-chiptod";
+
+ return pnv_chiptod_dt_xscom(dev, fdt, xscom_offset, compat, sizeof(compat));
+}
+
+static void pnv_chiptod_power11_class_init(ObjectClass *klass, const void *data)
+{
+ PnvChipTODClass *pctc = PNV_CHIPTOD_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass);
+
+ dc->desc = "PowerNV ChipTOD Controller (Power11)";
+ device_class_set_props(dc, pnv_chiptod_properties);
+
+ xdc->dt_xscom = pnv_chiptod_power11_dt_xscom;
+
+ pctc->broadcast_ttype = chiptod_power11_broadcast_ttype;
+ pctc->tx_ttype_target = chiptod_power11_tx_ttype_target;
+
+ pctc->xscom_size = PNV_XSCOM_CHIPTOD_SIZE;
+}
+
+static const TypeInfo pnv_chiptod_power11_type_info = {
+ .name = TYPE_PNV11_CHIPTOD,
+ .parent = TYPE_PNV_CHIPTOD,
+ .instance_size = sizeof(PnvChipTOD),
+ .class_init = pnv_chiptod_power11_class_init,
+ .interfaces = (const InterfaceInfo[]) {
+ { TYPE_PNV_XSCOM_INTERFACE },
+ { }
+ }
+};
+
static void pnv_chiptod_reset(void *dev)
{
PnvChipTOD *chiptod = PNV_CHIPTOD(dev);
@@ -579,6 +637,7 @@ static void pnv_chiptod_register_types(void)
type_register_static(&pnv_chiptod_type_info);
type_register_static(&pnv_chiptod_power9_type_info);
type_register_static(&pnv_chiptod_power10_type_info);
+ type_register_static(&pnv_chiptod_power11_type_info);
}
type_init(pnv_chiptod_register_types);
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 07/27] tests/powernv: Switch to buildroot images instead of op-build
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (5 preceding siblings ...)
2025-09-28 19:26 ` [PULL 06/27] ppc/pnv: Add ChipTOD model for Power11 Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 08/27] tests/powernv: Add PowerNV test for Power11 Harsh Prateek Bora
` (20 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel
Cc: Aditya Gupta, Cédric Le Goater, Cédric Le Goater,
Amit Machhiwal
From: Aditya Gupta <adityag@linux.ibm.com>
As op-build images haven't been updated from long time (and may not get
updated in future), use buildroot images provided by cedric [1].
Use existing nvme device being used in the test to mount the initrd.
Also replace the check for "zImage loaded message" to skiboot's message
when it starts the kernel: "Starting kernel at", since we are no longer
using zImage from op-build
This is required for newer processor tests such as Power11, as the
op-build kernel image is old and doesn't support Power11.
Power11 test has been added in a later patch.
[1]: https://github.com/legoater/qemu-ppc-boot/tree/main/buildroot/qemu_ppc64le_powernv8-2025.02
Suggested-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Tested-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925173049.891406-8-adityag@linux.ibm.com
Message-ID: <20250925173049.891406-8-adityag@linux.ibm.com>
---
tests/functional/ppc64/test_powernv.py | 30 ++++++++++++++------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/tests/functional/ppc64/test_powernv.py b/tests/functional/ppc64/test_powernv.py
index 685e2178ed..2b4db1cf99 100755
--- a/tests/functional/ppc64/test_powernv.py
+++ b/tests/functional/ppc64/test_powernv.py
@@ -18,9 +18,14 @@ class powernvMachine(LinuxKernelTest):
good_message = 'VFS: Cannot open root device'
ASSET_KERNEL = Asset(
- ('https://archives.fedoraproject.org/pub/archive/fedora-secondary/'
- 'releases/29/Everything/ppc64le/os/ppc/ppc64/vmlinuz'),
- '383c2f5c23bc0d9d32680c3924d3fd7ee25cc5ef97091ac1aa5e1d853422fc5f')
+ ('https://github.com/legoater/qemu-ppc-boot/raw/refs/heads/main/'
+ 'buildroot/qemu_ppc64le_powernv8-2025.02/vmlinux'),
+ '6fd29aff9ad4362511ea5d0acbb510667c7031928e97d64ec15bbc5daf4b8151')
+
+ ASSET_INITRD = Asset(
+ ('https://github.com/legoater/qemu-ppc-boot/raw/refs/heads/main/'
+ 'buildroot/qemu_ppc64le_powernv8-2025.02/rootfs.ext2'),
+ 'aee2192b692077c4bde31cb56ce474424b358f17cec323d5c94af3970c9aada2')
def do_test_linux_boot(self, command_line = KERNEL_COMMON_COMMAND_LINE):
self.require_accelerator("tcg")
@@ -78,27 +83,24 @@ def test_linux_big_boot(self):
wait_for_console_pattern(self, console_pattern, self.panic_message)
wait_for_console_pattern(self, self.good_message, self.panic_message)
-
- ASSET_EPAPR_KERNEL = Asset(
- ('https://github.com/open-power/op-build/releases/download/v2.7/'
- 'zImage.epapr'),
- '0ab237df661727e5392cee97460e8674057a883c5f74381a128fa772588d45cd')
-
def do_test_ppc64_powernv(self, proc):
self.require_accelerator("tcg")
- kernel_path = self.ASSET_EPAPR_KERNEL.fetch()
+ kernel_path = self.ASSET_KERNEL.fetch()
+ initrd_path = self.ASSET_INITRD.fetch()
self.vm.set_console()
self.vm.add_args('-kernel', kernel_path,
- '-append', 'console=tty0 console=hvc0',
+ '-drive',
+ f'file={initrd_path},format=raw,if=none,id=drive0,readonly=on',
+ '-append', 'root=/dev/nvme0n1 console=tty0 console=hvc0',
'-device', 'pcie-pci-bridge,id=bridge1,bus=pcie.1,addr=0x0',
- '-device', 'nvme,bus=pcie.2,addr=0x0,serial=1234',
+ '-device', 'nvme,drive=drive0,bus=pcie.2,addr=0x0,serial=1234',
'-device', 'e1000e,bus=bridge1,addr=0x3',
'-device', 'nec-usb-xhci,bus=bridge1,addr=0x2')
self.vm.launch()
self.wait_for_console_pattern("CPU: " + proc + " generation processor")
- self.wait_for_console_pattern("zImage starting: loaded")
- self.wait_for_console_pattern("Run /init as init process")
+ self.wait_for_console_pattern("INIT: Starting kernel at ")
+ self.wait_for_console_pattern("Run /sbin/init as init process")
# Device detection output driven by udev probing is sometimes cut off
# from console output, suspect S14silence-console init script.
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 08/27] tests/powernv: Add PowerNV test for Power11
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (6 preceding siblings ...)
2025-09-28 19:26 ` [PULL 07/27] tests/powernv: Switch to buildroot images instead of op-build Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 09/27] target/ppc: IBM PPE42 general regs and flags Harsh Prateek Bora
` (19 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Aditya Gupta, Cédric Le Goater, Amit Machhiwal
From: Aditya Gupta <adityag@linux.ibm.com>
With all Power11 support in place, add Power11 PowerNV test.
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Tested-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925173049.891406-9-adityag@linux.ibm.com
Message-ID: <20250925173049.891406-9-adityag@linux.ibm.com>
---
tests/functional/ppc64/test_powernv.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tests/functional/ppc64/test_powernv.py b/tests/functional/ppc64/test_powernv.py
index 2b4db1cf99..9ada832b78 100755
--- a/tests/functional/ppc64/test_powernv.py
+++ b/tests/functional/ppc64/test_powernv.py
@@ -116,5 +116,9 @@ def test_powernv10(self):
self.set_machine('powernv10')
self.do_test_ppc64_powernv('P10')
+ def test_powernv11(self):
+ self.set_machine('powernv11')
+ self.do_test_ppc64_powernv('Power11')
+
if __name__ == '__main__':
LinuxKernelTest.main()
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 09/27] target/ppc: IBM PPE42 general regs and flags
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (7 preceding siblings ...)
2025-09-28 19:26 ` [PULL 08/27] tests/powernv: Add PowerNV test for Power11 Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 10/27] target/ppc: Add IBM PPE42 family of processors Harsh Prateek Bora
` (18 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Glenn Miles, Chinmay Rath
From: Glenn Miles <milesg@linux.ibm.com>
Introduces general IBM PPE42 processor register definitions
and flags.
Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Chinmay Rath <rathc@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925201758.652077-2-milesg@linux.ibm.com
Message-ID: <20250925201758.652077-2-milesg@linux.ibm.com>
---
target/ppc/cpu-models.h | 4 ++++
target/ppc/cpu.h | 49 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/target/ppc/cpu-models.h b/target/ppc/cpu-models.h
index 72ad31ba50..c6cd27f390 100644
--- a/target/ppc/cpu-models.h
+++ b/target/ppc/cpu-models.h
@@ -69,6 +69,10 @@ enum {
/* Xilinx cores */
CPU_POWERPC_X2VP4 = 0x20010820,
CPU_POWERPC_X2VP20 = 0x20010860,
+ /* IBM PPE42 Family */
+ CPU_POWERPC_PPE42 = 0x42000000,
+ CPU_POWERPC_PPE42X = 0x42100000,
+ CPU_POWERPC_PPE42XM = 0x42200000,
/* PowerPC 440 family */
/* Generic PowerPC 440 */
#define CPU_POWERPC_440 CPU_POWERPC_440GXf
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 0e26e4343d..8e13ce41a9 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -282,6 +282,8 @@ typedef enum powerpc_input_t {
PPC_FLAGS_INPUT_POWER9,
/* Freescale RCPU bus */
PPC_FLAGS_INPUT_RCPU,
+ /* PPE42 bus */
+ PPC_FLAGS_INPUT_PPE42,
} powerpc_input_t;
#define PPC_INPUT(env) ((env)->bus_model)
@@ -433,39 +435,64 @@ typedef enum {
#define MSR_TM PPC_BIT_NR(31) /* Transactional Memory Available (Book3s) */
#define MSR_CM PPC_BIT_NR(32) /* Computation mode for BookE hflags */
#define MSR_ICM PPC_BIT_NR(33) /* Interrupt computation mode for BookE */
+#define MSR_SEM0 PPC_BIT_NR(33) /* SIB Error Mask Bit 0 (PPE42) */
+#define MSR_SEM1 PPC_BIT_NR(34) /* SIB Error Mask Bit 1 (PPE42) */
+#define MSR_SEM2 PPC_BIT_NR(35) /* SIB Error Mask Bit 2 (PPE42) */
#define MSR_GS PPC_BIT_NR(35) /* guest state for BookE */
+#define MSR_SEM3 PPC_BIT_NR(36) /* SIB Error Mask Bit 3 (PPE42) */
+#define MSR_SEM4 PPC_BIT_NR(37) /* SIB Error Mask Bit 4 (PPE42) */
#define MSR_UCLE PPC_BIT_NR(37) /* User-mode cache lock enable for BookE */
#define MSR_VR PPC_BIT_NR(38) /* altivec available x hflags */
#define MSR_SPE PPC_BIT_NR(38) /* SPE enable for BookE x hflags */
+#define MSR_SEM5 PPC_BIT_NR(38) /* SIB Error Mask Bit 5 (PPE42) */
+#define MSR_SEM6 PPC_BIT_NR(39) /* SIB Error Mask Bit 6 (PPE42) */
#define MSR_VSX PPC_BIT_NR(40) /* Vector Scalar Extension (>= 2.06)x hflags */
+#define MSR_IS0 PPC_BIT_NR(40) /* Instance Specific Bit 0 (PPE42) */
#define MSR_S PPC_BIT_NR(41) /* Secure state */
+#define MSR_SIBRC0 PPC_BIT_NR(41) /* Last SIB return code Bit 0 (PPE42) */
+#define MSR_SIBRC1 PPC_BIT_NR(42) /* Last SIB return code Bit 1 (PPE42) */
+#define MSR_SIBRC2 PPC_BIT_NR(43) /* Last SIB return code Bit 2 (PPE42) */
+#define MSR_LP PPC_BIT_NR(44) /* Low Priority (PPE42) */
#define MSR_KEY PPC_BIT_NR(44) /* key bit on 603e */
#define MSR_POW PPC_BIT_NR(45) /* Power management */
#define MSR_WE PPC_BIT_NR(45) /* Wait State Enable on 405 */
+#define MSR_IS1 PPC_BIT_NR(46) /* Instance Specific Bit 1 (PPE42) */
#define MSR_TGPR PPC_BIT_NR(46) /* TGPR usage on 602/603 x */
#define MSR_CE PPC_BIT_NR(46) /* Critical int. enable on embedded PPC x */
#define MSR_ILE PPC_BIT_NR(47) /* Interrupt little-endian mode */
+#define MSR_UIE PPC_BIT_NR(47) /* Unmaskable Interrupt Enable (PPE42) */
#define MSR_EE PPC_BIT_NR(48) /* External interrupt enable */
#define MSR_PR PPC_BIT_NR(49) /* Problem state hflags */
#define MSR_FP PPC_BIT_NR(50) /* Floating point available hflags */
#define MSR_ME PPC_BIT_NR(51) /* Machine check interrupt enable */
#define MSR_FE0 PPC_BIT_NR(52) /* Floating point exception mode 0 */
+#define MSR_IS2 PPC_BIT_NR(52) /* Instance Specific Bit 2 (PPE42) */
+#define MSR_IS3 PPC_BIT_NR(53) /* Instance Specific Bit 3 (PPE42) */
#define MSR_SE PPC_BIT_NR(53) /* Single-step trace enable x hflags */
#define MSR_DWE PPC_BIT_NR(53) /* Debug wait enable on 405 x */
#define MSR_UBLE PPC_BIT_NR(53) /* User BTB lock enable on e500 x */
#define MSR_BE PPC_BIT_NR(54) /* Branch trace enable x hflags */
#define MSR_DE PPC_BIT_NR(54) /* Debug int. enable on embedded PPC x */
#define MSR_FE1 PPC_BIT_NR(55) /* Floating point exception mode 1 */
+#define MSR_IPE PPC_BIT_NR(55) /* Imprecise Mode Enable (PPE42) */
#define MSR_AL PPC_BIT_NR(56) /* AL bit on POWER */
+#define MSR_SIBRCA0 PPC_BIT_NR(56) /* SIB Return Code Accumulator 0 (PPE42) */
+#define MSR_SIBRCA1 PPC_BIT_NR(57) /* SIB Return Code Accumulator 1 (PPE42) */
#define MSR_EP PPC_BIT_NR(57) /* Exception prefix on 601 */
#define MSR_IR PPC_BIT_NR(58) /* Instruction relocate */
#define MSR_IS PPC_BIT_NR(58) /* Instruction address space (BookE) */
+#define MSR_SIBRCA2 PPC_BIT_NR(58) /* SIB Return Code Accumulator 2 (PPE42) */
+#define MSR_SIBRCA3 PPC_BIT_NR(59) /* SIB Return Code Accumulator 3 (PPE42) */
#define MSR_DR PPC_BIT_NR(59) /* Data relocate */
#define MSR_DS PPC_BIT_NR(59) /* Data address space (BookE) */
#define MSR_PE PPC_BIT_NR(60) /* Protection enable on 403 */
+#define MSR_SIBRCA4 PPC_BIT_NR(60) /* SIB Return Code Accumulator 4 (PPE42) */
+#define MSR_SIBRCA5 PPC_BIT_NR(61) /* SIB Return Code Accumulator 5 (PPE42) */
#define MSR_PX PPC_BIT_NR(61) /* Protection exclusive on 403 x */
#define MSR_PMM PPC_BIT_NR(61) /* Performance monitor mark on POWER x */
#define MSR_RI PPC_BIT_NR(62) /* Recoverable interrupt 1 */
+#define MSR_SIBRCA6 PPC_BIT_NR(62) /* SIB Return Code Accumulator 6 (PPE42) */
+#define MSR_SIBRCA7 PPC_BIT_NR(63) /* SIB Return Code Accumulator 7 (PPE42) */
#define MSR_LE PPC_BIT_NR(63) /* Little-endian mode 1 hflags */
FIELD(MSR, SF, MSR_SF, 1)
@@ -517,6 +544,9 @@ FIELD(MSR, PX, MSR_PX, 1)
FIELD(MSR, PMM, MSR_PMM, 1)
FIELD(MSR, RI, MSR_RI, 1)
FIELD(MSR, LE, MSR_LE, 1)
+FIELD(MSR, SEM, MSR_SEM6, 7)
+FIELD(MSR, SIBRC, MSR_SIBRC2, 3)
+FIELD(MSR, SIBRCA, MSR_SIBRCA7, 8)
/*
* FE0 and FE1 bits are not side-by-side
@@ -785,6 +815,8 @@ enum {
POWERPC_FLAG_SMT_1LPAR = 0x00800000,
/* Has BHRB */
POWERPC_FLAG_BHRB = 0x01000000,
+ /* Use PPE42-specific behavior */
+ POWERPC_FLAG_PPE42 = 0x02000000,
};
/*
@@ -1754,9 +1786,12 @@ void ppc_compat_add_property(Object *obj, const char *name,
#define SPR_BOOKE_CSRR0 (0x03A)
#define SPR_BOOKE_CSRR1 (0x03B)
#define SPR_BOOKE_DEAR (0x03D)
+#define SPR_PPE42_EDR (0x03D)
#define SPR_IAMR (0x03D)
#define SPR_BOOKE_ESR (0x03E)
+#define SPR_PPE42_ISR (0x03E)
#define SPR_BOOKE_IVPR (0x03F)
+#define SPR_PPE42_IVPR (0x03F)
#define SPR_MPC_EIE (0x050)
#define SPR_MPC_EID (0x051)
#define SPR_MPC_NRI (0x052)
@@ -1822,6 +1857,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
#define SPR_TBU40 (0x11E)
#define SPR_SVR (0x11E)
#define SPR_BOOKE_PIR (0x11E)
+#define SPR_PPE42_PIR (0x11E)
#define SPR_PVR (0x11F)
#define SPR_HSPRG0 (0x130)
#define SPR_BOOKE_DBSR (0x130)
@@ -1831,6 +1867,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
#define SPR_BOOKE_EPCR (0x133)
#define SPR_SPURR (0x134)
#define SPR_BOOKE_DBCR0 (0x134)
+#define SPR_PPE42_DBCR (0x134)
#define SPR_IBCR (0x135)
#define SPR_PURR (0x135)
#define SPR_BOOKE_DBCR1 (0x135)
@@ -1848,6 +1885,7 @@ void ppc_compat_add_property(Object *obj, const char *name,
#define SPR_HSRR1 (0x13B)
#define SPR_BOOKE_IAC4 (0x13B)
#define SPR_BOOKE_DAC1 (0x13C)
+#define SPR_PPE42_DACR (0x13C)
#define SPR_MMCRH (0x13C)
#define SPR_DABR2 (0x13D)
#define SPR_BOOKE_DAC2 (0x13D)
@@ -1857,12 +1895,14 @@ void ppc_compat_add_property(Object *obj, const char *name,
#define SPR_BOOKE_DVC2 (0x13F)
#define SPR_LPIDR (0x13F)
#define SPR_BOOKE_TSR (0x150)
+#define SPR_PPE42_TSR (0x150)
#define SPR_HMER (0x150)
#define SPR_HMEER (0x151)
#define SPR_PCR (0x152)
#define SPR_HEIR (0x153)
#define SPR_BOOKE_LPIDR (0x152)
#define SPR_BOOKE_TCR (0x154)
+#define SPR_PPE42_TCR (0x154)
#define SPR_BOOKE_TLB0PS (0x158)
#define SPR_BOOKE_TLB1PS (0x159)
#define SPR_BOOKE_TLB2PS (0x15A)
@@ -2532,6 +2572,12 @@ enum {
PPC2_MEM_LWSYNC = 0x0000000000200000ULL,
/* ISA 2.06 BCD assist instructions */
PPC2_BCDA_ISA206 = 0x0000000000400000ULL,
+ /* PPE42 instructions */
+ PPC2_PPE42 = 0x0000000000800000ULL,
+ /* PPE42X instructions */
+ PPC2_PPE42X = 0x0000000001000000ULL,
+ /* PPE42XM instructions */
+ PPC2_PPE42XM = 0x0000000002000000ULL,
#define PPC_TCG_INSNS2 (PPC2_BOOKE206 | PPC2_VSX | PPC2_PRCNTL | PPC2_DBRX | \
PPC2_ISA205 | PPC2_VSX207 | PPC2_PERM_ISA206 | \
@@ -2541,7 +2587,8 @@ enum {
PPC2_ALTIVEC_207 | PPC2_ISA207S | PPC2_DFP | \
PPC2_FP_CVT_S64 | PPC2_TM | PPC2_PM_ISA206 | \
PPC2_ISA300 | PPC2_ISA310 | PPC2_MEM_LWSYNC | \
- PPC2_BCDA_ISA206)
+ PPC2_BCDA_ISA206 | PPC2_PPE42 | PPC2_PPE42X | \
+ PPC2_PPE42XM)
};
/*****************************************************************************/
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 10/27] target/ppc: Add IBM PPE42 family of processors
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (8 preceding siblings ...)
2025-09-28 19:26 ` [PULL 09/27] target/ppc: IBM PPE42 general regs and flags Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 11/27] target/ppc: IBM PPE42 exception flags and regs Harsh Prateek Bora
` (17 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Glenn Miles, Chinmay Rath
From: Glenn Miles <milesg@linux.ibm.com>
Adds the IBM PPE42 family of 32-bit processors supporting
the PPE42, PPE42X and PPE42XM processor versions. These
processors are used as embedded processors in the IBM
Power9, Power10 and Power12 processors for various
tasks. It is basically a stripped down version of the
IBM PowerPC 405 processor, with some added instructions
for handling 64-bit loads and stores.
For more information on the PPE 42 processor please visit:
https://wiki.raptorcs.com/w/images/a/a3/PPE_42X_Core_Users_Manual.pdf
Supports PPE42 SPR's (Including the MSR).
Does not yet support exceptions, new PPE42 instructions and
does not prevent access to some invalid instructions and
registers (currently allows access to invalid GPR's and CR
fields).
Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Chinmay Rath <rathc@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925201758.652077-3-milesg@linux.ibm.com
Message-ID: <20250925201758.652077-3-milesg@linux.ibm.com>
---
target/ppc/cpu-models.c | 7 ++
target/ppc/cpu_init.c | 207 ++++++++++++++++++++++++++++++++-------
target/ppc/helper_regs.c | 41 +++++---
target/ppc/translate.c | 6 +-
4 files changed, 205 insertions(+), 56 deletions(-)
diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
index ea86ea202a..09f73e23a8 100644
--- a/target/ppc/cpu-models.c
+++ b/target/ppc/cpu-models.c
@@ -116,6 +116,13 @@
NULL)
POWERPC_DEF("x2vp20", CPU_POWERPC_X2VP20, 405,
NULL)
+ /* PPE42 Embedded Controllers */
+ POWERPC_DEF("PPE42", CPU_POWERPC_PPE42, ppe42,
+ "Generic PPE 42")
+ POWERPC_DEF("PPE42X", CPU_POWERPC_PPE42X, ppe42x,
+ "Generic PPE 42X")
+ POWERPC_DEF("PPE42XM", CPU_POWERPC_PPE42XM, ppe42xm,
+ "Generic PPE 42XM")
/* PowerPC 440 family */
#if defined(TODO_USER_ONLY)
POWERPC_DEF("440", CPU_POWERPC_440, 440GP,
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index db841f1260..c78b255085 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -1653,6 +1653,47 @@ static void register_8xx_sprs(CPUPPCState *env)
* ... and more (thermal management, performance counters, ...)
*/
+static void register_ppe42_sprs(CPUPPCState *env)
+{
+ spr_register(env, SPR_PPE42_EDR, "EDR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_PPE42_ISR, "ISR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ spr_register(env, SPR_PPE42_IVPR, "IVPR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, SPR_NOACCESS,
+ 0xfff80000);
+ spr_register(env, SPR_PPE42_PIR, "PIR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_pir,
+ 0x00000000);
+ spr_register(env, SPR_PPE42_DBCR, "DBCR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_40x_dbcr0,
+ 0x00000000);
+ spr_register(env, SPR_PPE42_DACR, "DACR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_generic,
+ 0x00000000);
+ /* Timer */
+ spr_register(env, SPR_DECR, "DECR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_decr, &spr_write_decr,
+ 0x00000000);
+ spr_register(env, SPR_PPE42_TSR, "TSR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_booke_tsr,
+ 0x00000000);
+ spr_register(env, SPR_BOOKE_TCR, "TCR",
+ SPR_NOACCESS, SPR_NOACCESS,
+ &spr_read_generic, &spr_write_booke_tcr,
+ 0x00000000);
+}
+
/*****************************************************************************/
/* Exception vectors models */
static void init_excp_4xx(CPUPPCState *env)
@@ -2200,6 +2241,79 @@ POWERPC_FAMILY(405)(ObjectClass *oc, const void *data)
POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK;
}
+static void init_proc_ppe42(CPUPPCState *env)
+{
+ register_ppe42_sprs(env);
+
+ env->dcache_line_size = 32;
+ env->icache_line_size = 32;
+ /* Allocate hardware IRQ controller */
+ ppc40x_irq_init(env_archcpu(env));
+
+ SET_FIT_PERIOD(8, 12, 16, 20);
+ SET_WDT_PERIOD(16, 20, 24, 28);
+}
+
+static void ppe42_class_common_init(PowerPCCPUClass *pcc)
+{
+ pcc->init_proc = init_proc_ppe42;
+ pcc->check_pow = check_pow_nocheck;
+ pcc->check_attn = check_attn_none;
+ pcc->insns_flags = PPC_INSNS_BASE |
+ PPC_WRTEE |
+ PPC_CACHE |
+ PPC_CACHE_DCBZ |
+ PPC_MEM_SYNC;
+ pcc->msr_mask = R_MSR_SEM_MASK |
+ (1ull << MSR_IS0) |
+ R_MSR_SIBRC_MASK |
+ (1ull << MSR_LP) |
+ (1ull << MSR_WE) |
+ (1ull << MSR_IS1) |
+ (1ull << MSR_UIE) |
+ (1ull << MSR_EE) |
+ (1ull << MSR_ME) |
+ (1ull << MSR_IS2) |
+ (1ull << MSR_IS3) |
+ (1ull << MSR_IPE) |
+ R_MSR_SIBRCA_MASK;
+ pcc->mmu_model = POWERPC_MMU_REAL;
+ pcc->excp_model = POWERPC_EXCP_40x;
+ pcc->bus_model = PPC_FLAGS_INPUT_PPE42;
+ pcc->bfd_mach = bfd_mach_ppc_403;
+ pcc->flags = POWERPC_FLAG_PPE42 | POWERPC_FLAG_BUS_CLK;
+}
+
+POWERPC_FAMILY(ppe42)(ObjectClass *oc, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PPE 42";
+ pcc->insns_flags2 = PPC2_PPE42;
+ ppe42_class_common_init(pcc);
+}
+
+POWERPC_FAMILY(ppe42x)(ObjectClass *oc, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PPE 42X";
+ pcc->insns_flags2 = PPC2_PPE42 | PPC2_PPE42X;
+ ppe42_class_common_init(pcc);
+}
+
+POWERPC_FAMILY(ppe42xm)(ObjectClass *oc, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+ dc->desc = "PPE 42XM";
+ pcc->insns_flags2 = PPC2_PPE42 | PPC2_PPE42X | PPC2_PPE42XM;
+ ppe42_class_common_init(pcc);
+}
+
static void init_proc_440EP(CPUPPCState *env)
{
register_BookE_sprs(env, 0x000000000000FFFFULL);
@@ -6802,53 +6916,64 @@ static void init_ppc_proc(PowerPCCPU *cpu)
/* MSR bits & flags consistency checks */
if (env->msr_mask & (1 << 25)) {
- switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
+ switch (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE |
+ POWERPC_FLAG_PPE42)) {
case POWERPC_FLAG_SPE:
case POWERPC_FLAG_VRE:
+ case POWERPC_FLAG_PPE42:
break;
default:
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n");
+ "Should define POWERPC_FLAG_SPE or POWERPC_FLAG_VRE\n"
+ "or POWERPC_FLAG_PPE42\n");
exit(1);
}
- } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE)) {
+ } else if (env->flags & (POWERPC_FLAG_SPE | POWERPC_FLAG_VRE |
+ POWERPC_FLAG_PPE42)) {
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n");
+ "Should not define POWERPC_FLAG_SPE nor POWERPC_FLAG_VRE\n"
+ "nor POWERPC_FLAG_PPE42\n");
exit(1);
}
if (env->msr_mask & (1 << 17)) {
- switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
+ switch (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE |
+ POWERPC_FLAG_PPE42)) {
case POWERPC_FLAG_TGPR:
case POWERPC_FLAG_CE:
+ case POWERPC_FLAG_PPE42:
break;
default:
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n");
+ "Should define POWERPC_FLAG_TGPR or POWERPC_FLAG_CE\n"
+ "or POWERPC_FLAG_PPE42\n");
exit(1);
}
- } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE)) {
+ } else if (env->flags & (POWERPC_FLAG_TGPR | POWERPC_FLAG_CE |
+ POWERPC_FLAG_PPE42)) {
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n");
+ "Should not define POWERPC_FLAG_TGPR nor POWERPC_FLAG_CE\n"
+ "nor POWERPC_FLAG_PPE42\n");
exit(1);
}
if (env->msr_mask & (1 << 10)) {
switch (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_UBLE)) {
+ POWERPC_FLAG_UBLE | POWERPC_FLAG_PPE42)) {
case POWERPC_FLAG_SE:
case POWERPC_FLAG_DWE:
case POWERPC_FLAG_UBLE:
+ case POWERPC_FLAG_PPE42:
break;
default:
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
"Should define POWERPC_FLAG_SE or POWERPC_FLAG_DWE or "
- "POWERPC_FLAG_UBLE\n");
+ "POWERPC_FLAG_UBLE or POWERPC_FLAG_PPE42\n");
exit(1);
}
} else if (env->flags & (POWERPC_FLAG_SE | POWERPC_FLAG_DWE |
- POWERPC_FLAG_UBLE)) {
+ POWERPC_FLAG_UBLE | POWERPC_FLAG_PPE42)) {
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
"Should not define POWERPC_FLAG_SE nor POWERPC_FLAG_DWE nor "
- "POWERPC_FLAG_UBLE\n");
+ "POWERPC_FLAG_UBLE nor POWERPC_FLAG_PPE42\n");
exit(1);
}
if (env->msr_mask & (1 << 9)) {
@@ -6867,18 +6992,23 @@ static void init_ppc_proc(PowerPCCPU *cpu)
exit(1);
}
if (env->msr_mask & (1 << 2)) {
- switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
+ switch (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_PPE42)) {
case POWERPC_FLAG_PX:
case POWERPC_FLAG_PMM:
+ case POWERPC_FLAG_PPE42:
break;
default:
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n");
+ "Should define POWERPC_FLAG_PX or POWERPC_FLAG_PMM\n"
+ "or POWERPC_FLAG_PPE42\n");
exit(1);
}
- } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM)) {
+ } else if (env->flags & (POWERPC_FLAG_PX | POWERPC_FLAG_PMM |
+ POWERPC_FLAG_PPE42)) {
fprintf(stderr, "PowerPC MSR definition inconsistency\n"
- "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n");
+ "Should not define POWERPC_FLAG_PX nor POWERPC_FLAG_PMM\n"
+ "nor POWERPC_FLAG_PPE42\n");
exit(1);
}
if ((env->flags & POWERPC_FLAG_BUS_CLK) == 0) {
@@ -7243,39 +7373,40 @@ static void ppc_cpu_reset_hold(Object *obj, ResetType type)
}
msr = (target_ulong)0;
- msr |= (target_ulong)MSR_HVB;
- msr |= (target_ulong)1 << MSR_EP;
+ if (!(env->flags & POWERPC_FLAG_PPE42)) {
+ msr |= (target_ulong)MSR_HVB;
+ msr |= (target_ulong)1 << MSR_EP;
#if defined(DO_SINGLE_STEP) && 0
- /* Single step trace mode */
- msr |= (target_ulong)1 << MSR_SE;
- msr |= (target_ulong)1 << MSR_BE;
+ /* Single step trace mode */
+ msr |= (target_ulong)1 << MSR_SE;
+ msr |= (target_ulong)1 << MSR_BE;
#endif
#if defined(CONFIG_USER_ONLY)
- msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
- msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point exceptions */
- msr |= (target_ulong)1 << MSR_FE1;
- msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
- msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
- msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
- msr |= (target_ulong)1 << MSR_PR;
+ msr |= (target_ulong)1 << MSR_FP; /* Allow floating point usage */
+ msr |= (target_ulong)1 << MSR_FE0; /* Allow floating point exceptions */
+ msr |= (target_ulong)1 << MSR_FE1;
+ msr |= (target_ulong)1 << MSR_VR; /* Allow altivec usage */
+ msr |= (target_ulong)1 << MSR_VSX; /* Allow VSX usage */
+ msr |= (target_ulong)1 << MSR_SPE; /* Allow SPE usage */
+ msr |= (target_ulong)1 << MSR_PR;
#if defined(TARGET_PPC64)
- msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
+ msr |= (target_ulong)1 << MSR_TM; /* Transactional memory */
#endif
#if !TARGET_BIG_ENDIAN
- msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
- if (!((env->msr_mask >> MSR_LE) & 1)) {
- fprintf(stderr, "Selected CPU does not support little-endian.\n");
- exit(1);
- }
+ msr |= (target_ulong)1 << MSR_LE; /* Little-endian user mode */
+ if (!((env->msr_mask >> MSR_LE) & 1)) {
+ fprintf(stderr, "Selected CPU does not support little-endian.\n");
+ exit(1);
+ }
#endif
#endif
#if defined(TARGET_PPC64)
- if (mmu_is_64bit(env->mmu_model)) {
- msr |= (1ULL << MSR_SF);
- }
+ if (mmu_is_64bit(env->mmu_model)) {
+ msr |= (1ULL << MSR_SF);
+ }
#endif
-
+ }
hreg_store_msr(env, msr, 1);
#if !defined(CONFIG_USER_ONLY)
diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 5f21739749..41b7b939ec 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -308,9 +308,6 @@ int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv)
value &= ~(1 << MSR_ME);
value |= env->msr & (1 << MSR_ME);
}
- if ((value ^ env->msr) & (R_MSR_IR_MASK | R_MSR_DR_MASK)) {
- cpu_interrupt_exittb(cs);
- }
if ((env->mmu_model == POWERPC_MMU_BOOKE ||
env->mmu_model == POWERPC_MMU_BOOKE206) &&
((value ^ env->msr) & R_MSR_GS_MASK)) {
@@ -321,8 +318,14 @@ int hreg_store_msr(CPUPPCState *env, target_ulong value, int alter_hv)
/* Swap temporary saved registers with GPRs */
hreg_swap_gpr_tgpr(env);
}
- if (unlikely((value ^ env->msr) & R_MSR_EP_MASK)) {
- env->excp_prefix = FIELD_EX64(value, MSR, EP) * 0xFFF00000;
+ /* PPE42 uses IR, DR and EP MSR bits for other purposes */
+ if (likely(!(env->flags & POWERPC_FLAG_PPE42))) {
+ if ((value ^ env->msr) & (R_MSR_IR_MASK | R_MSR_DR_MASK)) {
+ cpu_interrupt_exittb(cs);
+ }
+ if (unlikely((value ^ env->msr) & R_MSR_EP_MASK)) {
+ env->excp_prefix = FIELD_EX64(value, MSR, EP) * 0xFFF00000;
+ }
}
/*
* If PR=1 then EE, IR and DR must be 1
@@ -464,6 +467,23 @@ void register_generic_sprs(PowerPCCPU *cpu)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
+
+ spr_register(env, SPR_PVR, "PVR",
+ /* Linux permits userspace to read PVR */
+#if defined(CONFIG_LINUX_USER)
+ &spr_read_generic,
+#else
+ SPR_NOACCESS,
+#endif
+ SPR_NOACCESS,
+ &spr_read_generic, SPR_NOACCESS,
+ pcc->pvr);
+
+ /* PPE42 doesn't support SPRG1-3, SVR or TB regs */
+ if (env->insns_flags2 & PPC2_PPE42) {
+ return;
+ }
+
spr_register(env, SPR_SPRG1, "SPRG1",
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
@@ -477,17 +497,6 @@ void register_generic_sprs(PowerPCCPU *cpu)
&spr_read_generic, &spr_write_generic,
0x00000000);
- spr_register(env, SPR_PVR, "PVR",
- /* Linux permits userspace to read PVR */
-#if defined(CONFIG_LINUX_USER)
- &spr_read_generic,
-#else
- SPR_NOACCESS,
-#endif
- SPR_NOACCESS,
- &spr_read_generic, SPR_NOACCESS,
- pcc->pvr);
-
/* Register SVR if it's defined to anything else than POWERPC_SVR_NONE */
if (pcc->svr != POWERPC_SVR_NONE) {
if (pcc->svr & POWERPC_SVR_E500) {
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 27f90c3cc5..fc817dab54 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -4264,8 +4264,10 @@ static void gen_mtmsr(DisasContext *ctx)
/* L=1 form only updates EE and RI */
mask &= (1ULL << MSR_RI) | (1ULL << MSR_EE);
} else {
- /* mtmsr does not alter S, ME, or LE */
- mask &= ~((1ULL << MSR_LE) | (1ULL << MSR_ME) | (1ULL << MSR_S));
+ if (likely(!(ctx->insns_flags2 & PPC2_PPE42))) {
+ /* mtmsr does not alter S, ME, or LE */
+ mask &= ~((1ULL << MSR_LE) | (1ULL << MSR_ME) | (1ULL << MSR_S));
+ }
/*
* XXX: we need to update nip before the store if we enter
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 11/27] target/ppc: IBM PPE42 exception flags and regs
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (9 preceding siblings ...)
2025-09-28 19:26 ` [PULL 10/27] target/ppc: Add IBM PPE42 family of processors Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 12/27] target/ppc: Add IBM PPE42 exception model Harsh Prateek Bora
` (16 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Glenn Miles, Chinmay Rath
From: Glenn Miles <milesg@linux.ibm.com>
Introduces flags and register definitions needed
for the IBM PPE42 exception model.
Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Chinmay Rath <rathc@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925201758.652077-4-milesg@linux.ibm.com
Message-ID: <20250925201758.652077-4-milesg@linux.ibm.com>
---
target/ppc/cpu.h | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 8e13ce41a9..787020f6f9 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -220,6 +220,8 @@ typedef enum powerpc_excp_t {
POWERPC_EXCP_POWER10,
/* POWER11 exception model */
POWERPC_EXCP_POWER11,
+ /* PPE42 exception model */
+ POWERPC_EXCP_PPE42,
} powerpc_excp_t;
/*****************************************************************************/
@@ -760,6 +762,31 @@ FIELD(MSR, SIBRCA, MSR_SIBRCA7, 8)
#define ESR_VLEMI PPC_BIT(58) /* VLE operation */
#define ESR_MIF PPC_BIT(62) /* Misaligned instruction (VLE) */
+/* PPE42 Interrupt Status Register bits */
+#define PPE42_ISR_SRSMS0 PPC_BIT_NR(48) /* Sys Reset State Machine State 0 */
+#define PPE42_ISR_SRSMS1 PPC_BIT_NR(49) /* Sys Reset State Machine State 1 */
+#define PPE42_ISR_SRSMS2 PPC_BIT_NR(50) /* Sys Reset State Machine State 2 */
+#define PPE42_ISR_SRSMS3 PPC_BIT_NR(51) /* Sys Reset State Machine State 3 */
+#define PPE42_ISR_EP PPC_BIT_NR(53) /* MSR[EE] Maskable Event Pending */
+#define PPE42_ISR_PTR PPC_BIT_NR(56) /* Program Interrupt from trap */
+#define PPE42_ISR_ST PPC_BIT_NR(57) /* Data Interrupt caused by store */
+#define PPE42_ISR_MFE PPC_BIT_NR(60) /* Multiple Fault Error */
+#define PPE42_ISR_MCS0 PPC_BIT_NR(61) /* Machine Check Status bit0 */
+#define PPE42_ISR_MCS1 PPC_BIT_NR(62) /* Machine Check Status bit1 */
+#define PPE42_ISR_MCS2 PPC_BIT_NR(63) /* Machine Check Status bit2 */
+FIELD(PPE42_ISR, SRSMS, PPE42_ISR_SRSMS3, 4)
+FIELD(PPE42_ISR, MCS, PPE42_ISR_MCS2, 3)
+
+/* PPE42 Machine Check Status field values */
+#define PPE42_ISR_MCS_INSTRUCTION 0
+#define PPE42_ISR_MCS_DATA_LOAD 1
+#define PPE42_ISR_MCS_DATA_PRECISE_STORE 2
+#define PPE42_ISR_MCS_DATA_IMPRECISE_STORE 3
+#define PPE42_ISR_MCS_PROGRAM 4
+#define PPE42_ISR_MCS_ISI 5
+#define PPE42_ISR_MCS_ALIGNMENT 6
+#define PPE42_ISR_MCS_DSI 7
+
/* Transaction EXception And Summary Register bits */
#define TEXASR_FAILURE_PERSISTENT (63 - 7)
#define TEXASR_DISALLOWED (63 - 8)
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 12/27] target/ppc: Add IBM PPE42 exception model
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (10 preceding siblings ...)
2025-09-28 19:26 ` [PULL 11/27] target/ppc: IBM PPE42 exception flags and regs Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 13/27] target/ppc: Support for IBM PPE42 MMU Harsh Prateek Bora
` (15 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Glenn Miles, Chinmay Rath
From: Glenn Miles <milesg@linux.ibm.com>
Add support for the IBM PPE42 exception model including
new exception vectors, exception priorities and setting
of PPE42 SPRs for determining the cause of an exception.
Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Chinmay Rath <rathc@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925201758.652077-5-milesg@linux.ibm.com
Message-ID: <20250925201758.652077-5-milesg@linux.ibm.com>
---
target/ppc/cpu_init.c | 39 ++++++++-
target/ppc/excp_helper.c | 163 +++++++++++++++++++++++++++++++++++
target/ppc/tcg-excp_helper.c | 12 +++
3 files changed, 213 insertions(+), 1 deletion(-)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index c78b255085..9e4ea8fd13 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -1720,6 +1720,30 @@ static void init_excp_4xx(CPUPPCState *env)
#endif
}
+static void init_excp_ppe42(CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ /* Machine Check vector changed after version 0 */
+ if (((env->spr[SPR_PVR] & 0xf00000ul) >> 20) == 0) {
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000000;
+ } else {
+ env->excp_vectors[POWERPC_EXCP_MCHECK] = 0x00000020;
+ }
+ env->excp_vectors[POWERPC_EXCP_RESET] = 0x00000040;
+ env->excp_vectors[POWERPC_EXCP_DSI] = 0x00000060;
+ env->excp_vectors[POWERPC_EXCP_ISI] = 0x00000080;
+ env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x000000A0;
+ env->excp_vectors[POWERPC_EXCP_ALIGN] = 0x000000C0;
+ env->excp_vectors[POWERPC_EXCP_PROGRAM] = 0x000000E0;
+ env->excp_vectors[POWERPC_EXCP_DECR] = 0x00000100;
+ env->excp_vectors[POWERPC_EXCP_FIT] = 0x00000120;
+ env->excp_vectors[POWERPC_EXCP_WDT] = 0x00000140;
+ env->ivpr_mask = 0xFFFFFE00UL;
+ /* Hardware reset vector */
+ env->hreset_vector = 0x00000040UL;
+#endif
+}
+
static void init_excp_MPC5xx(CPUPPCState *env)
{
#if !defined(CONFIG_USER_ONLY)
@@ -2245,6 +2269,7 @@ static void init_proc_ppe42(CPUPPCState *env)
{
register_ppe42_sprs(env);
+ init_excp_ppe42(env);
env->dcache_line_size = 32;
env->icache_line_size = 32;
/* Allocate hardware IRQ controller */
@@ -2278,7 +2303,7 @@ static void ppe42_class_common_init(PowerPCCPUClass *pcc)
(1ull << MSR_IPE) |
R_MSR_SIBRCA_MASK;
pcc->mmu_model = POWERPC_MMU_REAL;
- pcc->excp_model = POWERPC_EXCP_40x;
+ pcc->excp_model = POWERPC_EXCP_PPE42;
pcc->bus_model = PPC_FLAGS_INPUT_PPE42;
pcc->bfd_mach = bfd_mach_ppc_403;
pcc->flags = POWERPC_FLAG_PPE42 | POWERPC_FLAG_BUS_CLK;
@@ -7856,6 +7881,18 @@ void ppc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
* they can be read with "p $ivor0", "p $ivor1", etc.
*/
break;
+ case POWERPC_EXCP_PPE42:
+ qemu_fprintf(f, "SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx "\n",
+ env->spr[SPR_SRR0], env->spr[SPR_SRR1]);
+
+ qemu_fprintf(f, " TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx
+ " ISR " TARGET_FMT_lx " EDR " TARGET_FMT_lx "\n",
+ env->spr[SPR_PPE42_TCR], env->spr[SPR_PPE42_TSR],
+ env->spr[SPR_PPE42_ISR], env->spr[SPR_PPE42_EDR]);
+
+ qemu_fprintf(f, " PIR " TARGET_FMT_lx " IVPR " TARGET_FMT_lx "\n",
+ env->spr[SPR_PPE42_PIR], env->spr[SPR_PPE42_IVPR]);
+ break;
case POWERPC_EXCP_40x:
qemu_fprintf(f, " TCR " TARGET_FMT_lx " TSR " TARGET_FMT_lx
" ESR " TARGET_FMT_lx " DEAR " TARGET_FMT_lx "\n",
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c
index 1efdc4066e..d8bca19fff 100644
--- a/target/ppc/excp_helper.c
+++ b/target/ppc/excp_helper.c
@@ -949,6 +949,125 @@ static void powerpc_excp_74xx(PowerPCCPU *cpu, int excp)
powerpc_set_excp_state(cpu, vector, new_msr);
}
+static void powerpc_excp_ppe42(PowerPCCPU *cpu, int excp)
+{
+ CPUPPCState *env = &cpu->env;
+ target_ulong msr, new_msr, vector;
+ target_ulong mcs = PPE42_ISR_MCS_INSTRUCTION;
+ bool promote_unmaskable;
+
+ msr = env->msr;
+
+ /*
+ * New interrupt handler msr preserves SIBRC and ME unless explicitly
+ * overridden by the exception. All other MSR bits are zeroed out.
+ */
+ new_msr = env->msr & (((target_ulong)1 << MSR_ME) | R_MSR_SIBRC_MASK);
+
+ /* HV emu assistance interrupt only exists on server arch 2.05 or later */
+ if (excp == POWERPC_EXCP_HV_EMU) {
+ excp = POWERPC_EXCP_PROGRAM;
+ }
+
+ /*
+ * Unmaskable interrupts (Program, ISI, Alignment and DSI) are promoted to
+ * machine check if MSR_UIE is 0.
+ */
+ promote_unmaskable = !(msr & ((target_ulong)1 << MSR_UIE));
+
+
+ switch (excp) {
+ case POWERPC_EXCP_MCHECK: /* Machine check exception */
+ break;
+ case POWERPC_EXCP_DSI: /* Data storage exception */
+ trace_ppc_excp_dsi(env->spr[SPR_PPE42_ISR], env->spr[SPR_PPE42_EDR]);
+ if (promote_unmaskable) {
+ excp = POWERPC_EXCP_MCHECK;
+ mcs = PPE42_ISR_MCS_DSI;
+ }
+ break;
+ case POWERPC_EXCP_ISI: /* Instruction storage exception */
+ trace_ppc_excp_isi(msr, env->nip);
+ if (promote_unmaskable) {
+ excp = POWERPC_EXCP_MCHECK;
+ mcs = PPE42_ISR_MCS_ISI;
+ }
+ break;
+ case POWERPC_EXCP_EXTERNAL: /* External input */
+ break;
+ case POWERPC_EXCP_ALIGN: /* Alignment exception */
+ if (promote_unmaskable) {
+ excp = POWERPC_EXCP_MCHECK;
+ mcs = PPE42_ISR_MCS_ALIGNMENT;
+ }
+ break;
+ case POWERPC_EXCP_PROGRAM: /* Program exception */
+ if (promote_unmaskable) {
+ excp = POWERPC_EXCP_MCHECK;
+ mcs = PPE42_ISR_MCS_PROGRAM;
+ }
+ switch (env->error_code & ~0xF) {
+ case POWERPC_EXCP_INVAL:
+ trace_ppc_excp_inval(env->nip);
+ env->spr[SPR_PPE42_ISR] &= ~((target_ulong)1 << PPE42_ISR_PTR);
+ break;
+ case POWERPC_EXCP_TRAP:
+ env->spr[SPR_PPE42_ISR] |= ((target_ulong)1 << PPE42_ISR_PTR);
+ break;
+ default:
+ /* Should never occur */
+ cpu_abort(env_cpu(env), "Invalid program exception %d. Aborting\n",
+ env->error_code);
+ break;
+ }
+#ifdef CONFIG_TCG
+ env->spr[SPR_PPE42_EDR] = ppc_ldl_code(env, env->nip);
+#endif
+ break;
+ case POWERPC_EXCP_DECR: /* Decrementer exception */
+ break;
+ case POWERPC_EXCP_FIT: /* Fixed-interval timer interrupt */
+ trace_ppc_excp_print("FIT");
+ break;
+ case POWERPC_EXCP_WDT: /* Watchdog timer interrupt */
+ trace_ppc_excp_print("WDT");
+ break;
+ case POWERPC_EXCP_RESET: /* System reset exception */
+ /* reset exceptions don't have ME set */
+ new_msr &= ~((target_ulong)1 << MSR_ME);
+ break;
+ default:
+ cpu_abort(env_cpu(env), "Invalid PPE42 exception %d. Aborting\n",
+ excp);
+ break;
+ }
+
+ env->spr[SPR_SRR0] = env->nip;
+ env->spr[SPR_SRR1] = msr;
+
+ vector = env->excp_vectors[excp];
+ if (vector == (target_ulong)-1ULL) {
+ cpu_abort(env_cpu(env),
+ "Raised an exception without defined vector %d\n", excp);
+ }
+ vector |= env->spr[SPR_PPE42_IVPR];
+
+ if (excp == POWERPC_EXCP_MCHECK) {
+ /* Also set the Machine Check Status (MCS) */
+ env->spr[SPR_PPE42_ISR] &= ~R_PPE42_ISR_MCS_MASK;
+ env->spr[SPR_PPE42_ISR] |= (mcs & R_PPE42_ISR_MCS_MASK);
+ env->spr[SPR_PPE42_ISR] &= ~((target_ulong)1 << PPE42_ISR_MFE);
+
+ /* Machine checks halt execution if MSR_ME is 0 */
+ powerpc_mcheck_checkstop(env);
+
+ /* machine check exceptions don't have ME set */
+ new_msr &= ~((target_ulong)1 << MSR_ME);
+ }
+
+ powerpc_set_excp_state(cpu, vector, new_msr);
+}
+
static void powerpc_excp_booke(PowerPCCPU *cpu, int excp)
{
CPUPPCState *env = &cpu->env;
@@ -1589,6 +1708,9 @@ void powerpc_excp(PowerPCCPU *cpu, int excp)
case POWERPC_EXCP_POWER11:
powerpc_excp_books(cpu, excp);
break;
+ case POWERPC_EXCP_PPE42:
+ powerpc_excp_ppe42(cpu, excp);
+ break;
default:
g_assert_not_reached();
}
@@ -1945,6 +2067,43 @@ static int p9_next_unmasked_interrupt(CPUPPCState *env,
}
#endif /* TARGET_PPC64 */
+static int ppe42_next_unmasked_interrupt(CPUPPCState *env)
+{
+ bool async_deliver;
+
+ /* External reset */
+ if (env->pending_interrupts & PPC_INTERRUPT_RESET) {
+ return PPC_INTERRUPT_RESET;
+ }
+ /* Machine check exception */
+ if (env->pending_interrupts & PPC_INTERRUPT_MCK) {
+ return PPC_INTERRUPT_MCK;
+ }
+
+ async_deliver = FIELD_EX64(env->msr, MSR, EE);
+
+ if (async_deliver != 0) {
+ /* Watchdog timer */
+ if (env->pending_interrupts & PPC_INTERRUPT_WDT) {
+ return PPC_INTERRUPT_WDT;
+ }
+ /* External Interrupt */
+ if (env->pending_interrupts & PPC_INTERRUPT_EXT) {
+ return PPC_INTERRUPT_EXT;
+ }
+ /* Fixed interval timer */
+ if (env->pending_interrupts & PPC_INTERRUPT_FIT) {
+ return PPC_INTERRUPT_FIT;
+ }
+ /* Decrementer exception */
+ if (env->pending_interrupts & PPC_INTERRUPT_DECR) {
+ return PPC_INTERRUPT_DECR;
+ }
+ }
+
+ return 0;
+}
+
static int ppc_next_unmasked_interrupt(CPUPPCState *env)
{
uint32_t pending_interrupts = env->pending_interrupts;
@@ -1970,6 +2129,10 @@ static int ppc_next_unmasked_interrupt(CPUPPCState *env)
}
#endif
+ if (env->excp_model == POWERPC_EXCP_PPE42) {
+ return ppe42_next_unmasked_interrupt(env);
+ }
+
/* External reset */
if (pending_interrupts & PPC_INTERRUPT_RESET) {
return PPC_INTERRUPT_RESET;
diff --git a/target/ppc/tcg-excp_helper.c b/target/ppc/tcg-excp_helper.c
index f835be5156..edecfb8572 100644
--- a/target/ppc/tcg-excp_helper.c
+++ b/target/ppc/tcg-excp_helper.c
@@ -229,6 +229,18 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
case POWERPC_MMU_BOOKE206:
env->spr[SPR_BOOKE_DEAR] = vaddr;
break;
+ case POWERPC_MMU_REAL:
+ if (env->flags & POWERPC_FLAG_PPE42) {
+ env->spr[SPR_PPE42_EDR] = vaddr;
+ if (access_type == MMU_DATA_STORE) {
+ env->spr[SPR_PPE42_ISR] |= PPE42_ISR_ST;
+ } else {
+ env->spr[SPR_PPE42_ISR] &= ~PPE42_ISR_ST;
+ }
+ } else {
+ env->spr[SPR_DAR] = vaddr;
+ }
+ break;
default:
env->spr[SPR_DAR] = vaddr;
break;
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 13/27] target/ppc: Support for IBM PPE42 MMU
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (11 preceding siblings ...)
2025-09-28 19:26 ` [PULL 12/27] target/ppc: Add IBM PPE42 exception model Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 14/27] target/ppc: Add IBM PPE42 special instructions Harsh Prateek Bora
` (14 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Glenn Miles, Chinmay Rath
From: Glenn Miles <milesg@linux.ibm.com>
The IBM PPE42 processor only supports real mode
addressing and does not distinguish between
problem and supervisor states. It also uses
the IR and DR MSR bits for other purposes.
Therefore, add a check for PPE42 when we update
hflags and cause it to ignore the IR and DR bits
when calculating MMU indexes.
Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Chinmay Rath <rathc@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925201758.652077-6-milesg@linux.ibm.com
Message-ID: <20250925201758.652077-6-milesg@linux.ibm.com>
---
target/ppc/helper_regs.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/target/ppc/helper_regs.c b/target/ppc/helper_regs.c
index 41b7b939ec..a07e6a7b7b 100644
--- a/target/ppc/helper_regs.c
+++ b/target/ppc/helper_regs.c
@@ -186,6 +186,10 @@ static uint32_t hreg_compute_hflags_value(CPUPPCState *env)
if (env->spr[SPR_LPCR] & LPCR_HR) {
hflags |= 1 << HFLAGS_HR;
}
+ if (unlikely(ppc_flags & POWERPC_FLAG_PPE42)) {
+ /* PPE42 has a single address space and no problem state */
+ msr = 0;
+ }
#ifndef CONFIG_USER_ONLY
if (!env->has_hv_mode || (msr & (1ull << MSR_HV))) {
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 14/27] target/ppc: Add IBM PPE42 special instructions
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (12 preceding siblings ...)
2025-09-28 19:26 ` [PULL 13/27] target/ppc: Support for IBM PPE42 MMU Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 15/27] hw/ppc: Support for an IBM PPE42 CPU decrementer Harsh Prateek Bora
` (13 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Glenn Miles, Chinmay Rath
From: Glenn Miles <milesg@linux.ibm.com>
Adds the following instructions exclusively for
IBM PPE42 processors:
LSKU
LCXU
STSKU
STCXU
LVD
LVDU
LVDX
STVD
STVDU
STVDX
SLVD
SRVD
CMPWBC
CMPLWBC
CMPWIBC
BNBWI
BNBW
CLRBWIBC
CLRWBC
DCBQ
RLDICL
RLDICR
RLDIMI
A PPE42 GCC compiler is available here:
https://github.com/open-power/ppe42-gcc
For more information on the PPE42 processors please visit:
https://wiki.raptorcs.com/w/images/a/a3/PPE_42X_Core_Users_Manual.pdf
Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Chinmay Rath <rathc@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925201758.652077-7-milesg@linux.ibm.com
Message-ID: <20250925201758.652077-7-milesg@linux.ibm.com>
---
target/ppc/insn32.decode | 66 ++-
target/ppc/translate.c | 29 +-
target/ppc/translate/ppe-impl.c.inc | 609 ++++++++++++++++++++++++++++
3 files changed, 694 insertions(+), 10 deletions(-)
create mode 100644 target/ppc/translate/ppe-impl.c.inc
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index e53fd2840d..16652b5c13 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -58,6 +58,10 @@
%ds_rtp 22:4 !function=times_2
@DS_rtp ...... ....0 ra:5 .............. .. &D rt=%ds_rtp si=%ds_si
+%dd_si 3:s13
+&DD rt ra si:int64_t
+@DD ...... rt:5 ra:5 ............. . .. &DD si=%dd_si
+
&DX_b vrt b
%dx_b 6:10 16:5 0:1
@DX_b ...... vrt:5 ..... .......... ..... . &DX_b b=%dx_b
@@ -66,6 +70,11 @@
%dx_d 6:s10 16:5 0:1
@DX ...... rt:5 ..... .......... ..... . &DX d=%dx_d
+%md_sh 1:1 11:5
+%md_mb 5:1 6:5
+&MD rs ra sh mb rc
+@MD ...... rs:5 ra:5 ..... ...... ... . rc:1 &MD sh=%md_sh mb=%md_mb
+
&VA vrt vra vrb rc
@VA ...... vrt:5 vra:5 vrb:5 rc:5 ...... &VA
@@ -322,6 +331,13 @@ LDUX 011111 ..... ..... ..... 0000110101 - @X
LQ 111000 ..... ..... ............ ---- @DQ_rtp
+LVD 000101 ..... ..... ................ @D
+LVDU 001001 ..... ..... ................ @D
+LVDX 011111 ..... ..... ..... 0000010001 - @X
+LSKU 111010 ..... ..... ............. 0 11 @DD
+LCXU 111010 ..... ..... ............. 1 11 @DD
+
+
### Fixed-Point Store Instructions
STB 100110 ..... ..... ................ @D
@@ -346,6 +362,11 @@ STDUX 011111 ..... ..... ..... 0010110101 - @X
STQ 111110 ..... ..... ..............10 @DS_rtp
+STVDU 010110 ..... ..... ................ @D
+STVDX 011111 ..... ..... ..... 0010010001 - @X
+STSKU 111110 ..... ..... ............. 0 11 @DD
+STCXU 111110 ..... ..... ............. 1 11 @DD
+
### Fixed-Point Compare Instructions
CMP 011111 ... - . ..... ..... 0000000000 - @X_bfl
@@ -461,8 +482,14 @@ PRTYD 011111 ..... ..... ----- 0010111010 - @X_sa
BPERMD 011111 ..... ..... ..... 0011111100 - @X
CFUGED 011111 ..... ..... ..... 0011011100 - @X
-CNTLZDM 011111 ..... ..... ..... 0000111011 - @X
-CNTTZDM 011111 ..... ..... ..... 1000111011 - @X
+{
+ SLVD 011111 ..... ..... ..... 0000111011 . @X_rc
+ CNTLZDM 011111 ..... ..... ..... 0000111011 - @X
+}
+{
+ SRVD 011111 ..... ..... ..... 1000111011 . @X_rc
+ CNTTZDM 011111 ..... ..... ..... 1000111011 - @X
+}
PDEPD 011111 ..... ..... ..... 0010011100 - @X
PEXTD 011111 ..... ..... ..... 0010111100 - @X
@@ -981,8 +1008,16 @@ LXSSP 111001 ..... ..... .............. 11 @DS
STXSSP 111101 ..... ..... .............. 11 @DS
LXV 111101 ..... ..... ............ . 001 @DQ_TSX
STXV 111101 ..... ..... ............ . 101 @DQ_TSX
-LXVP 000110 ..... ..... ............ 0000 @DQ_TSXP
-STXVP 000110 ..... ..... ............ 0001 @DQ_TSXP
+
+# STVD PPE instruction overlaps with the LXVP and STXVP instructions
+{
+ STVD 000110 ..... ..... ................ @D
+ [
+ LXVP 000110 ..... ..... ............ 0000 @DQ_TSXP
+ STXVP 000110 ..... ..... ............ 0001 @DQ_TSXP
+ ]
+}
+
LXVX 011111 ..... ..... ..... 0100 - 01100 . @X_TSX
STXVX 011111 ..... ..... ..... 0110001100 . @X_TSX
LXVPX 011111 ..... ..... ..... 0101001101 - @X_TSXP
@@ -1300,3 +1335,26 @@ CLRBHRB 011111 ----- ----- ----- 0110101110 -
## Misc POWER instructions
ATTN 000000 00000 00000 00000 0100000000 0
+
+# Fused compare-branch instructions for PPE only
+%fcb_bdx 1:s10 !function=times_4
+&FCB px:bool ra rb:uint64_t bdx lk:bool
+@FCB ...... .. px:1 .. ra:5 rb:5 .......... lk:1 &FCB bdx=%fcb_bdx
+&FCB_bix px:bool bix ra rb:uint64_t bdx lk:bool
+@FCB_bix ...... .. px:1 bix:2 ra:5 rb:5 .......... lk:1 &FCB_bix bdx=%fcb_bdx
+
+CMPWBC 000001 00 . .. ..... ..... .......... . @FCB_bix
+CMPLWBC 000001 01 . .. ..... ..... .......... . @FCB_bix
+CMPWIBC 000001 10 . .. ..... ..... .......... . @FCB_bix
+BNBWI 000001 11 . 00 ..... ..... .......... . @FCB
+BNBW 000001 11 . 01 ..... ..... .......... . @FCB
+CLRBWIBC 000001 11 . 10 ..... ..... .......... . @FCB
+CLRBWBC 000001 11 . 11 ..... ..... .......... . @FCB
+
+# Data Cache Block Query for PPE only
+DCBQ 011111 ..... ..... ..... 0110010110 - @X
+
+# Rotate Doubleword Instructions for PPE only
+RLDICL 011110 ..... ..... ..... ...... 000 . . @MD
+RLDICR 011110 ..... ..... ..... ...... 001 . . @MD
+RLDIMI 011110 ..... ..... ..... ...... 011 . . @MD
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index fc817dab54..d422789a1d 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -209,6 +209,11 @@ struct DisasContext {
#define DISAS_CHAIN DISAS_TARGET_2 /* lookup next tb, pc updated */
#define DISAS_CHAIN_UPDATE DISAS_TARGET_3 /* lookup next tb, pc stale */
+static inline bool is_ppe(const DisasContext *ctx)
+{
+ return !!(ctx->flags & POWERPC_FLAG_PPE42);
+}
+
/* Return true iff byteswap is needed in a scalar memop */
static inline bool need_byteswap(const DisasContext *ctx)
{
@@ -556,11 +561,8 @@ void spr_access_nop(DisasContext *ctx, int sprn, int gprn)
#endif
-/* SPR common to all PowerPC */
-/* XER */
-void spr_read_xer(DisasContext *ctx, int gprn, int sprn)
+static void gen_get_xer(DisasContext *ctx, TCGv dst)
{
- TCGv dst = cpu_gpr[gprn];
TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
TCGv t2 = tcg_temp_new();
@@ -579,9 +581,16 @@ void spr_read_xer(DisasContext *ctx, int gprn, int sprn)
}
}
-void spr_write_xer(DisasContext *ctx, int sprn, int gprn)
+/* SPR common to all PowerPC */
+/* XER */
+void spr_read_xer(DisasContext *ctx, int gprn, int sprn)
+{
+ TCGv dst = cpu_gpr[gprn];
+ gen_get_xer(ctx, dst);
+}
+
+static void gen_set_xer(DisasContext *ctx, TCGv src)
{
- TCGv src = cpu_gpr[gprn];
/* Write all flags, while reading back check for isa300 */
tcg_gen_andi_tl(cpu_xer, src,
~((1u << XER_SO) |
@@ -594,6 +603,12 @@ void spr_write_xer(DisasContext *ctx, int sprn, int gprn)
tcg_gen_extract_tl(cpu_ca, src, XER_CA, 1);
}
+void spr_write_xer(DisasContext *ctx, int sprn, int gprn)
+{
+ TCGv src = cpu_gpr[gprn];
+ gen_set_xer(ctx, src);
+}
+
/* LR */
void spr_read_lr(DisasContext *ctx, int gprn, int sprn)
{
@@ -5755,6 +5770,8 @@ static bool resolve_PLS_D(DisasContext *ctx, arg_D *d, arg_PLS_D *a)
#include "translate/bhrb-impl.c.inc"
+#include "translate/ppe-impl.c.inc"
+
/* Handles lfdp */
static void gen_dform39(DisasContext *ctx)
{
diff --git a/target/ppc/translate/ppe-impl.c.inc b/target/ppc/translate/ppe-impl.c.inc
new file mode 100644
index 0000000000..0a0590344e
--- /dev/null
+++ b/target/ppc/translate/ppe-impl.c.inc
@@ -0,0 +1,609 @@
+/*
+ * IBM PPE Instructions
+ *
+ * Copyright (c) 2025, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+
+static bool vdr_is_valid(uint32_t vdr)
+{
+ const uint32_t valid_bitmap = 0xf00003ff;
+ return !!((1ul << (vdr & 0x1f)) & valid_bitmap);
+}
+
+static bool ppe_gpr_is_valid(uint32_t reg)
+{
+ const uint32_t valid_bitmap = 0xf00027ff;
+ return !!((1ul << (reg & 0x1f)) & valid_bitmap);
+}
+
+#define CHECK_VDR(CTX, VDR) \
+ do { \
+ if (unlikely(!vdr_is_valid(VDR))) { \
+ gen_invalid(CTX); \
+ return true; \
+ } \
+ } while (0)
+
+#define CHECK_PPE_GPR(CTX, REG) \
+ do { \
+ if (unlikely(!ppe_gpr_is_valid(REG))) { \
+ gen_invalid(CTX); \
+ return true; \
+ } \
+ } while (0)
+
+#define VDR_PAIR_REG(VDR) (((VDR) + 1) & 0x1f)
+
+#define CHECK_PPE_LEVEL(CTX, LVL) \
+ do { \
+ if (unlikely(!((CTX)->insns_flags2 & (LVL)))) { \
+ gen_invalid(CTX); \
+ return true; \
+ } \
+ } while (0)
+
+static bool trans_LCXU(DisasContext *ctx, arg_LCXU *a)
+{
+ int i;
+ TCGv base, EA;
+ TCGv lo, hi;
+ TCGv_i64 t8;
+ const uint8_t vd_list[] = {9, 7, 5, 3, 0};
+
+ if (unlikely(!is_ppe(ctx))) {
+ return false;
+ }
+ CHECK_PPE_LEVEL(ctx, PPC2_PPE42X);
+ CHECK_PPE_GPR(ctx, a->rt);
+
+ if (unlikely((a->rt != a->ra) || (a->ra == 0) || (a->si < 0xB))) {
+ gen_invalid(ctx);
+ return true;
+ }
+
+ EA = tcg_temp_new();
+ base = tcg_temp_new();
+
+ tcg_gen_addi_tl(base, cpu_gpr[a->ra], a->si * 8);
+ gen_store_spr(SPR_PPE42_EDR, base);
+
+ t8 = tcg_temp_new_i64();
+
+ tcg_gen_addi_tl(EA, base, -8);
+ tcg_gen_qemu_ld_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+ tcg_gen_extr_i64_tl(cpu_gpr[31], cpu_gpr[30], t8);
+
+ tcg_gen_addi_tl(EA, EA, -8);
+ tcg_gen_qemu_ld_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+ tcg_gen_extr_i64_tl(cpu_gpr[29], cpu_gpr[28], t8);
+
+ lo = tcg_temp_new();
+ hi = tcg_temp_new();
+
+ tcg_gen_addi_tl(EA, EA, -8);
+ tcg_gen_qemu_ld_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+ tcg_gen_extr_i64_tl(lo, hi, t8);
+ gen_store_spr(SPR_SRR0, hi);
+ gen_store_spr(SPR_SRR1, lo);
+
+ tcg_gen_addi_tl(EA, EA, -8);
+ tcg_gen_qemu_ld_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+ tcg_gen_extr_i64_tl(lo, hi, t8);
+ gen_set_xer(ctx, hi);
+ tcg_gen_mov_tl(cpu_ctr, lo);
+
+ for (i = 0; i < sizeof(vd_list); i++) {
+ int vd = vd_list[i];
+ tcg_gen_addi_tl(EA, EA, -8);
+ tcg_gen_qemu_ld_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+ tcg_gen_extr_i64_tl(cpu_gpr[VDR_PAIR_REG(vd)], cpu_gpr[vd], t8);
+ }
+
+ tcg_gen_addi_tl(EA, EA, -8);
+ tcg_gen_qemu_ld_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+ tcg_gen_extr_i64_tl(lo, hi, t8);
+ tcg_gen_shri_tl(hi, hi, 28);
+ tcg_gen_trunc_tl_i32(cpu_crf[0], hi);
+ gen_store_spr(SPR_SPRG0, lo);
+
+ tcg_gen_addi_tl(EA, base, 4);
+ tcg_gen_qemu_ld_tl(cpu_lr, EA, ctx->mem_idx, DEF_MEMOP(MO_32) | MO_ALIGN);
+ tcg_gen_mov_tl(cpu_gpr[a->ra], base);
+ return true;
+}
+
+static bool trans_LSKU(DisasContext *ctx, arg_LSKU *a)
+{
+ int64_t n;
+ TCGv base, EA;
+ TCGv lo, hi;
+ TCGv_i64 t8;
+
+ if (unlikely(!is_ppe(ctx))) {
+ return false;
+ }
+
+ CHECK_PPE_LEVEL(ctx, PPC2_PPE42X);
+ CHECK_PPE_GPR(ctx, a->rt);
+
+ if (unlikely((a->rt != a->ra) || (a->ra == 0) ||
+ (a->si & PPC_BIT(0)) || (a->si == 0))) {
+ gen_invalid(ctx);
+ return true;
+ }
+
+ EA = tcg_temp_new();
+ base = tcg_temp_new();
+ gen_addr_register(ctx, base);
+
+
+ tcg_gen_addi_tl(base, base, a->si * 8);
+ gen_store_spr(SPR_PPE42_EDR, base);
+
+ n = a->si - 1;
+ t8 = tcg_temp_new_i64();
+ if (n > 0) {
+ tcg_gen_addi_tl(EA, base, -8);
+ tcg_gen_qemu_ld_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+ hi = cpu_gpr[30];
+ lo = cpu_gpr[31];
+ tcg_gen_extr_i64_tl(lo, hi, t8);
+ }
+ if (n > 1) {
+ tcg_gen_addi_tl(EA, base, -16);
+ tcg_gen_qemu_ld_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+ hi = cpu_gpr[28];
+ lo = cpu_gpr[29];
+ tcg_gen_extr_i64_tl(lo, hi, t8);
+ }
+ tcg_gen_addi_tl(EA, base, 4);
+ tcg_gen_qemu_ld_tl(cpu_lr, EA, ctx->mem_idx, DEF_MEMOP(MO_32) | MO_ALIGN);
+ tcg_gen_mov_tl(cpu_gpr[a->ra], base);
+ return true;
+}
+
+static bool trans_STCXU(DisasContext *ctx, arg_STCXU *a)
+{
+ TCGv EA;
+ TCGv lo, hi;
+ TCGv_i64 t8;
+ int i;
+ const uint8_t vd_list[] = {9, 7, 5, 3, 0};
+
+ if (unlikely(!is_ppe(ctx))) {
+ return false;
+ }
+
+ CHECK_PPE_LEVEL(ctx, PPC2_PPE42X);
+ CHECK_PPE_GPR(ctx, a->rt);
+
+ if (unlikely((a->rt != a->ra) || (a->ra == 0) || !(a->si & PPC_BIT(0)))) {
+ gen_invalid(ctx);
+ return true;
+ }
+
+ EA = tcg_temp_new();
+ tcg_gen_addi_tl(EA, cpu_gpr[a->ra], 4);
+ tcg_gen_qemu_st_tl(cpu_lr, EA, ctx->mem_idx, DEF_MEMOP(MO_32) | MO_ALIGN);
+
+ gen_store_spr(SPR_PPE42_EDR, cpu_gpr[a->ra]);
+
+ t8 = tcg_temp_new_i64();
+
+ tcg_gen_concat_tl_i64(t8, cpu_gpr[31], cpu_gpr[30]);
+ tcg_gen_addi_tl(EA, cpu_gpr[a->ra], -8);
+ tcg_gen_qemu_st_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+
+ tcg_gen_concat_tl_i64(t8, cpu_gpr[29], cpu_gpr[28]);
+ tcg_gen_addi_tl(EA, EA, -8);
+ tcg_gen_qemu_st_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+
+ lo = tcg_temp_new();
+ hi = tcg_temp_new();
+
+ gen_load_spr(hi, SPR_SRR0);
+ gen_load_spr(lo, SPR_SRR1);
+ tcg_gen_concat_tl_i64(t8, lo, hi);
+ tcg_gen_addi_tl(EA, EA, -8);
+ tcg_gen_qemu_st_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+
+ gen_get_xer(ctx, hi);
+ tcg_gen_mov_tl(lo, cpu_ctr);
+ tcg_gen_concat_tl_i64(t8, lo, hi);
+ tcg_gen_addi_tl(EA, EA, -8);
+ tcg_gen_qemu_st_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+
+ for (i = 0; i < sizeof(vd_list); i++) {
+ int vd = vd_list[i];
+ tcg_gen_concat_tl_i64(t8, cpu_gpr[VDR_PAIR_REG(vd)], cpu_gpr[vd]);
+ tcg_gen_addi_tl(EA, EA, -8);
+ tcg_gen_qemu_st_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+ }
+
+ gen_load_spr(lo, SPR_SPRG0);
+ tcg_gen_extu_i32_tl(hi, cpu_crf[0]);
+ tcg_gen_shli_tl(hi, hi, 28);
+ tcg_gen_concat_tl_i64(t8, lo, hi);
+ tcg_gen_addi_tl(EA, EA, -8);
+ tcg_gen_qemu_st_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+
+ tcg_gen_addi_tl(EA, cpu_gpr[a->ra], a->si * 8);
+ tcg_gen_qemu_st_tl(cpu_gpr[a->rt], EA, ctx->mem_idx, DEF_MEMOP(MO_32) |
+ MO_ALIGN);
+ tcg_gen_mov_tl(cpu_gpr[a->ra], EA);
+ return true;
+}
+
+static bool trans_STSKU(DisasContext *ctx, arg_STSKU *a)
+{
+ int64_t n;
+ TCGv base, EA;
+ TCGv lo, hi;
+ TCGv_i64 t8;
+
+ if (unlikely(!is_ppe(ctx))) {
+ return false;
+ }
+
+ CHECK_PPE_LEVEL(ctx, PPC2_PPE42X);
+ CHECK_PPE_GPR(ctx, a->rt);
+
+ if (unlikely((a->rt != a->ra) || (a->ra == 0) || !(a->si & PPC_BIT(0)))) {
+ gen_invalid(ctx);
+ return true;
+ }
+
+ EA = tcg_temp_new();
+ base = tcg_temp_new();
+ gen_addr_register(ctx, base);
+ tcg_gen_addi_tl(EA, base, 4);
+ tcg_gen_qemu_st_tl(cpu_lr, EA, ctx->mem_idx, DEF_MEMOP(MO_32) | MO_ALIGN);
+
+ gen_store_spr(SPR_PPE42_EDR, base);
+
+ n = ~(a->si);
+
+ t8 = tcg_temp_new_i64();
+ if (n > 0) {
+ hi = cpu_gpr[30];
+ lo = cpu_gpr[31];
+ tcg_gen_concat_tl_i64(t8, lo, hi);
+ tcg_gen_addi_tl(EA, base, -8);
+ tcg_gen_qemu_st_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+ }
+ if (n > 1) {
+ hi = cpu_gpr[28];
+ lo = cpu_gpr[29];
+ tcg_gen_concat_tl_i64(t8, lo, hi);
+ tcg_gen_addi_tl(EA, base, -16);
+ tcg_gen_qemu_st_i64(t8, EA, ctx->mem_idx, DEF_MEMOP(MO_64) | MO_ALIGN);
+ }
+
+ tcg_gen_addi_tl(EA, base, a->si * 8);
+ tcg_gen_qemu_st_tl(cpu_gpr[a->rt], EA, ctx->mem_idx, DEF_MEMOP(MO_32) |
+ MO_ALIGN);
+ tcg_gen_mov_tl(cpu_gpr[a->ra], EA);
+ return true;
+}
+
+static bool do_ppe_ldst(DisasContext *ctx, int rt, int ra, TCGv disp,
+ bool update, bool store)
+{
+ TCGv ea;
+ int rt_lo;
+ TCGv_i64 t8;
+
+ CHECK_VDR(ctx, rt);
+ CHECK_PPE_GPR(ctx, ra);
+ rt_lo = VDR_PAIR_REG(rt);
+ if (update && (ra == 0 || (!store && ((ra == rt) || (ra == rt_lo))))) {
+ gen_invalid(ctx);
+ return true;
+ }
+ gen_set_access_type(ctx, ACCESS_INT);
+
+ ea = do_ea_calc(ctx, ra, disp);
+ t8 = tcg_temp_new_i64();
+ if (store) {
+ tcg_gen_concat_tl_i64(t8, cpu_gpr[rt_lo], cpu_gpr[rt]);
+ tcg_gen_qemu_st_i64(t8, ea, ctx->mem_idx, DEF_MEMOP(MO_64));
+ } else {
+ tcg_gen_qemu_ld_i64(t8, ea, ctx->mem_idx, DEF_MEMOP(MO_64));
+ tcg_gen_extr_i64_tl(cpu_gpr[rt_lo], cpu_gpr[rt], t8);
+ }
+ if (update) {
+ tcg_gen_mov_tl(cpu_gpr[ra], ea);
+ }
+ return true;
+}
+
+static bool do_ppe_ldst_D(DisasContext *ctx, arg_D *a, bool update, bool store)
+{
+ if (unlikely(!is_ppe(ctx))) {
+ return false;
+ }
+ return do_ppe_ldst(ctx, a->rt, a->ra, tcg_constant_tl(a->si), update,
+ store);
+}
+
+static bool do_ppe_ldst_X(DisasContext *ctx, arg_X *a, bool store)
+{
+ if (unlikely(!is_ppe(ctx))) {
+ return false;
+ }
+ CHECK_PPE_GPR(ctx, a->rb);
+ return do_ppe_ldst(ctx, a->rt, a->ra, cpu_gpr[a->rb], false, store);
+}
+
+TRANS(LVD, do_ppe_ldst_D, false, false)
+TRANS(LVDU, do_ppe_ldst_D, true, false)
+TRANS(STVD, do_ppe_ldst_D, false, true)
+TRANS(STVDU, do_ppe_ldst_D, true, true)
+TRANS(LVDX, do_ppe_ldst_X, false)
+TRANS(STVDX, do_ppe_ldst_X, true)
+
+
+static bool do_fcb(DisasContext *ctx, TCGv ra_val, TCGv rb_val, int bix,
+ int32_t bdx, bool s, bool px, bool lk)
+{
+ TCGCond cond;
+ uint32_t mask;
+ TCGLabel *no_branch;
+ target_ulong dest;
+
+ /* Update CR0 */
+ gen_op_cmp32(ra_val, rb_val, s, 0);
+
+ if (lk) {
+ gen_setlr(ctx, ctx->base.pc_next);
+ }
+
+
+ mask = PPC_BIT32(28 + bix);
+ cond = (px) ? TCG_COND_TSTEQ : TCG_COND_TSTNE;
+ no_branch = gen_new_label();
+ dest = ctx->cia + bdx;
+
+ /* Do the branch if CR0[bix] == PX */
+ tcg_gen_brcondi_i32(cond, cpu_crf[0], mask, no_branch);
+ gen_goto_tb(ctx, 0, dest);
+ gen_set_label(no_branch);
+ gen_goto_tb(ctx, 1, ctx->base.pc_next);
+ ctx->base.is_jmp = DISAS_NORETURN;
+ return true;
+}
+
+static bool do_cmp_branch(DisasContext *ctx, arg_FCB_bix *a, bool s,
+ bool rb_is_gpr)
+{
+ TCGv old_ra;
+ TCGv rb_val;
+
+ if (unlikely(!is_ppe(ctx))) {
+ return false;
+ }
+ CHECK_PPE_GPR(ctx, a->ra);
+ if (rb_is_gpr) {
+ CHECK_PPE_GPR(ctx, a->rb);
+ rb_val = cpu_gpr[a->rb];
+ } else {
+ rb_val = tcg_constant_tl(a->rb);
+ }
+ if (a->bix == 3) {
+ old_ra = tcg_temp_new();
+ tcg_gen_mov_tl(old_ra, cpu_gpr[a->ra]);
+ tcg_gen_sub_tl(cpu_gpr[a->ra], cpu_gpr[a->ra], rb_val);
+ return do_fcb(ctx, old_ra, rb_val, 2,
+ a->bdx, s, a->px, a->lk);
+ } else {
+ return do_fcb(ctx, cpu_gpr[a->ra], rb_val, a->bix,
+ a->bdx, s, a->px, a->lk);
+ }
+}
+
+TRANS(CMPWBC, do_cmp_branch, true, true)
+TRANS(CMPLWBC, do_cmp_branch, false, true)
+TRANS(CMPWIBC, do_cmp_branch, true, false)
+
+static bool do_mask_branch(DisasContext *ctx, arg_FCB * a, bool invert,
+ bool update, bool rb_is_gpr)
+{
+ TCGv r;
+ TCGv mask, shift;
+
+ if (unlikely(!is_ppe(ctx))) {
+ return false;
+ }
+ CHECK_PPE_GPR(ctx, a->ra);
+ if (rb_is_gpr) {
+ CHECK_PPE_GPR(ctx, a->rb);
+ mask = tcg_temp_new();
+ shift = tcg_temp_new();
+ tcg_gen_andi_tl(shift, cpu_gpr[a->rb], 0x1f);
+ tcg_gen_shr_tl(mask, tcg_constant_tl(0x80000000), shift);
+ } else {
+ mask = tcg_constant_tl(PPC_BIT32(a->rb));
+ }
+ if (invert) {
+ tcg_gen_not_tl(mask, mask);
+ }
+
+ /* apply mask to ra */
+ r = tcg_temp_new();
+ tcg_gen_and_tl(r, cpu_gpr[a->ra], mask);
+ if (update) {
+ tcg_gen_mov_tl(cpu_gpr[a->ra], r);
+ }
+ return do_fcb(ctx, r, tcg_constant_tl(0), 2,
+ a->bdx, false, a->px, a->lk);
+}
+
+TRANS(BNBWI, do_mask_branch, false, false, false)
+TRANS(BNBW, do_mask_branch, false, false, true)
+TRANS(CLRBWIBC, do_mask_branch, true, true, false)
+TRANS(CLRBWBC, do_mask_branch, true, true, true)
+
+static void gen_set_Rc0_i64(DisasContext *ctx, TCGv_i64 reg)
+{
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i32 t = tcg_temp_new_i32();
+
+ tcg_gen_movi_i64(t0, CRF_EQ);
+ tcg_gen_movi_i64(t1, CRF_LT);
+ tcg_gen_movcond_i64(TCG_COND_LT, t0, reg, tcg_constant_i64(0), t1, t0);
+ tcg_gen_movi_i64(t1, CRF_GT);
+ tcg_gen_movcond_i64(TCG_COND_GT, t0, reg, tcg_constant_i64(0), t1, t0);
+ tcg_gen_extrl_i64_i32(t, t0);
+ tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);
+ tcg_gen_or_i32(cpu_crf[0], cpu_crf[0], t);
+}
+
+static bool do_shift64(DisasContext *ctx, arg_X_rc *a, bool left)
+{
+ int rt_lo, ra_lo;
+ TCGv_i64 t0, t8;
+
+ if (unlikely(!is_ppe(ctx))) {
+ return false;
+ }
+ CHECK_PPE_LEVEL(ctx, PPC2_PPE42X);
+ CHECK_VDR(ctx, a->rt);
+ CHECK_VDR(ctx, a->ra);
+ CHECK_PPE_GPR(ctx, a->rb);
+ rt_lo = VDR_PAIR_REG(a->rt);
+ ra_lo = VDR_PAIR_REG(a->ra);
+ t8 = tcg_temp_new_i64();
+
+ /* AND rt with a mask that is 0 when rb >= 0x40 */
+ t0 = tcg_temp_new_i64();
+ tcg_gen_extu_tl_i64(t0, cpu_gpr[a->rb]);
+ tcg_gen_shli_i64(t0, t0, 0x39);
+ tcg_gen_sari_i64(t0, t0, 0x3f);
+
+ /* form 64bit value from two 32bit regs */
+ tcg_gen_concat_tl_i64(t8, cpu_gpr[rt_lo], cpu_gpr[a->rt]);
+
+ /* apply mask */
+ tcg_gen_andc_i64(t8, t8, t0);
+
+ /* do the shift */
+ tcg_gen_extu_tl_i64(t0, cpu_gpr[a->rb]);
+ tcg_gen_andi_i64(t0, t0, 0x3f);
+ if (left) {
+ tcg_gen_shl_i64(t8, t8, t0);
+ } else {
+ tcg_gen_shr_i64(t8, t8, t0);
+ }
+
+ /* split the 64bit word back into two 32bit regs */
+ tcg_gen_extr_i64_tl(cpu_gpr[ra_lo], cpu_gpr[a->ra], t8);
+
+ /* update CR0 if requested */
+ if (unlikely(a->rc != 0)) {
+ gen_set_Rc0_i64(ctx, t8);
+ }
+ return true;
+}
+
+TRANS(SRVD, do_shift64, false)
+TRANS(SLVD, do_shift64, true)
+
+static bool trans_DCBQ(DisasContext *ctx, arg_DCBQ * a)
+{
+ if (unlikely(!is_ppe(ctx))) {
+ return false;
+ }
+
+ CHECK_PPE_GPR(ctx, a->rt);
+ CHECK_PPE_GPR(ctx, a->ra);
+ CHECK_PPE_GPR(ctx, a->rb);
+
+ /* No cache exists, so just set RT to 0 */
+ tcg_gen_movi_tl(cpu_gpr[a->rt], 0);
+ return true;
+}
+
+static bool trans_RLDIMI(DisasContext *ctx, arg_RLDIMI *a)
+{
+ TCGv_i64 t_rs, t_ra;
+ int ra_lo, rs_lo;
+ uint32_t sh = a->sh;
+ uint32_t mb = a->mb;
+ uint32_t me = 63 - sh;
+
+ if (unlikely(!is_ppe(ctx))) {
+ return false;
+ }
+ CHECK_PPE_LEVEL(ctx, PPC2_PPE42X);
+ CHECK_VDR(ctx, a->rs);
+ CHECK_VDR(ctx, a->ra);
+
+ rs_lo = VDR_PAIR_REG(a->rs);
+ ra_lo = VDR_PAIR_REG(a->ra);
+
+ t_rs = tcg_temp_new_i64();
+ t_ra = tcg_temp_new_i64();
+
+ tcg_gen_concat_tl_i64(t_rs, cpu_gpr[rs_lo], cpu_gpr[a->rs]);
+ tcg_gen_concat_tl_i64(t_ra, cpu_gpr[ra_lo], cpu_gpr[a->ra]);
+
+ if (mb <= me) {
+ tcg_gen_deposit_i64(t_ra, t_ra, t_rs, sh, me - mb + 1);
+ } else {
+ uint64_t mask = mask_u64(mb, me);
+ TCGv_i64 t1 = tcg_temp_new_i64();
+
+ tcg_gen_rotli_i64(t1, t_rs, sh);
+ tcg_gen_andi_i64(t1, t1, mask);
+ tcg_gen_andi_i64(t_ra, t_ra, ~mask);
+ tcg_gen_or_i64(t_ra, t_ra, t1);
+ }
+
+ tcg_gen_extr_i64_tl(cpu_gpr[ra_lo], cpu_gpr[a->ra], t_ra);
+
+ if (unlikely(a->rc != 0)) {
+ gen_set_Rc0_i64(ctx, t_ra);
+ }
+ return true;
+}
+
+
+static bool gen_rldinm_i64(DisasContext *ctx, arg_MD *a, int mb, int me, int sh)
+{
+ int len = me - mb + 1;
+ int rsh = (64 - sh) & 63;
+ int ra_lo, rs_lo;
+ TCGv_i64 t8;
+
+ if (unlikely(!is_ppe(ctx))) {
+ return false;
+ }
+ CHECK_PPE_LEVEL(ctx, PPC2_PPE42X);
+ CHECK_VDR(ctx, a->rs);
+ CHECK_VDR(ctx, a->ra);
+
+ rs_lo = VDR_PAIR_REG(a->rs);
+ ra_lo = VDR_PAIR_REG(a->ra);
+ t8 = tcg_temp_new_i64();
+ tcg_gen_concat_tl_i64(t8, cpu_gpr[rs_lo], cpu_gpr[a->rs]);
+ if (sh != 0 && len > 0 && me == (63 - sh)) {
+ tcg_gen_deposit_z_i64(t8, t8, sh, len);
+ } else if (me == 63 && rsh + len <= 64) {
+ tcg_gen_extract_i64(t8, t8, rsh, len);
+ } else {
+ tcg_gen_rotli_i64(t8, t8, sh);
+ tcg_gen_andi_i64(t8, t8, mask_u64(mb, me));
+ }
+ tcg_gen_extr_i64_tl(cpu_gpr[ra_lo], cpu_gpr[a->ra], t8);
+ if (unlikely(a->rc != 0)) {
+ gen_set_Rc0_i64(ctx, t8);
+ }
+ return true;
+}
+
+TRANS(RLDICL, gen_rldinm_i64, a->mb, 63, a->sh)
+TRANS(RLDICR, gen_rldinm_i64, 0, a->mb, a->sh)
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 15/27] hw/ppc: Support for an IBM PPE42 CPU decrementer
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (13 preceding siblings ...)
2025-09-28 19:26 ` [PULL 14/27] target/ppc: Add IBM PPE42 special instructions Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 16/27] hw/ppc: Add a test machine for the IBM PPE42 CPU Harsh Prateek Bora
` (12 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Glenn Miles
From: Glenn Miles <milesg@linux.ibm.com>
The IBM PPE42 processors support a 32-bit decrementer
that can raise an external interrupt when DEC[0]
transitions from a 0 to a -1 (a non-negative value to a
negative value). It also continues decrementing
even after this condition is met.
The BookE timer is slightly different in that it
raises an interrupt when the DEC value reaches 0
and stops decrementing at that point.
Support a PPE42 version of the BookE timer by
adding a new PPC_TIMER_PPE flag that has the timer
code look for the transition from a non-negative value
to a negative value and allows the value to
continue decrementing.
Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925201758.652077-8-milesg@linux.ibm.com
Message-ID: <20250925201758.652077-8-milesg@linux.ibm.com>
---
include/hw/ppc/ppc.h | 1 +
hw/ppc/ppc_booke.c | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index 8a14d623f8..cb51d704c6 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -52,6 +52,7 @@ struct ppc_tb_t {
#define PPC_DECR_UNDERFLOW_LEVEL (1 << 4) /* Decr interrupt active when
* the most significant bit is 1.
*/
+#define PPC_TIMER_PPE (1 << 5) /* Enable PPE support */
uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset);
void cpu_ppc_tb_init(CPUPPCState *env, uint32_t freq);
diff --git a/hw/ppc/ppc_booke.c b/hw/ppc/ppc_booke.c
index 3872ae2822..13403a56b1 100644
--- a/hw/ppc/ppc_booke.c
+++ b/hw/ppc/ppc_booke.c
@@ -352,7 +352,12 @@ void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags)
booke_timer = g_new0(booke_timer_t, 1);
cpu->env.tb_env = tb_env;
- tb_env->flags = flags | PPC_TIMER_BOOKE | PPC_DECR_ZERO_TRIGGERED;
+ if (flags & PPC_TIMER_PPE) {
+ /* PPE's use a modified version of the booke behavior */
+ tb_env->flags = flags | PPC_DECR_UNDERFLOW_TRIGGERED;
+ } else {
+ tb_env->flags = flags | PPC_TIMER_BOOKE | PPC_DECR_ZERO_TRIGGERED;
+ }
tb_env->tb_freq = freq;
tb_env->decr_freq = freq;
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 16/27] hw/ppc: Add a test machine for the IBM PPE42 CPU
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (14 preceding siblings ...)
2025-09-28 19:26 ` [PULL 15/27] hw/ppc: Support for an IBM PPE42 CPU decrementer Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 17/27] tests/functional: Add test for IBM PPE42 instructions Harsh Prateek Bora
` (11 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Glenn Miles, Cédric Le Goater
From: Glenn Miles <milesg@linux.ibm.com>
Adds a test machine for the IBM PPE42 processor, including a
DEC, FIT, WDT and 512 KiB of ram.
The purpose of this machine is only to provide a generic platform
for testing instructions of the recently added PPE42 processor
model which is used extensively in the IBM Power9, Power10 and
future Power server processors.
Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925201758.652077-9-milesg@linux.ibm.com
Message-ID: <20250925201758.652077-9-milesg@linux.ibm.com>
---
MAINTAINERS | 6 +++
hw/ppc/ppe42_machine.c | 101 +++++++++++++++++++++++++++++++++++++++++
hw/ppc/Kconfig | 5 ++
hw/ppc/meson.build | 2 +
4 files changed, 114 insertions(+)
create mode 100644 hw/ppc/ppe42_machine.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 7d134a85e6..2ed9eb9353 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1530,6 +1530,12 @@ F: include/hw/pci-host/grackle.h
F: pc-bios/qemu_vga.ndrv
F: tests/functional/ppc/test_mac.py
+PPE42
+M: Glenn Miles <milesg@linux.ibm.com>
+L: qemu-ppc@nongnu.org
+S: Odd Fixes
+F: hw/ppc/ppe42_machine.c
+
PReP
M: Hervé Poussineau <hpoussin@reactos.org>
L: qemu-ppc@nongnu.org
diff --git a/hw/ppc/ppe42_machine.c b/hw/ppc/ppe42_machine.c
new file mode 100644
index 0000000000..f14a91b4e4
--- /dev/null
+++ b/hw/ppc/ppe42_machine.c
@@ -0,0 +1,101 @@
+/*
+ * Test Machine for the IBM PPE42 processor
+ *
+ * Copyright (c) 2025, IBM Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu/error-report.h"
+#include "system/address-spaces.h"
+#include "hw/boards.h"
+#include "hw/ppc/ppc.h"
+#include "system/system.h"
+#include "system/reset.h"
+#include "system/kvm.h"
+#include "qapi/error.h"
+
+#define TYPE_PPE42_MACHINE MACHINE_TYPE_NAME("ppe42_machine")
+typedef MachineClass Ppe42MachineClass;
+typedef struct Ppe42MachineState Ppe42MachineState;
+DECLARE_OBJ_CHECKERS(Ppe42MachineState, Ppe42MachineClass,
+ PPE42_MACHINE, TYPE_PPE42_MACHINE)
+
+struct Ppe42MachineState {
+ MachineState parent_obj;
+
+ PowerPCCPU cpu;
+};
+
+static void main_cpu_reset(void *opaque)
+{
+ PowerPCCPU *cpu = opaque;
+
+ cpu_reset(CPU(cpu));
+}
+
+static void ppe42_machine_init(MachineState *machine)
+{
+ Ppe42MachineState *pms = PPE42_MACHINE(machine);
+ PowerPCCPU *cpu = &pms->cpu;
+
+ if (kvm_enabled()) {
+ error_report("machine %s does not support the KVM accelerator",
+ MACHINE_GET_CLASS(machine)->name);
+ exit(EXIT_FAILURE);
+ }
+ if (machine->ram_size > 512 * KiB) {
+ error_report("RAM size more than 512 KiB is not supported");
+ exit(1);
+ }
+
+ /* init CPU */
+ object_initialize_child(OBJECT(pms), "cpu", cpu, machine->cpu_type);
+ if (!qdev_realize(DEVICE(cpu), NULL, &error_fatal)) {
+ return;
+ }
+
+ qemu_register_reset(main_cpu_reset, cpu);
+
+ /* This sets the decrementer timebase */
+ ppc_booke_timers_init(cpu, 37500000, PPC_TIMER_PPE);
+
+ /* RAM */
+ memory_region_add_subregion(get_system_memory(), 0xfff80000, machine->ram);
+}
+
+
+static void ppe42_machine_class_init(ObjectClass *oc, const void *data)
+{
+ MachineClass *mc = MACHINE_CLASS(oc);
+ static const char * const valid_cpu_types[] = {
+ POWERPC_CPU_TYPE_NAME("PPE42"),
+ POWERPC_CPU_TYPE_NAME("PPE42X"),
+ POWERPC_CPU_TYPE_NAME("PPE42XM"),
+ NULL,
+ };
+
+ mc->desc = "PPE42 Test Machine";
+ mc->init = ppe42_machine_init;
+ mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("PPE42XM");
+ mc->valid_cpu_types = valid_cpu_types;
+ mc->default_ram_id = "ram";
+ mc->default_ram_size = 512 * KiB;
+}
+
+static const TypeInfo ppe42_machine_info = {
+ .name = TYPE_PPE42_MACHINE,
+ .parent = TYPE_MACHINE,
+ .instance_size = sizeof(Ppe42MachineState),
+ .class_init = ppe42_machine_class_init,
+ .class_size = sizeof(Ppe42MachineClass),
+};
+
+static void ppe42_machine_register_types(void)
+{
+ type_register_static(&ppe42_machine_info);
+}
+
+type_init(ppe42_machine_register_types);
diff --git a/hw/ppc/Kconfig b/hw/ppc/Kconfig
index ced6bbc740..7091d72fd8 100644
--- a/hw/ppc/Kconfig
+++ b/hw/ppc/Kconfig
@@ -44,6 +44,11 @@ config POWERNV
select SSI_M25P80
select PNV_SPI
+config PPC405
+ bool
+ default y
+ depends on PPC
+
config PPC440
bool
default y
diff --git a/hw/ppc/meson.build b/hw/ppc/meson.build
index 9893f8adeb..170b90ae7d 100644
--- a/hw/ppc/meson.build
+++ b/hw/ppc/meson.build
@@ -57,6 +57,8 @@ ppc_ss.add(when: 'CONFIG_POWERNV', if_true: files(
'pnv_n1_chiplet.c',
))
# PowerPC 4xx boards
+ppc_ss.add(when: 'CONFIG_PPC405', if_true: files(
+ 'ppe42_machine.c'))
ppc_ss.add(when: 'CONFIG_PPC440', if_true: files(
'ppc440_bamboo.c',
'ppc440_uc.c'))
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 17/27] tests/functional: Add test for IBM PPE42 instructions
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (15 preceding siblings ...)
2025-09-28 19:26 ` [PULL 16/27] hw/ppc: Add a test machine for the IBM PPE42 CPU Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 18/27] hw/intc/xics: Add missing call to register vmstate_icp_server Harsh Prateek Bora
` (10 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Glenn Miles, Thomas Huth, Cédric Le Goater
From: Glenn Miles <milesg@linux.ibm.com>
Adds a functional test for the IBM PPE42 instructions which
downloads a test image from a public github repo and then
loads and executes the image.
(see https://github.com/milesg-github/ppe42-tests for details)
Test status is checked by periodically issuing 'info register'
commands and checking the NIP value. If the NIP is 0xFFF80200
then the test successfully executed to completion. If the
machine stops before the test completes or if a 90 second
timeout is reached, then the test is marked as having failed.
This test does not test any PowerPC instructions as it is
expected that these instructions are well covered in other
tests. Only instructions that are unique to the IBM PPE42
processor are tested.
Signed-off-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250925201758.652077-10-milesg@linux.ibm.com
Message-ID: <20250925201758.652077-10-milesg@linux.ibm.com>
---
MAINTAINERS | 1 +
tests/functional/ppc/meson.build | 1 +
tests/functional/ppc/test_ppe42.py | 79 ++++++++++++++++++++++++++++++
3 files changed, 81 insertions(+)
create mode 100644 tests/functional/ppc/test_ppe42.py
diff --git a/MAINTAINERS b/MAINTAINERS
index 2ed9eb9353..406cef88f0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1535,6 +1535,7 @@ M: Glenn Miles <milesg@linux.ibm.com>
L: qemu-ppc@nongnu.org
S: Odd Fixes
F: hw/ppc/ppe42_machine.c
+F: tests/functional/ppc/test_ppe42.py
PReP
M: Hervé Poussineau <hpoussin@reactos.org>
diff --git a/tests/functional/ppc/meson.build b/tests/functional/ppc/meson.build
index 3d562010d8..ae061fe5a6 100644
--- a/tests/functional/ppc/meson.build
+++ b/tests/functional/ppc/meson.build
@@ -15,6 +15,7 @@ tests_ppc_system_thorough = [
'bamboo',
'mac',
'mpc8544ds',
+ 'ppe42',
'replay',
'sam460ex',
'tuxrun',
diff --git a/tests/functional/ppc/test_ppe42.py b/tests/functional/ppc/test_ppe42.py
new file mode 100644
index 0000000000..26bbe11b2d
--- /dev/null
+++ b/tests/functional/ppc/test_ppe42.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+#
+# Functional tests for the IBM PPE42 processor
+#
+# Copyright (c) 2025, IBM Corporation
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset
+import asyncio
+
+class Ppe42Machine(QemuSystemTest):
+
+ timeout = 90
+ poll_period = 1.0
+
+ ASSET_PPE42_TEST_IMAGE = Asset(
+ ('https://github.com/milesg-github/ppe42-tests/raw/refs/heads/main/'
+ 'images/ppe42-test.out'),
+ '03c1ac0fb7f6c025102a02776a93b35101dae7c14b75e4eab36a337e39042ea8')
+
+ def _test_completed(self):
+ self.log.info("Checking for test completion...")
+ try:
+ output = self.vm.cmd('human-monitor-command',
+ command_line='info registers')
+ except Exception as err:
+ self.log.debug(f"'info registers' cmd failed due to {err=},"
+ " {type(err)=}")
+ raise
+
+ self.log.info(output)
+ if "NIP fff80200" in output:
+ self.log.info("<test completed>")
+ return True
+ else:
+ self.log.info("<test not completed>")
+ return False
+
+ def _wait_pass_fail(self, timeout):
+ while not self._test_completed():
+ if timeout >= self.poll_period:
+ timeout = timeout - self.poll_period
+ self.log.info(f"Waiting {self.poll_period} seconds for test"
+ " to complete...")
+ e = None
+ try:
+ e = self.vm.event_wait('STOP', self.poll_period)
+
+ except asyncio.TimeoutError:
+ self.log.info("Poll period ended.")
+ pass
+
+ except Exception as err:
+ self.log.debug(f"event_wait() failed due to {err=},"
+ " {type(err)=}")
+ raise
+
+ if e != None:
+ self.log.debug(f"Execution stopped: {e}")
+ self.log.debug("Exiting due to test failure")
+ self.fail("Failure detected!")
+ break
+ else:
+ self.fail("Timed out waiting for test completion.")
+
+ def test_ppe42_instructions(self):
+ self.set_machine('ppe42_machine')
+ self.require_accelerator("tcg")
+ image_path = self.ASSET_PPE42_TEST_IMAGE.fetch()
+ self.vm.add_args('-nographic')
+ self.vm.add_args('-device', f'loader,file={image_path}')
+ self.vm.add_args('-device', 'loader,addr=0xfff80040,cpu-num=0')
+ self.vm.add_args('-action', 'panic=pause')
+ self.vm.launch()
+ self._wait_pass_fail(self.timeout)
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 18/27] hw/intc/xics: Add missing call to register vmstate_icp_server
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (16 preceding siblings ...)
2025-09-28 19:26 ` [PULL 17/27] tests/functional: Add test for IBM PPE42 instructions Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-29 19:32 ` Michael Tokarev
2025-09-28 19:26 ` [PULL 19/27] ppc/spapr: init lrdr-capapcity phys with ram size if maxmem not provided Harsh Prateek Bora
` (9 subsequent siblings)
27 siblings, 1 reply; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel
Cc: Fabian Vogt, Philippe Mathieu-Daudé, Fabiano Rosas,
Gautam Menghani
From: Fabian Vogt <fvogt@suse.de>
An obsolete wrapper function with a workaround was removed entirely,
without restoring the call it wrapped.
Without this, the guest is stuck after savevm/loadvm.
Fixes: 24ee9229fe31 ("ppc/spapr: remove deprecated machine pseries-2.9")
Signed-off-by: Fabian Vogt <fvogt@suse.de>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Link: https://lore.kernel.org/qemu-devel/6187781.lOV4Wx5bFT@fvogt-thinkpad
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Gautam Menghani <gautam@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250819223905.2247-2-farosas@suse.de
Message-ID: <20250819223905.2247-2-farosas@suse.de>
---
hw/intc/xics.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index d9a199e883..200710eb6c 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -335,6 +335,8 @@ static void icp_realize(DeviceState *dev, Error **errp)
return;
}
}
+
+ vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp);
}
static void icp_unrealize(DeviceState *dev)
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 19/27] ppc/spapr: init lrdr-capapcity phys with ram size if maxmem not provided
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (17 preceding siblings ...)
2025-09-28 19:26 ` [PULL 18/27] hw/intc/xics: Add missing call to register vmstate_icp_server Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-29 19:36 ` Michael Tokarev
2025-09-28 19:26 ` [PULL 20/27] ppc/xive2: Fix integer overflow warning in xive2_redistribute() Harsh Prateek Bora
` (8 subsequent siblings)
27 siblings, 1 reply; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Gaurav Batra, David Christensen, Shivaprasad G Bhat
lrdr-capacity contains phys field which communicates the maximum address
in bytes and therefore, the most memory that can be allocated to this
partition. This is usually populated when maxmem is provided alongwith
memory size on qemu command line. However since maxmem is an optional
param, this leads to bits being set to 0 in absence of maxmem param.
Fix this by initializing the respective bits as per total mem size in
such case.
Reported-by: Gaurav Batra <gbatra@us.ibm.com>
Tested-by: David Christensen <drc@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Reviewed-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Link: https://lore.kernel.org/r/20250506042903.76250-1-harshpb@linux.ibm.com
Message-ID: <20250506042903.76250-1-harshpb@linux.ibm.com>
---
hw/ppc/spapr.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index eb22333404..82fb23beaa 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -907,6 +907,7 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
int rtas;
GString *hypertas = g_string_sized_new(256);
GString *qemu_hypertas = g_string_sized_new(256);
+ uint64_t max_device_addr = 0;
uint32_t lrdr_capacity[] = {
0,
0,
@@ -917,13 +918,15 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
/* Do we have device memory? */
if (MACHINE(spapr)->device_memory) {
- uint64_t max_device_addr = MACHINE(spapr)->device_memory->base +
+ max_device_addr = MACHINE(spapr)->device_memory->base +
memory_region_size(&MACHINE(spapr)->device_memory->mr);
-
- lrdr_capacity[0] = cpu_to_be32(max_device_addr >> 32);
- lrdr_capacity[1] = cpu_to_be32(max_device_addr & 0xffffffff);
+ } else if (ms->ram_size == ms->maxram_size) {
+ max_device_addr = ms->ram_size;
}
+ lrdr_capacity[0] = cpu_to_be32(max_device_addr >> 32);
+ lrdr_capacity[1] = cpu_to_be32(max_device_addr & 0xffffffff);
+
_FDT(rtas = fdt_add_subnode(fdt, 0, "rtas"));
/* hypertas */
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 20/27] ppc/xive2: Fix integer overflow warning in xive2_redistribute()
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (18 preceding siblings ...)
2025-09-28 19:26 ` [PULL 19/27] ppc/spapr: init lrdr-capapcity phys with ram size if maxmem not provided Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 21/27] target/ppc: Move floating-point rounding and conversion instructions to decodetree Harsh Prateek Bora
` (7 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Gautam Menghani, Glenn Miles, Amit Machhiwal
From: Gautam Menghani <gautam@linux.ibm.com>
Coverity reported an integer overflow warning in xive2_redistribute()
where the code does a left shift operation "0xffffffff << crowd". Fix the
warning by using a 64 byte integer type. Also refactor the calculation
into dedicated routines.
Resolves: Coverity CID 1612608
Fixes: 555e446019f5 ("ppc/xive2: Support redistribution of group interrupts")
Reviewed-by: Glenn Miles <milesg@linux.ibm.com>
Signed-off-by: Gautam Menghani <gautam@linux.ibm.com>
Reviewed-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250811074912.162774-1-gautam@linux.ibm.com
Message-ID: <20250811074912.162774-1-gautam@linux.ibm.com>
---
hw/intc/xive2.c | 45 +++++++++++++++++++++++++++++++--------------
1 file changed, 31 insertions(+), 14 deletions(-)
diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
index ee5fa26178..fbb3b7975e 100644
--- a/hw/intc/xive2.c
+++ b/hw/intc/xive2.c
@@ -95,6 +95,35 @@ static void xive2_nvgc_set_backlog(Xive2Nvgc *nvgc, uint8_t priority,
}
}
+static uint32_t xive2_nvgc_get_idx(uint32_t nvp_idx, uint8_t group)
+{
+ uint32_t nvgc_idx;
+
+ if (group > 0) {
+ nvgc_idx = (nvp_idx & (0xffffffffULL << group)) |
+ ((1 << (group - 1)) - 1);
+ } else {
+ nvgc_idx = nvp_idx;
+ }
+
+ return nvgc_idx;
+}
+
+static uint8_t xive2_nvgc_get_blk(uint8_t nvp_blk, uint8_t crowd)
+{
+ uint8_t nvgc_blk;
+
+ if (crowd > 0) {
+ crowd = (crowd == 3) ? 4 : crowd;
+ nvgc_blk = (nvp_blk & (0xffffffffULL << crowd)) |
+ ((1 << (crowd - 1)) - 1);
+ } else {
+ nvgc_blk = nvp_blk;
+ }
+
+ return nvgc_blk;
+}
+
uint64_t xive2_presenter_nvgc_backlog_op(XivePresenter *xptr,
bool crowd,
uint8_t blk, uint32_t idx,
@@ -638,20 +667,8 @@ static void xive2_redistribute(Xive2Router *xrtr, XiveTCTX *tctx, uint8_t ring)
trace_xive_redistribute(tctx->cs->cpu_index, ring, nvp_blk, nvp_idx);
/* convert crowd/group to blk/idx */
- if (group > 0) {
- nvgc_idx = (nvp_idx & (0xffffffff << group)) |
- ((1 << (group - 1)) - 1);
- } else {
- nvgc_idx = nvp_idx;
- }
-
- if (crowd > 0) {
- crowd = (crowd == 3) ? 4 : crowd;
- nvgc_blk = (nvp_blk & (0xffffffff << crowd)) |
- ((1 << (crowd - 1)) - 1);
- } else {
- nvgc_blk = nvp_blk;
- }
+ nvgc_idx = xive2_nvgc_get_idx(nvp_idx, group);
+ nvgc_blk = xive2_nvgc_get_blk(nvp_blk, crowd);
/* Use blk/idx to retrieve the NVGC */
if (xive2_router_get_nvgc(xrtr, crowd, nvgc_blk, nvgc_idx, &nvgc)) {
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 21/27] target/ppc: Move floating-point rounding and conversion instructions to decodetree.
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (19 preceding siblings ...)
2025-09-28 19:26 ` [PULL 20/27] ppc/xive2: Fix integer overflow warning in xive2_redistribute() Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 22/27] target/ppc: Move floating-point compare " Harsh Prateek Bora
` (6 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Chinmay Rath, Richard Henderson
From: Chinmay Rath <rathc@linux.ibm.com>
Move below instructions to decodetree specification :
fr{sp, in, iz, im}[s][.],
fcti{w, d}[u, z, uz][s][.],
fcfid[s, u, us][s][.] : X-form
The changes were verified by validating that the tcg ops generated by
those instructions remain the same, which were captured with the '-d
in_asm,op' flag.
Signed-off-by: Chinmay Rath <rathc@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250619095840.369351-2-rathc@linux.ibm.com
Message-ID: <20250619095840.369351-2-rathc@linux.ibm.com>
---
target/ppc/helper.h | 34 +++++-----
target/ppc/insn32.decode | 24 ++++++++
target/ppc/fpu_helper.c | 34 +++++-----
target/ppc/translate/fp-impl.c.inc | 99 ++++++++++++------------------
target/ppc/translate/fp-ops.c.inc | 21 -------
5 files changed, 98 insertions(+), 114 deletions(-)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index ca414f2f43..96000f4f0d 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -97,23 +97,23 @@ DEF_HELPER_FLAGS_1(tosingle, TCG_CALL_NO_RWG_SE, i32, i64)
DEF_HELPER_4(fcmpo, void, env, i64, i64, i32)
DEF_HELPER_4(fcmpu, void, env, i64, i64, i32)
-DEF_HELPER_2(fctiw, i64, env, i64)
-DEF_HELPER_2(fctiwu, i64, env, i64)
-DEF_HELPER_2(fctiwz, i64, env, i64)
-DEF_HELPER_2(fctiwuz, i64, env, i64)
-DEF_HELPER_2(fcfid, i64, env, i64)
-DEF_HELPER_2(fcfidu, i64, env, i64)
-DEF_HELPER_2(fcfids, i64, env, i64)
-DEF_HELPER_2(fcfidus, i64, env, i64)
-DEF_HELPER_2(fctid, i64, env, i64)
-DEF_HELPER_2(fctidu, i64, env, i64)
-DEF_HELPER_2(fctidz, i64, env, i64)
-DEF_HELPER_2(fctiduz, i64, env, i64)
-DEF_HELPER_2(frsp, i64, env, i64)
-DEF_HELPER_2(frin, i64, env, i64)
-DEF_HELPER_2(friz, i64, env, i64)
-DEF_HELPER_2(frip, i64, env, i64)
-DEF_HELPER_2(frim, i64, env, i64)
+DEF_HELPER_2(FCTIW, i64, env, i64)
+DEF_HELPER_2(FCTIWU, i64, env, i64)
+DEF_HELPER_2(FCTIWZ, i64, env, i64)
+DEF_HELPER_2(FCTIWUZ, i64, env, i64)
+DEF_HELPER_2(FCFID, i64, env, i64)
+DEF_HELPER_2(FCFIDU, i64, env, i64)
+DEF_HELPER_2(FCFIDS, i64, env, i64)
+DEF_HELPER_2(FCFIDUS, i64, env, i64)
+DEF_HELPER_2(FCTID, i64, env, i64)
+DEF_HELPER_2(FCTIDU, i64, env, i64)
+DEF_HELPER_2(FCTIDZ, i64, env, i64)
+DEF_HELPER_2(FCTIDUZ, i64, env, i64)
+DEF_HELPER_2(FRSP, i64, env, i64)
+DEF_HELPER_2(FRIN, i64, env, i64)
+DEF_HELPER_2(FRIZ, i64, env, i64)
+DEF_HELPER_2(FRIP, i64, env, i64)
+DEF_HELPER_2(FRIM, i64, env, i64)
DEF_HELPER_3(FADD, f64, env, f64, f64)
DEF_HELPER_3(FADDS, f64, env, f64, f64)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 16652b5c13..0c7472d929 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -568,6 +568,30 @@ FNMADDS 111011 ..... ..... ..... ..... 11111 . @A
FNMSUB 111111 ..... ..... ..... ..... 11110 . @A
FNMSUBS 111011 ..... ..... ..... ..... 11110 . @A
+### Floating-Point Rounding and Conversion Instructions
+
+FRSP 111111 ..... ----- ..... 0000001100 . @X_tb_rc
+
+FRIN 111111 ..... ----- ..... 0110001000 . @X_tb_rc
+FRIZ 111111 ..... ----- ..... 0110101000 . @X_tb_rc
+FRIP 111111 ..... ----- ..... 0111001000 . @X_tb_rc
+FRIM 111111 ..... ----- ..... 0111101000 . @X_tb_rc
+
+FCTIW 111111 ..... ----- ..... 0000001110 . @X_tb_rc
+FCTIWU 111111 ..... ----- ..... 0010001110 . @X_tb_rc
+FCTIWZ 111111 ..... ----- ..... 0000001111 . @X_tb_rc
+FCTIWUZ 111111 ..... ----- ..... 0010001111 . @X_tb_rc
+
+FCTID 111111 ..... ----- ..... 1100101110 . @X_tb_rc
+FCTIDU 111111 ..... ----- ..... 1110101110 . @X_tb_rc
+FCTIDZ 111111 ..... ----- ..... 1100101111 . @X_tb_rc
+FCTIDUZ 111111 ..... ----- ..... 1110101111 . @X_tb_rc
+
+FCFID 111111 ..... ----- ..... 1101001110 . @X_tb_rc
+FCFIDS 111011 ..... ----- ..... 1101001110 . @X_tb_rc
+FCFIDU 111111 ..... ----- ..... 1111001110 . @X_tb_rc
+FCFIDUS 111011 ..... ----- ..... 1111001110 . @X_tb_rc
+
### Floating-Point Select Instruction
FSEL 111111 ..... ..... ..... ..... 10111 . @A
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 07b782f971..503cbd98ad 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -562,14 +562,14 @@ uint64_t helper_##op(CPUPPCState *env, float64 arg) \
return ret; \
}
-FPU_FCTI(fctiw, int32, 0x80000000U)
-FPU_FCTI(fctiwz, int32_round_to_zero, 0x80000000U)
-FPU_FCTI(fctiwu, uint32, 0x00000000U)
-FPU_FCTI(fctiwuz, uint32_round_to_zero, 0x00000000U)
-FPU_FCTI(fctid, int64, 0x8000000000000000ULL)
-FPU_FCTI(fctidz, int64_round_to_zero, 0x8000000000000000ULL)
-FPU_FCTI(fctidu, uint64, 0x0000000000000000ULL)
-FPU_FCTI(fctiduz, uint64_round_to_zero, 0x0000000000000000ULL)
+FPU_FCTI(FCTIW, int32, 0x80000000U)
+FPU_FCTI(FCTIWZ, int32_round_to_zero, 0x80000000U)
+FPU_FCTI(FCTIWU, uint32, 0x00000000U)
+FPU_FCTI(FCTIWUZ, uint32_round_to_zero, 0x00000000U)
+FPU_FCTI(FCTID, int64, 0x8000000000000000ULL)
+FPU_FCTI(FCTIDZ, int64_round_to_zero, 0x8000000000000000ULL)
+FPU_FCTI(FCTIDU, uint64, 0x0000000000000000ULL)
+FPU_FCTI(FCTIDUZ, uint64_round_to_zero, 0x0000000000000000ULL)
#define FPU_FCFI(op, cvtr, is_single) \
uint64_t helper_##op(CPUPPCState *env, uint64_t arg) \
@@ -586,10 +586,10 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg) \
return farg.ll; \
}
-FPU_FCFI(fcfid, int64_to_float64, 0)
-FPU_FCFI(fcfids, int64_to_float32, 1)
-FPU_FCFI(fcfidu, uint64_to_float64, 0)
-FPU_FCFI(fcfidus, uint64_to_float32, 1)
+FPU_FCFI(FCFID, int64_to_float64, 0)
+FPU_FCFI(FCFIDS, int64_to_float32, 1)
+FPU_FCFI(FCFIDU, uint64_to_float64, 0)
+FPU_FCFI(FCFIDUS, uint64_to_float32, 1)
static uint64_t do_fri(CPUPPCState *env, uint64_t arg,
FloatRoundMode rounding_mode)
@@ -613,22 +613,22 @@ static uint64_t do_fri(CPUPPCState *env, uint64_t arg,
return arg;
}
-uint64_t helper_frin(CPUPPCState *env, uint64_t arg)
+uint64_t helper_FRIN(CPUPPCState *env, uint64_t arg)
{
return do_fri(env, arg, float_round_ties_away);
}
-uint64_t helper_friz(CPUPPCState *env, uint64_t arg)
+uint64_t helper_FRIZ(CPUPPCState *env, uint64_t arg)
{
return do_fri(env, arg, float_round_to_zero);
}
-uint64_t helper_frip(CPUPPCState *env, uint64_t arg)
+uint64_t helper_FRIP(CPUPPCState *env, uint64_t arg)
{
return do_fri(env, arg, float_round_up);
}
-uint64_t helper_frim(CPUPPCState *env, uint64_t arg)
+uint64_t helper_FRIM(CPUPPCState *env, uint64_t arg)
{
return do_fri(env, arg, float_round_down);
}
@@ -697,7 +697,7 @@ static uint64_t do_frsp(CPUPPCState *env, uint64_t arg, uintptr_t retaddr)
return helper_todouble(f32);
}
-uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)
+uint64_t helper_FRSP(CPUPPCState *env, uint64_t arg)
{
return do_frsp(env, arg, GETPC());
}
diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc
index a66b83398b..f296cfcdb0 100644
--- a/target/ppc/translate/fp-impl.c.inc
+++ b/target/ppc/translate/fp-impl.c.inc
@@ -98,28 +98,26 @@ static bool do_helper_ac(DisasContext *ctx, arg_A_tac *a,
return true;
}
-#define GEN_FLOAT_B(name, op2, op3, set_fprf, type) \
-static void gen_f##name(DisasContext *ctx) \
-{ \
- TCGv_i64 t0; \
- TCGv_i64 t1; \
- if (unlikely(!ctx->fpu_enabled)) { \
- gen_exception(ctx, POWERPC_EXCP_FPU); \
- return; \
- } \
- t0 = tcg_temp_new_i64(); \
- t1 = tcg_temp_new_i64(); \
- gen_reset_fpstatus(); \
- get_fpr(t0, rB(ctx->opcode)); \
- gen_helper_f##name(t1, tcg_env, t0); \
- set_fpr(rD(ctx->opcode), t1); \
- if (set_fprf) { \
- gen_helper_compute_fprf_float64(tcg_env, t1); \
- } \
- gen_helper_float_check_status(tcg_env); \
- if (unlikely(Rc(ctx->opcode) != 0)) { \
- gen_set_cr1_from_fpscr(ctx); \
- } \
+static bool do_round_convert(DisasContext *ctx, arg_X_tb_rc *a,
+ void (*helper)(TCGv_i64, TCGv_env, TCGv_i64),
+ bool set_fprf)
+{
+ TCGv_i64 t0, t1;
+ REQUIRE_FPU(ctx);
+ t0 = tcg_temp_new_i64();
+ t1 = tcg_temp_new_i64();
+ gen_reset_fpstatus();
+ get_fpr(t0, a->rb);
+ helper(t1, tcg_env, t0);
+ set_fpr(a->rt, t1);
+ if (set_fprf) {
+ gen_helper_compute_fprf_float64(tcg_env, t1);
+ }
+ gen_helper_float_check_status(tcg_env);
+ if (unlikely(a->rc)) {
+ gen_set_cr1_from_fpscr(ctx);
+ }
+ return true;
}
static bool do_helper_bs(DisasContext *ctx, arg_A_tb *a,
@@ -213,41 +211,26 @@ TRANS(FSQRT, do_helper_fsqrt, gen_helper_FSQRT);
TRANS(FSQRTS, do_helper_fsqrt, gen_helper_FSQRTS);
/*** Floating-Point round & convert ***/
-/* fctiw */
-GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT);
-/* fctiwu */
-GEN_FLOAT_B(ctiwu, 0x0E, 0x04, 0, PPC2_FP_CVT_ISA206);
-/* fctiwz */
-GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT);
-/* fctiwuz */
-GEN_FLOAT_B(ctiwuz, 0x0F, 0x04, 0, PPC2_FP_CVT_ISA206);
-/* frsp */
-GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT);
-/* fcfid */
-GEN_FLOAT_B(cfid, 0x0E, 0x1A, 1, PPC2_FP_CVT_S64);
-/* fcfids */
-GEN_FLOAT_B(cfids, 0x0E, 0x1A, 0, PPC2_FP_CVT_ISA206);
-/* fcfidu */
-GEN_FLOAT_B(cfidu, 0x0E, 0x1E, 0, PPC2_FP_CVT_ISA206);
-/* fcfidus */
-GEN_FLOAT_B(cfidus, 0x0E, 0x1E, 0, PPC2_FP_CVT_ISA206);
-/* fctid */
-GEN_FLOAT_B(ctid, 0x0E, 0x19, 0, PPC2_FP_CVT_S64);
-/* fctidu */
-GEN_FLOAT_B(ctidu, 0x0E, 0x1D, 0, PPC2_FP_CVT_ISA206);
-/* fctidz */
-GEN_FLOAT_B(ctidz, 0x0F, 0x19, 0, PPC2_FP_CVT_S64);
-/* fctidu */
-GEN_FLOAT_B(ctiduz, 0x0F, 0x1D, 0, PPC2_FP_CVT_ISA206);
-
-/* frin */
-GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT);
-/* friz */
-GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT);
-/* frip */
-GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT);
-/* frim */
-GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT);
+TRANS_FLAGS(FLOAT, FRSP, do_round_convert, gen_helper_FRSP, true);
+TRANS_FLAGS(FLOAT_EXT, FRIN, do_round_convert, gen_helper_FRIN, true);
+TRANS_FLAGS(FLOAT_EXT, FRIZ, do_round_convert, gen_helper_FRIZ, true);
+TRANS_FLAGS(FLOAT_EXT, FRIP, do_round_convert, gen_helper_FRIP, true);
+TRANS_FLAGS(FLOAT_EXT, FRIM, do_round_convert, gen_helper_FRIM, true);
+
+TRANS_FLAGS(FLOAT, FCTIW, do_round_convert, gen_helper_FCTIW, false);
+TRANS_FLAGS2(FP_CVT_ISA206, FCTIWU, do_round_convert, gen_helper_FCTIWU, false);
+TRANS_FLAGS(FLOAT, FCTIWZ, do_round_convert, gen_helper_FCTIWZ, false);
+TRANS_FLAGS2(FP_CVT_ISA206, FCTIWUZ, do_round_convert, gen_helper_FCTIWUZ, false);
+
+TRANS_FLAGS2(FP_CVT_S64, FCTID, do_round_convert, gen_helper_FCTID, false);
+TRANS_FLAGS2(FP_CVT_ISA206, FCTIDU, do_round_convert, gen_helper_FCTIDU, false);
+TRANS_FLAGS2(FP_CVT_S64, FCTIDZ, do_round_convert, gen_helper_FCTIDZ, false);
+TRANS_FLAGS2(FP_CVT_ISA206, FCTIDUZ, do_round_convert, gen_helper_FCTIDUZ, false);
+
+TRANS_FLAGS2(FP_CVT_S64, FCFID, do_round_convert, gen_helper_FCFID, true);
+TRANS_FLAGS2(FP_CVT_ISA206, FCFIDS, do_round_convert, gen_helper_FCFIDS, false);
+TRANS_FLAGS2(FP_CVT_ISA206, FCFIDU, do_round_convert, gen_helper_FCFIDU, false);
+TRANS_FLAGS2(FP_CVT_ISA206, FCFIDUS, do_round_convert, gen_helper_FCFIDUS, false);
static bool trans_FTDIV(DisasContext *ctx, arg_X_bf *a)
{
@@ -1051,8 +1034,6 @@ TRANS(STFDX, do_lsfp_X, false, true, false)
TRANS(STFDUX, do_lsfp_X, true, true, false)
TRANS(PSTFD, do_lsfp_PLS_D, false, true, false)
-#undef GEN_FLOAT_B
-
#undef GEN_LDF
#undef GEN_LDUF
#undef GEN_LDUXF
diff --git a/target/ppc/translate/fp-ops.c.inc b/target/ppc/translate/fp-ops.c.inc
index cef4b5dfcb..acb8ac32da 100644
--- a/target/ppc/translate/fp-ops.c.inc
+++ b/target/ppc/translate/fp-ops.c.inc
@@ -1,24 +1,3 @@
-#define GEN_FLOAT_B(name, op2, op3, set_fprf, type) \
-GEN_HANDLER(f##name, 0x3F, op2, op3, 0x001F0000, type)
-
-GEN_FLOAT_B(ctiw, 0x0E, 0x00, 0, PPC_FLOAT),
-GEN_HANDLER_E(fctiwu, 0x3F, 0x0E, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_FLOAT_B(ctiwz, 0x0F, 0x00, 0, PPC_FLOAT),
-GEN_HANDLER_E(fctiwuz, 0x3F, 0x0F, 0x04, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_FLOAT_B(rsp, 0x0C, 0x00, 1, PPC_FLOAT),
-GEN_HANDLER_E(fcfid, 0x3F, 0x0E, 0x1A, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
-GEN_HANDLER_E(fcfids, 0x3B, 0x0E, 0x1A, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_HANDLER_E(fcfidu, 0x3F, 0x0E, 0x1E, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_HANDLER_E(fcfidus, 0x3B, 0x0E, 0x1E, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_HANDLER_E(fctid, 0x3F, 0x0E, 0x19, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
-GEN_HANDLER_E(fctidu, 0x3F, 0x0E, 0x1D, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_HANDLER_E(fctidz, 0x3F, 0x0F, 0x19, 0x001F0000, PPC_NONE, PPC2_FP_CVT_S64),
-GEN_HANDLER_E(fctiduz, 0x3F, 0x0F, 0x1D, 0, PPC_NONE, PPC2_FP_CVT_ISA206),
-GEN_FLOAT_B(rin, 0x08, 0x0C, 1, PPC_FLOAT_EXT),
-GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
-GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
-GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
-
GEN_HANDLER_E(lfdepx, 0x1F, 0x1F, 0x12, 0x00000001, PPC_NONE, PPC2_BOOKE206),
GEN_HANDLER_E(lfiwax, 0x1f, 0x17, 0x1a, 0x00000001, PPC_NONE, PPC2_ISA205),
GEN_HANDLER_E(lfiwzx, 0x1f, 0x17, 0x1b, 0x1, PPC_NONE, PPC2_FP_CVT_ISA206),
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 22/27] target/ppc: Move floating-point compare instructions to decodetree.
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (20 preceding siblings ...)
2025-09-28 19:26 ` [PULL 21/27] target/ppc: Move floating-point rounding and conversion instructions to decodetree Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 23/27] target/ppc: Move floating-point move " Harsh Prateek Bora
` (5 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Chinmay Rath, Richard Henderson
From: Chinmay Rath <rathc@linux.ibm.com>
Move below instructions to decodetree specification :
fcmp{u, o} : X-form
The changes were verified by validating that the tcg ops generated by
those instructions remain the same, which were captured with the '-d
in_asm,op' flag.
Signed-off-by: Chinmay Rath <rathc@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250619095840.369351-3-rathc@linux.ibm.com
Message-ID: <20250619095840.369351-3-rathc@linux.ibm.com>
---
target/ppc/helper.h | 4 +--
target/ppc/insn32.decode | 5 ++++
target/ppc/fpu_helper.c | 4 +--
target/ppc/translate/fp-impl.c.inc | 45 +++++++++---------------------
target/ppc/translate/fp-ops.c.inc | 2 --
5 files changed, 22 insertions(+), 38 deletions(-)
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 96000f4f0d..e99c8c824b 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -94,8 +94,8 @@ DEF_HELPER_2(fpscr_setbit, void, env, i32)
DEF_HELPER_FLAGS_1(todouble, TCG_CALL_NO_RWG_SE, i64, i32)
DEF_HELPER_FLAGS_1(tosingle, TCG_CALL_NO_RWG_SE, i32, i64)
-DEF_HELPER_4(fcmpo, void, env, i64, i64, i32)
-DEF_HELPER_4(fcmpu, void, env, i64, i64, i32)
+DEF_HELPER_4(FCMPO, void, env, i64, i64, i32)
+DEF_HELPER_4(FCMPU, void, env, i64, i64, i32)
DEF_HELPER_2(FCTIW, i64, env, i64)
DEF_HELPER_2(FCTIWU, i64, env, i64)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 0c7472d929..d446ec534d 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -592,6 +592,11 @@ FCFIDS 111011 ..... ----- ..... 1101001110 . @X_tb_rc
FCFIDU 111111 ..... ----- ..... 1111001110 . @X_tb_rc
FCFIDUS 111011 ..... ----- ..... 1111001110 . @X_tb_rc
+### Floating-Point Compare Instructions
+
+FCMPU 111111 ... -- ..... ..... 0000000000 - @X_bf
+FCMPO 111111 ... -- ..... ..... 0000100000 - @X_bf
+
### Floating-Point Select Instruction
FSEL 111111 ..... ..... ..... ..... 10111 . @A
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 503cbd98ad..850aca6ed1 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -871,7 +871,7 @@ uint32_t helper_FTSQRT(uint64_t frb)
return 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0);
}
-void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
+void helper_FCMPU(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
uint32_t crfD)
{
CPU_DoubleU farg1, farg2;
@@ -902,7 +902,7 @@ void helper_fcmpu(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
}
}
-void helper_fcmpo(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
+void helper_FCMPO(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
uint32_t crfD)
{
CPU_DoubleU farg1, farg2;
diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc
index f296cfcdb0..4e18d350c0 100644
--- a/target/ppc/translate/fp-impl.c.inc
+++ b/target/ppc/translate/fp-impl.c.inc
@@ -257,46 +257,27 @@ static bool trans_FTSQRT(DisasContext *ctx, arg_X_bf_b *a)
}
/*** Floating-Point compare ***/
-
-/* fcmpo */
-static void gen_fcmpo(DisasContext *ctx)
+static bool do_helper_cmp(DisasContext *ctx, arg_X_bf *a,
+ void (*helper)(TCGv_env, TCGv_i64, TCGv_i64,
+ TCGv_i32))
{
TCGv_i32 crf;
- TCGv_i64 t0;
- TCGv_i64 t1;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
+ TCGv_i64 t0, t1;
+ REQUIRE_INSNS_FLAGS(ctx, FLOAT);
+ REQUIRE_FPU(ctx);
t0 = tcg_temp_new_i64();
t1 = tcg_temp_new_i64();
gen_reset_fpstatus();
- crf = tcg_constant_i32(crfD(ctx->opcode));
- get_fpr(t0, rA(ctx->opcode));
- get_fpr(t1, rB(ctx->opcode));
- gen_helper_fcmpo(tcg_env, t0, t1, crf);
+ crf = tcg_constant_i32(a->bf);
+ get_fpr(t0, a->ra);
+ get_fpr(t1, a->rb);
+ helper(tcg_env, t0, t1, crf);
gen_helper_float_check_status(tcg_env);
+ return true;
}
-/* fcmpu */
-static void gen_fcmpu(DisasContext *ctx)
-{
- TCGv_i32 crf;
- TCGv_i64 t0;
- TCGv_i64 t1;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
- gen_reset_fpstatus();
- crf = tcg_constant_i32(crfD(ctx->opcode));
- get_fpr(t0, rA(ctx->opcode));
- get_fpr(t1, rB(ctx->opcode));
- gen_helper_fcmpu(tcg_env, t0, t1, crf);
- gen_helper_float_check_status(tcg_env);
-}
+TRANS(FCMPU, do_helper_cmp, gen_helper_FCMPU);
+TRANS(FCMPO, do_helper_cmp, gen_helper_FCMPO);
/*** Floating-point move ***/
/* fabs */
diff --git a/target/ppc/translate/fp-ops.c.inc b/target/ppc/translate/fp-ops.c.inc
index acb8ac32da..502453da35 100644
--- a/target/ppc/translate/fp-ops.c.inc
+++ b/target/ppc/translate/fp-ops.c.inc
@@ -10,8 +10,6 @@ GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
GEN_HANDLER_E(stfdepx, 0x1F, 0x1F, 0x16, 0x00000001, PPC_NONE, PPC2_BOOKE206),
GEN_HANDLER_E(stfdpx, 0x1F, 0x17, 0x1C, 0x00200001, PPC_NONE, PPC2_ISA205),
-GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT),
-GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT),
GEN_HANDLER(fabs, 0x3F, 0x08, 0x08, 0x001F0000, PPC_FLOAT),
GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
GEN_HANDLER(fnabs, 0x3F, 0x08, 0x04, 0x001F0000, PPC_FLOAT),
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 23/27] target/ppc: Move floating-point move instructions to decodetree.
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (21 preceding siblings ...)
2025-09-28 19:26 ` [PULL 22/27] target/ppc: Move floating-point compare " Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 24/27] target/ppc: Move remaining " Harsh Prateek Bora
` (4 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Chinmay Rath, Richard Henderson
From: Chinmay Rath <rathc@linux.ibm.com>
Move below instructions to decodetree specification:
f{mr, neg, abs, nabs} : X-form
The changes were verified by validating that the tcg ops generated by
those instructions remain the same, which were captured with the '-d
in_asm,op' flag.
Signed-off-by: Chinmay Rath <rathc@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250619095840.369351-4-rathc@linux.ibm.com
Message-ID: <20250619095840.369351-4-rathc@linux.ibm.com>
---
target/ppc/insn32.decode | 7 +++
target/ppc/translate/fp-impl.c.inc | 80 ++++++++----------------------
target/ppc/translate/fp-ops.c.inc | 4 --
3 files changed, 28 insertions(+), 63 deletions(-)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index d446ec534d..063d5726cb 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -530,6 +530,13 @@ STFDU 110111 ..... ...... ............... @D
STFDX 011111 ..... ...... .... 1011010111 - @X
STFDUX 011111 ..... ...... .... 1011110111 - @X
+### Floating-Point Move Instructions
+
+FMR 111111 ..... ----- ..... 0001001000 . @X_tb_rc
+FNEG 111111 ..... ----- ..... 0000101000 . @X_tb_rc
+FABS 111111 ..... ----- ..... 0100001000 . @X_tb_rc
+FNABS 111111 ..... ----- ..... 0010001000 . @X_tb_rc
+
### Floating-Point Arithmetic Instructions
FADD 111111 ..... ..... ..... ----- 10101 . @A_tab
diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc
index 4e18d350c0..2843f71122 100644
--- a/target/ppc/translate/fp-impl.c.inc
+++ b/target/ppc/translate/fp-impl.c.inc
@@ -280,82 +280,44 @@ TRANS(FCMPU, do_helper_cmp, gen_helper_FCMPU);
TRANS(FCMPO, do_helper_cmp, gen_helper_FCMPO);
/*** Floating-point move ***/
-/* fabs */
-/* XXX: beware that fabs never checks for NaNs nor update FPSCR */
-static void gen_fabs(DisasContext *ctx)
-{
- TCGv_i64 t0;
- TCGv_i64 t1;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
- get_fpr(t0, rB(ctx->opcode));
- tcg_gen_andi_i64(t1, t0, ~(1ULL << 63));
- set_fpr(rD(ctx->opcode), t1);
- if (unlikely(Rc(ctx->opcode))) {
- gen_set_cr1_from_fpscr(ctx);
- }
-}
/* fmr - fmr. */
/* XXX: beware that fmr never checks for NaNs nor update FPSCR */
-static void gen_fmr(DisasContext *ctx)
+static bool trans_FMR(DisasContext *ctx, arg_FMR *a)
{
TCGv_i64 t0;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
+ REQUIRE_INSNS_FLAGS(ctx, FLOAT);
+ REQUIRE_FPU(ctx);
t0 = tcg_temp_new_i64();
- get_fpr(t0, rB(ctx->opcode));
- set_fpr(rD(ctx->opcode), t0);
- if (unlikely(Rc(ctx->opcode))) {
+ get_fpr(t0, a->rb);
+ set_fpr(a->rt, t0);
+ if (unlikely(a->rc)) {
gen_set_cr1_from_fpscr(ctx);
}
+ return true;
}
-/* fnabs */
-/* XXX: beware that fnabs never checks for NaNs nor update FPSCR */
-static void gen_fnabs(DisasContext *ctx)
+/* XXX: beware that f{neg, abs, nabs} never checks for NaNs nor update FPSCR */
+static bool do_move_b(DisasContext *ctx, arg_X_tb_rc *a, int64_t val,
+ void (*tcg_op)(TCGv_i64, TCGv_i64, int64_t))
{
- TCGv_i64 t0;
- TCGv_i64 t1;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
+ TCGv_i64 t0, t1;
+ REQUIRE_INSNS_FLAGS(ctx, FLOAT);
+ REQUIRE_FPU(ctx);
t0 = tcg_temp_new_i64();
t1 = tcg_temp_new_i64();
- get_fpr(t0, rB(ctx->opcode));
- tcg_gen_ori_i64(t1, t0, 1ULL << 63);
- set_fpr(rD(ctx->opcode), t1);
- if (unlikely(Rc(ctx->opcode))) {
+ get_fpr(t0, a->rb);
+ tcg_op(t1, t0, val);
+ set_fpr(a->rt, t1);
+ if (unlikely(a->rc)) {
gen_set_cr1_from_fpscr(ctx);
}
+ return true;
}
-/* fneg */
-/* XXX: beware that fneg never checks for NaNs nor update FPSCR */
-static void gen_fneg(DisasContext *ctx)
-{
- TCGv_i64 t0;
- TCGv_i64 t1;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- t0 = tcg_temp_new_i64();
- t1 = tcg_temp_new_i64();
- get_fpr(t0, rB(ctx->opcode));
- tcg_gen_xori_i64(t1, t0, 1ULL << 63);
- set_fpr(rD(ctx->opcode), t1);
- if (unlikely(Rc(ctx->opcode))) {
- gen_set_cr1_from_fpscr(ctx);
- }
-}
+TRANS(FNEG, do_move_b, 1ULL << 63, tcg_gen_xori_i64);
+TRANS(FABS, do_move_b, ~(1ULL << 63), tcg_gen_andi_i64);
+TRANS(FNABS, do_move_b, 1ULL << 63, tcg_gen_ori_i64);
/* fcpsgn: PowerPC 2.05 specification */
/* XXX: beware that fcpsgn never checks for NaNs nor update FPSCR */
diff --git a/target/ppc/translate/fp-ops.c.inc b/target/ppc/translate/fp-ops.c.inc
index 502453da35..5053cb135c 100644
--- a/target/ppc/translate/fp-ops.c.inc
+++ b/target/ppc/translate/fp-ops.c.inc
@@ -10,10 +10,6 @@ GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
GEN_HANDLER_E(stfdepx, 0x1F, 0x1F, 0x16, 0x00000001, PPC_NONE, PPC2_BOOKE206),
GEN_HANDLER_E(stfdpx, 0x1F, 0x17, 0x1C, 0x00200001, PPC_NONE, PPC2_ISA205),
-GEN_HANDLER(fabs, 0x3F, 0x08, 0x08, 0x001F0000, PPC_FLOAT),
-GEN_HANDLER(fmr, 0x3F, 0x08, 0x02, 0x001F0000, PPC_FLOAT),
-GEN_HANDLER(fnabs, 0x3F, 0x08, 0x04, 0x001F0000, PPC_FLOAT),
-GEN_HANDLER(fneg, 0x3F, 0x08, 0x01, 0x001F0000, PPC_FLOAT),
GEN_HANDLER_E(fcpsgn, 0x3F, 0x08, 0x00, 0x00000000, PPC_NONE, PPC2_ISA205),
GEN_HANDLER_E(fmrgew, 0x3F, 0x06, 0x1E, 0x00000001, PPC_NONE, PPC2_VSX207),
GEN_HANDLER_E(fmrgow, 0x3F, 0x06, 0x1A, 0x00000001, PPC_NONE, PPC2_VSX207),
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 24/27] target/ppc: Move remaining floating-point move instructions to decodetree.
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (22 preceding siblings ...)
2025-09-28 19:26 ` [PULL 23/27] target/ppc: Move floating-point move " Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 25/27] target/ppc: Introduce macro for deprecating PowerPC CPUs Harsh Prateek Bora
` (3 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Chinmay Rath, Richard Henderson
From: Chinmay Rath <rathc@linux.ibm.com>
Move below instructions to decodetree specification:
fcpsgn, fmrg{e, o}w : X-form
The changes were verified by validating that the tcg ops generated by
those instructions remain the same, which were captured with the '-d
in_asm,op' flag.
Signed-off-by: Chinmay Rath <rathc@linux.ibm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250619095840.369351-5-rathc@linux.ibm.com
Message-ID: <20250619095840.369351-5-rathc@linux.ibm.com>
---
target/ppc/insn32.decode | 4 ++
target/ppc/translate/fp-impl.c.inc | 65 +++++++++++++-----------------
target/ppc/translate/fp-ops.c.inc | 3 --
3 files changed, 32 insertions(+), 40 deletions(-)
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 063d5726cb..0e9c68f2fb 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -537,6 +537,10 @@ FNEG 111111 ..... ----- ..... 0000101000 . @X_tb_rc
FABS 111111 ..... ----- ..... 0100001000 . @X_tb_rc
FNABS 111111 ..... ----- ..... 0010001000 . @X_tb_rc
+FCPSGN 111111 ..... ..... ..... 0000001000 . @X_rc
+FMRGEW 111111 ..... ..... ..... 1111000110 - @X
+FMRGOW 111111 ..... ..... ..... 1101000110 - @X
+
### Floating-Point Arithmetic Instructions
FADD 111111 ..... ..... ..... ----- 10101 . @A_tab
diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc
index 2843f71122..28dda15040 100644
--- a/target/ppc/translate/fp-impl.c.inc
+++ b/target/ppc/translate/fp-impl.c.inc
@@ -321,62 +321,53 @@ TRANS(FNABS, do_move_b, 1ULL << 63, tcg_gen_ori_i64);
/* fcpsgn: PowerPC 2.05 specification */
/* XXX: beware that fcpsgn never checks for NaNs nor update FPSCR */
-static void gen_fcpsgn(DisasContext *ctx)
+static bool trans_FCPSGN(DisasContext *ctx, arg_FCPSGN *a)
{
- TCGv_i64 t0;
- TCGv_i64 t1;
- TCGv_i64 t2;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
+ TCGv_i64 t0, t1, t2;
+ REQUIRE_INSNS_FLAGS2(ctx, ISA205);
+ REQUIRE_FPU(ctx);
t0 = tcg_temp_new_i64();
t1 = tcg_temp_new_i64();
t2 = tcg_temp_new_i64();
- get_fpr(t0, rA(ctx->opcode));
- get_fpr(t1, rB(ctx->opcode));
+ get_fpr(t0, a->ra);
+ get_fpr(t1, a->rb);
tcg_gen_deposit_i64(t2, t0, t1, 0, 63);
- set_fpr(rD(ctx->opcode), t2);
- if (unlikely(Rc(ctx->opcode))) {
+ set_fpr(a->rt, t2);
+ if (unlikely(a->rc)) {
gen_set_cr1_from_fpscr(ctx);
}
+ return true;
}
-static void gen_fmrgew(DisasContext *ctx)
+static bool trans_FMRGEW(DisasContext *ctx, arg_FMRGEW *a)
{
- TCGv_i64 b0;
- TCGv_i64 t0;
- TCGv_i64 t1;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
- b0 = tcg_temp_new_i64();
+ TCGv_i64 t0, t1, t2;
+ REQUIRE_INSNS_FLAGS2(ctx, VSX207);
+ REQUIRE_FPU(ctx);
t0 = tcg_temp_new_i64();
t1 = tcg_temp_new_i64();
- get_fpr(t0, rB(ctx->opcode));
- tcg_gen_shri_i64(b0, t0, 32);
- get_fpr(t0, rA(ctx->opcode));
- tcg_gen_deposit_i64(t1, t0, b0, 0, 32);
- set_fpr(rD(ctx->opcode), t1);
+ t2 = tcg_temp_new_i64();
+ get_fpr(t1, a->rb);
+ tcg_gen_shri_i64(t0, t1, 32);
+ get_fpr(t1, a->ra);
+ tcg_gen_deposit_i64(t2, t1, t0, 0, 32);
+ set_fpr(a->rt, t2);
+ return true;
}
-static void gen_fmrgow(DisasContext *ctx)
+static bool trans_FMRGOW(DisasContext *ctx, arg_FMRGOW *a)
{
- TCGv_i64 t0;
- TCGv_i64 t1;
- TCGv_i64 t2;
- if (unlikely(!ctx->fpu_enabled)) {
- gen_exception(ctx, POWERPC_EXCP_FPU);
- return;
- }
+ TCGv_i64 t0, t1, t2;
+ REQUIRE_INSNS_FLAGS2(ctx, VSX207);
+ REQUIRE_FPU(ctx);
t0 = tcg_temp_new_i64();
t1 = tcg_temp_new_i64();
t2 = tcg_temp_new_i64();
- get_fpr(t0, rB(ctx->opcode));
- get_fpr(t1, rA(ctx->opcode));
+ get_fpr(t0, a->rb);
+ get_fpr(t1, a->ra);
tcg_gen_deposit_i64(t2, t0, t1, 32, 32);
- set_fpr(rD(ctx->opcode), t2);
+ set_fpr(a->rt, t2);
+ return true;
}
/*** Floating-Point status & ctrl register ***/
diff --git a/target/ppc/translate/fp-ops.c.inc b/target/ppc/translate/fp-ops.c.inc
index 5053cb135c..9bc9c3a3c3 100644
--- a/target/ppc/translate/fp-ops.c.inc
+++ b/target/ppc/translate/fp-ops.c.inc
@@ -10,9 +10,6 @@ GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
GEN_HANDLER_E(stfdepx, 0x1F, 0x1F, 0x16, 0x00000001, PPC_NONE, PPC2_BOOKE206),
GEN_HANDLER_E(stfdpx, 0x1F, 0x17, 0x1C, 0x00200001, PPC_NONE, PPC2_ISA205),
-GEN_HANDLER_E(fcpsgn, 0x3F, 0x08, 0x00, 0x00000000, PPC_NONE, PPC2_ISA205),
-GEN_HANDLER_E(fmrgew, 0x3F, 0x06, 0x1E, 0x00000001, PPC_NONE, PPC2_VSX207),
-GEN_HANDLER_E(fmrgow, 0x3F, 0x06, 0x1A, 0x00000001, PPC_NONE, PPC2_VSX207),
GEN_HANDLER(mcrfs, 0x3F, 0x00, 0x02, 0x0063F801, PPC_FLOAT),
GEN_HANDLER(mtfsb0, 0x3F, 0x06, 0x02, 0x001FF800, PPC_FLOAT),
GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT),
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 25/27] target/ppc: Introduce macro for deprecating PowerPC CPUs
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (23 preceding siblings ...)
2025-09-28 19:26 ` [PULL 24/27] target/ppc: Move remaining " Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 26/27] target/ppc: Deprecate Power8E and Power8NVL Harsh Prateek Bora
` (2 subsequent siblings)
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel
Cc: Aditya Gupta, Cédric Le Goater, Philippe Mathieu-Daudé,
Anushree Mathur
From: Aditya Gupta <adityag@linux.ibm.com>
QEMU has a way to deprecate CPUs by setting the 'deprecation_note' in
CPUClass.
Currently PowerPC CPUs don't use this deprecation process.
Introduce 'POWERPC_DEPRECATED_CPU' macro to deprecate particular PowerPC
CPUs in future.
With the change, QEMU will print a warning like below when the
deprecated CPU/Chips are used (example output if power8nvl is deprecated):
$ ./build/qemu-system-ppc64 -M powernv8 --cpu power8nvl -nographic
qemu-system-ppc64: warning: CPU model power8nvl_v1.0-powerpc64-cpu is deprecated -- CPU is unmaintained.
...
Also, print '(deprecated)' for deprecated CPUs in 'qemu-system-ppc64
--cpu ?' (example output if power8nvl is deprecated):
$ ./build/qemu-system-ppc64 --cpu help
...
power8e (alias for power8e_v2.1)
power8nvl_v1.0 PVR 004c0100 (deprecated)
power8nvl (alias for power8nvl_v1.0)
power8_v2.0 PVR 004d0200
...
Suggested-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Tested-by: Anushree Mathur <anushree.mathur@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250607110412.2342511-2-adityag@linux.ibm.com
Message-ID: <20250607110412.2342511-2-adityag@linux.ibm.com>
---
target/ppc/cpu-models.c | 12 +++++++++++-
target/ppc/cpu_init.c | 7 ++++++-
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
index 09f73e23a8..334b1d2ff3 100644
--- a/target/ppc/cpu-models.c
+++ b/target/ppc/cpu-models.c
@@ -32,17 +32,20 @@
/* PowerPC CPU definitions */
#define POWERPC_DEF_PREFIX(pvr, svr, type) \
glue(glue(glue(glue(pvr, _), svr), _), type)
-#define POWERPC_DEF_SVR(_name, _desc, _pvr, _svr, _type) \
+#define POWERPC_DEF_SVR_DEPR(_name, _desc, _pvr, _svr, _type, _deprecation_note) \
static void \
glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_class_init) \
(ObjectClass *oc, const void *data) \
{ \
DeviceClass *dc = DEVICE_CLASS(oc); \
+ CPUClass *cc = CPU_CLASS(oc); \
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); \
\
pcc->pvr = _pvr; \
pcc->svr = _svr; \
dc->desc = _desc; \
+ \
+ cc->deprecation_note = _deprecation_note; \
} \
\
static const TypeInfo \
@@ -63,6 +66,13 @@
type_init( \
glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_register_types))
+#define POWERPC_DEF_SVR(_name, _desc, _pvr, _svr, _type) \
+ POWERPC_DEF_SVR_DEPR(_name, _desc, _pvr, _svr, _type, NULL)
+
+#define POWERPC_DEPRECATED_CPU(_name, _pvr, _type, _desc, _deprecation_note)\
+ POWERPC_DEF_SVR_DEPR(_name, _desc, _pvr, POWERPC_SVR_NONE, _type, \
+ _deprecation_note)
+
#define POWERPC_DEF(_name, _pvr, _type, _desc) \
POWERPC_DEF_SVR(_name, _desc, _pvr, POWERPC_SVR_NONE, _type)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 9e4ea8fd13..3aa3aefc13 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -7298,6 +7298,7 @@ static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
{
ObjectClass *oc = data;
PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+ CPUClass *cc = CPU_CLASS(oc);
DeviceClass *family = DEVICE_CLASS(ppc_cpu_get_family_class(pcc));
const char *typename = object_class_get_name(oc);
char *name;
@@ -7308,7 +7309,11 @@ static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
}
name = cpu_model_from_type(typename);
- qemu_printf(" %-16s PVR %08x\n", name, pcc->pvr);
+ if (cc->deprecation_note) {
+ qemu_printf(" %-16s PVR %08x (deprecated)\n", name, pcc->pvr);
+ } else {
+ qemu_printf(" %-16s PVR %08x\n", name, pcc->pvr);
+ }
for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model);
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 26/27] target/ppc: Deprecate Power8E and Power8NVL
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (24 preceding siblings ...)
2025-09-28 19:26 ` [PULL 25/27] target/ppc: Introduce macro for deprecating PowerPC CPUs Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 27/27] target/ppc: use MAKE_64BIT_MASK for mcrfs exception clear mask Harsh Prateek Bora
2025-09-29 16:50 ` [PULL 00/27] ppc-for-20250928 queue Richard Henderson
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel
Cc: Aditya Gupta, Cédric Le Goater, Philippe Mathieu-Daudé,
Cédric Le Goater, Anushree Mathur
From: Aditya Gupta <adityag@linux.ibm.com>
Power8E and Power8NVL variants are not of much use in QEMU now, and not
being maintained either.
Power8NVL CPU doesn't boot since skiboot v7.0, or following skiboot commit
to be exact:
commit c5424f683ee3 ("Remove support for POWER8 DD1")
Deprecate the 8E and 8NVL variants.
Suggested-by: Cédric Le Goater <clg@kaod.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Signed-off-by: Aditya Gupta <adityag@linux.ibm.com>
Tested-by: Anushree Mathur <anushree.mathur@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250607110412.2342511-3-adityag@linux.ibm.com
Message-ID: <20250607110412.2342511-3-adityag@linux.ibm.com>
---
docs/about/deprecated.rst | 9 +++++++++
target/ppc/cpu-models.c | 8 ++++----
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index aa300bbd50..b8d60c1a90 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -253,6 +253,15 @@ embedded 405 for power management (OCC) and other internal tasks, it
is theoretically possible to use QEMU to model them. Let's keep the
CPU implementation for a while before removing all support.
+Power8E and Power8NVL CPUs and corresponding Pnv chips (since 10.1)
+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The Power8E and Power8NVL variants of Power8 are not really useful anymore
+in qemu, and are old and unmaintained now.
+
+The CPUs as well as corresponding Power8NVL and Power8E PnvChips will also
+be considered deprecated.
+
System emulator machines
------------------------
diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
index 334b1d2ff3..89ae763c7f 100644
--- a/target/ppc/cpu-models.c
+++ b/target/ppc/cpu-models.c
@@ -739,12 +739,12 @@
"POWER7 v2.3")
POWERPC_DEF("power7p_v2.1", CPU_POWERPC_POWER7P_v21, POWER7,
"POWER7+ v2.1")
- POWERPC_DEF("power8e_v2.1", CPU_POWERPC_POWER8E_v21, POWER8,
- "POWER8E v2.1")
+ POWERPC_DEPRECATED_CPU("power8e_v2.1", CPU_POWERPC_POWER8E_v21, POWER8,
+ "POWER8E v2.1", "CPU is unmaintained.")
POWERPC_DEF("power8_v2.0", CPU_POWERPC_POWER8_v20, POWER8,
"POWER8 v2.0")
- POWERPC_DEF("power8nvl_v1.0", CPU_POWERPC_POWER8NVL_v10, POWER8,
- "POWER8NVL v1.0")
+ POWERPC_DEPRECATED_CPU("power8nvl_v1.0", CPU_POWERPC_POWER8NVL_v10, POWER8,
+ "POWER8NVL v1.0", "CPU is unmaintained.")
POWERPC_DEF("power9_v2.0", CPU_POWERPC_POWER9_DD20, POWER9,
"POWER9 v2.0")
POWERPC_DEF("power9_v2.2", CPU_POWERPC_POWER9_DD22, POWER9,
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* [PULL 27/27] target/ppc: use MAKE_64BIT_MASK for mcrfs exception clear mask
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (25 preceding siblings ...)
2025-09-28 19:26 ` [PULL 26/27] target/ppc: Deprecate Power8E and Power8NVL Harsh Prateek Bora
@ 2025-09-28 19:26 ` Harsh Prateek Bora
2025-09-29 16:50 ` [PULL 00/27] ppc-for-20250928 queue Richard Henderson
27 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-28 19:26 UTC (permalink / raw)
To: qemu-devel; +Cc: Denis Sergeev, Chinmay Rath
From: Denis Sergeev <zeff@altlinux.org>
In gen_mcrfs() the FPSCR nibble mask is computed as:
`~((0xF << shift) & FP_EX_CLEAR_BITS)`
Here, 0xF is of type int, so the left shift is performed in
32-bit signed arithmetic. For bfa=0 we get shift=28,
and (0xF << 28) = 0xF0000000, which is not representable as a 32-bit
signed int. Static analyzers flag this as a potential integer
overflow.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Signed-off-by: Denis Sergeev <zeff@altlinux.org>
Reviewed-by: Chinmay Rath <rathc@linux.ibm.com>
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
Link: https://lore.kernel.org/r/20250915080118.29898-1-zeff@altlinux.org
Message-ID: <20250915080118.29898-1-zeff@altlinux.org>
---
target/ppc/translate/fp-impl.c.inc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc
index 28dda15040..464fb1d90f 100644
--- a/target/ppc/translate/fp-impl.c.inc
+++ b/target/ppc/translate/fp-impl.c.inc
@@ -396,7 +396,7 @@ static void gen_mcrfs(DisasContext *ctx)
tcg_gen_extu_tl_i64(tnew_fpscr, cpu_fpscr);
/* Only the exception bits (including FX) should be cleared if read */
tcg_gen_andi_i64(tnew_fpscr, tnew_fpscr,
- ~((0xF << shift) & FP_EX_CLEAR_BITS));
+ ~(MAKE_64BIT_MASK(shift, 4) & FP_EX_CLEAR_BITS));
/* FEX and VX need to be updated, so don't set fpscr directly */
tmask = tcg_constant_i32(1 << nibble);
gen_helper_store_fpscr(tcg_env, tnew_fpscr, tmask);
--
2.43.5
^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: [PULL 00/27] ppc-for-20250928 queue
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
` (26 preceding siblings ...)
2025-09-28 19:26 ` [PULL 27/27] target/ppc: use MAKE_64BIT_MASK for mcrfs exception clear mask Harsh Prateek Bora
@ 2025-09-29 16:50 ` Richard Henderson
27 siblings, 0 replies; 33+ messages in thread
From: Richard Henderson @ 2025-09-29 16:50 UTC (permalink / raw)
To: qemu-devel
On 9/28/25 12:26, Harsh Prateek Bora wrote:
> The following changes since commit d6dfd8d40cebebc3378d379cd28879e0345fbf91:
>
> Merge tag 'pull-target-arm-20250926' ofhttps://gitlab.com/pm215/qemu into staging (2025-09-26 13:27:01 -0700)
>
> are available in the Git repository at:
>
> https://gitlab.com/harshpb/qemu.git tags/pull-ppc-for-20250928-20250929
>
> for you to fetch changes up to 6c51df580d2a64b4e1ef7bdbffeb3615ffe25d43:
>
> target/ppc: use MAKE_64BIT_MASK for mcrfs exception clear mask (2025-09-28 23:50:36 +0530)
>
> ----------------------------------------------------------------
> ppc queue for 20250928
>
> * Support for PowerNV11 and PPE42 CPU/Machines.
> * Deprecation of Power8E and Power8NVL
> * Decodetree patches for some floating-point instructions
> * Minor bug fixes, improvements in ppc/spapr/xive/xics.
>
> Qemu CI:https://gitlab.com/harshpb/qemu/-/pipelines/2068351418
Applied, thanks. Please update https://wiki.qemu.org/ChangeLog/10.2 as appropriate.
r~
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PULL 18/27] hw/intc/xics: Add missing call to register vmstate_icp_server
2025-09-28 19:26 ` [PULL 18/27] hw/intc/xics: Add missing call to register vmstate_icp_server Harsh Prateek Bora
@ 2025-09-29 19:32 ` Michael Tokarev
2025-09-30 4:15 ` Harsh Prateek Bora
0 siblings, 1 reply; 33+ messages in thread
From: Michael Tokarev @ 2025-09-29 19:32 UTC (permalink / raw)
To: Harsh Prateek Bora, qemu-devel
Cc: Fabian Vogt, Philippe Mathieu-Daudé, Fabiano Rosas,
Gautam Menghani, qemu-stable
On 9/28/25 22:26, Harsh Prateek Bora wrote:
> From: Fabian Vogt <fvogt@suse.de>
>
> An obsolete wrapper function with a workaround was removed entirely,
> without restoring the call it wrapped.
>
> Without this, the guest is stuck after savevm/loadvm.
>
> Fixes: 24ee9229fe31 ("ppc/spapr: remove deprecated machine pseries-2.9")
> Signed-off-by: Fabian Vogt <fvogt@suse.de>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Link: https://lore.kernel.org/qemu-devel/6187781.lOV4Wx5bFT@fvogt-thinkpad
> Signed-off-by: Fabiano Rosas <farosas@suse.de>
> Reviewed-by: Gautam Menghani <gautam@linux.ibm.com>
> Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
> Link: https://lore.kernel.org/r/20250819223905.2247-2-farosas@suse.de
> Message-ID: <20250819223905.2247-2-farosas@suse.de>
I'm picking this up for both 10.1.x and 10.0.x stable qemu series.
Please let me know if I understood the previous discussion in a wrong
way and it should only be picked up for 10.1.x, but not for 10.0.x.
Thanks,
/mjt
> hw/intc/xics.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
> index d9a199e883..200710eb6c 100644
> --- a/hw/intc/xics.c
> +++ b/hw/intc/xics.c
> @@ -335,6 +335,8 @@ static void icp_realize(DeviceState *dev, Error **errp)
> return;
> }
> }
> +
> + vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server, icp);
> }
>
> static void icp_unrealize(DeviceState *dev)
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PULL 19/27] ppc/spapr: init lrdr-capapcity phys with ram size if maxmem not provided
2025-09-28 19:26 ` [PULL 19/27] ppc/spapr: init lrdr-capapcity phys with ram size if maxmem not provided Harsh Prateek Bora
@ 2025-09-29 19:36 ` Michael Tokarev
2025-09-30 4:18 ` Harsh Prateek Bora
0 siblings, 1 reply; 33+ messages in thread
From: Michael Tokarev @ 2025-09-29 19:36 UTC (permalink / raw)
To: Harsh Prateek Bora, qemu-devel
Cc: Gaurav Batra, David Christensen, Shivaprasad G Bhat, qemu-stable
On 9/28/25 22:26, Harsh Prateek Bora wrote:
> lrdr-capacity contains phys field which communicates the maximum address
> in bytes and therefore, the most memory that can be allocated to this
> partition. This is usually populated when maxmem is provided alongwith
> memory size on qemu command line. However since maxmem is an optional
> param, this leads to bits being set to 0 in absence of maxmem param.
> Fix this by initializing the respective bits as per total mem size in
> such case.
>
> Reported-by: Gaurav Batra <gbatra@us.ibm.com>
> Tested-by: David Christensen <drc@linux.ibm.com>
> Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
> Reviewed-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
> Link: https://lore.kernel.org/r/20250506042903.76250-1-harshpb@linux.ibm.com
> Message-ID: <20250506042903.76250-1-harshpb@linux.ibm.com>
This feels like a qemu-stable matherial (for 10.0 & 10.1 series).
Please let me know if it isn't.
Thanks,
/mjt
> ---
> hw/ppc/spapr.c | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index eb22333404..82fb23beaa 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -907,6 +907,7 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
> int rtas;
> GString *hypertas = g_string_sized_new(256);
> GString *qemu_hypertas = g_string_sized_new(256);
> + uint64_t max_device_addr = 0;
> uint32_t lrdr_capacity[] = {
> 0,
> 0,
> @@ -917,13 +918,15 @@ static void spapr_dt_rtas(SpaprMachineState *spapr, void *fdt)
>
> /* Do we have device memory? */
> if (MACHINE(spapr)->device_memory) {
> - uint64_t max_device_addr = MACHINE(spapr)->device_memory->base +
> + max_device_addr = MACHINE(spapr)->device_memory->base +
> memory_region_size(&MACHINE(spapr)->device_memory->mr);
> -
> - lrdr_capacity[0] = cpu_to_be32(max_device_addr >> 32);
> - lrdr_capacity[1] = cpu_to_be32(max_device_addr & 0xffffffff);
> + } else if (ms->ram_size == ms->maxram_size) {
> + max_device_addr = ms->ram_size;
> }
>
> + lrdr_capacity[0] = cpu_to_be32(max_device_addr >> 32);
> + lrdr_capacity[1] = cpu_to_be32(max_device_addr & 0xffffffff);
> +
> _FDT(rtas = fdt_add_subnode(fdt, 0, "rtas"));
>
> /* hypertas */
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PULL 18/27] hw/intc/xics: Add missing call to register vmstate_icp_server
2025-09-29 19:32 ` Michael Tokarev
@ 2025-09-30 4:15 ` Harsh Prateek Bora
0 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-30 4:15 UTC (permalink / raw)
To: Michael Tokarev, qemu-devel
Cc: Fabian Vogt, Philippe Mathieu-Daudé, Fabiano Rosas,
Gautam Menghani, qemu-stable
Hi Michael,
On 9/30/25 01:02, Michael Tokarev wrote:
> On 9/28/25 22:26, Harsh Prateek Bora wrote:
>> From: Fabian Vogt <fvogt@suse.de>
>>
>> An obsolete wrapper function with a workaround was removed entirely,
>> without restoring the call it wrapped.
>>
>> Without this, the guest is stuck after savevm/loadvm.
>>
>> Fixes: 24ee9229fe31 ("ppc/spapr: remove deprecated machine pseries-2.9")
>> Signed-off-by: Fabian Vogt <fvogt@suse.de>
>> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
>> Link:
>> https://lore.kernel.org/qemu-devel/6187781.lOV4Wx5bFT@fvogt-thinkpad
>> Signed-off-by: Fabiano Rosas <farosas@suse.de>
>> Reviewed-by: Gautam Menghani <gautam@linux.ibm.com>
>> Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
>> Link: https://lore.kernel.org/r/20250819223905.2247-2-farosas@suse.de
>> Message-ID: <20250819223905.2247-2-farosas@suse.de>
>
> I'm picking this up for both 10.1.x and 10.0.x stable qemu series.
> Please let me know if I understood the previous discussion in a wrong
> way and it should only be picked up for 10.1.x, but not for 10.0.x.
It's applicable for all releases where the commit specified in Fixes:
(24ee9229fe31) is present.
Thanks
Harsh
>
> Thanks,
>
> /mjt
>
>> hw/intc/xics.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/hw/intc/xics.c b/hw/intc/xics.c
>> index d9a199e883..200710eb6c 100644
>> --- a/hw/intc/xics.c
>> +++ b/hw/intc/xics.c
>> @@ -335,6 +335,8 @@ static void icp_realize(DeviceState *dev, Error
>> **errp)
>> return;
>> }
>> }
>> +
>> + vmstate_register(NULL, icp->cs->cpu_index, &vmstate_icp_server,
>> icp);
>> }
>> static void icp_unrealize(DeviceState *dev)
>
^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: [PULL 19/27] ppc/spapr: init lrdr-capapcity phys with ram size if maxmem not provided
2025-09-29 19:36 ` Michael Tokarev
@ 2025-09-30 4:18 ` Harsh Prateek Bora
0 siblings, 0 replies; 33+ messages in thread
From: Harsh Prateek Bora @ 2025-09-30 4:18 UTC (permalink / raw)
To: Michael Tokarev, qemu-devel
Cc: Gaurav Batra, David Christensen, Shivaprasad G Bhat, qemu-stable
On 9/30/25 01:06, Michael Tokarev wrote:
> On 9/28/25 22:26, Harsh Prateek Bora wrote:
>> lrdr-capacity contains phys field which communicates the maximum address
>> in bytes and therefore, the most memory that can be allocated to this
>> partition. This is usually populated when maxmem is provided alongwith
>> memory size on qemu command line. However since maxmem is an optional
>> param, this leads to bits being set to 0 in absence of maxmem param.
>> Fix this by initializing the respective bits as per total mem size in
>> such case.
>>
>> Reported-by: Gaurav Batra <gbatra@us.ibm.com>
>> Tested-by: David Christensen <drc@linux.ibm.com>
>> Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
>> Reviewed-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
>> Link:
>> https://lore.kernel.org/r/20250506042903.76250-1-harshpb@linux.ibm.com
>> Message-ID: <20250506042903.76250-1-harshpb@linux.ibm.com>
>
> This feels like a qemu-stable matherial (for 10.0 & 10.1 series).
> Please let me know if it isn't.
Yes, it can be picked for stable releases as well. Thanks.
regards,
Harsh
>
> Thanks,
>
> /mjt
>
>> ---
>> hw/ppc/spapr.c | 11 +++++++----
>> 1 file changed, 7 insertions(+), 4 deletions(-)
>>
>> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
>> index eb22333404..82fb23beaa 100644
>> --- a/hw/ppc/spapr.c
>> +++ b/hw/ppc/spapr.c
>> @@ -907,6 +907,7 @@ static void spapr_dt_rtas(SpaprMachineState
>> *spapr, void *fdt)
>> int rtas;
>> GString *hypertas = g_string_sized_new(256);
>> GString *qemu_hypertas = g_string_sized_new(256);
>> + uint64_t max_device_addr = 0;
>> uint32_t lrdr_capacity[] = {
>> 0,
>> 0,
>> @@ -917,13 +918,15 @@ static void spapr_dt_rtas(SpaprMachineState
>> *spapr, void *fdt)
>> /* Do we have device memory? */
>> if (MACHINE(spapr)->device_memory) {
>> - uint64_t max_device_addr = MACHINE(spapr)->device_memory->base +
>> + max_device_addr = MACHINE(spapr)->device_memory->base +
>> memory_region_size(&MACHINE(spapr)->device_memory->mr);
>> -
>> - lrdr_capacity[0] = cpu_to_be32(max_device_addr >> 32);
>> - lrdr_capacity[1] = cpu_to_be32(max_device_addr & 0xffffffff);
>> + } else if (ms->ram_size == ms->maxram_size) {
>> + max_device_addr = ms->ram_size;
>> }
>> + lrdr_capacity[0] = cpu_to_be32(max_device_addr >> 32);
>> + lrdr_capacity[1] = cpu_to_be32(max_device_addr & 0xffffffff);
>> +
>> _FDT(rtas = fdt_add_subnode(fdt, 0, "rtas"));
>> /* hypertas */
>
>
^ permalink raw reply [flat|nested] 33+ messages in thread
end of thread, other threads:[~2025-09-30 4:22 UTC | newest]
Thread overview: 33+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-28 19:26 [PULL 00/27] ppc-for-20250928 queue Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 01/27] ppc/pnv: Introduce Pnv11Chip Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 02/27] ppc/pnv: Introduce Power11 PowerNV machine Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 03/27] ppc/pnv: Add PnvChipClass handler to get reference to interrupt controller Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 04/27] ppc/pnv: Add XIVE2 controller to Power11 Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 05/27] ppc/pnv: Add PHB5 PCIe Host bridge " Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 06/27] ppc/pnv: Add ChipTOD model for Power11 Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 07/27] tests/powernv: Switch to buildroot images instead of op-build Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 08/27] tests/powernv: Add PowerNV test for Power11 Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 09/27] target/ppc: IBM PPE42 general regs and flags Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 10/27] target/ppc: Add IBM PPE42 family of processors Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 11/27] target/ppc: IBM PPE42 exception flags and regs Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 12/27] target/ppc: Add IBM PPE42 exception model Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 13/27] target/ppc: Support for IBM PPE42 MMU Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 14/27] target/ppc: Add IBM PPE42 special instructions Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 15/27] hw/ppc: Support for an IBM PPE42 CPU decrementer Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 16/27] hw/ppc: Add a test machine for the IBM PPE42 CPU Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 17/27] tests/functional: Add test for IBM PPE42 instructions Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 18/27] hw/intc/xics: Add missing call to register vmstate_icp_server Harsh Prateek Bora
2025-09-29 19:32 ` Michael Tokarev
2025-09-30 4:15 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 19/27] ppc/spapr: init lrdr-capapcity phys with ram size if maxmem not provided Harsh Prateek Bora
2025-09-29 19:36 ` Michael Tokarev
2025-09-30 4:18 ` Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 20/27] ppc/xive2: Fix integer overflow warning in xive2_redistribute() Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 21/27] target/ppc: Move floating-point rounding and conversion instructions to decodetree Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 22/27] target/ppc: Move floating-point compare " Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 23/27] target/ppc: Move floating-point move " Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 24/27] target/ppc: Move remaining " Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 25/27] target/ppc: Introduce macro for deprecating PowerPC CPUs Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 26/27] target/ppc: Deprecate Power8E and Power8NVL Harsh Prateek Bora
2025-09-28 19:26 ` [PULL 27/27] target/ppc: use MAKE_64BIT_MASK for mcrfs exception clear mask Harsh Prateek Bora
2025-09-29 16:50 ` [PULL 00/27] ppc-for-20250928 queue Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).