Browse Source

Merge changes Id72a0370,I2bafba38,I2bd48441,I164c579c,Iddf8aea0, ... into integration

* changes:
  feat(rpi): add Raspberry Pi 5 support
  fix(rpi): consider MT when calculating core index from MPIDR
  refactor(rpi): move register definitions out of rpi_hw.h
  refactor(rpi): add platform macro for the crash UART base address
  refactor(rpi): split out console registration logic
  refactor(rpi): move more platform-specific code into common
André Przywara 1 month ago
parent
commit
5318255f12

+ 3 - 0
changelog.yaml

@@ -544,6 +544,9 @@ subsections:
           - title: Raspberry Pi 4
             scope: rpi4
 
+          - title: Raspberry Pi 5
+            scope: rpi5
+
       - title: Renesas
         scope: renesas
 

+ 1 - 0
docs/plat/index.rst

@@ -38,6 +38,7 @@ Platform Ports
    qti-msm8916
    rpi3
    rpi4
+   rpi5
    rcar-gen3
    rz-g2
    rockchip

+ 78 - 0
docs/plat/rpi5.rst

@@ -0,0 +1,78 @@
+Raspberry Pi 5
+==============
+
+The `Raspberry Pi 5`_ is a single-board computer that contains four
+Arm Cortex-A76 cores.
+
+This port is a minimal BL31 implementation capable of booting 64-bit EL2
+payloads such as Linux and EDK2.
+
+**IMPORTANT NOTE**: This port isn't secure. All of the memory used is DRAM,
+which is available from both the Non-secure and Secure worlds. The SoC does
+not seem to feature a secure memory controller of any kind, so portions of
+DRAM can't be protected properly from the Non-secure world.
+
+Build
+------------------
+
+To build this platform, run:
+
+.. code:: shell
+
+    CROSS_COMPILE=aarch64-linux-gnu- make PLAT=rpi5 DEBUG=1
+
+The firmware will be generated at ``build/rpi5/debug/bl31.bin``.
+
+The following build options are supported:
+
+- ``RPI3_DIRECT_LINUX_BOOT``: Enabled by default. Allows direct boot of the Linux
+  kernel from the firmware.
+
+- ``PRELOADED_BL33_BASE``: Used to specify the fixed address of a BL33 binary
+  that has been preloaded by earlier boot stages (VPU). Useful for bundling
+  BL31 and BL33 in the same ``armstub`` image (e.g. TF-A + EDK2).
+
+- ``RPI3_PRELOADED_DTB_BASE``: This option allows to specify the fixed address of
+  a DTB in memory. Can only be used if ``device_tree_address=`` is present in
+  config.txt.
+
+- ``RPI3_RUNTIME_UART``: Indicates whether TF-A should use the debug UART for
+  runtime messages or not. ``-1`` (default) disables the option, any other value
+  enables it.
+
+Usage
+------------------
+
+Copy the firmware binary to the first FAT32 partition of a supported boot media
+(SD, USB) and append ``armstub=bl31.bin`` to config.txt, or just rename the
+file to ``armstub8-2712.bin``.
+
+No other config options or files are required by the firmware alone, this will
+depend on the payload you intend to run.
+
+For Linux, you must also place an appropriate DTB and kernel in the boot
+partition. This has been validated with a copy of Raspberry Pi OS.
+
+The VPU will preload a BL33 AArch64 image named either ``kernel_2712.img`` or
+``kernel8.img``, which can be overridden by adding a ``kernel=filename`` option
+to config.txt.
+
+Kernel and DTB load addresses are also chosen by the VPU and can be changed with
+``kernel_address=`` and ``device_tree_address=`` in config.txt. If TF-A was built
+with ``PRELOADED_BL33_BASE`` or ``RPI3_PRELOADED_DTB_BASE``, setting those config
+options may be necessary.
+
+By default, all boot stages print messages to the dedicated UART debug port.
+Configuration is ``115200 8n1``.
+
+Design
+------------------
+
+This port is largely based on the RPi 4 one.
+
+The boot process is essentially the same, the only notable difference being that
+all VPU blobs have been moved into EEPROM (former start4.elf & fixup4.dat). There's
+also a custom BL31 TF-A armstub included for PSCI, which can be replaced with this
+port.
+
+.. _Raspberry Pi 5: https://www.raspberrypi.com/products/raspberry-pi-5/

+ 14 - 1
drivers/rpi3/rng/rpi3_rng.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,6 +11,19 @@
 
 #include <rpi_hw.h>
 
+#define RPI3_RNG_CTRL_OFFSET		ULL(0x00000000)
+#define RPI3_RNG_STATUS_OFFSET		ULL(0x00000004)
+#define RPI3_RNG_DATA_OFFSET		ULL(0x00000008)
+#define RPI3_RNG_INT_MASK_OFFSET	ULL(0x00000010)
+/* Enable/disable RNG */
+#define RPI3_RNG_CTRL_ENABLE		U(0x1)
+#define RPI3_RNG_CTRL_DISABLE		U(0x0)
+/* Number of currently available words */
+#define RPI3_RNG_STATUS_NUM_WORDS_SHIFT	U(24)
+#define RPI3_RNG_STATUS_NUM_WORDS_MASK	U(0xFF)
+/* Value to mask interrupts caused by the RNG */
+#define RPI3_RNG_INT_MASK_DISABLE	U(0x1)
+
 /* Initial amount of values to discard */
 #define RNG_WARMUP_COUNT	U(0x40000)
 

+ 17 - 1
include/drivers/rpi3/mailbox/rpi3_mbox.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -16,6 +16,22 @@ typedef struct __packed __aligned(16) rpi3_mbox_request {
 	uint32_t	tags[0];
 } rpi3_mbox_request_t;
 
+/* VideoCore -> ARM */
+#define RPI3_MBOX0_READ_OFFSET		ULL(0x00000000)
+#define RPI3_MBOX0_PEEK_OFFSET		ULL(0x00000010)
+#define RPI3_MBOX0_SENDER_OFFSET	ULL(0x00000014)
+#define RPI3_MBOX0_STATUS_OFFSET	ULL(0x00000018)
+#define RPI3_MBOX0_CONFIG_OFFSET	ULL(0x0000001C)
+/* ARM -> VideoCore */
+#define RPI3_MBOX1_WRITE_OFFSET		ULL(0x00000020)
+#define RPI3_MBOX1_PEEK_OFFSET		ULL(0x00000030)
+#define RPI3_MBOX1_SENDER_OFFSET	ULL(0x00000034)
+#define RPI3_MBOX1_STATUS_OFFSET	ULL(0x00000038)
+#define RPI3_MBOX1_CONFIG_OFFSET	ULL(0x0000003C)
+/* Mailbox status constants */
+#define RPI3_MBOX_STATUS_FULL_MASK	U(0x80000000) /* Set if full */
+#define RPI3_MBOX_STATUS_EMPTY_MASK	U(0x40000000) /* Set if empty */
+
 #define RPI3_MBOX_BUFFER_SIZE		U(256)
 
 /* Constants to perform a request/check the status of a request. */

+ 1 - 1
plat/rpi/rpi4/aarch64/armstub8_header.S → plat/rpi/common/aarch64/armstub8_header.S

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */

+ 27 - 4
plat/rpi/common/aarch64/plat_helpers.S

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,10 +27,19 @@
 	 *
 	 *  This function uses the plat_rpi3_calc_core_pos()
 	 *  definition to get the index of the calling CPU.
+	 *
+	 *  When MT is set, lowest affinity represents the thread ID.
+	 *  Since we only support one thread per core, discard this field
+	 *  so cluster and core IDs go back into Aff1 and Aff0 respectively.
+	 *  The upper bits are also affected, but plat_rpi3_calc_core_pos()
+	 *  does not use them.
 	 * -----------------------------------------------------
 	 */
 func plat_my_core_pos
 	mrs	x0, mpidr_el1
+	tst	x0, #MPIDR_MT_MASK
+	lsr	x1, x0, #MPIDR_AFFINITY_BITS
+	csel	x0, x1, x0, ne
 	b	plat_rpi3_calc_core_pos
 endfunc plat_my_core_pos
 
@@ -164,10 +173,16 @@ endfunc platform_mem_init
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_init
-	mov_imm	x0, PLAT_RPI_MINI_UART_BASE
+	mov_imm	x0, PLAT_RPI_CRASH_UART_BASE
+#if PLAT_RPI_CRASH_UART_BASE == PLAT_RPI_PL011_UART_BASE
+	mov_imm	x1, RPI4_PL011_UART_CLOCK
+	mov_imm	x2, PLAT_RPI_UART_BAUDRATE
+	b	console_pl011_core_init
+#else
 	mov	x1, xzr
 	mov	x2, xzr
 	b	console_16550_core_init
+#endif
 endfunc plat_crash_console_init
 
 	/* ---------------------------------------------
@@ -178,8 +193,12 @@ endfunc plat_crash_console_init
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_putc
-	mov_imm	x1, PLAT_RPI_MINI_UART_BASE
+	mov_imm	x1, PLAT_RPI_CRASH_UART_BASE
+#if PLAT_RPI_CRASH_UART_BASE == PLAT_RPI_PL011_UART_BASE
+	b	console_pl011_core_putc
+#else
 	b	console_16550_core_putc
+#endif
 endfunc plat_crash_console_putc
 
 	/* ---------------------------------------------
@@ -191,8 +210,12 @@ endfunc plat_crash_console_putc
 	 * ---------------------------------------------
 	 */
 func plat_crash_console_flush
-	mov_imm	x0, PLAT_RPI_MINI_UART_BASE
+	mov_imm	x0, PLAT_RPI_CRASH_UART_BASE
+#if PLAT_RPI_CRASH_UART_BASE == PLAT_RPI_PL011_UART_BASE
+	b	console_pl011_core_flush
+#else
 	b	console_16550_core_flush
+#endif
 endfunc plat_crash_console_flush
 
 	/* ---------------------------------------------

+ 1 - 1
plat/rpi/rpi3/include/plat_macros.S → plat/rpi/common/include/plat_macros.S

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */

+ 16 - 2
plat/rpi/common/include/rpi_shared.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,14 +7,20 @@
 #ifndef RPI_SHARED_H
 #define RPI_SHARED_H
 
+#include <stddef.h>
 #include <stdint.h>
 
+#include <drivers/console.h>
+
 /*******************************************************************************
  * Function and variable prototypes
  ******************************************************************************/
 
-/* Utility functions */
+/* Serial console functions */
 void rpi3_console_init(void);
+int rpi3_register_used_uart(console_t *console);
+
+/* Utility functions */
 void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size,
 			    uintptr_t code_start, uintptr_t code_limit,
 			    uintptr_t rodata_start, uintptr_t rodata_limit
@@ -23,6 +29,8 @@ void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size,
 #endif
 			    );
 
+uintptr_t rpi4_get_dtb_address(void);
+
 /* Optional functions required in the Raspberry Pi 3 port */
 unsigned int plat_rpi3_calc_core_pos(u_register_t mpidr);
 
@@ -38,4 +46,10 @@ int rpi3_vc_hardware_get_board_revision(uint32_t *revision);
 
 int plat_rpi_get_model(void);
 
+/*******************************************************************************
+ * Platform implemented functions
+ ******************************************************************************/
+
+void plat_rpi_bl31_custom_setup(void);
+
 #endif /* RPI3_PRIVATE_H */

+ 2 - 22
plat/rpi/common/rpi3_common.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,9 +13,6 @@
 #include <common/debug.h>
 #include <bl31/interrupt_mgmt.h>
 #include <drivers/console.h>
-#include <drivers/rpi3/gpio/rpi3_gpio.h>
-#include <drivers/ti/uart/uart_16550.h>
-#include <drivers/arm/pl011.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 
 #include <rpi_hw.h>
@@ -106,12 +103,6 @@ static const mmap_region_t plat_rpi3_mmap[] = {
  ******************************************************************************/
 static console_t rpi3_console;
 
-
-static bool rpi3_use_mini_uart(void)
-{
-	return rpi3_gpio_get_select(14) == RPI3_GPIO_FUNC_ALT5;
-}
-
 void rpi3_console_init(void)
 {
 	int console_scope = CONSOLE_FLAG_BOOT;
@@ -120,18 +111,7 @@ void rpi3_console_init(void)
 	if (RPI3_RUNTIME_UART != -1)
 		console_scope |= CONSOLE_FLAG_RUNTIME;
 
-	rpi3_gpio_init();
-
-	if (rpi3_use_mini_uart())
-		rc = console_16550_register(PLAT_RPI_MINI_UART_BASE,
-					    0,
-					    PLAT_RPI_UART_BAUDRATE,
-					    &rpi3_console);
-	else
-		rc = console_pl011_register(PLAT_RPI_PL011_UART_BASE,
-					    PLAT_RPI_PL011_UART_CLOCK,
-					    PLAT_RPI_UART_BAUDRATE,
-					    &rpi3_console);
+	rc = rpi3_register_used_uart(&rpi3_console);
 
 	if (rc == 0) {
 		/*

+ 35 - 0
plat/rpi/common/rpi3_console_dual.c

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/pl011.h>
+#include <drivers/console.h>
+#include <drivers/rpi3/gpio/rpi3_gpio.h>
+#include <drivers/ti/uart/uart_16550.h>
+#include <platform_def.h>
+
+#include <rpi_shared.h>
+
+static bool rpi3_use_mini_uart(void)
+{
+	return rpi3_gpio_get_select(14) == RPI3_GPIO_FUNC_ALT5;
+}
+
+int rpi3_register_used_uart(console_t *console)
+{
+	rpi3_gpio_init();
+
+	if (rpi3_use_mini_uart())
+		return console_16550_register(PLAT_RPI_MINI_UART_BASE,
+					      0,
+					      PLAT_RPI_UART_BAUDRATE,
+					      console);
+	else
+		return console_pl011_register(PLAT_RPI_PL011_UART_BASE,
+					      PLAT_RPI_PL011_UART_CLOCK,
+					      PLAT_RPI_UART_BAUDRATE,
+					      console);
+}

+ 20 - 0
plat/rpi/common/rpi3_console_pl011.c

@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/arm/pl011.h>
+#include <drivers/console.h>
+#include <platform_def.h>
+
+#include <rpi_shared.h>
+
+int rpi3_register_used_uart(console_t *console)
+{
+	return console_pl011_register(PLAT_RPI_PL011_UART_BASE,
+				      PLAT_RPI_PL011_UART_CLOCK,
+				      PLAT_RPI_UART_BAUDRATE,
+				      console);
+}

+ 17 - 1
plat/rpi/common/rpi3_pm.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,6 +21,22 @@
 #include <drivers/arm/gicv2.h>
 #endif
 
+/* Registers on top of RPI3_PM_BASE. */
+#define RPI3_PM_RSTC_OFFSET		ULL(0x0000001C)
+#define RPI3_PM_RSTS_OFFSET		ULL(0x00000020)
+#define RPI3_PM_WDOG_OFFSET		ULL(0x00000024)
+/* Watchdog constants */
+#define RPI3_PM_PASSWORD		U(0x5A000000)
+#define RPI3_PM_RSTC_WRCFG_MASK		U(0x00000030)
+#define RPI3_PM_RSTC_WRCFG_FULL_RESET	U(0x00000020)
+/*
+ * The RSTS register is used by the VideoCore firmware when booting the
+ * Raspberry Pi to know which partition to boot from. The partition value is
+ * formed by bits 0, 2, 4, 6, 8 and 10. Partition 63 is used by said firmware
+ * to indicate halt.
+ */
+#define RPI3_PM_RSTS_WRCFG_HALT		U(0x00000555)
+
 /* Make composite power state parameter till power level 0 */
 #if PSCI_EXTENDED_STATE_ID
 

+ 18 - 3
plat/rpi/common/rpi3_topology.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -39,12 +39,27 @@ int plat_core_pos_by_mpidr(u_register_t mpidr)
 	unsigned int cluster_id, cpu_id;
 
 	mpidr &= MPIDR_AFFINITY_MASK;
+
+	/*
+	 * When MT is set, lowest affinity represents the thread ID.
+	 * Since we only support one thread per core, discard this field
+	 * so cluster and core IDs go back into Aff1 and Aff0 respectively.
+	 * The upper bits are also affected, but plat_rpi3_calc_core_pos()
+	 * does not use them.
+	 */
+	if ((read_mpidr() & MPIDR_MT_MASK) != 0) {
+		if (MPIDR_AFFLVL0_VAL(mpidr) != 0) {
+			return -1;
+		}
+		mpidr >>= MPIDR_AFFINITY_BITS;
+	}
+
 	if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) {
 		return -1;
 	}
 
-	cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
-	cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+	cluster_id = MPIDR_AFFLVL1_VAL(mpidr);
+	cpu_id = MPIDR_AFFLVL0_VAL(mpidr);
 
 	if (cluster_id >= PLATFORM_CLUSTER_COUNT) {
 		return -1;

+ 8 - 103
plat/rpi/rpi4/rpi4_bl31_setup.c → plat/rpi/common/rpi4_bl31_setup.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,21 +8,15 @@
 #include <inttypes.h>
 #include <stdint.h>
 
-#include <libfdt.h>
-
-#include <platform_def.h>
 #include <arch_helpers.h>
 #include <common/bl_common.h>
+#include <drivers/arm/gicv2.h>
 #include <lib/mmio.h>
 #include <lib/xlat_tables/xlat_mmu_helpers.h>
 #include <lib/xlat_tables/xlat_tables_defs.h>
 #include <lib/xlat_tables/xlat_tables_v2.h>
 #include <plat/common/platform.h>
-#include <common/fdt_fixup.h>
-#include <common/fdt_wrappers.h>
-#include <libfdt.h>
-
-#include <drivers/arm/gicv2.h>
+#include <platform_def.h>
 
 #include <rpi_shared.h>
 
@@ -85,7 +79,7 @@ uintptr_t plat_get_ns_image_entrypoint(void)
 #endif
 }
 
-static uintptr_t rpi4_get_dtb_address(void)
+uintptr_t rpi4_get_dtb_address(void)
 {
 #ifdef RPI3_PRELOADED_DTB_BASE
 	return RPI3_PRELOADED_DTB_BASE;
@@ -151,7 +145,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	 * r1 = machine type number, optional in DT-only platforms (~0 if so)
 	 * r2 = Physical address of the device tree blob
 	 */
-	VERBOSE("rpi4: Preparing to boot 32-bit Linux kernel\n");
+	VERBOSE("rpi: Preparing to boot 32-bit Linux kernel\n");
 	bl33_image_ep_info.args.arg0 = 0U;
 	bl33_image_ep_info.args.arg1 = ~0U;
 	bl33_image_ep_info.args.arg2 = rpi4_get_dtb_address();
@@ -162,7 +156,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
 	 * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
 	 * must be 0.
 	 */
-	VERBOSE("rpi4: Preparing to boot 64-bit Linux kernel\n");
+	VERBOSE("rpi: Preparing to boot 64-bit Linux kernel\n");
 	bl33_image_ep_info.args.arg0 = rpi4_get_dtb_address();
 	bl33_image_ep_info.args.arg1 = 0ULL;
 	bl33_image_ep_info.args.arg2 = 0ULL;
@@ -203,102 +197,13 @@ 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: %" PRId64 "\n",
-		     size);
-	}
-}
-
-static void rpi4_prepare_dtb(void)
-{
-	void *dtb = (void *)rpi4_get_dtb_address();
-	uint32_t gic_int_prop[3];
-	int ret, offs;
-
-	/* Return if no device tree is detected */
-	if (fdt_check_header(dtb) != 0)
-		return;
-
-	ret = fdt_open_into(dtb, dtb, 0x100000);
-	if (ret < 0) {
-		ERROR("Invalid Device Tree at %p: error %d\n", dtb, ret);
-		return;
-	}
-
-	if (dt_add_psci_node(dtb)) {
-		ERROR("Failed to add PSCI Device Tree node\n");
-		return;
-	}
-
-	if (dt_add_psci_cpu_enable_methods(dtb)) {
-		ERROR("Failed to add PSCI cpu enable methods in Device Tree\n");
-		return;
-	}
-
-	/*
-	 * 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");
-
-	offs = fdt_node_offset_by_compatible(dtb, 0, "arm,gic-400");
-	gic_int_prop[0] = cpu_to_fdt32(1);		// PPI
-	gic_int_prop[1] = cpu_to_fdt32(9);		// PPI #9
-	gic_int_prop[2] = cpu_to_fdt32(0x0f04);		// all cores, level high
-	fdt_setprop(dtb, offs, "interrupts", gic_int_prop, 12);
-
-	offs = fdt_path_offset(dtb, "/chosen");
-	fdt_setprop_string(dtb, offs, "stdout-path", "serial0");
-
-	ret = fdt_pack(dtb);
-	if (ret < 0)
-		ERROR("Failed to pack Device Tree at %p: error %d\n", dtb, ret);
-
-	clean_dcache_range((uintptr_t)dtb, fdt_blob_size(dtb));
-	INFO("Changed device tree to advertise PSCI.\n");
-}
-
 void bl31_platform_setup(void)
 {
-	rpi4_prepare_dtb();
-
 	/* Configure the interrupt controller */
 	gicv2_driver_init(&rpi4_gic_data);
 	gicv2_distif_init();
 	gicv2_pcpu_distif_init();
 	gicv2_cpuif_enable();
+
+	plat_rpi_bl31_custom_setup();
 }

+ 2 - 1
plat/rpi/rpi3/include/platform_def.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -254,6 +254,7 @@
 #define PLAT_RPI_PL011_UART_BASE	RPI3_PL011_UART_BASE
 #define PLAT_RPI_PL011_UART_CLOCK	RPI3_PL011_UART_CLOCK
 #define PLAT_RPI_UART_BAUDRATE		ULL(115200)
+#define PLAT_RPI_CRASH_UART_BASE	PLAT_RPI_MINI_UART_BASE
 
 /*
  * System counter

+ 1 - 43
plat/rpi/rpi3/include/rpi_hw.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,60 +21,18 @@
  */
 #define RPI3_MBOX_OFFSET		ULL(0x0000B880)
 #define RPI3_MBOX_BASE			(RPI_IO_BASE + RPI3_MBOX_OFFSET)
-/* VideoCore -> ARM */
-#define RPI3_MBOX0_READ_OFFSET		ULL(0x00000000)
-#define RPI3_MBOX0_PEEK_OFFSET		ULL(0x00000010)
-#define RPI3_MBOX0_SENDER_OFFSET	ULL(0x00000014)
-#define RPI3_MBOX0_STATUS_OFFSET	ULL(0x00000018)
-#define RPI3_MBOX0_CONFIG_OFFSET	ULL(0x0000001C)
-/* ARM -> VideoCore */
-#define RPI3_MBOX1_WRITE_OFFSET		ULL(0x00000020)
-#define RPI3_MBOX1_PEEK_OFFSET		ULL(0x00000030)
-#define RPI3_MBOX1_SENDER_OFFSET	ULL(0x00000034)
-#define RPI3_MBOX1_STATUS_OFFSET	ULL(0x00000038)
-#define RPI3_MBOX1_CONFIG_OFFSET	ULL(0x0000003C)
-/* Mailbox status constants */
-#define RPI3_MBOX_STATUS_FULL_MASK	U(0x80000000) /* Set if full */
-#define RPI3_MBOX_STATUS_EMPTY_MASK	U(0x40000000) /* Set if empty */
 
 /*
  * Power management, reset controller, watchdog.
  */
 #define RPI3_IO_PM_OFFSET		ULL(0x00100000)
 #define RPI3_PM_BASE			(RPI_IO_BASE + RPI3_IO_PM_OFFSET)
-/* Registers on top of RPI3_PM_BASE. */
-#define RPI3_PM_RSTC_OFFSET		ULL(0x0000001C)
-#define RPI3_PM_RSTS_OFFSET		ULL(0x00000020)
-#define RPI3_PM_WDOG_OFFSET		ULL(0x00000024)
-/* Watchdog constants */
-#define RPI3_PM_PASSWORD		U(0x5A000000)
-#define RPI3_PM_RSTC_WRCFG_MASK		U(0x00000030)
-#define RPI3_PM_RSTC_WRCFG_FULL_RESET	U(0x00000020)
-/*
- * The RSTS register is used by the VideoCore firmware when booting the
- * Raspberry Pi to know which partition to boot from. The partition value is
- * formed by bits 0, 2, 4, 6, 8 and 10. Partition 63 is used by said firmware
- * to indicate halt.
- */
-#define RPI3_PM_RSTS_WRCFG_HALT		U(0x00000555)
 
 /*
  * Hardware random number generator.
  */
 #define RPI3_IO_RNG_OFFSET		ULL(0x00104000)
 #define RPI3_RNG_BASE			(RPI_IO_BASE + RPI3_IO_RNG_OFFSET)
-#define RPI3_RNG_CTRL_OFFSET		ULL(0x00000000)
-#define RPI3_RNG_STATUS_OFFSET		ULL(0x00000004)
-#define RPI3_RNG_DATA_OFFSET		ULL(0x00000008)
-#define RPI3_RNG_INT_MASK_OFFSET	ULL(0x00000010)
-/* Enable/disable RNG */
-#define RPI3_RNG_CTRL_ENABLE		U(0x1)
-#define RPI3_RNG_CTRL_DISABLE		U(0x0)
-/* Number of currently available words */
-#define RPI3_RNG_STATUS_NUM_WORDS_SHIFT	U(24)
-#define RPI3_RNG_STATUS_NUM_WORDS_MASK	U(0xFF)
-/* Value to mask interrupts caused by the RNG */
-#define RPI3_RNG_INT_MASK_DISABLE	U(0x1)
 
 /*
  * Serial ports:

+ 1 - 0
plat/rpi/rpi3/platform.mk

@@ -17,6 +17,7 @@ PLAT_BL_COMMON_SOURCES	:=	drivers/ti/uart/aarch64/16550_console.S	\
 				drivers/rpi3/gpio/rpi3_gpio.c		\
 				plat/rpi/common/aarch64/plat_helpers.S	\
 				plat/rpi/common/rpi3_common.c		\
+				plat/rpi/common/rpi3_console_dual.c	\
 				${XLAT_TABLES_LIB_SRCS}
 
 BL1_SOURCES		+=	drivers/io/io_fip.c			\

+ 0 - 20
plat/rpi/rpi4/include/plat_macros.S

@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#ifndef PLAT_MACROS_S
-#define PLAT_MACROS_S
-
-	/* ---------------------------------------------
-	 * The below required platform porting macro
-	 * prints out relevant platform registers
-	 * whenever an unhandled exception is taken in
-	 * BL31.
-	 * Clobbers: x0 - x10, x16, x17, sp
-	 * ---------------------------------------------
-	 */
-	.macro plat_crash_print_regs
-	.endm
-
-#endif /* PLAT_MACROS_S */

+ 2 - 1
plat/rpi/rpi4/include/platform_def.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -131,6 +131,7 @@
 #define PLAT_RPI_PL011_UART_BASE	RPI4_PL011_UART_BASE
 #define PLAT_RPI_PL011_UART_CLOCK       RPI4_PL011_UART_CLOCK
 #define PLAT_RPI_UART_BAUDRATE          ULL(115200)
+#define PLAT_RPI_CRASH_UART_BASE	PLAT_RPI_MINI_UART_BASE
 
 /*
  * System counter

+ 1 - 43
plat/rpi/rpi4/include/rpi_hw.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2021, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -23,60 +23,18 @@
  */
 #define RPI3_MBOX_OFFSET		ULL(0x0000B880)
 #define RPI3_MBOX_BASE			(RPI_LEGACY_BASE + RPI3_MBOX_OFFSET)
-/* VideoCore -> ARM */
-#define RPI3_MBOX0_READ_OFFSET		ULL(0x00000000)
-#define RPI3_MBOX0_PEEK_OFFSET		ULL(0x00000010)
-#define RPI3_MBOX0_SENDER_OFFSET	ULL(0x00000014)
-#define RPI3_MBOX0_STATUS_OFFSET	ULL(0x00000018)
-#define RPI3_MBOX0_CONFIG_OFFSET	ULL(0x0000001C)
-/* ARM -> VideoCore */
-#define RPI3_MBOX1_WRITE_OFFSET		ULL(0x00000020)
-#define RPI3_MBOX1_PEEK_OFFSET		ULL(0x00000030)
-#define RPI3_MBOX1_SENDER_OFFSET	ULL(0x00000034)
-#define RPI3_MBOX1_STATUS_OFFSET	ULL(0x00000038)
-#define RPI3_MBOX1_CONFIG_OFFSET	ULL(0x0000003C)
-/* Mailbox status constants */
-#define RPI3_MBOX_STATUS_FULL_MASK	U(0x80000000) /* Set if full */
-#define RPI3_MBOX_STATUS_EMPTY_MASK	U(0x40000000) /* Set if empty */
 
 /*
  * Power management, reset controller, watchdog.
  */
 #define RPI3_IO_PM_OFFSET		ULL(0x00100000)
 #define RPI3_PM_BASE			(RPI_LEGACY_BASE + RPI3_IO_PM_OFFSET)
-/* Registers on top of RPI3_PM_BASE. */
-#define RPI3_PM_RSTC_OFFSET		ULL(0x0000001C)
-#define RPI3_PM_RSTS_OFFSET		ULL(0x00000020)
-#define RPI3_PM_WDOG_OFFSET		ULL(0x00000024)
-/* Watchdog constants */
-#define RPI3_PM_PASSWORD		U(0x5A000000)
-#define RPI3_PM_RSTC_WRCFG_MASK		U(0x00000030)
-#define RPI3_PM_RSTC_WRCFG_FULL_RESET	U(0x00000020)
-/*
- * The RSTS register is used by the VideoCore firmware when booting the
- * Raspberry Pi to know which partition to boot from. The partition value is
- * formed by bits 0, 2, 4, 6, 8 and 10. Partition 63 is used by said firmware
- * to indicate halt.
- */
-#define RPI3_PM_RSTS_WRCFG_HALT		U(0x00000555)
 
 /*
  * Hardware random number generator.
  */
 #define RPI3_IO_RNG_OFFSET		ULL(0x00104000)
 #define RPI3_RNG_BASE			(RPI_LEGACY_BASE + RPI3_IO_RNG_OFFSET)
-#define RPI3_RNG_CTRL_OFFSET		ULL(0x00000000)
-#define RPI3_RNG_STATUS_OFFSET		ULL(0x00000004)
-#define RPI3_RNG_DATA_OFFSET		ULL(0x00000008)
-#define RPI3_RNG_INT_MASK_OFFSET	ULL(0x00000010)
-/* Enable/disable RNG */
-#define RPI3_RNG_CTRL_ENABLE		U(0x1)
-#define RPI3_RNG_CTRL_DISABLE		U(0x0)
-/* Number of currently available words */
-#define RPI3_RNG_STATUS_NUM_WORDS_SHIFT	U(24)
-#define RPI3_RNG_STATUS_NUM_WORDS_MASK	U(0xFF)
-/* Value to mask interrupts caused by the RNG */
-#define RPI3_RNG_INT_MASK_DISABLE	U(0x1)
 
 /*
  * Serial ports:

+ 4 - 2
plat/rpi/rpi4/platform.mk

@@ -15,16 +15,18 @@ PLAT_INCLUDES		:=	-Iplat/rpi/common/include		\
 PLAT_BL_COMMON_SOURCES	:=	drivers/ti/uart/aarch64/16550_console.S	\
 				drivers/arm/pl011/aarch64/pl011_console.S \
 				plat/rpi/common/rpi3_common.c		\
+				plat/rpi/common/rpi3_console_dual.c	\
 				${XLAT_TABLES_LIB_SRCS}
 
 BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a72.S		\
 				plat/rpi/common/aarch64/plat_helpers.S	\
-				plat/rpi/rpi4/aarch64/armstub8_header.S	\
+				plat/rpi/common/aarch64/armstub8_header.S \
 				drivers/delay_timer/delay_timer.c	\
 				drivers/gpio/gpio.c			\
 				drivers/rpi3/gpio/rpi3_gpio.c		\
 				plat/common/plat_gicv2.c                \
-				plat/rpi/rpi4/rpi4_bl31_setup.c		\
+				plat/rpi/common/rpi4_bl31_setup.c	\
+				plat/rpi/rpi4/rpi4_setup.c		\
 				plat/rpi/common/rpi3_pm.c		\
 				plat/common/plat_psci_common.c		\
 				plat/rpi/common/rpi3_topology.c		\

+ 109 - 0
plat/rpi/rpi4/rpi4_setup.c

@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdint.h>
+
+#include <arch_helpers.h>
+#include <common/fdt_fixup.h>
+#include <common/fdt_wrappers.h>
+
+#include <rpi_shared.h>
+
+/*
+ * 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: %" PRId64 "\n",
+		     size);
+	}
+}
+
+static void rpi4_prepare_dtb(void)
+{
+	void *dtb = (void *)rpi4_get_dtb_address();
+	uint32_t gic_int_prop[3];
+	int ret, offs;
+
+	/* Return if no device tree is detected */
+	if (fdt_check_header(dtb) != 0)
+		return;
+
+	ret = fdt_open_into(dtb, dtb, 0x100000);
+	if (ret < 0) {
+		ERROR("Invalid Device Tree at %p: error %d\n", dtb, ret);
+		return;
+	}
+
+	if (dt_add_psci_node(dtb)) {
+		ERROR("Failed to add PSCI Device Tree node\n");
+		return;
+	}
+
+	if (dt_add_psci_cpu_enable_methods(dtb)) {
+		ERROR("Failed to add PSCI cpu enable methods in Device Tree\n");
+		return;
+	}
+
+	/*
+	 * 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");
+
+	offs = fdt_node_offset_by_compatible(dtb, 0, "arm,gic-400");
+	gic_int_prop[0] = cpu_to_fdt32(1);		// PPI
+	gic_int_prop[1] = cpu_to_fdt32(9);		// PPI #9
+	gic_int_prop[2] = cpu_to_fdt32(0x0f04);		// all cores, level high
+	fdt_setprop(dtb, offs, "interrupts", gic_int_prop, 12);
+
+	offs = fdt_path_offset(dtb, "/chosen");
+	fdt_setprop_string(dtb, offs, "stdout-path", "serial0");
+
+	ret = fdt_pack(dtb);
+	if (ret < 0)
+		ERROR("Failed to pack Device Tree at %p: error %d\n", dtb, ret);
+
+	clean_dcache_range((uintptr_t)dtb, fdt_blob_size(dtb));
+	INFO("Changed device tree to advertise PSCI.\n");
+}
+
+void plat_rpi_bl31_custom_setup(void)
+{
+	rpi4_prepare_dtb();
+}

+ 23 - 0
plat/rpi/rpi5/include/plat.ld.S

@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Stub linker script to provide the armstub8.bin header before the actual
+ * code. If the GPU firmware finds a magic value at offset 240 in
+ * armstub8.bin, it will put the DTB and kernel load address in subsequent
+ * words. We can then read those values to find the proper NS entry point
+ * and find our DTB more flexibly.
+ */
+
+MEMORY {
+    PRERAM (rwx): ORIGIN = 0, LENGTH = 4096
+}
+
+SECTIONS
+{
+    .armstub8 . : {
+        *armstub8_header.o(.text*)
+        KEEP(*(.armstub8))
+    } >PRERAM
+}

+ 141 - 0
plat/rpi/rpi5/include/platform_def.h

@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PLATFORM_DEF_H
+#define PLATFORM_DEF_H
+
+#include <arch.h>
+#include <common/tbbr/tbbr_img_def.h>
+#include <lib/utils_def.h>
+#include <plat/common/common_def.h>
+
+#include "rpi_hw.h"
+
+/* Special value used to verify platform parameters from BL2 to BL31 */
+#define RPI3_BL31_PLAT_PARAM_VAL	ULL(0x0F1E2D3C4B5A6978)
+
+#define PLATFORM_STACK_SIZE		ULL(0x1000)
+
+#define PLATFORM_MAX_CPUS_PER_CLUSTER	U(4)
+#define PLATFORM_CLUSTER_COUNT		U(1)
+#define PLATFORM_CLUSTER0_CORE_COUNT	PLATFORM_MAX_CPUS_PER_CLUSTER
+#define PLATFORM_CORE_COUNT		PLATFORM_CLUSTER0_CORE_COUNT
+
+#define RPI_PRIMARY_CPU			U(0)
+
+#define PLAT_MAX_PWR_LVL		MPIDR_AFFLVL1
+#define PLAT_NUM_PWR_DOMAINS		(PLATFORM_CLUSTER_COUNT + \
+					 PLATFORM_CORE_COUNT)
+
+#define PLAT_MAX_RET_STATE		U(1)
+#define PLAT_MAX_OFF_STATE		U(2)
+
+/* Local power state for power domains in Run state. */
+#define PLAT_LOCAL_STATE_RUN		U(0)
+/* Local power state for retention. Valid only for CPU power domains */
+#define PLAT_LOCAL_STATE_RET		U(1)
+/*
+ * Local power state for OFF/power-down. Valid for CPU and cluster power
+ * domains.
+ */
+#define PLAT_LOCAL_STATE_OFF		U(2)
+
+/*
+ * Macros used to parse state information from State-ID if it is using the
+ * recommended encoding for State-ID.
+ */
+#define PLAT_LOCAL_PSTATE_WIDTH		U(4)
+#define PLAT_LOCAL_PSTATE_MASK		((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1)
+
+/*
+ * Some data must be aligned on the biggest cache line size in the platform.
+ * This is known only to the platform as it might have a combination of
+ * integrated and external caches.
+ */
+#define CACHE_WRITEBACK_SHIFT		U(6)
+#define CACHE_WRITEBACK_GRANULE		(U(1) << CACHE_WRITEBACK_SHIFT)
+
+/*
+ * I/O registers.
+ */
+#define DEVICE0_BASE			RPI_IO_BASE
+#define DEVICE0_SIZE			RPI_IO_SIZE
+
+/*
+ * Mailbox to control the secondary cores. All secondary cores are held in a
+ * wait loop in cold boot. To release them perform the following steps (plus
+ * any additional barriers that may be needed):
+ *
+ *     uint64_t *entrypoint = (uint64_t *)PLAT_RPI3_TM_ENTRYPOINT;
+ *     *entrypoint = ADDRESS_TO_JUMP_TO;
+ *
+ *     uint64_t *mbox_entry = (uint64_t *)PLAT_RPI3_TM_HOLD_BASE;
+ *     mbox_entry[cpu_id] = PLAT_RPI3_TM_HOLD_STATE_GO;
+ *
+ *     sev();
+ */
+/* The secure entry point to be used on warm reset by all CPUs. */
+#define PLAT_RPI3_TM_ENTRYPOINT		0x100
+#define PLAT_RPI3_TM_ENTRYPOINT_SIZE	ULL(8)
+
+/* Hold entries for each CPU. */
+#define PLAT_RPI3_TM_HOLD_BASE		(PLAT_RPI3_TM_ENTRYPOINT + \
+					 PLAT_RPI3_TM_ENTRYPOINT_SIZE)
+#define PLAT_RPI3_TM_HOLD_ENTRY_SIZE	ULL(8)
+#define PLAT_RPI3_TM_HOLD_SIZE		(PLAT_RPI3_TM_HOLD_ENTRY_SIZE * \
+					 PLATFORM_CORE_COUNT)
+
+#define PLAT_RPI3_TRUSTED_MAILBOX_SIZE	(PLAT_RPI3_TM_ENTRYPOINT_SIZE + \
+					 PLAT_RPI3_TM_HOLD_SIZE)
+
+#define PLAT_RPI3_TM_HOLD_STATE_WAIT	ULL(0)
+#define PLAT_RPI3_TM_HOLD_STATE_GO	ULL(1)
+#define PLAT_RPI3_TM_HOLD_STATE_BSP_OFF	ULL(2)
+
+/*
+ * BL31 specific defines.
+ *
+ * Put BL31 at the top of the Trusted SRAM. BL31_BASE is calculated using the
+ * current BL31 debug size plus a little space for growth.
+ */
+#define PLAT_MAX_BL31_SIZE		ULL(0x80000)
+
+#define BL31_BASE			ULL(0x1000)
+#define BL31_LIMIT			ULL(0x80000)
+#define BL31_PROGBITS_LIMIT		ULL(0x80000)
+
+#define SEC_SRAM_ID			0
+#define SEC_DRAM_ID			1
+
+/*
+ * Other memory-related defines.
+ */
+#define PLAT_PHY_ADDR_SPACE_SIZE	(ULL(1) << 40)
+#define PLAT_VIRT_ADDR_SPACE_SIZE	(ULL(1) << 40)
+
+#define MAX_MMAP_REGIONS		8
+#define MAX_XLAT_TABLES			4
+
+#define MAX_IO_DEVICES			U(3)
+#define MAX_IO_HANDLES			U(4)
+
+#define MAX_IO_BLOCK_DEVICES		U(1)
+
+/*
+ * Serial-related constants.
+ */
+#define PLAT_RPI_PL011_UART_BASE	RPI4_PL011_UART_BASE
+#define PLAT_RPI_PL011_UART_CLOCK	RPI4_PL011_UART_CLOCK
+#define PLAT_RPI_UART_BAUDRATE		ULL(115200)
+#define PLAT_RPI_CRASH_UART_BASE	PLAT_RPI_PL011_UART_BASE
+
+/*
+ * System counter
+ */
+#define SYS_COUNTER_FREQ_IN_TICKS	ULL(54000000)
+
+#endif /* PLATFORM_DEF_H */

+ 51 - 0
plat/rpi/rpi5/include/rpi_hw.h

@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef RPI_HW_H
+#define RPI_HW_H
+
+#include <lib/utils_def.h>
+
+/*
+ * Peripherals
+ */
+
+#define RPI_IO_BASE			ULL(0x1000000000)
+#define RPI_IO_SIZE			ULL(0x1000000000)
+
+/*
+ * ARM <-> VideoCore mailboxes
+ */
+#define RPI3_MBOX_BASE			(RPI_IO_BASE + ULL(0x7c013880))
+
+/*
+ * Power management, reset controller, watchdog.
+ */
+#define RPI3_PM_BASE			(RPI_IO_BASE + ULL(0x7d200000))
+
+/*
+ * Hardware random number generator.
+ */
+#define RPI3_RNG_BASE			(RPI_IO_BASE + ULL(0x7d208000))
+
+/*
+ * PL011 system serial port
+ */
+#define RPI4_PL011_UART_BASE		(RPI_IO_BASE + ULL(0x7d001000))
+#define RPI4_PL011_UART_CLOCK		ULL(44000000)
+
+/*
+ * GIC interrupt controller
+ */
+#define RPI_HAVE_GIC
+#define RPI4_GIC_GICD_BASE		(RPI_IO_BASE + ULL(0x7fff9000))
+#define RPI4_GIC_GICC_BASE		(RPI_IO_BASE + ULL(0x7fffa000))
+
+#define	RPI4_LOCAL_CONTROL_BASE_ADDRESS		(RPI_IO_BASE + ULL(0x7c280000))
+#define	RPI4_LOCAL_CONTROL_PRESCALER		(RPI_IO_BASE + ULL(0x7c280008))
+
+#endif /* RPI_HW_H */

+ 107 - 0
plat/rpi/rpi5/platform.mk

@@ -0,0 +1,107 @@
+#
+# Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include lib/xlat_tables_v2/xlat_tables.mk
+
+include drivers/arm/gic/v2/gicv2.mk
+
+PLAT_INCLUDES		:=	-Iplat/rpi/common/include			\
+				-Iplat/rpi/rpi5/include
+
+PLAT_BL_COMMON_SOURCES	:=	drivers/arm/pl011/aarch64/pl011_console.S 	\
+				plat/rpi/common/rpi3_common.c			\
+				plat/rpi/common/rpi3_console_pl011.c		\
+				${XLAT_TABLES_LIB_SRCS}
+
+BL31_SOURCES		+=	lib/cpus/aarch64/cortex_a76.S			\
+				plat/rpi/common/aarch64/plat_helpers.S		\
+				plat/rpi/common/aarch64/armstub8_header.S 	\
+				drivers/delay_timer/delay_timer.c		\
+				plat/common/plat_gicv2.c			\
+				plat/rpi/common/rpi4_bl31_setup.c		\
+				plat/rpi/rpi5/rpi5_setup.c			\
+				plat/rpi/common/rpi3_pm.c			\
+				plat/common/plat_psci_common.c			\
+				plat/rpi/common/rpi3_topology.c			\
+				${GICV2_SOURCES}
+
+# For now we only support BL31, using the kernel loaded by the GPU firmware.
+RESET_TO_BL31		:=	1
+
+# All CPUs enter armstub8.bin.
+COLD_BOOT_SINGLE_CPU	:=	0
+
+# Tune compiler for Cortex-A76
+ifeq ($(notdir $(CC)),armclang)
+    TF_CFLAGS_aarch64	+=	-mcpu=cortex-a76
+else ifneq ($(findstring clang,$(notdir $(CC))),)
+    TF_CFLAGS_aarch64	+=	-mcpu=cortex-a76
+else
+    TF_CFLAGS_aarch64	+=	-mtune=cortex-a76
+endif
+
+# Add support for platform supplied linker script for BL31 build
+$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT))
+
+# Enable all errata workarounds for Cortex-A76 r4p1
+ERRATA_A76_1946160		:= 1
+ERRATA_A76_2743102		:= 1
+
+# Add new default target when compiling this platform
+all: bl31
+
+# Build config flags
+# ------------------
+
+# Disable stack protector by default
+ENABLE_STACK_PROTECTOR	 	:= 0
+
+# Have different sections for code and rodata
+SEPARATE_CODE_AND_RODATA	:= 1
+
+# Hardware-managed coherency
+HW_ASSISTED_COHERENCY		:= 1
+USE_COHERENT_MEM		:= 0
+
+# Cortex-A76 is 64-bit only
+CTX_INCLUDE_AARCH32_REGS	:= 0
+
+# Platform build flags
+# --------------------
+
+# There is not much else than a Linux kernel to load at the moment.
+RPI3_DIRECT_LINUX_BOOT		:= 1
+
+# BL33 images can only be AArch64 on this platform.
+RPI3_BL33_IN_AARCH32		:= 0
+
+# UART to use at runtime. -1 means the runtime UART is disabled.
+# Any other value means the default UART will be used.
+RPI3_RUNTIME_UART		:= 0
+
+# Use normal memory mapping for ROM, FIP, SRAM and DRAM
+RPI3_USE_UEFI_MAP		:= 0
+
+# Process platform flags
+# ----------------------
+
+$(eval $(call add_define,RPI3_BL33_IN_AARCH32))
+$(eval $(call add_define,RPI3_DIRECT_LINUX_BOOT))
+ifdef RPI3_PRELOADED_DTB_BASE
+$(eval $(call add_define,RPI3_PRELOADED_DTB_BASE))
+endif
+$(eval $(call add_define,RPI3_RUNTIME_UART))
+$(eval $(call add_define,RPI3_USE_UEFI_MAP))
+
+ifeq (${ARCH},aarch32)
+  $(error Error: AArch32 not supported on rpi5)
+endif
+
+ifneq ($(ENABLE_STACK_PROTECTOR), 0)
+PLAT_BL_COMMON_SOURCES	+=	drivers/rpi3/rng/rpi3_rng.c		\
+				plat/rpi/common/rpi3_stack_protector.c
+endif

+ 12 - 0
plat/rpi/rpi5/rpi5_setup.c

@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2024, Mario Bălănică <mariobalanica02@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <rpi_shared.h>
+
+void plat_rpi_bl31_custom_setup(void)
+{
+	/* Nothing to do here yet. */
+}