On Wed, Mar 06, 2019 at 09:50:14AM +0100, Cédric Le Goater wrote: > The NSR register of the HV ring has a different, although similar, bit > layout. TM_QW3_NSR_HE_PHYS bit should now be raised when the > Hypervisor interrupt line is signaled. Other bits TM_QW3_NSR_HE_POOL > and TM_QW3_NSR_HE_LSI are not modeled. LSI are for special interrupts > reserved for HW bringup and the POOL bit is used when signaling a > group of VPs. This is not currently implemented in Linux but it is in > pHyp. > > The most important special commands on the HV TIMA page are added to > let the core manage interrupts : acking and changing the CPU priority. > > Signed-off-by: Cédric Le Goater <c...@kaod.org> > --- > hw/intc/xive.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++--- > 1 file changed, 54 insertions(+), 3 deletions(-) > > diff --git a/hw/intc/xive.c b/hw/intc/xive.c > index 7d7992c0ce3f..a0b87001da25 100644 > --- a/hw/intc/xive.c > +++ b/hw/intc/xive.c > @@ -54,6 +54,8 @@ static uint8_t exception_mask(uint8_t ring) > switch (ring) { > case TM_QW1_OS: > return TM_QW1_NSR_EO; > + case TM_QW3_HV_PHYS: > + return TM_QW3_NSR_HE; > default: > g_assert_not_reached(); > } > @@ -88,7 +90,16 @@ static void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring) > uint8_t *regs = &tctx->regs[ring]; > > if (regs[TM_PIPR] < regs[TM_CPPR]) { > - regs[TM_NSR] |= exception_mask(ring);
This means there's only one remaining caller to exception_mask, so it might be better to just open code it at that site. That can be a later cleanup though, so applied to ppc-for-4.0. > + switch (ring) { > + case TM_QW1_OS: > + regs[TM_NSR] |= TM_QW1_NSR_EO; > + break; > + case TM_QW3_HV_PHYS: > + regs[TM_NSR] |= (TM_QW3_NSR_HE_PHYS << 6); > + break; > + default: > + g_assert_not_reached(); > + } > qemu_irq_raise(tctx->output); > } > } > @@ -109,6 +120,38 @@ static void xive_tctx_set_cppr(XiveTCTX *tctx, uint8_t > ring, uint8_t cppr) > * XIVE Thread Interrupt Management Area (TIMA) > */ > > +static void xive_tm_set_hv_cppr(XiveTCTX *tctx, hwaddr offset, > + uint64_t value, unsigned size) > +{ > + xive_tctx_set_cppr(tctx, TM_QW3_HV_PHYS, value & 0xff); > +} > + > +static uint64_t xive_tm_ack_hv_reg(XiveTCTX *tctx, hwaddr offset, unsigned > size) > +{ > + return xive_tctx_accept(tctx, TM_QW3_HV_PHYS); > +} > + > +static uint64_t xive_tm_pull_pool_ctx(XiveTCTX *tctx, hwaddr offset, > + unsigned size) > +{ > + uint64_t ret; > + > + ret = tctx->regs[TM_QW2_HV_POOL + TM_WORD2] & TM_QW2W2_POOL_CAM; > + tctx->regs[TM_QW2_HV_POOL + TM_WORD2] &= ~TM_QW2W2_POOL_CAM; > + return ret; > +} > + > +static void xive_tm_vt_push(XiveTCTX *tctx, hwaddr offset, > + uint64_t value, unsigned size) > +{ > + tctx->regs[TM_QW3_HV_PHYS + TM_WORD2] = value & 0xff; > +} > + > +static uint64_t xive_tm_vt_poll(XiveTCTX *tctx, hwaddr offset, unsigned size) > +{ > + return tctx->regs[TM_QW3_HV_PHYS + TM_WORD2] & 0xff; > +} > + > /* > * Define an access map for each page of the TIMA that we will use in > * the memory region ops to filter values when doing loads and stores > @@ -288,10 +331,16 @@ static const XiveTmOp xive_tm_operations[] = { > * effects > */ > { XIVE_TM_OS_PAGE, TM_QW1_OS + TM_CPPR, 1, xive_tm_set_os_cppr, NULL }, > + { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_CPPR, 1, xive_tm_set_hv_cppr, > NULL }, > + { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, xive_tm_vt_push, NULL }, > + { XIVE_TM_HV_PAGE, TM_QW3_HV_PHYS + TM_WORD2, 1, NULL, xive_tm_vt_poll }, > > /* MMIOs above 2K : special operations with side effects */ > { XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_REG, 2, NULL, xive_tm_ack_os_reg }, > { XIVE_TM_OS_PAGE, TM_SPC_SET_OS_PENDING, 1, xive_tm_set_os_pending, > NULL }, > + { XIVE_TM_HV_PAGE, TM_SPC_ACK_HV_REG, 2, NULL, xive_tm_ack_hv_reg }, > + { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX, 4, NULL, xive_tm_pull_pool_ctx > }, > + { XIVE_TM_HV_PAGE, TM_SPC_PULL_POOL_CTX, 8, NULL, xive_tm_pull_pool_ctx > }, > }; > > static const XiveTmOp *xive_tm_find_op(hwaddr offset, unsigned size, bool > write) > @@ -323,7 +372,7 @@ void xive_tctx_tm_write(XiveTCTX *tctx, hwaddr offset, > uint64_t value, > const XiveTmOp *xto; > > /* > - * TODO: check V bit in Q[0-3]W2, check PTER bit associated with CPU > + * TODO: check V bit in Q[0-3]W2 > */ > > /* > @@ -360,7 +409,7 @@ uint64_t xive_tctx_tm_read(XiveTCTX *tctx, hwaddr offset, > unsigned size) > const XiveTmOp *xto; > > /* > - * TODO: check V bit in Q[0-3]W2, check PTER bit associated with CPU > + * TODO: check V bit in Q[0-3]W2 > */ > > /* > @@ -472,6 +521,8 @@ static void xive_tctx_reset(void *dev) > */ > tctx->regs[TM_QW1_OS + TM_PIPR] = > ipb_to_pipr(tctx->regs[TM_QW1_OS + TM_IPB]); > + tctx->regs[TM_QW3_HV_PHYS + TM_PIPR] = > + ipb_to_pipr(tctx->regs[TM_QW3_HV_PHYS + TM_IPB]); > } > > static void xive_tctx_realize(DeviceState *dev, Error **errp) -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
signature.asc
Description: PGP signature