Commit c7c0a4c5d77c58efd048b34498110972bdac43ce

Authored by Hou Zhiqiang
Committed by Priyanka Jain
1 parent 28121af8c1

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
loading 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>

Showing 1 changed file with 11 additions and 1 deletions Side-by-side Diff

arch/arm/lib/gic-v3-its.c
... ... @@ -3,6 +3,7 @@
3 3 * Copyright 2019 Broadcom.
4 4 */
5 5 #include <common.h>
  6 +#include <cpu_func.h>
6 7 #include <asm/gic.h>
7 8 #include <asm/gic-v3.h>
8 9 #include <asm/io.h>
... ... @@ -28,6 +29,8 @@
28 29 int i;
29 30 u64 redist_lpi_base;
30 31 u64 pend_base = GICR_BASE + GICR_PENDBASER;
  32 + ulong pend_tab_total_sz;
  33 + void *pend_tab_va;
31 34  
32 35 gicd_typer = readl(GICD_BASE + GICD_TYPER);
33 36  
34 37  
... ... @@ -76,12 +79,19 @@
76 79  
77 80 redist_lpi_base = base + LPI_PROPBASE_SZ;
78 81  
  82 + pend_tab_total_sz = num_redist * LPI_PENDBASE_SZ;
  83 + pend_tab_va = map_physmem(redist_lpi_base, pend_tab_total_sz, MAP_NOCACHE);
  84 + memset(pend_tab_va, 0, pend_tab_total_sz);
  85 + flush_cache((ulong)pend_tab_va, pend_tab_total_sz);
  86 + unmap_physmem(pend_tab_va, MAP_NOCACHE);
  87 +
79 88 for (i = 0; i < num_redist; i++) {
80 89 u32 offset = i * GIC_REDISTRIBUTOR_OFFSET;
81 90  
82 91 val = ((redist_lpi_base + (i * LPI_PENDBASE_SZ)) |
83 92 GICR_PENDBASER_INNERSHAREABLE |
84   - GICR_PENDBASER_RAWAWB);
  93 + GICR_PENDBASER_RAWAWB |
  94 + GICR_PENDBASER_PTZ);
85 95  
86 96 writeq(val, (uintptr_t)(pend_base + offset));
87 97 tmp = readq((uintptr_t)(pend_base + offset));