fix(rpi4): drop /memreserve/ region

Most DTBs used on the RaspberryPi contain a FDT /memreserve/ region,
that covers the original secondaries' spin table.
We need to reserve more memory than described there, to cover the whole
of the TF-A image, so we add a /reserved-memory node to the DTB.

However having the same memory region described by both methods upsets
the Linux kernel and U-Boot, so we have to make sure there is only one
instance describing this reserved memory.

Keep our currently used /reserved-memory node, since it's more capable
(it allows to mark the region as secure memory). Add some code to drop
the original /memreserve/ region, since we don't need this anymore,
because we take the secondaries out of their original spin loop.

We explicitly check for the currently used size of 4KB for this region,
to be alerted by any changes to this region in the upstream DTB.

Change-Id: Ia3105560deb3f939e026f6ed715a9bbe68b56230
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
Andre Przywara 2021-04-19 17:25:53 +01:00
parent be3a51ce18
commit 5d2793a61a
1 changed files with 43 additions and 1 deletions

View File

@ -201,6 +201,44 @@ void bl31_plat_arch_setup(void)
enable_mmu_el3(0);
}
/*
* Remove the FDT /memreserve/ entry that covers the region at the very
* beginning of memory (if that exists). This is where the secondaries
* originally spin, but we pull them out there.
* Having overlapping /reserved-memory and /memreserve/ regions confuses
* the Linux kernel, so we need to get rid of this one.
*/
static void remove_spintable_memreserve(void *dtb)
{
uint64_t addr, size;
int regions = fdt_num_mem_rsv(dtb);
int i;
for (i = 0; i < regions; i++) {
if (fdt_get_mem_rsv(dtb, i, &addr, &size) != 0) {
return;
}
if (size == 0U) {
return;
}
/* We only look for the region at the beginning of DRAM. */
if (addr != 0U) {
continue;
}
/*
* Currently the region in the existing DTs is exactly 4K
* in size. Should this value ever change, there is probably
* a reason for that, so inform the user about this.
*/
if (size == 4096U) {
fdt_del_mem_rsv(dtb, i);
return;
}
WARN("Keeping unknown /memreserve/ region at 0, size: %lld\n",
size);
}
}
static void rpi4_prepare_dtb(void)
{
void *dtb = (void *)rpi4_get_dtb_address();
@ -227,7 +265,11 @@ static void rpi4_prepare_dtb(void)
return;
}
/* Reserve memory used by Trusted Firmware. */
/*
* Remove the original reserved region (used for the spintable), and
* replace it with a region describing the whole of Trusted Firmware.
*/
remove_spintable_memreserve(dtb);
if (fdt_add_reserved_memory(dtb, "atf@0", 0, 0x80000))
WARN("Failed to add reserved memory nodes to DT.\n");