When PC_TCTXT_CHIPID_OVERRIDE is configured, the PC_TCTXT_CHIPID field overrides the hardwired chip ID in the Powerbus operations and for CAM compares. This is typically used in one block-per-chip configurations to associate a unique block id number to each IC of the system.
The model does support multiple blocks per chip. Signed-off-by: Cédric Le Goater <c...@kaod.org> --- include/hw/ppc/pnv_xive.h | 3 -- include/hw/ppc/xive.h | 2 ++ hw/intc/pnv_xive.c | 66 +++++++++++++++++++++------------------ hw/intc/spapr_xive.c | 6 ++++ hw/intc/xive.c | 10 +++++- 5 files changed, 53 insertions(+), 34 deletions(-) diff --git a/include/hw/ppc/pnv_xive.h b/include/hw/ppc/pnv_xive.h index 4fdaa9247d65..f4c7caad40ee 100644 --- a/include/hw/ppc/pnv_xive.h +++ b/include/hw/ppc/pnv_xive.h @@ -72,9 +72,6 @@ typedef struct PnvXive { /* Interrupt controller registers */ uint64_t regs[0x300]; - /* Can be configured by FW */ - uint32_t tctx_chipid; - /* * Virtual Structure Descriptor tables : EAT, SBE, ENDT, NVTT, IRQ * These are in a SRAM protected by ECC. diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h index 251a8f2de10e..8828dd1eb06c 100644 --- a/include/hw/ppc/xive.h +++ b/include/hw/ppc/xive.h @@ -355,6 +355,7 @@ typedef struct XiveRouterClass { int (*write_nvt)(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx, XiveNVT *nvt, uint8_t word_number); XiveTCTX *(*get_tctx)(XiveRouter *xrtr, CPUState *cs); + uint8_t (*get_block_id)(XiveRouter *xrtr); } XiveRouterClass; int xive_router_get_eas(XiveRouter *xrtr, uint8_t eas_blk, uint32_t eas_idx, @@ -368,6 +369,7 @@ int xive_router_get_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx, int xive_router_write_nvt(XiveRouter *xrtr, uint8_t nvt_blk, uint32_t nvt_idx, XiveNVT *nvt, uint8_t word_number); XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs); +uint8_t xive_router_get_block_id(XiveRouter *xrtr); void xive_router_notify(XiveNotifier *xn, uint32_t lisn); /* diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c index 403e8c8ca5b4..c1501a6b5bce 100644 --- a/hw/intc/pnv_xive.c +++ b/hw/intc/pnv_xive.c @@ -83,6 +83,23 @@ static inline uint64_t SETFIELD(uint64_t mask, uint64_t word, return (word & ~mask) | ((value << ctz64(mask)) & mask); } +/* + * When PC_TCTXT_CHIPID_OVERRIDE is configured, the PC_TCTXT_CHIPID + * field overrides the hardwired chip ID in the Powerbus operations + * and for CAM compares + */ +static uint8_t pnv_xive_block_id(PnvXive *xive) +{ + uint8_t blk = xive->chip->chip_id; + uint64_t cfg_val = xive->regs[PC_TCTXT_CFG >> 3]; + + if (cfg_val & PC_TCTXT_CHIPID_OVERRIDE) { + blk = GETFIELD(PC_TCTXT_CHIPID, cfg_val); + } + + return blk; +} + /* * Remote access to controllers. HW uses MMIOs. For now, a simple scan * of the chips is good enough. @@ -98,7 +115,7 @@ static PnvXive *pnv_xive_get_ic(uint8_t blk) Pnv9Chip *chip9 = PNV9_CHIP(pnv->chips[i]); PnvXive *xive = &chip9->xive; - if (xive->chip->chip_id == blk) { + if (pnv_xive_block_id(xive) == blk) { return xive; } } @@ -384,6 +401,11 @@ static XiveTCTX *pnv_xive_get_tctx(XiveRouter *xrtr, CPUState *cs) return tctx; } +static uint8_t pnv_xive_get_block_id(XiveRouter *xrtr) +{ + return pnv_xive_block_id(PNV_XIVE(xrtr)); +} + /* * The internal sources (IPIs) of the interrupt controller have no * knowledge of the XIVE chip on which they reside. Encode the block @@ -394,7 +416,7 @@ static XiveTCTX *pnv_xive_get_tctx(XiveRouter *xrtr, CPUState *cs) static void pnv_xive_notify(XiveNotifier *xn, uint32_t srcno) { PnvXive *xive = PNV_XIVE(xn); - uint8_t blk = xive->chip->chip_id; + uint8_t blk = pnv_xive_block_id(xive); xive_router_notify(xn, XIVE_SRCNO(blk, srcno)); } @@ -758,21 +780,9 @@ static void pnv_xive_ic_reg_write(void *opaque, hwaddr offset, case PC_TCTXT_CFG: /* * TODO: block group support - * - * PC_TCTXT_CFG_BLKGRP_EN - * PC_TCTXT_CFG_HARD_CHIPID_BLK : - * Moves the chipid into block field for hardwired CAM compares. - * Block offset value is adjusted to 0b0..01 & ThrdId - * - * Will require changes in xive_presenter_tctx_match(). I am - * not sure how to handle that yet. */ - - /* Overrides hardwired chip ID with the chip ID field */ - if (val & PC_TCTXT_CHIPID_OVERRIDE) { - xive->tctx_chipid = GETFIELD(PC_TCTXT_CHIPID, val); - } break; + case PC_TCTXT_TRACK: /* * PC_TCTXT_TRACK_EN: @@ -1555,7 +1565,8 @@ static void xive_nvt_pic_print_info(XiveNVT *nvt, uint32_t nvt_idx, void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon) { XiveRouter *xrtr = XIVE_ROUTER(xive); - uint8_t blk = xive->chip->chip_id; + uint8_t blk = pnv_xive_block_id(xive); + uint8_t chip_id = xive->chip->chip_id; uint32_t srcno0 = XIVE_SRCNO(blk, 0); uint32_t nr_ipis = pnv_xive_nr_ipis(xive, blk); XiveEAS eas; @@ -1563,12 +1574,12 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon) XiveNVT nvt; int i; - monitor_printf(mon, "XIVE[%x] Source %08x .. %08x\n", blk, srcno0, - srcno0 + nr_ipis - 1); + monitor_printf(mon, "XIVE[%x] #%d Source %08x .. %08x\n", chip_id, blk, + srcno0, srcno0 + nr_ipis - 1); xive_source_pic_print_info(&xive->ipi_source, srcno0, mon); - monitor_printf(mon, "XIVE[%x] EAT %08x .. %08x\n", blk, srcno0, - srcno0 + nr_ipis - 1); + monitor_printf(mon, "XIVE[%x] #%d EAT %08x .. %08x\n", chip_id, blk, + srcno0, srcno0 + nr_ipis - 1); for (i = 0; i < nr_ipis; i++) { if (xive_router_get_eas(xrtr, blk, i, &eas)) { break; @@ -1578,20 +1589,20 @@ void pnv_xive_pic_print_info(PnvXive *xive, Monitor *mon) } } - monitor_printf(mon, "XIVE[%x] ENDT\n", blk); + monitor_printf(mon, "XIVE[%x] #%d ENDT\n", chip_id, blk); i = 0; while (!xive_router_get_end(xrtr, blk, i, &end)) { xive_end_pic_print_info(&end, i++, mon); } - monitor_printf(mon, "XIVE[%x] END Escalation EAT\n", blk); + monitor_printf(mon, "XIVE[%x] #%d END Escalation EAT\n", chip_id, blk); i = 0; while (!xive_router_get_end(xrtr, blk, i, &end)) { xive_end_eas_pic_print_info(&end, i++, mon); } - monitor_printf(mon, "XIVE[%x] NVTT %08x .. %08x\n", blk, 0, - XIVE_NVT_COUNT - 1); + monitor_printf(mon, "XIVE[%x] #%d NVTT %08x .. %08x\n", chip_id, blk, + 0, XIVE_NVT_COUNT - 1); for (i = 0; i < XIVE_NVT_COUNT; i += XIVE_NVT_PER_PAGE) { while (!xive_router_get_nvt(xrtr, blk, i, &nvt)) { xive_nvt_pic_print_info(&nvt, i++, mon); @@ -1605,12 +1616,6 @@ static void pnv_xive_reset(void *dev) XiveSource *xsrc = &xive->ipi_source; XiveENDSource *end_xsrc = &xive->end_source; - /* - * Use the PnvChip id to identify the XIVE interrupt controller. - * It can be overriden by configuration at runtime. - */ - xive->tctx_chipid = xive->chip->chip_id; - /* Default page size (Should be changed at runtime to 64k) */ xive->ic_shift = xive->vc_shift = xive->pc_shift = 12; @@ -1803,6 +1808,7 @@ static void pnv_xive_class_init(ObjectClass *klass, void *data) xrc->get_nvt = pnv_xive_get_nvt; xrc->write_nvt = pnv_xive_write_nvt; xrc->get_tctx = pnv_xive_get_tctx; + xrc->get_block_id = pnv_xive_get_block_id; xnc->notify = pnv_xive_notify; }; diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index ba012c7b0fdc..1c5fb1e0e633 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -419,6 +419,11 @@ static XiveTCTX *spapr_xive_get_tctx(XiveRouter *xrtr, CPUState *cs) return spapr_cpu_state(cpu)->tctx; } +static uint8_t spapr_xive_get_block_id(XiveRouter *xrtr) +{ + return SPAPR_XIVE_BLOCK_ID; +} + static const VMStateDescription vmstate_spapr_xive_end = { .name = TYPE_SPAPR_XIVE "/end", .version_id = 1, @@ -508,6 +513,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data) xrc->get_nvt = spapr_xive_get_nvt; xrc->write_nvt = spapr_xive_write_nvt; xrc->get_tctx = spapr_xive_get_tctx; + xrc->get_block_id = spapr_xive_get_block_id; } static const TypeInfo spapr_xive_info = { diff --git a/hw/intc/xive.c b/hw/intc/xive.c index bcb22ad7e69a..18371ab60d3a 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -1340,6 +1340,13 @@ XiveTCTX *xive_router_get_tctx(XiveRouter *xrtr, CPUState *cs) return xrc->get_tctx(xrtr, cs); } +uint8_t xive_router_get_block_id(XiveRouter *xrtr) +{ + XiveRouterClass *xrc = XIVE_ROUTER_GET_CLASS(xrtr); + + return xrc->get_block_id(xrtr); +} + /* * Encode the HW CAM line in the block group mode format : * @@ -1349,8 +1356,9 @@ static uint32_t xive_tctx_hw_cam_line(XiveTCTX *tctx) { CPUPPCState *env = &POWERPC_CPU(tctx->cs)->env; uint32_t pir = env->spr_cb[SPR_PIR].default_value; + uint8_t blk = xive_router_get_block_id(XIVE_ROUTER(tctx->xrtr)); - return xive_nvt_cam_line((pir >> 8) & 0xf, 1 << 7 | (pir & 0x7f)); + return xive_nvt_cam_line(blk, 1 << 7 | (pir & 0x7f)); } /* -- 2.21.0