On Mon May 12, 2025 at 1:10 PM AEST, Nicholas Piggin wrote:
> From: Glenn Miles <mil...@linux.ibm.com>
>
> The queue size of an Event Notification Descriptor (END)
> is determined by the 'cl' and QsZ fields of the END.
> If the cl field is 1, then the queue size (in bytes) will
> be the size of a cache line 128B * 2^QsZ and QsZ is limited
> to 4.  Otherwise, it will be 4096B * 2^QsZ with QsZ limited
> to 12.
>

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

> Fixes: f8a233dedf2 ("ppc/xive2: Introduce a XIVE2 core framework")
> Signed-off-by: Glenn Miles <mil...@linux.ibm.com>
> ---
>  hw/intc/xive2.c             | 25 +++++++++++++++++++------
>  include/hw/ppc/xive2_regs.h |  1 +
>  2 files changed, 20 insertions(+), 6 deletions(-)
>
> diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c
> index 7d584dfafa..790152a2a6 100644
> --- a/hw/intc/xive2.c
> +++ b/hw/intc/xive2.c
> @@ -188,12 +188,27 @@ void xive2_eas_pic_print_info(Xive2Eas *eas, uint32_t 
> lisn, GString *buf)
>                             (uint32_t) xive_get_field64(EAS2_END_DATA, 
> eas->w));
>  }
>  
> +#define XIVE2_QSIZE_CHUNK_CL    128
> +#define XIVE2_QSIZE_CHUNK_4k   4096
> +/* Calculate max number of queue entries for an END */
> +static uint32_t xive2_end_get_qentries(Xive2End *end)
> +{
> +    uint32_t w3 = end->w3;
> +    uint32_t qsize = xive_get_field32(END2_W3_QSIZE, w3);
> +    if (xive_get_field32(END2_W3_CL, w3)) {
> +        g_assert(qsize <= 4);
> +        return (XIVE2_QSIZE_CHUNK_CL << qsize) / sizeof(uint32_t);
> +    } else {
> +        g_assert(qsize <= 12);
> +        return (XIVE2_QSIZE_CHUNK_4k << qsize) / sizeof(uint32_t);
> +    }
> +}
> +
>  void xive2_end_queue_pic_print_info(Xive2End *end, uint32_t width, GString 
> *buf)
>  {
>      uint64_t qaddr_base = xive2_end_qaddr(end);
> -    uint32_t qsize = xive_get_field32(END2_W3_QSIZE, end->w3);
>      uint32_t qindex = xive_get_field32(END2_W1_PAGE_OFF, end->w1);
> -    uint32_t qentries = 1 << (qsize + 10);
> +    uint32_t qentries = xive2_end_get_qentries(end);
>      int i;
>  
>      /*
> @@ -223,8 +238,7 @@ void xive2_end_pic_print_info(Xive2End *end, uint32_t 
> end_idx, GString *buf)
>      uint64_t qaddr_base = xive2_end_qaddr(end);
>      uint32_t qindex = xive_get_field32(END2_W1_PAGE_OFF, end->w1);
>      uint32_t qgen = xive_get_field32(END2_W1_GENERATION, end->w1);
> -    uint32_t qsize = xive_get_field32(END2_W3_QSIZE, end->w3);
> -    uint32_t qentries = 1 << (qsize + 10);
> +    uint32_t qentries = xive2_end_get_qentries(end);
>  
>      uint32_t nvx_blk = xive_get_field32(END2_W6_VP_BLOCK, end->w6);
>      uint32_t nvx_idx = xive_get_field32(END2_W6_VP_OFFSET, end->w6);
> @@ -341,13 +355,12 @@ void xive2_nvgc_pic_print_info(Xive2Nvgc *nvgc, 
> uint32_t nvgc_idx, GString *buf)
>  static void xive2_end_enqueue(Xive2End *end, uint32_t data)
>  {
>      uint64_t qaddr_base = xive2_end_qaddr(end);
> -    uint32_t qsize = xive_get_field32(END2_W3_QSIZE, end->w3);
>      uint32_t qindex = xive_get_field32(END2_W1_PAGE_OFF, end->w1);
>      uint32_t qgen = xive_get_field32(END2_W1_GENERATION, end->w1);
>  
>      uint64_t qaddr = qaddr_base + (qindex << 2);
>      uint32_t qdata = cpu_to_be32((qgen << 31) | (data & 0x7fffffff));
> -    uint32_t qentries = 1 << (qsize + 10);
> +    uint32_t qentries = xive2_end_get_qentries(end);
>  
>      if (dma_memory_write(&address_space_memory, qaddr, &qdata, sizeof(qdata),
>                           MEMTXATTRS_UNSPECIFIED)) {
> diff --git a/include/hw/ppc/xive2_regs.h b/include/hw/ppc/xive2_regs.h
> index b11395c563..3c28de8a30 100644
> --- a/include/hw/ppc/xive2_regs.h
> +++ b/include/hw/ppc/xive2_regs.h
> @@ -87,6 +87,7 @@ typedef struct Xive2End {
>  #define END2_W2_EQ_ADDR_HI         PPC_BITMASK32(8, 31)
>          uint32_t       w3;
>  #define END2_W3_EQ_ADDR_LO         PPC_BITMASK32(0, 24)
> +#define END2_W3_CL                 PPC_BIT32(27)
>  #define END2_W3_QSIZE              PPC_BITMASK32(28, 31)
>          uint32_t       w4;
>  #define END2_W4_END_BLOCK          PPC_BITMASK32(4, 7)


Reply via email to