diff --git a/changelog.yaml b/changelog.yaml index 7f0c1ec5d..3875a48c7 100644 --- a/changelog.yaml +++ b/changelog.yaml @@ -544,6 +544,9 @@ subsections: - 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 43f4898d2..35cc27df3 100644 --- a/docs/plat/index.rst +++ b/docs/plat/index.rst @@ -38,6 +38,7 @@ Platform Ports 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 000000000..f2e1b9f2d --- /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 b6bf0052a..16733e15c 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 +#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 c1074402b..33458e384 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 @@ 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. */ 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 246358d04..dc1e54e13 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 f045e2113..18873af7f 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 @@ 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 /* --------------------------------------------- diff --git a/plat/rpi/rpi3/include/plat_macros.S b/plat/rpi/common/include/plat_macros.S similarity index 87% rename from plat/rpi/rpi3/include/plat_macros.S rename to plat/rpi/common/include/plat_macros.S index c0c396791..576d0ffc9 100644 --- a/plat/rpi/rpi3/include/plat_macros.S +++ b/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 */ diff --git a/plat/rpi/common/include/rpi_shared.h b/plat/rpi/common/include/rpi_shared.h index ddf239eb5..8562c3d56 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 #include +#include + /******************************************************************************* * 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 */ diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c index ef88bf10e..89764969d 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 #include #include -#include -#include -#include #include #include @@ -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) { /* diff --git a/plat/rpi/common/rpi3_console_dual.c b/plat/rpi/common/rpi3_console_dual.c new file mode 100644 index 000000000..15ee3e70a --- /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ă + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +#include + +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 000000000..6ab720972 --- /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ă + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include + +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 d98ac66f4..456e1603c 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 #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 3747287c2..5fef777c3 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 @@ 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; 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 2fb4d3df1..a7228fd4f 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 #include -#include - -#include #include #include +#include #include #include #include #include #include -#include -#include -#include - -#include +#include #include @@ -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(); } diff --git a/plat/rpi/rpi3/include/platform_def.h b/plat/rpi/rpi3/include/platform_def.h index f44d1f526..757c64ad9 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 2aecab379..dec596333 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 26a3268bc..8034fa479 100644 --- a/plat/rpi/rpi3/platform.mk +++ b/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 \ diff --git a/plat/rpi/rpi4/include/plat_macros.S b/plat/rpi/rpi4/include/plat_macros.S deleted file mode 100644 index 6007d031e..000000000 --- a/plat/rpi/rpi4/include/plat_macros.S +++ /dev/null @@ -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 */ diff --git a/plat/rpi/rpi4/include/platform_def.h b/plat/rpi/rpi4/include/platform_def.h index 6787ebfee..b72aedcfa 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 0430d464d..816249212 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 42a54164e..f17911fec 100644 --- a/plat/rpi/rpi4/platform.mk +++ b/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 \ diff --git a/plat/rpi/rpi4/rpi4_setup.c b/plat/rpi/rpi4/rpi4_setup.c new file mode 100644 index 000000000..82200b976 --- /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 +#include +#include + +#include +#include +#include + +#include + +/* + * 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 000000000..961c630c6 --- /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 000000000..a4c2f5b9d --- /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ă + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include +#include +#include +#include + +#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 000000000..384542e66 --- /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ă + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RPI_HW_H +#define RPI_HW_H + +#include + +/* + * 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 000000000..81b7dedfb --- /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ă +# +# 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 000000000..de82300de --- /dev/null +++ b/plat/rpi/rpi5/rpi5_setup.c @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2024, Mario Bălănică + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +void plat_rpi_bl31_custom_setup(void) +{ + /* Nothing to do here yet. */ +}