[PATCHv2] arm64: gic-v3-its: Clear the Pending table before enabling LPIs

Laurentiu Tudor laurentiu.tudor at nxp.com
Fri Mar 5 06:49:06 CET 2021


Hi Zhiqiang,

On 3/5/2021 4:21 AM, Zhiqiang Hou wrote:
> From: Hou Zhiqiang <Zhiqiang.Hou at nxp.com>
> 
> The GICv3 RM requires "The first 1KB of memory for the LPI Pending tables
> must contain only zeros on initial allocation, and this must be visible
> to the Redistributors, or else the effect is UNPREDICTABLE".
> 
> And as the following statement, we here clear the whole Pending tables
> instead of the first 1KB.
> "An LPI Pending table that contains only zeros, including in the first 1KB,
> indicates that there are no pending LPIs.
> The first 1KB of the LPI Pending table is IMPLEMENTATION DEFINED. However,
> if the first 1KB of the LPI Pending table and the rest of the table contain
> only zeros, this must indicate that there are no pending LPIs."
> 
> And there isn't any pending LPI under U-Boot, so it's unnecessary to
> load the contents of the Pending table during the enablement, then set
> the GICR_PENDBASER.PTZ flag.
> 
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou at nxp.com>
> ---
> V2:
>  - Clear the Pending tables using virtual address.
>  - Correct some typos in the change log.
> 
>  arch/arm/lib/gic-v3-its.c | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/lib/gic-v3-its.c b/arch/arm/lib/gic-v3-its.c
> index f5a921b3d1..2dadc48a50 100644
> --- a/arch/arm/lib/gic-v3-its.c
> +++ b/arch/arm/lib/gic-v3-its.c
> @@ -3,6 +3,7 @@
>   * Copyright 2019 Broadcom.
>   */
>  #include <common.h>
> +#include <cpu_func.h>
>  #include <dm.h>
>  #include <regmap.h>
>  #include <syscon.h>
> @@ -108,6 +109,8 @@ int gic_lpi_tables_init(void)
>  	int i;
>  	u64 redist_lpi_base;
>  	u64 pend_base;
> +	ulong pend_tab_total_sz;
> +	void *pend_tab_va;
>  
>  	if (gic_v3_its_get_gic_addr(&priv))
>  		return -EINVAL;
> @@ -160,7 +163,12 @@ int gic_lpi_tables_init(void)
>  		}
>  	}
>  
> -	redist_lpi_base = priv.lpi_base + LPI_PROPBASE_SZ;

I don't think you want to drop this.

> +	pend_tab_total_sz = priv.num_redist * LPI_PENDBASE_SZ;
> +	pend_tab_va = map_physmem(redist_lpi_base, pend_tab_total_sz,
> +				  MAP_NOCACHE);
> +	memset(pend_tab_va, 0, pend_tab_total_sz);
> +	flush_cache((ulong)pend_tab_va, pend_tab_total_sz);

Given that the memory is mapped as non-cacheable, is this flush necessary?

---
Best Regards, Laurentiu

> +	unmap_physmem(pend_tab_va, MAP_NOCACHE);
>  
>  	pend_base = priv.gicr_base + GICR_PENDBASER;
>  	for (i = 0; i < priv.num_redist; i++) {
> @@ -168,7 +176,8 @@ int gic_lpi_tables_init(void)
>  
>  		val = ((redist_lpi_base + (i * LPI_PENDBASE_SZ)) |
>  			GICR_PENDBASER_INNERSHAREABLE |
> -			GICR_PENDBASER_RAWAWB);
> +			GICR_PENDBASER_RAWAWB |
> +			GICR_PENDBASER_PTZ);
>  
>  		writeq(val, (uintptr_t)(pend_base + offset));
>  		tmp = readq((uintptr_t)(pend_base + offset));
> 


More information about the U-Boot mailing list