Reviewed-by: Glenn Miles <mil...@linux.ibm.com>
On Mon, 2025-05-12 at 13:10 +1000, Nicholas Piggin wrote:
> Rather than functions to return masks to test NSR bits, have functions
> to test those bits directly. This should be no functional change, it
> just makes the code more readable.
>
> Signed-off-by: Nicholas Piggin <npig...@gmail.com>
> ---
> hw/intc/xive.c | 51 +++++++++++++++++++++++++++++++++++--------
> include/hw/ppc/xive.h | 4 ++++
> 2 files changed, 46 insertions(+), 9 deletions(-)
>
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index bb40a69c5b..c2da23f9ea 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -25,6 +25,45 @@
> /*
> * XIVE Thread Interrupt Management context
> */
> +bool xive_nsr_indicates_exception(uint8_t ring, uint8_t nsr)
> +{
> + switch (ring) {
> + case TM_QW1_OS:
> + return !!(nsr & TM_QW1_NSR_EO);
> + case TM_QW2_HV_POOL:
> + case TM_QW3_HV_PHYS:
> + return !!(nsr & TM_QW3_NSR_HE);
> + default:
> + g_assert_not_reached();
> + }
> +}
> +
> +bool xive_nsr_indicates_group_exception(uint8_t ring, uint8_t nsr)
> +{
> + if ((nsr & TM_NSR_GRP_LVL) > 0) {
> + g_assert(xive_nsr_indicates_exception(ring, nsr));
> + return true;
> + }
> + return false;
> +}
> +
> +uint8_t xive_nsr_exception_ring(uint8_t ring, uint8_t nsr)
> +{
> + /* NSR determines if pool/phys ring is for phys or pool interrupt */
> + if ((ring == TM_QW3_HV_PHYS) || (ring == TM_QW2_HV_POOL)) {
> + uint8_t he = (nsr & TM_QW3_NSR_HE) >> 6;
> +
> + if (he == TM_QW3_NSR_HE_PHYS) {
> + return TM_QW3_HV_PHYS;
> + } else if (he == TM_QW3_NSR_HE_POOL) {
> + return TM_QW2_HV_POOL;
> + } else {
> + /* Don't support LSI mode */
> + g_assert_not_reached();
> + }
> + }
> + return ring;
> +}
>
> static qemu_irq xive_tctx_output(XiveTCTX *tctx, uint8_t ring)
> {
> @@ -48,18 +87,12 @@ static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t
> ring)
>
> qemu_irq_lower(xive_tctx_output(tctx, ring));
>
> - if (regs[TM_NSR] != 0) {
> + if (xive_nsr_indicates_exception(ring, nsr)) {
> uint8_t cppr = regs[TM_PIPR];
> uint8_t alt_ring;
> uint8_t *alt_regs;
>
> - /* POOL interrupt uses IPB in QW2, POOL ring */
> - if ((ring == TM_QW3_HV_PHYS) &&
> - ((nsr & TM_QW3_NSR_HE) == (TM_QW3_NSR_HE_POOL << 6))) {
> - alt_ring = TM_QW2_HV_POOL;
> - } else {
> - alt_ring = ring;
> - }
> + alt_ring = xive_nsr_exception_ring(ring, nsr);
> alt_regs = &tctx->regs[alt_ring];
>
> regs[TM_CPPR] = cppr;
> @@ -68,7 +101,7 @@ static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t
> ring)
> * If the interrupt was for a specific VP, reset the pending
> * buffer bit, otherwise clear the logical server indicator
> */
> - if (!(regs[TM_NSR] & TM_NSR_GRP_LVL)) {
> + if (!xive_nsr_indicates_group_exception(ring, nsr)) {
> alt_regs[TM_IPB] &= ~xive_priority_to_ipb(cppr);
> }
>
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index 538f438681..28f0f1b79a 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -365,6 +365,10 @@ static inline uint32_t xive_tctx_word2(uint8_t *ring)
> return *((uint32_t *) &ring[TM_WORD2]);
> }
>
> +bool xive_nsr_indicates_exception(uint8_t ring, uint8_t nsr);
> +bool xive_nsr_indicates_group_exception(uint8_t ring, uint8_t nsr);
> +uint8_t xive_nsr_exception_ring(uint8_t ring, uint8_t nsr);
> +
> /*
> * XIVE Router
> */