summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatryk Biel <[email protected]>2026-07-14 11:49:14 +0200
committerPeng Fan <[email protected]>2026-08-11 16:05:24 +0800
commit5a32ebc96295795a7325d6cbaa2d8b0bdfaa6d75 (patch)
treea82ee8c97c25b81166c55fb08d7dc0d639647a43
parent9f82dcd489246c66eb780235d1fedb536771c787 (diff)
armv8: layerscape: Fix TF-A DRAM reservation with empty banks
The TF-A DRAM bank setup currently assumes that the number of banks reported by TF-A matches the number of entries available in gd->bd->bi_dram[]. Limit the loop by CONFIG_NR_DRAM_BANKS so that a platform with fewer configured DRAM banks does not write past the array. The reserved RAM setup also checks higher DRAM banks before falling back to bank 0. When a higher bank is empty and board_reserve_ram_top() returns 0, the old test succeeds for a zero-sized bank. This can set gd->arch.resv_ram to 0. On systems with CONFIG_GIC_V3_ITS this value is later used by ls_gic_rd_tables_init() to place the GIC LPI tables: gd->arch.resv_ram - GIC_LPI_SIZE If gd->arch.resv_ram is 0, the subtraction underflows and the GIC LPI tables are placed at an invalid high address. Skip empty banks when selecting the reserved RAM area and fail GIC LPI table setup if no reserved RAM address was established. This fixes LS1028A systems with 2 GiB of RAM, where TF-A reports only one populated DRAM bank. Tested on an LS1028ARDB with TF-A modified to report 2 GiB of RAM, and on a custom LS1028A-based board equipped with 2 GiB of RAM. Signed-off-by: Patryk Biel <[email protected]> Signed-off-by: Peng Fan <[email protected]>
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/cpu.c33
-rw-r--r--arch/arm/cpu/armv8/fsl-layerscape/soc.c5
2 files changed, 27 insertions, 11 deletions
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
index 88adcf35432..37687a96600 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/cpu.c
@@ -1402,32 +1402,43 @@ static int tfa_dram_init_banksize(void)
dram_size -= gd->dram[i].size;
i++;
- } while (dram_size);
+ } while (dram_size && i < CONFIG_NR_DRAM_BANKS);
+
+ if (dram_size)
+ printf("Warning: CONFIG_NR_DRAM_BANKS is too small, %llx bytes left unassigned\n",
+ dram_size);
if (i > 0)
ret = 0;
#if defined(CONFIG_RESV_RAM) && !defined(CONFIG_XPL_BUILD)
/* Assign memory for MC */
-#ifdef CONFIG_SYS_DDR_BLOCK3_BASE
- if (gd->dram[2].size >=
+#if defined(CONFIG_SYS_DDR_BLOCK3_BASE) && (CONFIG_NR_DRAM_BANKS >= 3)
+ if (gd->dram[2].size &&
+ gd->dram[2].size >=
board_reserve_ram_top(gd->dram[2].size)) {
gd->arch.resv_ram = gd->dram[2].start +
- gd->dram[2].size -
- board_reserve_ram_top(gd->dram[2].size);
+ gd->dram[2].size -
+ board_reserve_ram_top(gd->dram[2].size);
} else
#endif
{
- if (gd->dram[1].size >=
+#if defined(CFG_SYS_DDR_BLOCK2_BASE) && (CONFIG_NR_DRAM_BANKS >= 2)
+ if (gd->dram[1].size &&
+ gd->dram[1].size >=
board_reserve_ram_top(gd->dram[1].size)) {
gd->arch.resv_ram = gd->dram[1].start +
gd->dram[1].size -
board_reserve_ram_top(gd->dram[1].size);
- } else if (gd->dram[0].size >
- board_reserve_ram_top(gd->dram[0].size)) {
- gd->arch.resv_ram = gd->dram[0].start +
- gd->dram[0].size -
- board_reserve_ram_top(gd->dram[0].size);
+ } else
+#endif
+ {
+ if (gd->dram[0].size >
+ board_reserve_ram_top(gd->dram[0].size)) {
+ gd->arch.resv_ram = gd->dram[0].start +
+ gd->dram[0].size -
+ board_reserve_ram_top(gd->dram[0].size);
+ }
}
}
#endif /* CONFIG_RESV_RAM */
diff --git a/arch/arm/cpu/armv8/fsl-layerscape/soc.c b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
index d85a630f8a3..24ccb8bb0c4 100644
--- a/arch/arm/cpu/armv8/fsl-layerscape/soc.c
+++ b/arch/arm/cpu/armv8/fsl-layerscape/soc.c
@@ -65,6 +65,11 @@ int ls_gic_rd_tables_init(void *blob)
u64 gic_lpi_base;
int ret;
+ if (!gd->arch.resv_ram) {
+ debug("%s: failed to reserve memory for gic-lpi-tables\n", __func__);
+ return -ENOMEM;
+ }
+
gic_lpi_base = ALIGN(gd->arch.resv_ram - GIC_LPI_SIZE, SZ_64K);
ret = fdt_add_resv_mem_gic_rd_tables(blob, gic_lpi_base, GIC_LPI_SIZE);
if (ret)