summaryrefslogtreecommitdiffstats
path: root/plat/rpi/common/rpi3_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'plat/rpi/common/rpi3_common.c')
-rw-r--r--plat/rpi/common/rpi3_common.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c
new file mode 100644
index 0000000..ef88bf1
--- /dev/null
+++ b/plat/rpi/common/rpi3_common.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#include <platform_def.h>
+
+#include <arch_helpers.h>
+#include <common/bl_common.h>
+#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>
+#include <rpi_shared.h>
+
+#define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \
+ DEVICE0_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+
+#ifdef SHARED_RAM_BASE
+#define MAP_SHARED_RAM MAP_REGION_FLAT(SHARED_RAM_BASE, \
+ SHARED_RAM_SIZE, \
+ MT_DEVICE | MT_RW | MT_SECURE)
+#endif
+
+#ifdef RPI3_PRELOADED_DTB_BASE
+#define MAP_NS_DTB MAP_REGION_FLAT(RPI3_PRELOADED_DTB_BASE, 0x10000, \
+ MT_MEMORY | MT_RW | MT_NS)
+#endif
+
+#define MAP_NS_DRAM0 MAP_REGION_FLAT(NS_DRAM0_BASE, NS_DRAM0_SIZE, \
+ MT_MEMORY | MT_RW | MT_NS)
+
+#define MAP_FIP MAP_REGION_FLAT(PLAT_RPI3_FIP_BASE, \
+ PLAT_RPI3_FIP_MAX_SIZE, \
+ MT_MEMORY | MT_RO | MT_NS)
+
+#define MAP_BL32_MEM MAP_REGION_FLAT(BL32_MEM_BASE, BL32_MEM_SIZE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+
+#ifdef SPD_opteed
+#define MAP_OPTEE_PAGEABLE MAP_REGION_FLAT( \
+ RPI3_OPTEE_PAGEABLE_LOAD_BASE, \
+ RPI3_OPTEE_PAGEABLE_LOAD_SIZE, \
+ MT_MEMORY | MT_RW | MT_SECURE)
+#endif
+
+/*
+ * Table of regions for various BL stages to map using the MMU.
+ */
+#ifdef IMAGE_BL1
+static const mmap_region_t plat_rpi3_mmap[] = {
+#ifdef MAP_SHARED_RAM
+ MAP_SHARED_RAM,
+#endif
+ MAP_DEVICE0,
+ MAP_FIP,
+#ifdef SPD_opteed
+ MAP_OPTEE_PAGEABLE,
+#endif
+ {0}
+};
+#endif
+
+#ifdef IMAGE_BL2
+static const mmap_region_t plat_rpi3_mmap[] = {
+#ifdef MAP_SHARED_RAM
+ MAP_SHARED_RAM,
+#endif
+ MAP_DEVICE0,
+ MAP_FIP,
+ MAP_NS_DRAM0,
+#ifdef BL32_BASE
+ MAP_BL32_MEM,
+#endif
+ {0}
+};
+#endif
+
+#ifdef IMAGE_BL31
+static const mmap_region_t plat_rpi3_mmap[] = {
+#ifdef MAP_SHARED_RAM
+ MAP_SHARED_RAM,
+#endif
+ MAP_DEVICE0,
+#ifdef RPI3_PRELOADED_DTB_BASE
+ MAP_NS_DTB,
+#endif
+#ifdef BL32_BASE
+ MAP_BL32_MEM,
+#endif
+ {0}
+};
+#endif
+
+/*******************************************************************************
+ * Function that sets up the console
+ ******************************************************************************/
+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;
+ int rc;
+
+ 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);
+
+ if (rc == 0) {
+ /*
+ * The crash console doesn't use the multi console API, it uses
+ * the core console functions directly. It is safe to call panic
+ * and let it print debug information.
+ */
+ panic();
+ }
+
+ console_set_scope(&rpi3_console, console_scope);
+}
+
+/*******************************************************************************
+ * Function that sets up the translation tables.
+ ******************************************************************************/
+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
+#if USE_COHERENT_MEM
+ , uintptr_t coh_start, uintptr_t coh_limit
+#endif
+ )
+{
+ /*
+ * Map the Trusted SRAM with appropriate memory attributes.
+ * Subsequent mappings will adjust the attributes for specific regions.
+ */
+ VERBOSE("Trusted SRAM seen by this BL image: %p - %p\n",
+ (void *) total_base, (void *) (total_base + total_size));
+ mmap_add_region(total_base, total_base,
+ total_size,
+ MT_MEMORY | MT_RW | MT_SECURE);
+
+ /* Re-map the code section */
+ VERBOSE("Code region: %p - %p\n",
+ (void *) code_start, (void *) code_limit);
+ mmap_add_region(code_start, code_start,
+ code_limit - code_start,
+ MT_CODE | MT_SECURE);
+
+ /* Re-map the read-only data section */
+ VERBOSE("Read-only data region: %p - %p\n",
+ (void *) rodata_start, (void *) rodata_limit);
+ mmap_add_region(rodata_start, rodata_start,
+ rodata_limit - rodata_start,
+ MT_RO_DATA | MT_SECURE);
+
+#if USE_COHERENT_MEM
+ /* Re-map the coherent memory region */
+ VERBOSE("Coherent region: %p - %p\n",
+ (void *) coh_start, (void *) coh_limit);
+ mmap_add_region(coh_start, coh_start,
+ coh_limit - coh_start,
+ MT_DEVICE | MT_RW | MT_SECURE);
+#endif
+
+ mmap_add(plat_rpi3_mmap);
+
+ init_xlat_tables();
+}
+
+/*******************************************************************************
+ * Gets SPSR for BL32 entry
+ ******************************************************************************/
+uint32_t rpi3_get_spsr_for_bl32_entry(void)
+{
+ /*
+ * The Secure Payload Dispatcher service is responsible for
+ * setting the SPSR prior to entry into the BL32 image.
+ */
+ return 0;
+}
+
+/*******************************************************************************
+ * Gets SPSR for BL33 entry
+ ******************************************************************************/
+uint32_t rpi3_get_spsr_for_bl33_entry(void)
+{
+#if RPI3_BL33_IN_AARCH32
+ INFO("BL33 will boot in Non-secure AArch32 Hypervisor mode\n");
+ return SPSR_MODE32(MODE32_hyp, SPSR_T_ARM, SPSR_E_LITTLE,
+ DISABLE_ALL_EXCEPTIONS);
+#else
+ return SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
+#endif
+}
+
+unsigned int plat_get_syscnt_freq2(void)
+{
+ return SYS_COUNTER_FREQ_IN_TICKS;
+}
+
+uint32_t plat_ic_get_pending_interrupt_type(void)
+{
+ ERROR("rpi3: Interrupt routed to EL3.\n");
+ return INTR_TYPE_INVAL;
+}
+
+uint32_t plat_interrupt_type_to_line(uint32_t type, uint32_t security_state)
+{
+ assert((type == INTR_TYPE_S_EL1) || (type == INTR_TYPE_EL3) ||
+ (type == INTR_TYPE_NS));
+
+ assert(sec_state_is_valid(security_state));
+
+ /* Non-secure interrupts are signalled on the IRQ line always. */
+ if (type == INTR_TYPE_NS)
+ return __builtin_ctz(SCR_IRQ_BIT);
+
+ /* Secure interrupts are signalled on the FIQ line always. */
+ return __builtin_ctz(SCR_FIQ_BIT);
+}