rpi3: Add mem reserve region to DTB if present
authorAntonio Nino Diaz <antonio.ninodiaz@arm.com>
Thu, 18 Oct 2018 23:57:16 +0000 (00:57 +0100)
committerAntonio Nino Diaz <antonio.ninodiaz@arm.com>
Wed, 24 Oct 2018 12:54:41 +0000 (13:54 +0100)
When a device tree blob is present at a known address, instead of, for
example, relying on the user modifying the Linux command line to warn
about the memory reserved for the Trusted Firmware, pass it on the DTB.

The current code deletes the memory reserved for the default bootstrap
of the Raspberry Pi and adds the region used by the Trusted Firmware.

This system replaces the previous one consisting on adding
``memmap=16M$256M`` to the Linux command line. It's also meant to be
used by U-Boot and any other bootloader that understands DTB files.

Change-Id: I13ee528475fb043d6e8d9e9f24228e37ac3ac436
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
docs/plat/rpi3.rst
plat/rpi3/platform.mk
plat/rpi3/rpi3_bl31_setup.c
plat/rpi3/rpi3_common.c

index fbf753b09dd06275d49a14cf90a784b378cb5ca7..db475646b07fc54ec6381feb8783f51a2537752c 100644 (file)
@@ -133,9 +133,12 @@ secure platform!
     0x40000000 +-----------------+
 
 The area between **0x10000000** and **0x11000000** has to be manually protected
-so that the kernel doesn't use it. That is done by adding ``memmap=16M$256M`` to
-the command line passed to the kernel. See the `Setup SD card`_ instructions to
-see how to do it.
+so that the kernel doesn't use it. The current port tries to modify the live DTB
+to add a memreserve region that reserves the previously mentioned area.
+
+If this is not possible, the user may manually add ``memmap=16M$256M`` to the
+command line passed to the kernel in ``cmdline.txt``. See the `Setup SD card`_
+instructions to see how to do it. This system is strongly discouraged.
 
 The last 16 MiB of DRAM can only be accessed by the VideoCore, that has
 different mappings than the Arm cores in which the I/O addresses don't overlap
@@ -384,14 +387,9 @@ untouched). They have been tested with the image available in 2018-03-13.
    bootloader will look for a file called ``armstub8.bin`` and load it at
    address **0x0** instead of a predefined one.
 
-4. Open ``cmdline.txt`` and add ``memmap=16M$256M`` to prevent the kernel from
-   using the memory needed by TF-A. If you want to enable the serial port
-   "Mini UART", make sure that this file also contains
+4. To enable the serial port "Mini UART" in Linux, open ``cmdline.txt`` and add
    ``console=serial0,115200 console=tty1``.
 
-   Note that the 16 MiB reserved this way won't be available for Linux, the same
-   way as the memory reserved in DRAM for the GPU isn't available.
-
 5. Open ``config.txt`` and add the following lines at the end (``enable_uart=1``
    is only needed to enable debugging through the Mini UART):
 
index a7b0991fb4d807d5b055ac1abc09a4ed2b0accd0..36c1ee2b41991fc0960dced48898e70b72d132c3 100644 (file)
@@ -4,12 +4,16 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+include lib/libfdt/libfdt.mk
+include lib/xlat_tables_v2/xlat_tables.mk
+
 PLAT_INCLUDES          :=      -Iinclude/common/tbbr                   \
                                -Iplat/rpi3/include
 
 PLAT_BL_COMMON_SOURCES :=      drivers/console/aarch64/console.S       \
                                drivers/ti/uart/aarch64/16550_console.S \
-                               plat/rpi3/rpi3_common.c
+                               plat/rpi3/rpi3_common.c                 \
+                               ${XLAT_TABLES_LIB_SRCS}
 
 BL1_SOURCES            +=      drivers/io/io_fip.c                     \
                                drivers/io/io_memmap.c                  \
@@ -37,12 +41,8 @@ BL31_SOURCES         +=      lib/cpus/aarch64/cortex_a53.S           \
                                plat/rpi3/aarch64/plat_helpers.S        \
                                plat/rpi3/rpi3_bl31_setup.c             \
                                plat/rpi3/rpi3_pm.c                     \
-                               plat/rpi3/rpi3_topology.c
-
-# Translation tables library
-include lib/xlat_tables_v2/xlat_tables.mk
-
-PLAT_BL_COMMON_SOURCES +=      ${XLAT_TABLES_LIB_SRCS}
+                               plat/rpi3/rpi3_topology.c               \
+                               ${LIBFDT_SRCS}
 
 # Tune compiler for Cortex-A53
 ifeq ($(notdir $(CC)),armclang)
index 0ae783e12aa1b438e65cdfa52af72eb8d628f3ca..483d150f0a7c774162e9e4308f14351984f77388 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 #include <bl_common.h>
+#include <libfdt.h>
 #include <platform.h>
 #include <platform_def.h>
 #include <xlat_mmu_helpers.h>
@@ -137,12 +138,74 @@ void bl31_plat_arch_setup(void)
        enable_mmu_el3(0);
 }
 
-void bl31_platform_setup(void)
+/*
+ * Add information to the device tree (if any) about the reserved DRAM used by
+ * the Trusted Firmware.
+ */
+static void rpi3_dtb_add_mem_rsv(void)
 {
+       int i, regions, rc;
+       uint64_t addr, size;
+       void *dtb = (void *)RPI3_PRELOADED_DTB_BASE;
+
+       INFO("rpi3: Checking DTB...\n");
+
+       /* Return if no device tree is detected */
+       if (fdt_check_header(dtb) != 0)
+               return;
+
+       regions = fdt_num_mem_rsv(dtb);
+
+       VERBOSE("rpi3: Found %d mem reserve region(s)\n", regions);
+
+       /* We expect to find one reserved region that we can modify */
+       if (regions < 1)
+               return;
+
+       /*
+        * Look for the region that corresponds to the default boot firmware. It
+        * starts at address 0, and it is not needed when the default firmware
+        * is replaced by this port of the Trusted Firmware.
+        */
+       for (i = 0; i < regions; i++) {
+               if (fdt_get_mem_rsv(dtb, i, &addr, &size) != 0)
+                       continue;
+
+               if (addr != 0x0)
+                       continue;
+
+               VERBOSE("rpi3: Firmware mem reserve region found\n");
+
+               rc = fdt_del_mem_rsv(dtb, i);
+               if (rc != 0) {
+                       INFO("rpi3: Can't remove mem reserve region (%d)\n", rc);
+               }
+
+               break;
+       }
+
+       if (i == regions) {
+               VERBOSE("rpi3: Firmware mem reserve region not found\n");
+       }
+
        /*
-        * Do initial security configuration to allow DRAM/device access
-        * (if earlier BL has not already done so).
+        * Reserve all SRAM. As said in the documentation, this isn't actually
+        * secure memory, so it is needed to tell BL33 that this is a reserved
+        * memory region. It doesn't guarantee it won't use it, though.
         */
+       rc = fdt_add_mem_rsv(dtb, SEC_SRAM_BASE, SEC_SRAM_SIZE);
+       if (rc != 0) {
+               WARN("rpi3: Can't add mem reserve region (%d)\n", rc);
+       }
+
+       INFO("rpi3: Reserved 0x%llx - 0x%llx in DTB\n", SEC_SRAM_BASE,
+            SEC_SRAM_BASE + SEC_SRAM_SIZE);
+}
 
-       return;
+void bl31_platform_setup(void)
+{
+#ifdef RPI3_PRELOADED_DTB_BASE
+       /* Only modify a DTB if we know where to look for it */
+       rpi3_dtb_add_mem_rsv();
+#endif
 }
index 98cf534c73766bb068c07b1800108ce4da1cbdd8..18ff1c82ebe7f7d9777d5dc9732c679157afda7f 100644 (file)
 
 #define MAP_SHARED_RAM MAP_REGION_FLAT(SHARED_RAM_BASE,                \
                                        SHARED_RAM_SIZE,                \
-                                       MT_DEVICE  | MT_RW | MT_SECURE)
+                                       MT_DEVICE | MT_RW | MT_SECURE)
+
+#ifdef RPI3_PRELOADED_DTB_BASE
+#define MAP_NS_DTB     MAP_REGION_FLAT(RPI3_PRELOADED_DTB_BASE, 0x10000, \
+                                       MT_MEMORY | MT_RW | MT_NS)
+#endif
 
 #define MAP_NS_DRAM0   MAP_REGION_FLAT(NS_DRAM0_BASE, NS_DRAM0_SIZE,   \
                                        MT_MEMORY | MT_RW | MT_NS)
@@ -74,6 +79,9 @@ static const mmap_region_t plat_rpi3_mmap[] = {
 static const mmap_region_t plat_rpi3_mmap[] = {
        MAP_SHARED_RAM,
        MAP_DEVICE0,
+#ifdef RPI3_PRELOADED_DTB_BASE
+       MAP_NS_DTB,
+#endif
 #ifdef BL32_BASE
        MAP_BL32_MEM,
 #endif