ppc/psi: Add support for StoreEOI and 64k ESB pages (POWER10)

POWER10 adds support for StoreEOI operation and 64K ESB pages on PSIHB
to be consistent with the other interrupt sources of the system.

Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
This commit is contained in:
Cédric Le Goater 2022-03-02 06:51:39 +01:00
parent 924996766b
commit 24c8fa968a
2 changed files with 30 additions and 6 deletions

View File

@ -1500,6 +1500,9 @@ static void pnv_chip_power9_realize(DeviceState *dev, Error **errp)
/* Processor Service Interface (PSI) Host Bridge */ /* Processor Service Interface (PSI) Host Bridge */
object_property_set_int(OBJECT(&chip9->psi), "bar", PNV9_PSIHB_BASE(chip), object_property_set_int(OBJECT(&chip9->psi), "bar", PNV9_PSIHB_BASE(chip),
&error_fatal); &error_fatal);
/* This is the only device with 4k ESB pages */
object_property_set_int(OBJECT(&chip9->psi), "shift", XIVE_ESB_4K,
&error_fatal);
if (!qdev_realize(DEVICE(&chip9->psi), NULL, errp)) { if (!qdev_realize(DEVICE(&chip9->psi), NULL, errp)) {
return; return;
} }
@ -1704,6 +1707,9 @@ static void pnv_chip_power10_realize(DeviceState *dev, Error **errp)
/* Processor Service Interface (PSI) Host Bridge */ /* Processor Service Interface (PSI) Host Bridge */
object_property_set_int(OBJECT(&chip10->psi), "bar", object_property_set_int(OBJECT(&chip10->psi), "bar",
PNV10_PSIHB_BASE(chip), &error_fatal); PNV10_PSIHB_BASE(chip), &error_fatal);
/* PSI can now be configured to use 64k ESB pages on POWER10 */
object_property_set_int(OBJECT(&chip10->psi), "shift", XIVE_ESB_64K,
&error_fatal);
if (!qdev_realize(DEVICE(&chip10->psi), NULL, errp)) { if (!qdev_realize(DEVICE(&chip10->psi), NULL, errp)) {
return; return;
} }

View File

@ -601,7 +601,6 @@ static const TypeInfo pnv_psi_power8_info = {
#define PSIHB9_IRQ_METHOD PPC_BIT(0) #define PSIHB9_IRQ_METHOD PPC_BIT(0)
#define PSIHB9_IRQ_RESET PPC_BIT(1) #define PSIHB9_IRQ_RESET PPC_BIT(1)
#define PSIHB9_ESB_CI_BASE 0x60 #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_ADDR_MASK PPC_BITMASK(8, 47)
#define PSIHB9_ESB_CI_VALID PPC_BIT(63) #define PSIHB9_ESB_CI_VALID PPC_BIT(63)
#define PSIHB9_ESB_NOTIF_ADDR 0x68 #define PSIHB9_ESB_NOTIF_ADDR 0x68
@ -646,6 +645,14 @@ static const TypeInfo pnv_psi_power8_info = {
#define PSIHB9_IRQ_STAT_DIO PPC_BIT(12) #define PSIHB9_IRQ_STAT_DIO PPC_BIT(12)
#define PSIHB9_IRQ_STAT_PSU PPC_BIT(13) #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) static void pnv_psi_notify(XiveNotifier *xf, uint32_t srcno)
{ {
PnvPsi *psi = PNV_PSI(xf); PnvPsi *psi = PNV_PSI(xf);
@ -704,6 +711,13 @@ static void pnv_psi_p9_mmio_write(void *opaque, hwaddr addr,
switch (addr) { switch (addr) {
case PSIHB9_CR: 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: case PSIHB9_SEMR:
/* FSP stuff */ /* FSP stuff */
break; break;
@ -715,15 +729,20 @@ static void pnv_psi_p9_mmio_write(void *opaque, hwaddr addr,
break; break;
case PSIHB9_ESB_CI_BASE: 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 (!(val & PSIHB9_ESB_CI_VALID)) {
if (psi->regs[reg] & PSIHB9_ESB_CI_VALID) { if (psi->regs[reg] & PSIHB9_ESB_CI_VALID) {
memory_region_del_subregion(sysmem, &psi9->source.esb_mmio); memory_region_del_subregion(sysmem, &psi9->source.esb_mmio);
} }
} else { } else {
if (!(psi->regs[reg] & PSIHB9_ESB_CI_VALID)) { if (!(psi->regs[reg] & PSIHB9_ESB_CI_VALID)) {
memory_region_add_subregion(sysmem, hwaddr addr = val & ~(PSIHB9_ESB_CI_VALID | PSIHB10_ESB_CI_64K);
val & ~PSIHB9_ESB_CI_VALID, memory_region_add_subregion(sysmem, addr,
&psi9->source.esb_mmio); &psi9->source.esb_mmio);
} }
} }
psi->regs[reg] = val; psi->regs[reg] = val;
@ -831,6 +850,7 @@ static void pnv_psi_power9_instance_init(Object *obj)
Pnv9Psi *psi = PNV9_PSI(obj); Pnv9Psi *psi = PNV9_PSI(obj);
object_initialize_child(obj, "source", &psi->source, TYPE_XIVE_SOURCE); object_initialize_child(obj, "source", &psi->source, TYPE_XIVE_SOURCE);
object_property_add_alias(obj, "shift", OBJECT(&psi->source), "shift");
} }
static void pnv_psi_power9_realize(DeviceState *dev, Error **errp) static void pnv_psi_power9_realize(DeviceState *dev, Error **errp)
@ -839,8 +859,6 @@ static void pnv_psi_power9_realize(DeviceState *dev, Error **errp)
XiveSource *xsrc = &PNV9_PSI(psi)->source; XiveSource *xsrc = &PNV9_PSI(psi)->source;
int i; int i;
/* This is the only device with 4k ESB pages */
object_property_set_int(OBJECT(xsrc), "shift", XIVE_ESB_4K, &error_fatal);
object_property_set_int(OBJECT(xsrc), "nr-irqs", PSIHB9_NUM_IRQS, object_property_set_int(OBJECT(xsrc), "nr-irqs", PSIHB9_NUM_IRQS,
&error_fatal); &error_fatal);
object_property_set_link(OBJECT(xsrc), "xive", OBJECT(psi), &error_abort); object_property_set_link(OBJECT(xsrc), "xive", OBJECT(psi), &error_abort);