aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2021-04-19 17:25:53 +0100
committerAndre Przywara <andre.przywara@arm.com>2021-08-16 17:29:59 +0100
commit5d2793a61aded9602af86e90a571f64ff07f93b3 (patch)
tree2ea78bafbedc7ababb906a3e38657adb9168c389
parentbe3a51ce18499947b13b847a31552f52359375eb (diff)
downloadarm-trusted-firmware-5d2793a61aded9602af86e90a571f64ff07f93b3.tar.gz
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>
-rw-r--r--plat/rpi/rpi4/rpi4_bl31_setup.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c
index cfacd1fe1..525985913 100644
--- a/plat/rpi/rpi4/rpi4_bl31_setup.c
+++ b/plat/rpi/rpi4/rpi4_bl31_setup.c
@@ -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");