[PATCH 19/65] hw/intc/arm_gicv5: Implement IRS_MAP_L2_ISTR

Peter Maydell posted 65 patches 1 month, 2 weeks ago
Maintainers: Peter Maydell <peter.maydell@linaro.org>, Pierrick Bouvier <pierrick.bouvier@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, Eduardo Habkost <eduardo@habkost.net>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>
There is a newer version of this series
[PATCH 19/65] hw/intc/arm_gicv5: Implement IRS_MAP_L2_ISTR
Posted by Peter Maydell 1 month, 2 weeks ago
The IRS register IRS_MAP_L2_ISTR is used by software to tell the IRS
that it has updated the address in an L1 IST entry to point to an
L2 IST. The sequence of events here is:
 * software writes to L1_ISTE.L2_ADDR for some L1 ISTE which is
   not valid (i.e. where L1_ISTE.VALID is 0); it leaves VALID at 0
 * software writes to IRS_MAP_L2_ISTR with some INTID that is inside
   the range for this L1 ISTE
 * the IRS sets IRS_IST_STATUSR.IDLE to 0
 * the IRS takes note of this information
 * the IRS writes to the L1_ISTE to set VALID=1
 * the IRS sets IRS_IST_STATUSR.IDLE to 1 to indicate that the
   update is complete

For QEMU, we're strictly synchronous, so (as with IRS_IST_BASER
updates) we don't need to model the IDLE transitions and can have
IRS_IST_STATUSR always return IDLE=1.  We also don't currently cache
anything for ISTE lookups, so we don't need to invalidate or update
anything when software makes the L2 valid.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/intc/arm_gicv5.c | 41 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/hw/intc/arm_gicv5.c b/hw/intc/arm_gicv5.c
index 8572823edc..af27fb7e63 100644
--- a/hw/intc/arm_gicv5.c
+++ b/hw/intc/arm_gicv5.c
@@ -492,6 +492,44 @@ void gicv5_set_priority(GICv5Common *cs, uint32_t id,
     put_l2_iste(cs, cfg, &h);
 }
 
+static void irs_map_l2_istr_write(GICv5 *s, GICv5Domain domain, uint64_t value)
+{
+    GICv5Common *cs = ARM_GICV5_COMMON(s);
+    GICv5ISTConfig *cfg = &s->phys_lpi_config[domain];
+    uint32_t intid = FIELD_EX32(value, IRS_MAP_L2_ISTR, ID);
+    hwaddr l1_addr;
+    uint64_t l1_iste;
+    MemTxResult res;
+
+    if (!FIELD_EX64(cs->irs_ist_baser[domain], IRS_IST_BASER, VALID) ||
+        !cfg->structure) {
+        /* WI if no IST set up or it is not 2-level */
+        return;
+    }
+
+    /* Find the relevant L1 ISTE and set its VALID bit */
+    l1_addr = l1_iste_addr(cs, cfg, intid);
+
+    l1_iste = address_space_ldq_le(&cs->dma_as, l1_addr, cfg->txattrs, &res);
+    if (res != MEMTX_OK) {
+        goto txfail;
+    }
+
+    l1_iste = FIELD_DP64(l1_iste, L1_ISTE, VALID, 1);
+
+    address_space_stq_le(&cs->dma_as, l1_addr, l1_iste, cfg->txattrs, &res);
+    if (res != MEMTX_OK) {
+        goto txfail;
+    }
+    return;
+
+txfail:
+    /* Reportable with EC=0x0 if sw error reporting implemented */
+    qemu_log_mask(LOG_GUEST_ERROR, "L1 ISTE update failed for ID 0x%x at "
+                  "physical address 0x" HWADDR_FMT_plx "\n", intid, l1_addr);
+}
+
+
 static void irs_ist_baser_write(GICv5 *s, GICv5Domain domain, uint64_t value)
 {
     GICv5Common *cs = ARM_GICV5_COMMON(s);
@@ -675,6 +713,9 @@ static bool config_writel(GICv5 *s, GICv5Domain domain, hwaddr offset,
             cs->irs_ist_cfgr[domain] = data;
         }
         return true;
+    case A_IRS_MAP_L2_ISTR:
+        irs_map_l2_istr_write(s, domain, data);
+        return true;
     }
     return false;
 }
-- 
2.43.0
Re: [PATCH 19/65] hw/intc/arm_gicv5: Implement IRS_MAP_L2_ISTR
Posted by Jonathan Cameron via qemu development 1 month ago
On Mon, 23 Feb 2026 17:01:26 +0000
Peter Maydell <peter.maydell@linaro.org> wrote:

> The IRS register IRS_MAP_L2_ISTR is used by software to tell the IRS
> that it has updated the address in an L1 IST entry to point to an
> L2 IST. The sequence of events here is:
>  * software writes to L1_ISTE.L2_ADDR for some L1 ISTE which is
>    not valid (i.e. where L1_ISTE.VALID is 0); it leaves VALID at 0
>  * software writes to IRS_MAP_L2_ISTR with some INTID that is inside
>    the range for this L1 ISTE
>  * the IRS sets IRS_IST_STATUSR.IDLE to 0
>  * the IRS takes note of this information
>  * the IRS writes to the L1_ISTE to set VALID=1
>  * the IRS sets IRS_IST_STATUSR.IDLE to 1 to indicate that the
>    update is complete
> 
> For QEMU, we're strictly synchronous, so (as with IRS_IST_BASER
> updates) we don't need to model the IDLE transitions and can have
> IRS_IST_STATUSR always return IDLE=1.  We also don't currently cache
> anything for ISTE lookups, so we don't need to invalidate or update
> anything when software makes the L2 valid.
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
One trivial thing inline.

Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>

That's enough for today, not sure when I'll get back to the rest of the series.
So far very nice and clean. Makes reviewing pleasant!

J
> ---
>  hw/intc/arm_gicv5.c | 41 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 41 insertions(+)
> 
> diff --git a/hw/intc/arm_gicv5.c b/hw/intc/arm_gicv5.c
> index 8572823edc..af27fb7e63 100644
> --- a/hw/intc/arm_gicv5.c
> +++ b/hw/intc/arm_gicv5.c
> @@ -492,6 +492,44 @@ void gicv5_set_priority(GICv5Common *cs, uint32_t id,
>      put_l2_iste(cs, cfg, &h);
>  }
>  
> +static void irs_map_l2_istr_write(GICv5 *s, GICv5Domain domain, uint64_t value)
> +{
> +    GICv5Common *cs = ARM_GICV5_COMMON(s);
> +    GICv5ISTConfig *cfg = &s->phys_lpi_config[domain];
> +    uint32_t intid = FIELD_EX32(value, IRS_MAP_L2_ISTR, ID);
> +    hwaddr l1_addr;
> +    uint64_t l1_iste;
> +    MemTxResult res;
> +
> +    if (!FIELD_EX64(cs->irs_ist_baser[domain], IRS_IST_BASER, VALID) ||
> +        !cfg->structure) {
> +        /* WI if no IST set up or it is not 2-level */
> +        return;
> +    }
> +
> +    /* Find the relevant L1 ISTE and set its VALID bit */
> +    l1_addr = l1_iste_addr(cs, cfg, intid);
> +
> +    l1_iste = address_space_ldq_le(&cs->dma_as, l1_addr, cfg->txattrs, &res);
> +    if (res != MEMTX_OK) {
> +        goto txfail;
> +    }
> +
> +    l1_iste = FIELD_DP64(l1_iste, L1_ISTE, VALID, 1);
> +
> +    address_space_stq_le(&cs->dma_as, l1_addr, l1_iste, cfg->txattrs, &res);
> +    if (res != MEMTX_OK) {
> +        goto txfail;
> +    }
> +    return;
> +
> +txfail:
> +    /* Reportable with EC=0x0 if sw error reporting implemented */
> +    qemu_log_mask(LOG_GUEST_ERROR, "L1 ISTE update failed for ID 0x%x at "
> +                  "physical address 0x" HWADDR_FMT_plx "\n", intid, l1_addr);
> +}
> +

I think other code is all one blank line between functions.  Guessing no
particular reason for 2 here?

> +
>  static void irs_ist_baser_write(GICv5 *s, GICv5Domain domain, uint64_t value)
>  {
>      GICv5Common *cs = ARM_GICV5_COMMON(s);
> @@ -675,6 +713,9 @@ static bool config_writel(GICv5 *s, GICv5Domain domain, hwaddr offset,
>              cs->irs_ist_cfgr[domain] = data;
>          }
>          return true;
> +    case A_IRS_MAP_L2_ISTR:
> +        irs_map_l2_istr_write(s, domain, data);
> +        return true;
>      }
>      return false;
>  }
Re: [PATCH 19/65] hw/intc/arm_gicv5: Implement IRS_MAP_L2_ISTR
Posted by Peter Maydell 1 month ago
On Fri, 6 Mar 2026 at 18:10, Jonathan Cameron
<jonathan.cameron@huawei.com> wrote:
>
> On Mon, 23 Feb 2026 17:01:26 +0000
> Peter Maydell <peter.maydell@linaro.org> wrote:
>
> > The IRS register IRS_MAP_L2_ISTR is used by software to tell the IRS
> > that it has updated the address in an L1 IST entry to point to an
> > L2 IST. The sequence of events here is:
> >  * software writes to L1_ISTE.L2_ADDR for some L1 ISTE which is
> >    not valid (i.e. where L1_ISTE.VALID is 0); it leaves VALID at 0
> >  * software writes to IRS_MAP_L2_ISTR with some INTID that is inside
> >    the range for this L1 ISTE
> >  * the IRS sets IRS_IST_STATUSR.IDLE to 0
> >  * the IRS takes note of this information
> >  * the IRS writes to the L1_ISTE to set VALID=1
> >  * the IRS sets IRS_IST_STATUSR.IDLE to 1 to indicate that the
> >    update is complete
> >
> > For QEMU, we're strictly synchronous, so (as with IRS_IST_BASER
> > updates) we don't need to model the IDLE transitions and can have
> > IRS_IST_STATUSR always return IDLE=1.  We also don't currently cache
> > anything for ISTE lookups, so we don't need to invalidate or update
> > anything when software makes the L2 valid.
> >
> > Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> One trivial thing inline.
>
> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>

> I think other code is all one blank line between functions.  Guessing no
> particular reason for 2 here?

No, no reason. This kind of thing usually creeps in during rebasing
or shuffling around of pieces between patches and I don't always
spot it.

thanks
-- PMM