On Mon May 12, 2025 at 1:10 PM AEST, Nicholas Piggin wrote:
> From: Glenn Miles <mil...@linux.ibm.com>
>
> Booting AIX in a PowerVM partition requires the use of the "Acknowledge
> O/S Interrupt to even O/S reporting line" special operation provided by
> the IBM XIVE interrupt controller. This operation is invoked by writing
> a byte (data is irrelevant) to offset 0xC10 of the Thread Interrupt
> Management Area (TIMA). It can be used by software to notify the XIVE
> logic that the interrupt was received.

Reviewed-by: Nicholas Piggin <npig...@gmail.com>

>
> Signed-off-by: Glenn Miles <mil...@linux.ibm.com>
> ---
>  hw/intc/xive.c         |  8 ++++---
>  hw/intc/xive2.c        | 50 ++++++++++++++++++++++++++++++++++++++++++
>  include/hw/ppc/xive.h  |  1 +
>  include/hw/ppc/xive2.h |  3 ++-
>  4 files changed, 58 insertions(+), 4 deletions(-)
>
> diff --git a/hw/intc/xive.c b/hw/intc/xive.c
> index 7461dbecb8..9ec1193dfc 100644
> --- a/hw/intc/xive.c
> +++ b/hw/intc/xive.c
> @@ -80,7 +80,7 @@ static qemu_irq xive_tctx_output(XiveTCTX *tctx, uint8_t 
> ring)
>          }
>  }
>  
> -static uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
> +uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring)
>  {
>      uint8_t *regs = &tctx->regs[ring];
>      uint8_t nsr = regs[TM_NSR];
> @@ -340,14 +340,14 @@ static uint64_t xive_tm_vt_poll(XivePresenter *xptr, 
> XiveTCTX *tctx,
>  
>  static const uint8_t xive_tm_hw_view[] = {
>      3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-0 User */
> -    3, 3, 3, 3,   3, 3, 0, 2,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-1 OS   */
> +    3, 3, 3, 3,   3, 3, 0, 2,   3, 3, 3, 3,   0, 0, 0, 3, /* QW-1 OS   */
>      0, 0, 3, 3,   0, 3, 3, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
>      3, 3, 3, 3,   0, 3, 0, 2,   3, 0, 0, 3,   3, 3, 3, 0, /* QW-3 PHYS */
>  };
>  
>  static const uint8_t xive_tm_hv_view[] = {
>      3, 0, 0, 0,   0, 0, 0, 0,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-0 User */
> -    3, 3, 3, 3,   3, 3, 0, 2,   3, 3, 3, 3,   0, 0, 0, 0, /* QW-1 OS   */
> +    3, 3, 3, 3,   3, 3, 0, 2,   3, 3, 3, 3,   0, 0, 0, 3, /* QW-1 OS   */
>      0, 0, 3, 3,   0, 3, 3, 0,   0, 3, 3, 3,   0, 0, 0, 0, /* QW-2 POOL */
>      3, 3, 3, 3,   0, 3, 0, 2,   3, 0, 0, 3,   0, 0, 0, 0, /* QW-3 PHYS */
>  };
> @@ -718,6 +718,8 @@ static const XiveTmOp xive2_tm_operations[] = {
>                                                       xive_tm_pull_phys_ctx },
>      { XIVE_TM_HV_PAGE, TM_SPC_PULL_PHYS_CTX_OL,   1, 
> xive2_tm_pull_phys_ctx_ol,
>                                                       NULL },
> +    { XIVE_TM_OS_PAGE, TM_SPC_ACK_OS_EL,          1, xive2_tm_ack_os_el,
> +                                                     NULL },
>  };
>  
>  static const XiveTmOp *xive_tm_find_op(XivePresenter *xptr, hwaddr offset,
> diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
> index ec4b9320b4..68be138335 100644
> --- a/hw/intc/xive2.c
> +++ b/hw/intc/xive2.c
> @@ -1009,6 +1009,56 @@ static int xive2_tctx_get_nvp_indexes(XiveTCTX *tctx, 
> uint8_t ring,
>      return 0;
>  }
>  
> +static void xive2_tctx_accept_el(XivePresenter *xptr, XiveTCTX *tctx,
> +                                 uint8_t ring, uint8_t cl_ring)
> +{
> +    uint64_t rd;
> +    Xive2Router *xrtr = XIVE2_ROUTER(xptr);
> +    uint32_t nvp_blk, nvp_idx, xive2_cfg;
> +    Xive2Nvp nvp;
> +    uint64_t phys_addr;
> +    uint8_t OGen = 0;
> +
> +    xive2_tctx_get_nvp_indexes(tctx, cl_ring, &nvp_blk, &nvp_idx);
> +
> +    if (xive2_router_get_nvp(xrtr, (uint8_t)nvp_blk, nvp_idx, &nvp)) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "XIVE: No NVP %x/%x\n",
> +                      nvp_blk, nvp_idx);
> +        return;
> +    }
> +
> +    if (!xive2_nvp_is_valid(&nvp)) {
> +        qemu_log_mask(LOG_GUEST_ERROR, "XIVE: invalid NVP %x/%x\n",
> +                      nvp_blk, nvp_idx);
> +        return;
> +    }
> +
> +
> +    rd = xive_tctx_accept(tctx, ring);
> +
> +    if (ring == TM_QW1_OS) {
> +        OGen = tctx->regs[ring + TM_OGEN];
> +    }
> +    xive2_cfg = xive2_router_get_config(xrtr);
> +    phys_addr = xive2_nvp_reporting_addr(&nvp);
> +    uint8_t report_data[REPORT_LINE_GEN1_SIZE];
> +    memset(report_data, 0xff, sizeof(report_data));
> +    if ((OGen == 1) || (xive2_cfg & XIVE2_GEN1_TIMA_OS)) {
> +        report_data[8] = (rd >> 8) & 0xff;
> +        report_data[9] = rd & 0xff;
> +    } else {
> +        report_data[0] = (rd >> 8) & 0xff;
> +        report_data[1] = rd & 0xff;
> +    }
> +    cpu_physical_memory_write(phys_addr, report_data, REPORT_LINE_GEN1_SIZE);
> +}
> +
> +void xive2_tm_ack_os_el(XivePresenter *xptr, XiveTCTX *tctx,
> +                        hwaddr offset, uint64_t value, unsigned size)
> +{
> +    xive2_tctx_accept_el(xptr, tctx, TM_QW1_OS, TM_QW1_OS);
> +}
> +
>  static void xive2_tctx_set_cppr(XiveTCTX *tctx, uint8_t ring, uint8_t cppr)
>  {
>      uint8_t *regs = &tctx->regs[ring];
> diff --git a/include/hw/ppc/xive.h b/include/hw/ppc/xive.h
> index 28f0f1b79a..46d05d74fb 100644
> --- a/include/hw/ppc/xive.h
> +++ b/include/hw/ppc/xive.h
> @@ -561,6 +561,7 @@ void xive_tctx_pipr_update(XiveTCTX *tctx, uint8_t ring, 
> uint8_t priority,
>                             uint8_t group_level);
>  void xive_tctx_reset_signal(XiveTCTX *tctx, uint8_t ring);
>  void xive_tctx_notify(XiveTCTX *tctx, uint8_t ring, uint8_t group_level);
> +uint64_t xive_tctx_accept(XiveTCTX *tctx, uint8_t ring);
>  
>  /*
>   * KVM XIVE device helpers
> diff --git a/include/hw/ppc/xive2.h b/include/hw/ppc/xive2.h
> index 760b94a962..ff02ce2549 100644
> --- a/include/hw/ppc/xive2.h
> +++ b/include/hw/ppc/xive2.h
> @@ -142,5 +142,6 @@ void xive2_tm_set_hv_target(XivePresenter *xptr, XiveTCTX 
> *tctx,
>                              hwaddr offset, uint64_t value, unsigned size);
>  void xive2_tm_pull_phys_ctx_ol(XivePresenter *xptr, XiveTCTX *tctx,
>                                 hwaddr offset, uint64_t value, unsigned size);
> -
> +void xive2_tm_ack_os_el(XivePresenter *xptr, XiveTCTX *tctx,
> +                        hwaddr offset, uint64_t value, unsigned size);
>  #endif /* PPC_XIVE2_H */


Reply via email to