mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-18 02:24:18 +00:00

BL2_AT_EL3 is an overloaded macro which has two uses: 1. When BL2 is entry point into TF-A(no BL1) 2. When BL2 is running at EL3 exception level These two scenarios are not exactly same even though first implicitly means second to be true. To distinguish between these two use cases we introduce new macros. BL2_AT_EL3 is renamed to RESET_TO_BL2 to better convey both 1. and 2. Additional macro BL2_RUNS_AT_EL3 is added to cover all scenarious where BL2 runs at EL3 (including four world systems). BREAKING CHANGE: BL2_AT_EL3 renamed to RESET_TO_BL2 across the repository. Change-Id: I477e1d0f843b44b799c216670e028fcb3509fb72 Signed-off-by: Arvind Ram Prakash <arvind.ramprakash@arm.com> Signed-off-by: Maksims Svecovs <maksims.svecovs@arm.com>
156 lines
4.8 KiB
C
156 lines
4.8 KiB
C
/*
|
|
* Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <common/debug.h>
|
|
#include <drivers/arm/smmu_v3.h>
|
|
#include <fconf_hw_config_getter.h>
|
|
#include <lib/fconf/fconf.h>
|
|
#include <lib/fconf/fconf_dyn_cfg_getter.h>
|
|
#include <lib/mmio.h>
|
|
#include <plat/arm/common/arm_config.h>
|
|
#include <plat/arm/common/plat_arm.h>
|
|
#include <plat/common/platform.h>
|
|
|
|
#include "fvp_private.h"
|
|
|
|
static const struct dyn_cfg_dtb_info_t *hw_config_info __unused;
|
|
|
|
void __init bl31_early_platform_setup2(u_register_t arg0,
|
|
u_register_t arg1, u_register_t arg2, u_register_t arg3)
|
|
{
|
|
/* Initialize the console to provide early debug support */
|
|
arm_console_boot_init();
|
|
|
|
#if !RESET_TO_BL31 && !RESET_TO_BL2
|
|
const struct dyn_cfg_dtb_info_t *soc_fw_config_info;
|
|
|
|
INFO("BL31 FCONF: FW_CONFIG address = %lx\n", (uintptr_t)arg1);
|
|
/* Fill the properties struct with the info from the config dtb */
|
|
fconf_populate("FW_CONFIG", arg1);
|
|
|
|
soc_fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, SOC_FW_CONFIG_ID);
|
|
if (soc_fw_config_info != NULL) {
|
|
arg1 = soc_fw_config_info->config_addr;
|
|
}
|
|
|
|
/*
|
|
* arg2 is currently holding the 'secure' address of HW_CONFIG.
|
|
* But arm_bl31_early_platform_setup() below expects the 'non-secure'
|
|
* address of HW_CONFIG (which it will pass to BL33).
|
|
* This why we need to override arg2 here.
|
|
*/
|
|
hw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, HW_CONFIG_ID);
|
|
assert(hw_config_info != NULL);
|
|
assert(hw_config_info->secondary_config_addr != 0UL);
|
|
arg2 = hw_config_info->secondary_config_addr;
|
|
#endif /* !RESET_TO_BL31 && !RESET_TO_BL2 */
|
|
|
|
arm_bl31_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3);
|
|
|
|
/* Initialize the platform config for future decision making */
|
|
fvp_config_setup();
|
|
|
|
/*
|
|
* Initialize the correct interconnect for this cluster during cold
|
|
* boot. No need for locks as no other CPU is active.
|
|
*/
|
|
fvp_interconnect_init();
|
|
|
|
/*
|
|
* Enable coherency in interconnect for the primary CPU's cluster.
|
|
* Earlier bootloader stages might already do this (e.g. Trusted
|
|
* Firmware's BL1 does it) but we can't assume so. There is no harm in
|
|
* executing this code twice anyway.
|
|
* FVP PSCI code will enable coherency for other clusters.
|
|
*/
|
|
fvp_interconnect_enable();
|
|
|
|
/* Initialize System level generic or SP804 timer */
|
|
fvp_timer_init();
|
|
|
|
/* On FVP RevC, initialize SMMUv3 */
|
|
if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U)
|
|
smmuv3_init(PLAT_FVP_SMMUV3_BASE);
|
|
}
|
|
|
|
void __init bl31_plat_arch_setup(void)
|
|
{
|
|
int rc __unused;
|
|
uintptr_t hw_config_base_align __unused;
|
|
size_t mapped_size_align __unused;
|
|
|
|
arm_bl31_plat_arch_setup();
|
|
|
|
/*
|
|
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run.
|
|
* So there is no BL2 to load the HW_CONFIG dtb into memory before
|
|
* control is passed to BL31. The code below relies on dynamic mapping
|
|
* capability, which is not supported by xlat tables lib V1.
|
|
* TODO: remove the ARM_XLAT_TABLES_LIB_V1 check when its support
|
|
* gets deprecated.
|
|
*/
|
|
#if !RESET_TO_BL31 && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1
|
|
assert(hw_config_info != NULL);
|
|
assert(hw_config_info->config_addr != 0UL);
|
|
|
|
/* Page aligned address and size if necessary */
|
|
hw_config_base_align = page_align(hw_config_info->config_addr, DOWN);
|
|
mapped_size_align = page_align(hw_config_info->config_max_size, UP);
|
|
|
|
if ((hw_config_info->config_addr != hw_config_base_align) &&
|
|
(hw_config_info->config_max_size == mapped_size_align)) {
|
|
mapped_size_align += PAGE_SIZE;
|
|
}
|
|
|
|
/*
|
|
* map dynamically HW config region with its aligned base address and
|
|
* size
|
|
*/
|
|
rc = mmap_add_dynamic_region((unsigned long long)hw_config_base_align,
|
|
hw_config_base_align,
|
|
mapped_size_align,
|
|
MT_RO_DATA);
|
|
if (rc != 0) {
|
|
ERROR("Error while mapping HW_CONFIG device tree (%d).\n", rc);
|
|
panic();
|
|
}
|
|
|
|
/* Populate HW_CONFIG device tree with the mapped address */
|
|
fconf_populate("HW_CONFIG", hw_config_info->config_addr);
|
|
|
|
/* unmap the HW_CONFIG memory region */
|
|
rc = mmap_remove_dynamic_region(hw_config_base_align, mapped_size_align);
|
|
if (rc != 0) {
|
|
ERROR("Error while unmapping HW_CONFIG device tree (%d).\n",
|
|
rc);
|
|
panic();
|
|
}
|
|
#endif /* !RESET_TO_BL31 && !RESET_TO_BL2 && !ARM_XLAT_TABLES_LIB_V1 */
|
|
}
|
|
|
|
unsigned int plat_get_syscnt_freq2(void)
|
|
{
|
|
unsigned int counter_base_frequency;
|
|
|
|
#if !RESET_TO_BL31 && !RESET_TO_BL2
|
|
/* Get the frequency through FCONF API for HW_CONFIG */
|
|
counter_base_frequency = FCONF_GET_PROPERTY(hw_config, cpu_timer, clock_freq);
|
|
if (counter_base_frequency > 0U) {
|
|
return counter_base_frequency;
|
|
}
|
|
#endif
|
|
|
|
/* Read the frequency from Frequency modes table */
|
|
counter_base_frequency = mmio_read_32(ARM_SYS_CNTCTL_BASE + CNTFID_OFF);
|
|
|
|
/* The first entry of the frequency modes table must not be 0 */
|
|
if (counter_base_frequency == 0U) {
|
|
panic();
|
|
}
|
|
|
|
return counter_base_frequency;
|
|
}
|