181528dbcSRoberto Vargas /* 2973e0b7fSDivin Raj * Copyright (c) 2017-2024, ARM Limited and Contributors. All rights reserved. 381528dbcSRoberto Vargas * 481528dbcSRoberto Vargas * SPDX-License-Identifier: BSD-3-Clause 581528dbcSRoberto Vargas */ 609d40e0eSAntonio Nino Diaz 7d323af9eSDaniel Boulby #include <assert.h> 809d40e0eSAntonio Nino Diaz 909d40e0eSAntonio Nino Diaz #include <drivers/generic_delay_timer.h> 106ed98c45SHarsimran Singh Tungal #include <drivers/partition/partition.h> 11973e0b7fSDivin Raj #include <lib/fconf/fconf.h> 12973e0b7fSDivin Raj #include <lib/fconf/fconf_dyn_cfg_getter.h> 13bd9344f6SAntonio Nino Diaz #include <plat/arm/common/plat_arm.h> 1409d40e0eSAntonio Nino Diaz #include <plat/common/platform.h> 15234bc7f8SAntonio Nino Diaz #include <platform_def.h> 1609d40e0eSAntonio Nino Diaz 1781528dbcSRoberto Vargas #pragma weak bl2_el3_early_platform_setup 1881528dbcSRoberto Vargas #pragma weak bl2_el3_plat_arch_setup 1981528dbcSRoberto Vargas #pragma weak bl2_el3_plat_prepare_exit 2081528dbcSRoberto Vargas 21d323af9eSDaniel Boulby #define MAP_BL2_EL3_TOTAL MAP_REGION_FLAT( \ 22d323af9eSDaniel Boulby bl2_el3_tzram_layout.total_base, \ 23d323af9eSDaniel Boulby bl2_el3_tzram_layout.total_size, \ 24d323af9eSDaniel Boulby MT_MEMORY | MT_RW | MT_SECURE) 25d323af9eSDaniel Boulby 2681528dbcSRoberto Vargas static meminfo_t bl2_el3_tzram_layout; 2781528dbcSRoberto Vargas 2881528dbcSRoberto Vargas /* 2981528dbcSRoberto Vargas * Perform arm specific early platform setup. At this moment we only initialize 3081528dbcSRoberto Vargas * the console and the memory layout. 3181528dbcSRoberto Vargas */ 3281528dbcSRoberto Vargas void arm_bl2_el3_early_platform_setup(void) 3381528dbcSRoberto Vargas { 3481528dbcSRoberto Vargas /* Initialize the console to provide early debug support */ 3588a0523eSAntonio Nino Diaz arm_console_boot_init(); 3681528dbcSRoberto Vargas 3781528dbcSRoberto Vargas /* 3881528dbcSRoberto Vargas * Allow BL2 to see the whole Trusted RAM. This is determined 3981528dbcSRoberto Vargas * statically since we cannot rely on BL1 passing this information 4042d4d3baSArvind Ram Prakash * in the RESET_TO_BL2 case. 4181528dbcSRoberto Vargas */ 4281528dbcSRoberto Vargas bl2_el3_tzram_layout.total_base = ARM_BL_RAM_BASE; 4381528dbcSRoberto Vargas bl2_el3_tzram_layout.total_size = ARM_BL_RAM_SIZE; 4481528dbcSRoberto Vargas 4581528dbcSRoberto Vargas /* Initialise the IO layer and register platform IO devices */ 4681528dbcSRoberto Vargas plat_arm_io_setup(); 4781528dbcSRoberto Vargas } 4881528dbcSRoberto Vargas 4981528dbcSRoberto Vargas void bl2_el3_early_platform_setup(u_register_t arg0 __unused, 5081528dbcSRoberto Vargas u_register_t arg1 __unused, 5181528dbcSRoberto Vargas u_register_t arg2 __unused, 5281528dbcSRoberto Vargas u_register_t arg3 __unused) 5381528dbcSRoberto Vargas { 5481528dbcSRoberto Vargas arm_bl2_el3_early_platform_setup(); 55*36fbcf4dSAhmed Azeem #if !HW_ASSISTED_COHERENCY 5681528dbcSRoberto Vargas /* 5781528dbcSRoberto Vargas * Initialize Interconnect for this cluster during cold boot. 5881528dbcSRoberto Vargas * No need for locks as no other CPU is active. 5981528dbcSRoberto Vargas */ 6081528dbcSRoberto Vargas plat_arm_interconnect_init(); 6181528dbcSRoberto Vargas /* 6281528dbcSRoberto Vargas * Enable Interconnect coherency for the primary CPU's cluster. 6381528dbcSRoberto Vargas */ 6481528dbcSRoberto Vargas plat_arm_interconnect_enter_coherency(); 65*36fbcf4dSAhmed Azeem #endif 6681528dbcSRoberto Vargas generic_delay_timer_init(); 6781528dbcSRoberto Vargas } 6881528dbcSRoberto Vargas 69973e0b7fSDivin Raj #if ARM_FW_CONFIG_LOAD_ENABLE 70973e0b7fSDivin Raj /************************************************************************************* 71973e0b7fSDivin Raj * FW CONFIG load function for BL2 when RESET_TO_BL2=1 && ARM_FW_CONFIG_LOAD_ENABLE=1 72973e0b7fSDivin Raj *************************************************************************************/ 73973e0b7fSDivin Raj void arm_bl2_el3_plat_config_load(void) 74973e0b7fSDivin Raj { 75973e0b7fSDivin Raj int ret; 76973e0b7fSDivin Raj const struct dyn_cfg_dtb_info_t *fw_config_info; 77973e0b7fSDivin Raj 78973e0b7fSDivin Raj /* Set global DTB info for fixed fw_config information */ 79973e0b7fSDivin Raj set_config_info(PLAT_FW_CONFIG_BASE, ~0UL, PLAT_FW_CONFIG_MAX_SIZE, FW_CONFIG_ID); 80973e0b7fSDivin Raj 81973e0b7fSDivin Raj /* Fill the device tree information struct with the info from the config dtb */ 82973e0b7fSDivin Raj ret = fconf_load_config(FW_CONFIG_ID); 83973e0b7fSDivin Raj if (ret < 0) { 84973e0b7fSDivin Raj ERROR("Loading of FW_CONFIG failed %d\n", ret); 85973e0b7fSDivin Raj plat_error_handler(ret); 86973e0b7fSDivin Raj } 87973e0b7fSDivin Raj 88973e0b7fSDivin Raj /* 89973e0b7fSDivin Raj * FW_CONFIG loaded successfully. Check the FW_CONFIG device tree parsing 90973e0b7fSDivin Raj * is successful. 91973e0b7fSDivin Raj */ 92973e0b7fSDivin Raj fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID); 93973e0b7fSDivin Raj if (fw_config_info == NULL) { 94973e0b7fSDivin Raj ret = -1; 95973e0b7fSDivin Raj ERROR("Invalid FW_CONFIG address\n"); 96973e0b7fSDivin Raj plat_error_handler(ret); 97973e0b7fSDivin Raj } 98973e0b7fSDivin Raj ret = fconf_populate_dtb_registry(fw_config_info->config_addr); 99973e0b7fSDivin Raj if (ret < 0) { 100973e0b7fSDivin Raj ERROR("Parsing of FW_CONFIG failed %d\n", ret); 101973e0b7fSDivin Raj plat_error_handler(ret); 102973e0b7fSDivin Raj } 103973e0b7fSDivin Raj } 104973e0b7fSDivin Raj #endif /* ARM_FW_CONFIG_LOAD_ENABLE */ 105973e0b7fSDivin Raj 10681528dbcSRoberto Vargas /******************************************************************************* 10781528dbcSRoberto Vargas * Perform the very early platform specific architectural setup here. At the 10881528dbcSRoberto Vargas * moment this is only initializes the mmu in a quick and dirty way. 10981528dbcSRoberto Vargas ******************************************************************************/ 11081528dbcSRoberto Vargas void arm_bl2_el3_plat_arch_setup(void) 11181528dbcSRoberto Vargas { 112d323af9eSDaniel Boulby 11381528dbcSRoberto Vargas #if USE_COHERENT_MEM 11442d4d3baSArvind Ram Prakash /* Ensure ARM platforms dont use coherent memory 11542d4d3baSArvind Ram Prakash * in RESET_TO_BL2 11642d4d3baSArvind Ram Prakash */ 117d323af9eSDaniel Boulby assert(BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE == 0U); 11881528dbcSRoberto Vargas #endif 119d323af9eSDaniel Boulby 120d323af9eSDaniel Boulby const mmap_region_t bl_regions[] = { 121d323af9eSDaniel Boulby MAP_BL2_EL3_TOTAL, 1222ecaafd2SDaniel Boulby ARM_MAP_BL_RO, 123d323af9eSDaniel Boulby {0} 124d323af9eSDaniel Boulby }; 125d323af9eSDaniel Boulby 1260916c38dSRoberto Vargas setup_page_tables(bl_regions, plat_arm_get_mmap()); 12781528dbcSRoberto Vargas 128402b3cf8SJulius Werner #ifdef __aarch64__ 12981528dbcSRoberto Vargas enable_mmu_el3(0); 130402b3cf8SJulius Werner #else 131402b3cf8SJulius Werner enable_mmu_svc_mon(0); 13281528dbcSRoberto Vargas #endif 13381528dbcSRoberto Vargas } 13481528dbcSRoberto Vargas 13581528dbcSRoberto Vargas void bl2_el3_plat_arch_setup(void) 13681528dbcSRoberto Vargas { 1376ed98c45SHarsimran Singh Tungal int __maybe_unused ret; 13881528dbcSRoberto Vargas arm_bl2_el3_plat_arch_setup(); 1396ed98c45SHarsimran Singh Tungal #if ARM_GPT_SUPPORT 1406ed98c45SHarsimran Singh Tungal ret = gpt_partition_init(); 1416ed98c45SHarsimran Singh Tungal if (ret != 0) { 1426ed98c45SHarsimran Singh Tungal ERROR("GPT partition initialisation failed!\n"); 1436ed98c45SHarsimran Singh Tungal panic(); 1446ed98c45SHarsimran Singh Tungal } 1456ed98c45SHarsimran Singh Tungal #endif /* ARM_GPT_SUPPORT */ 14681528dbcSRoberto Vargas } 14781528dbcSRoberto Vargas 14881528dbcSRoberto Vargas void bl2_el3_plat_prepare_exit(void) 14981528dbcSRoberto Vargas { 15081528dbcSRoberto Vargas } 151