19a40c0fbSSheetal Tigadoli /*
2*46163dddSSalman Nabi * Copyright (c) 2015-2024, ARM Limited and Contributors. All rights reserved.
39a40c0fbSSheetal Tigadoli *
49a40c0fbSSheetal Tigadoli * SPDX-License-Identifier: BSD-3-Clause
59a40c0fbSSheetal Tigadoli */
69a40c0fbSSheetal Tigadoli
79a40c0fbSSheetal Tigadoli #include <assert.h>
89a40c0fbSSheetal Tigadoli
99a40c0fbSSheetal Tigadoli #include <arch.h>
109a40c0fbSSheetal Tigadoli #include <arch_helpers.h>
119a40c0fbSSheetal Tigadoli #include <common/bl_common.h>
129a40c0fbSSheetal Tigadoli #include <common/debug.h>
139a40c0fbSSheetal Tigadoli #include <drivers/arm/sp804_delay_timer.h>
149a40c0fbSSheetal Tigadoli #include <lib/utils.h>
159a40c0fbSSheetal Tigadoli #include <plat/common/platform.h>
169a40c0fbSSheetal Tigadoli
179a40c0fbSSheetal Tigadoli #include <bcm_console.h>
189a40c0fbSSheetal Tigadoli #include <plat_brcm.h>
199a40c0fbSSheetal Tigadoli #include <platform_def.h>
209a40c0fbSSheetal Tigadoli
219a40c0fbSSheetal Tigadoli #ifdef BL33_SHARED_DDR_BASE
229a40c0fbSSheetal Tigadoli struct bl33_info *bl33_info = (struct bl33_info *)BL33_SHARED_DDR_BASE;
239a40c0fbSSheetal Tigadoli #endif
249a40c0fbSSheetal Tigadoli
259a40c0fbSSheetal Tigadoli /*
269a40c0fbSSheetal Tigadoli * Placeholder variables for copying the arguments that have been passed to
279a40c0fbSSheetal Tigadoli * BL31 from BL2.
289a40c0fbSSheetal Tigadoli */
299a40c0fbSSheetal Tigadoli static entry_point_info_t bl32_image_ep_info;
309a40c0fbSSheetal Tigadoli static entry_point_info_t bl33_image_ep_info;
319a40c0fbSSheetal Tigadoli
329a40c0fbSSheetal Tigadoli /* Weak definitions may be overridden in specific BRCM platform */
339a40c0fbSSheetal Tigadoli #pragma weak plat_bcm_bl31_early_platform_setup
349a40c0fbSSheetal Tigadoli #pragma weak plat_brcm_pwrc_setup
359a40c0fbSSheetal Tigadoli #pragma weak plat_brcm_security_setup
369a40c0fbSSheetal Tigadoli
plat_brcm_security_setup(void)379a40c0fbSSheetal Tigadoli void plat_brcm_security_setup(void)
389a40c0fbSSheetal Tigadoli {
399a40c0fbSSheetal Tigadoli
409a40c0fbSSheetal Tigadoli }
419a40c0fbSSheetal Tigadoli
plat_brcm_pwrc_setup(void)429a40c0fbSSheetal Tigadoli void plat_brcm_pwrc_setup(void)
439a40c0fbSSheetal Tigadoli {
449a40c0fbSSheetal Tigadoli
459a40c0fbSSheetal Tigadoli }
469a40c0fbSSheetal Tigadoli
plat_bcm_bl31_early_platform_setup(void * from_bl2,bl_params_t * plat_params_from_bl2)479a40c0fbSSheetal Tigadoli void plat_bcm_bl31_early_platform_setup(void *from_bl2,
489a40c0fbSSheetal Tigadoli bl_params_t *plat_params_from_bl2)
499a40c0fbSSheetal Tigadoli {
509a40c0fbSSheetal Tigadoli
519a40c0fbSSheetal Tigadoli }
529a40c0fbSSheetal Tigadoli
539a40c0fbSSheetal Tigadoli /*******************************************************************************
549a40c0fbSSheetal Tigadoli * Return a pointer to the 'entry_point_info' structure of the next image for
559a40c0fbSSheetal Tigadoli * the security state specified. BL33 corresponds to the non-secure image type
569a40c0fbSSheetal Tigadoli * while BL32 corresponds to the secure image type. A NULL pointer is returned
579a40c0fbSSheetal Tigadoli * if the image does not exist.
589a40c0fbSSheetal Tigadoli ******************************************************************************/
bl31_plat_get_next_image_ep_info(uint32_t type)599a40c0fbSSheetal Tigadoli struct entry_point_info *bl31_plat_get_next_image_ep_info(uint32_t type)
609a40c0fbSSheetal Tigadoli {
619a40c0fbSSheetal Tigadoli entry_point_info_t *next_image_info;
629a40c0fbSSheetal Tigadoli
639a40c0fbSSheetal Tigadoli assert(sec_state_is_valid(type));
649a40c0fbSSheetal Tigadoli next_image_info = (type == NON_SECURE)
659a40c0fbSSheetal Tigadoli ? &bl33_image_ep_info : &bl32_image_ep_info;
669a40c0fbSSheetal Tigadoli /*
679a40c0fbSSheetal Tigadoli * None of the images on the ARM development platforms can have 0x0
689a40c0fbSSheetal Tigadoli * as the entrypoint
699a40c0fbSSheetal Tigadoli */
709a40c0fbSSheetal Tigadoli if (next_image_info->pc)
719a40c0fbSSheetal Tigadoli return next_image_info;
729a40c0fbSSheetal Tigadoli else
739a40c0fbSSheetal Tigadoli return NULL;
749a40c0fbSSheetal Tigadoli }
759a40c0fbSSheetal Tigadoli
769a40c0fbSSheetal Tigadoli /*******************************************************************************
779a40c0fbSSheetal Tigadoli * Perform any BL31 early platform setup common to ARM standard platforms.
789a40c0fbSSheetal Tigadoli * Here is an opportunity to copy parameters passed by the calling EL (S-EL1
799a40c0fbSSheetal Tigadoli * in BL2 & EL3 in BL1) before they are lost (potentially). This needs to be
809a40c0fbSSheetal Tigadoli * done before the MMU is initialized so that the memory layout can be used
819a40c0fbSSheetal Tigadoli * while creating page tables. BL2 has flushed this information to memory, so
829a40c0fbSSheetal Tigadoli * we are guaranteed to pick up good data.
839a40c0fbSSheetal Tigadoli ******************************************************************************/
brcm_bl31_early_platform_setup(void * from_bl2,uintptr_t soc_fw_config,uintptr_t hw_config,void * plat_params_from_bl2)849a40c0fbSSheetal Tigadoli void __init brcm_bl31_early_platform_setup(void *from_bl2,
859a40c0fbSSheetal Tigadoli uintptr_t soc_fw_config,
869a40c0fbSSheetal Tigadoli uintptr_t hw_config,
879a40c0fbSSheetal Tigadoli void *plat_params_from_bl2)
889a40c0fbSSheetal Tigadoli {
899a40c0fbSSheetal Tigadoli /* Initialize the console to provide early debug support */
909a40c0fbSSheetal Tigadoli bcm_console_boot_init();
919a40c0fbSSheetal Tigadoli
929a40c0fbSSheetal Tigadoli /* Initialize delay timer driver using SP804 dual timer 0 */
939a40c0fbSSheetal Tigadoli sp804_timer_init(SP804_TIMER0_BASE,
949a40c0fbSSheetal Tigadoli SP804_TIMER0_CLKMULT, SP804_TIMER0_CLKDIV);
959a40c0fbSSheetal Tigadoli
969a40c0fbSSheetal Tigadoli #if RESET_TO_BL31
979a40c0fbSSheetal Tigadoli /* There are no parameters from BL2 if BL31 is a reset vector */
989a40c0fbSSheetal Tigadoli assert(from_bl2 == NULL);
999a40c0fbSSheetal Tigadoli assert(plat_params_from_bl2 == NULL);
1009a40c0fbSSheetal Tigadoli
1019a40c0fbSSheetal Tigadoli # ifdef BL32_BASE
1029a40c0fbSSheetal Tigadoli /* Populate entry point information for BL32 */
1039a40c0fbSSheetal Tigadoli SET_PARAM_HEAD(&bl32_image_ep_info,
1049a40c0fbSSheetal Tigadoli PARAM_EP,
1059a40c0fbSSheetal Tigadoli VERSION_1,
1069a40c0fbSSheetal Tigadoli 0);
1079a40c0fbSSheetal Tigadoli SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
1089a40c0fbSSheetal Tigadoli bl32_image_ep_info.pc = BL32_BASE;
1099a40c0fbSSheetal Tigadoli bl32_image_ep_info.spsr = brcm_get_spsr_for_bl32_entry();
1109a40c0fbSSheetal Tigadoli # endif /* BL32_BASE */
1119a40c0fbSSheetal Tigadoli
1129a40c0fbSSheetal Tigadoli /* Populate entry point information for BL33 */
1139a40c0fbSSheetal Tigadoli SET_PARAM_HEAD(&bl33_image_ep_info,
1149a40c0fbSSheetal Tigadoli PARAM_EP,
1159a40c0fbSSheetal Tigadoli VERSION_1,
1169a40c0fbSSheetal Tigadoli 0);
1179a40c0fbSSheetal Tigadoli /*
1189a40c0fbSSheetal Tigadoli * Tell BL31 where the non-trusted software image
1199a40c0fbSSheetal Tigadoli * is located and the entry state information
1209a40c0fbSSheetal Tigadoli */
1219a40c0fbSSheetal Tigadoli bl33_image_ep_info.pc = plat_get_ns_image_entrypoint();
1229a40c0fbSSheetal Tigadoli
1239a40c0fbSSheetal Tigadoli bl33_image_ep_info.spsr = brcm_get_spsr_for_bl33_entry();
1249a40c0fbSSheetal Tigadoli SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
1259a40c0fbSSheetal Tigadoli
1269a40c0fbSSheetal Tigadoli # if ARM_LINUX_KERNEL_AS_BL33
1279a40c0fbSSheetal Tigadoli /*
1289a40c0fbSSheetal Tigadoli * According to the file ``Documentation/arm64/booting.txt`` of the
1299a40c0fbSSheetal Tigadoli * Linux kernel tree, Linux expects the physical address of the device
1309a40c0fbSSheetal Tigadoli * tree blob (DTB) in x0, while x1-x3 are reserved for future use and
1319a40c0fbSSheetal Tigadoli * must be 0.
1329a40c0fbSSheetal Tigadoli */
1339a40c0fbSSheetal Tigadoli bl33_image_ep_info.args.arg0 = (u_register_t)PRELOADED_DTB_BASE;
1349a40c0fbSSheetal Tigadoli bl33_image_ep_info.args.arg1 = 0U;
1359a40c0fbSSheetal Tigadoli bl33_image_ep_info.args.arg2 = 0U;
1369a40c0fbSSheetal Tigadoli bl33_image_ep_info.args.arg3 = 0U;
1379a40c0fbSSheetal Tigadoli # endif
1389a40c0fbSSheetal Tigadoli
1399a40c0fbSSheetal Tigadoli #else /* RESET_TO_BL31 */
1409a40c0fbSSheetal Tigadoli
1419a40c0fbSSheetal Tigadoli /*
1429a40c0fbSSheetal Tigadoli * In debug builds, we pass a special value in 'plat_params_from_bl2'
1439a40c0fbSSheetal Tigadoli * to verify platform parameters from BL2 to BL31.
1449a40c0fbSSheetal Tigadoli * In release builds, it's not used.
1459a40c0fbSSheetal Tigadoli */
1469a40c0fbSSheetal Tigadoli assert(((unsigned long long)plat_params_from_bl2) ==
1479a40c0fbSSheetal Tigadoli BRCM_BL31_PLAT_PARAM_VAL);
1489a40c0fbSSheetal Tigadoli
1499a40c0fbSSheetal Tigadoli /*
1509a40c0fbSSheetal Tigadoli * Check params passed from BL2 should not be NULL
1519a40c0fbSSheetal Tigadoli */
1529a40c0fbSSheetal Tigadoli bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2;
1539a40c0fbSSheetal Tigadoli
1549a40c0fbSSheetal Tigadoli assert(params_from_bl2 != NULL);
1559a40c0fbSSheetal Tigadoli assert(params_from_bl2->h.type == PARAM_BL_PARAMS);
1569a40c0fbSSheetal Tigadoli assert(params_from_bl2->h.version >= VERSION_2);
1579a40c0fbSSheetal Tigadoli
1589a40c0fbSSheetal Tigadoli bl_params_node_t *bl_params = params_from_bl2->head;
1599a40c0fbSSheetal Tigadoli
1609a40c0fbSSheetal Tigadoli /*
1619a40c0fbSSheetal Tigadoli * Copy BL33 and BL32 (if present), entry point information.
1629a40c0fbSSheetal Tigadoli * They are stored in Secure RAM, in BL2's address space.
1639a40c0fbSSheetal Tigadoli */
1649a40c0fbSSheetal Tigadoli while (bl_params != NULL) {
1659a40c0fbSSheetal Tigadoli if (bl_params->image_id == BL32_IMAGE_ID &&
1669a40c0fbSSheetal Tigadoli bl_params->image_info->h.attr != IMAGE_ATTRIB_SKIP_LOADING)
1679a40c0fbSSheetal Tigadoli bl32_image_ep_info = *bl_params->ep_info;
1689a40c0fbSSheetal Tigadoli
1699a40c0fbSSheetal Tigadoli if (bl_params->image_id == BL33_IMAGE_ID)
1709a40c0fbSSheetal Tigadoli bl33_image_ep_info = *bl_params->ep_info;
1719a40c0fbSSheetal Tigadoli
1729a40c0fbSSheetal Tigadoli bl_params = bl_params->next_params_info;
1739a40c0fbSSheetal Tigadoli }
1749a40c0fbSSheetal Tigadoli
1759a40c0fbSSheetal Tigadoli if (bl33_image_ep_info.pc == 0U)
1769a40c0fbSSheetal Tigadoli panic();
1779a40c0fbSSheetal Tigadoli #endif /* RESET_TO_BL31 */
1789a40c0fbSSheetal Tigadoli
1799a40c0fbSSheetal Tigadoli #ifdef BL33_SHARED_DDR_BASE
1809a40c0fbSSheetal Tigadoli /* Pass information to BL33 thorugh x0 */
1819a40c0fbSSheetal Tigadoli bl33_image_ep_info.args.arg0 = (u_register_t)BL33_SHARED_DDR_BASE;
1829a40c0fbSSheetal Tigadoli bl33_image_ep_info.args.arg1 = 0ULL;
1839a40c0fbSSheetal Tigadoli bl33_image_ep_info.args.arg2 = 0ULL;
1849a40c0fbSSheetal Tigadoli bl33_image_ep_info.args.arg3 = 0ULL;
1859a40c0fbSSheetal Tigadoli #endif
1869a40c0fbSSheetal Tigadoli }
1879a40c0fbSSheetal Tigadoli
bl31_early_platform_setup2(u_register_t arg0,u_register_t arg1,u_register_t arg2,u_register_t arg3)1889a40c0fbSSheetal Tigadoli void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1,
1899a40c0fbSSheetal Tigadoli u_register_t arg2, u_register_t arg3)
1909a40c0fbSSheetal Tigadoli {
1919a40c0fbSSheetal Tigadoli #ifdef BL31_LOG_LEVEL
1929a40c0fbSSheetal Tigadoli SET_LOG_LEVEL(BL31_LOG_LEVEL);
1939a40c0fbSSheetal Tigadoli #endif
1949a40c0fbSSheetal Tigadoli
1959a40c0fbSSheetal Tigadoli brcm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
1969a40c0fbSSheetal Tigadoli
1979a40c0fbSSheetal Tigadoli plat_bcm_bl31_early_platform_setup((void *)arg0, (void *)arg3);
1989a40c0fbSSheetal Tigadoli
1999a40c0fbSSheetal Tigadoli #ifdef DRIVER_CC_ENABLE
2009a40c0fbSSheetal Tigadoli /*
2019a40c0fbSSheetal Tigadoli * Initialize Interconnect for this cluster during cold boot.
2029a40c0fbSSheetal Tigadoli * No need for locks as no other CPU is active.
2039a40c0fbSSheetal Tigadoli */
2049a40c0fbSSheetal Tigadoli plat_brcm_interconnect_init();
2059a40c0fbSSheetal Tigadoli
2069a40c0fbSSheetal Tigadoli /*
2079a40c0fbSSheetal Tigadoli * Enable Interconnect coherency for the primary CPU's cluster.
2089a40c0fbSSheetal Tigadoli * Earlier bootloader stages might already do this (e.g. Trusted
2099a40c0fbSSheetal Tigadoli * Firmware's BL1 does it) but we can't assume so. There is no harm in
2109a40c0fbSSheetal Tigadoli * executing this code twice anyway.
2119a40c0fbSSheetal Tigadoli * Platform specific PSCI code will enable coherency for other
2129a40c0fbSSheetal Tigadoli * clusters.
2139a40c0fbSSheetal Tigadoli */
2149a40c0fbSSheetal Tigadoli plat_brcm_interconnect_enter_coherency();
2159a40c0fbSSheetal Tigadoli #endif
2169a40c0fbSSheetal Tigadoli }
2179a40c0fbSSheetal Tigadoli
2189a40c0fbSSheetal Tigadoli /*******************************************************************************
2199a40c0fbSSheetal Tigadoli * Perform any BL31 platform setup common to ARM standard platforms
2209a40c0fbSSheetal Tigadoli ******************************************************************************/
brcm_bl31_platform_setup(void)2219a40c0fbSSheetal Tigadoli void brcm_bl31_platform_setup(void)
2229a40c0fbSSheetal Tigadoli {
2239a40c0fbSSheetal Tigadoli /* Initialize the GIC driver, cpu and distributor interfaces */
2249a40c0fbSSheetal Tigadoli plat_brcm_gic_driver_init();
2259a40c0fbSSheetal Tigadoli plat_brcm_gic_init();
2269a40c0fbSSheetal Tigadoli
2279a40c0fbSSheetal Tigadoli /* Initialize power controller before setting up topology */
2289a40c0fbSSheetal Tigadoli plat_brcm_pwrc_setup();
2299a40c0fbSSheetal Tigadoli }
2309a40c0fbSSheetal Tigadoli
2319a40c0fbSSheetal Tigadoli /*******************************************************************************
2329a40c0fbSSheetal Tigadoli * Perform any BL31 platform runtime setup prior to BL31 exit common to ARM
2339a40c0fbSSheetal Tigadoli * standard platforms
2349a40c0fbSSheetal Tigadoli * Perform BL31 platform setup
2359a40c0fbSSheetal Tigadoli ******************************************************************************/
brcm_bl31_plat_runtime_setup(void)2369a40c0fbSSheetal Tigadoli void brcm_bl31_plat_runtime_setup(void)
2379a40c0fbSSheetal Tigadoli {
2389a40c0fbSSheetal Tigadoli /* Initialize the runtime console */
2399a40c0fbSSheetal Tigadoli bcm_console_runtime_init();
2409a40c0fbSSheetal Tigadoli }
2419a40c0fbSSheetal Tigadoli
bl31_platform_setup(void)2429a40c0fbSSheetal Tigadoli void bl31_platform_setup(void)
2439a40c0fbSSheetal Tigadoli {
2449a40c0fbSSheetal Tigadoli brcm_bl31_platform_setup();
2459a40c0fbSSheetal Tigadoli
2469a40c0fbSSheetal Tigadoli /* Initialize the secure environment */
2479a40c0fbSSheetal Tigadoli plat_brcm_security_setup();
2489a40c0fbSSheetal Tigadoli }
2499a40c0fbSSheetal Tigadoli
bl31_plat_runtime_setup(void)2509a40c0fbSSheetal Tigadoli void bl31_plat_runtime_setup(void)
2519a40c0fbSSheetal Tigadoli {
2529a40c0fbSSheetal Tigadoli brcm_bl31_plat_runtime_setup();
2539a40c0fbSSheetal Tigadoli }
2549a40c0fbSSheetal Tigadoli
2559a40c0fbSSheetal Tigadoli /*******************************************************************************
2569a40c0fbSSheetal Tigadoli * Perform the very early platform specific architectural setup shared between
2579a40c0fbSSheetal Tigadoli * ARM standard platforms. This only does basic initialization. Later
2589a40c0fbSSheetal Tigadoli * architectural setup (bl31_arch_setup()) does not do anything platform
2599a40c0fbSSheetal Tigadoli * specific.
2609a40c0fbSSheetal Tigadoli ******************************************************************************/
brcm_bl31_plat_arch_setup(void)2619a40c0fbSSheetal Tigadoli void __init brcm_bl31_plat_arch_setup(void)
2629a40c0fbSSheetal Tigadoli {
2639a40c0fbSSheetal Tigadoli #ifndef MMU_DISABLED
2649a40c0fbSSheetal Tigadoli const mmap_region_t bl_regions[] = {
2659a40c0fbSSheetal Tigadoli MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE,
2669a40c0fbSSheetal Tigadoli MT_MEMORY | MT_RW | MT_SECURE),
2679a40c0fbSSheetal Tigadoli MAP_REGION_FLAT(BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE,
2689a40c0fbSSheetal Tigadoli MT_CODE | MT_SECURE),
2699a40c0fbSSheetal Tigadoli MAP_REGION_FLAT(BL_RO_DATA_BASE,
2709a40c0fbSSheetal Tigadoli BL_RO_DATA_END - BL_RO_DATA_BASE,
2719a40c0fbSSheetal Tigadoli MT_RO_DATA | MT_SECURE),
2729a40c0fbSSheetal Tigadoli #if USE_COHERENT_MEM
2739a40c0fbSSheetal Tigadoli MAP_REGION_FLAT(BL_COHERENT_RAM_BASE,
2749a40c0fbSSheetal Tigadoli BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE,
2759a40c0fbSSheetal Tigadoli MT_DEVICE | MT_RW | MT_SECURE),
2769a40c0fbSSheetal Tigadoli #endif
2779a40c0fbSSheetal Tigadoli {0}
2789a40c0fbSSheetal Tigadoli };
2799a40c0fbSSheetal Tigadoli
2809a40c0fbSSheetal Tigadoli setup_page_tables(bl_regions, plat_brcm_get_mmap());
2819a40c0fbSSheetal Tigadoli
2829a40c0fbSSheetal Tigadoli enable_mmu_el3(0);
2839a40c0fbSSheetal Tigadoli #endif
2849a40c0fbSSheetal Tigadoli }
2859a40c0fbSSheetal Tigadoli
bl31_plat_arch_setup(void)2869a40c0fbSSheetal Tigadoli void __init bl31_plat_arch_setup(void)
2879a40c0fbSSheetal Tigadoli {
2889a40c0fbSSheetal Tigadoli brcm_bl31_plat_arch_setup();
2899a40c0fbSSheetal Tigadoli }
290