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
diff --git a/changelog.yaml b/changelog.yaml
index 7f0c1ec..3875a48 100644
--- a/changelog.yaml
+++ b/changelog.yaml
@@ -544,6 +544,9 @@
- title: Raspberry Pi 4
scope: rpi4
+ - title: Raspberry Pi 5
+ scope: rpi5
+
- title: Renesas
scope: renesas
diff --git a/docs/plat/index.rst b/docs/plat/index.rst
index 43f4898..35cc27d 100644
--- a/docs/plat/index.rst
+++ b/docs/plat/index.rst
@@ -38,6 +38,7 @@
qti-msm8916
rpi3
rpi4
+ rpi5
rcar-gen3
rz-g2
rockchip
diff --git a/docs/plat/rpi5.rst b/docs/plat/rpi5.rst
new file mode 100644
index 0000000..f2e1b9f
--- /dev/null
+++ b/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/
diff --git a/drivers/rpi3/rng/rpi3_rng.c b/drivers/rpi3/rng/rpi3_rng.c
index b6bf005..16733e1 100644
--- a/drivers/rpi3/rng/rpi3_rng.c
+++ b/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)
diff --git a/include/drivers/rpi3/mailbox/rpi3_mbox.h b/include/drivers/rpi3/mailbox/rpi3_mbox.h
index c107440..33458e3 100644
--- a/include/drivers/rpi3/mailbox/rpi3_mbox.h
+++ b/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 @@
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. */
diff --git a/plat/rpi/rpi4/aarch64/armstub8_header.S b/plat/rpi/common/aarch64/armstub8_header.S
similarity index 89%
rename from plat/rpi/rpi4/aarch64/armstub8_header.S
rename to plat/rpi/common/aarch64/armstub8_header.S
index 246358d..dc1e54e 100644
--- a/plat/rpi/rpi4/aarch64/armstub8_header.S
+++ b/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
*/
diff --git a/plat/rpi/common/aarch64/plat_helpers.S b/plat/rpi/common/aarch64/plat_helpers.S
index f045e21..18873af 100644
--- a/plat/rpi/common/aarch64/plat_helpers.S
+++ b/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 @@
* ---------------------------------------------
*/
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 @@
* ---------------------------------------------
*/
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 @@
* ---------------------------------------------
*/
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
/* ---------------------------------------------
diff --git a/plat/rpi/rpi4/include/plat_macros.S b/plat/rpi/common/include/plat_macros.S
similarity index 87%
rename from plat/rpi/rpi4/include/plat_macros.S
rename to plat/rpi/common/include/plat_macros.S
index 6007d03..576d0ff 100644
--- a/plat/rpi/rpi4/include/plat_macros.S
+++ b/plat/rpi/common/include/plat_macros.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2024, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/rpi/common/include/rpi_shared.h b/plat/rpi/common/include/rpi_shared.h
index ddf239e..8562c3d 100644
--- a/plat/rpi/common/include/rpi_shared.h
+++ b/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 @@
#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 plat_rpi_get_model(void);
+/*******************************************************************************
+ * Platform implemented functions
+ ******************************************************************************/
+
+void plat_rpi_bl31_custom_setup(void);
+
#endif /* RPI3_PRIVATE_H */
diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c
index ef88bf1..8976496 100644
--- a/plat/rpi/common/rpi3_common.c
+++ b/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 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 @@
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) {
/*
diff --git a/plat/rpi/common/rpi3_console_dual.c b/plat/rpi/common/rpi3_console_dual.c
new file mode 100644
index 0000000..15ee3e7
--- /dev/null
+++ b/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);
+}
diff --git a/plat/rpi/common/rpi3_console_pl011.c b/plat/rpi/common/rpi3_console_pl011.c
new file mode 100644
index 0000000..6ab7209
--- /dev/null
+++ b/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);
+}
diff --git a/plat/rpi/common/rpi3_pm.c b/plat/rpi/common/rpi3_pm.c
index d98ac66..456e160 100644
--- a/plat/rpi/common/rpi3_pm.c
+++ b/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
diff --git a/plat/rpi/common/rpi3_topology.c b/plat/rpi/common/rpi3_topology.c
index 3747287..5fef777 100644
--- a/plat/rpi/common/rpi3_topology.c
+++ b/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 @@
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;
diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/common/rpi4_bl31_setup.c
similarity index 67%
rename from plat/rpi/rpi4/rpi4_bl31_setup.c
rename to plat/rpi/common/rpi4_bl31_setup.c
index 2fb4d3d..a7228fd 100644
--- a/plat/rpi/rpi4/rpi4_bl31_setup.c
+++ b/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 @@
#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 @@
* 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 @@
* 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 @@
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();
}
diff --git a/plat/rpi/rpi3/include/plat_macros.S b/plat/rpi/rpi3/include/plat_macros.S
deleted file mode 100644
index c0c3967..0000000
--- a/plat/rpi/rpi3/include/plat_macros.S
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2016-2018, 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 */
diff --git a/plat/rpi/rpi3/include/platform_def.h b/plat/rpi/rpi3/include/platform_def.h
index f44d1f5..757c64a 100644
--- a/plat/rpi/rpi3/include/platform_def.h
+++ b/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
diff --git a/plat/rpi/rpi3/include/rpi_hw.h b/plat/rpi/rpi3/include/rpi_hw.h
index 2aecab3..dec5963 100644
--- a/plat/rpi/rpi3/include/rpi_hw.h
+++ b/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:
diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk
index 26a3268..8034fa4 100644
--- a/plat/rpi/rpi3/platform.mk
+++ b/plat/rpi/rpi3/platform.mk
@@ -17,6 +17,7 @@
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 \
diff --git a/plat/rpi/rpi4/include/platform_def.h b/plat/rpi/rpi4/include/platform_def.h
index 6787ebf..b72aedc 100644
--- a/plat/rpi/rpi4/include/platform_def.h
+++ b/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
diff --git a/plat/rpi/rpi4/include/rpi_hw.h b/plat/rpi/rpi4/include/rpi_hw.h
index 0430d46..8162492 100644
--- a/plat/rpi/rpi4/include/rpi_hw.h
+++ b/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:
diff --git a/plat/rpi/rpi4/platform.mk b/plat/rpi/rpi4/platform.mk
index 42a5416..f17911f 100644
--- a/plat/rpi/rpi4/platform.mk
+++ b/plat/rpi/rpi4/platform.mk
@@ -15,16 +15,18 @@
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 \
diff --git a/plat/rpi/rpi4/rpi4_setup.c b/plat/rpi/rpi4/rpi4_setup.c
new file mode 100644
index 0000000..82200b9
--- /dev/null
+++ b/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();
+}
diff --git a/plat/rpi/rpi5/include/plat.ld.S b/plat/rpi/rpi5/include/plat.ld.S
new file mode 100644
index 0000000..961c630
--- /dev/null
+++ b/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
+}
diff --git a/plat/rpi/rpi5/include/platform_def.h b/plat/rpi/rpi5/include/platform_def.h
new file mode 100644
index 0000000..a4c2f5b
--- /dev/null
+++ b/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 */
diff --git a/plat/rpi/rpi5/include/rpi_hw.h b/plat/rpi/rpi5/include/rpi_hw.h
new file mode 100644
index 0000000..384542e
--- /dev/null
+++ b/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 */
diff --git a/plat/rpi/rpi5/platform.mk b/plat/rpi/rpi5/platform.mk
new file mode 100644
index 0000000..81b7ded
--- /dev/null
+++ b/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
diff --git a/plat/rpi/rpi5/rpi5_setup.c b/plat/rpi/rpi5/rpi5_setup.c
new file mode 100644
index 0000000..de82300
--- /dev/null
+++ b/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. */
+}