summaryrefslogtreecommitdiff
path: root/arch/arm/lib
diff options
context:
space:
mode:
authorHou Zhiqiang <Zhiqiang.Hou@nxp.com>2021-03-05 10:02:35 +0300
committerTom Rini <trini@konsulko.com>2021-04-20 14:31:12 +0300
commit6f6876a0c0304acc117d075344275d716f8a935a (patch)
tree2b4ed6d1b9abcc3f22ee9a6d622d5688d4a7a493 /arch/arm/lib
parent612729b178d25b34199e169e8e24689d4fd4a820 (diff)
downloadu-boot-6f6876a0c0304acc117d075344275d716f8a935a.tar.xz
arm64: gic-v3-its: Clear the Pending table before enabling LPIs
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@nxp.com> Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com> # NXP LS1028A Reviewed-by: Wasim Khan <wasim.khan@nxp.com> Reviewed-by: Priyanka Jain <priyanka.jain@nxp.com>
Diffstat (limited to 'arch/arm/lib')
-rw-r--r--arch/arm/lib/gic-v3-its.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/arch/arm/lib/gic-v3-its.c b/arch/arm/lib/gic-v3-its.c
index f5a921b3d1..2d3fdb600e 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;
@@ -161,6 +164,12 @@ int gic_lpi_tables_init(void)
}
redist_lpi_base = priv.lpi_base + LPI_PROPBASE_SZ;
+ 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);
+ unmap_physmem(pend_tab_va, MAP_NOCACHE);
pend_base = priv.gicr_base + GICR_PENDBASER;
for (i = 0; i < priv.num_redist; i++) {
@@ -168,7 +177,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));