POWER10 adds support for StoreEOI operation and 64K ESB pages on PSIHB to be consistent with the other interrupt sources of the system.
Signed-off-by: Cédric Le Goater <c...@kaod.org> --- hw/ppc/pnv.c | 6 ++++++ hw/ppc/pnv_psi.c | 32 +++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index ac4bd2a17a9e..0062e9b5ab28 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1523,6 +1523,9 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp) /* Processor Service Interface (PSI) Host Bridge */ object_property_set_int(OBJECT(&chip9->psi), PNV9_PSIHB_BASE(chip), "bar", &error_fatal); + /* This is the only device with 4k ESB pages */ + object_property_set_int(OBJECT(&chip9->psi), XIVE_ESB_4K, "shift", + &error_fatal); object_property_set_bool(OBJECT(&chip9->psi), true, "realized", &local_err); if (local_err) { error_propagate(errp, local_err); @@ -1795,6 +1798,9 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp) /* Processor Service Interface (PSI) Host Bridge */ object_property_set_int(OBJECT(&chip10->psi), PNV10_PSIHB_BASE(chip), "bar", &error_fatal); + /* PSI can now be configured to use 64k ESB pages on POWER10 */ + object_property_set_int(OBJECT(&chip10->psi), XIVE_ESB_64K, "shift", + &error_fatal); object_property_set_bool(OBJECT(&chip10->psi), true, "realized", &local_err); if (local_err) { diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c index c34a49b000f2..fbf92cf93a22 100644 --- a/hw/ppc/pnv_psi.c +++ b/hw/ppc/pnv_psi.c @@ -607,7 +607,6 @@ static const TypeInfo pnv_psi_power8_info = { #define PSIHB9_IRQ_METHOD PPC_BIT(0) #define PSIHB9_IRQ_RESET PPC_BIT(1) #define PSIHB9_ESB_CI_BASE 0x60 -#define PSIHB9_ESB_CI_64K PPC_BIT(1) #define PSIHB9_ESB_CI_ADDR_MASK PPC_BITMASK(8, 47) #define PSIHB9_ESB_CI_VALID PPC_BIT(63) #define PSIHB9_ESB_NOTIF_ADDR 0x68 @@ -652,6 +651,14 @@ static const TypeInfo pnv_psi_power8_info = { #define PSIHB9_IRQ_STAT_DIO PPC_BIT(12) #define PSIHB9_IRQ_STAT_PSU PPC_BIT(13) +/* P10 register extensions */ + +#define PSIHB10_CR PSIHB9_CR +#define PSIHB10_CR_STORE_EOI PPC_BIT(12) + +#define PSIHB10_ESB_CI_BASE PSIHB9_ESB_CI_BASE +#define PSIHB10_ESB_CI_64K PPC_BIT(1) + static void pnv_psi_notify(XiveNotifier *xf, uint32_t srcno) { PnvPsi *psi = PNV_PSI(xf); @@ -710,6 +717,13 @@ static void pnv_psi_p9_mmio_write(void *opaque, hwaddr addr, switch (addr) { case PSIHB9_CR: + if (val & PSIHB10_CR_STORE_EOI) { + psi9->source.esb_flags |= XIVE_SRC_STORE_EOI; + } else { + psi9->source.esb_flags &= ~XIVE_SRC_STORE_EOI; + } + break; + case PSIHB9_SEMR: /* FSP stuff */ break; @@ -721,15 +735,20 @@ static void pnv_psi_p9_mmio_write(void *opaque, hwaddr addr, break; case PSIHB9_ESB_CI_BASE: + if (val & PSIHB10_ESB_CI_64K) { + psi9->source.esb_shift = XIVE_ESB_64K; + } else { + psi9->source.esb_shift = XIVE_ESB_4K; + } if (!(val & PSIHB9_ESB_CI_VALID)) { if (psi->regs[reg] & PSIHB9_ESB_CI_VALID) { memory_region_del_subregion(sysmem, &psi9->source.esb_mmio); } } else { if (!(psi->regs[reg] & PSIHB9_ESB_CI_VALID)) { - memory_region_add_subregion(sysmem, - val & ~PSIHB9_ESB_CI_VALID, - &psi9->source.esb_mmio); + hwaddr addr = val & ~(PSIHB9_ESB_CI_VALID | PSIHB10_ESB_CI_64K); + memory_region_add_subregion(sysmem, addr, + &psi9->source.esb_mmio); } } psi->regs[reg] = val; @@ -838,6 +857,8 @@ static void pnv_psi_power9_instance_init(Object *obj) object_initialize_child(obj, "source", &psi->source, sizeof(psi->source), TYPE_XIVE_SOURCE, &error_abort, NULL); + object_property_add_alias(obj, "shift", OBJECT(&psi->source), "shift", + &error_abort); } static void pnv_psi_power9_realize(DeviceState *dev, Error **errp) @@ -847,9 +868,6 @@ static void pnv_psi_power9_realize(DeviceState *dev, Error **errp) Error *local_err = NULL; int i; - /* This is the only device with 4k ESB pages */ - object_property_set_int(OBJECT(xsrc), XIVE_ESB_4K, "shift", - &error_fatal); object_property_set_int(OBJECT(xsrc), PSIHB9_NUM_IRQS, "nr-irqs", &error_fatal); object_property_set_link(OBJECT(xsrc), OBJECT(psi), "xive", &error_abort); -- 2.25.4