mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-15 17:14:21 +00:00

To enable the support to load Hafnium as BL32, BL31 needs firmware configuration info to get BL32 manifest load location. The load address of BL32 is passed via firmware config info. Add the support to get the address using fconf framework from dynamic config info. Signed-off-by: Nishant Sharma <nishant.sharma@arm.com> Signed-off-by: Rakshit Goyal <rakshit.goyal@arm.com> Change-Id: I3a2a5706789ed290dc7f4a67e62e03751b930c02
183 lines
4.8 KiB
C
183 lines
4.8 KiB
C
/*
|
|
* Copyright (c) 2018-2025, Arm Limited and Contributors. All rights reserved.
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#include <libfdt.h>
|
|
|
|
#include <arch_helpers.h>
|
|
#include <common/debug.h>
|
|
#include <common/desc_image_load.h>
|
|
#include <drivers/arm/css/sds.h>
|
|
#include <lib/fconf/fconf.h>
|
|
#include <lib/fconf/fconf_dyn_cfg_getter.h>
|
|
#include <plat/arm/common/plat_arm.h>
|
|
#include <plat/common/platform.h>
|
|
#include <platform_def.h>
|
|
|
|
#include <nrd_variant.h>
|
|
|
|
/*
|
|
* Information about the isolated CPUs obtained from SDS.
|
|
*/
|
|
struct isolated_cpu_mpid_list {
|
|
uint64_t num_entries; /* Number of entries in the list */
|
|
uint64_t mpid_list[PLATFORM_CORE_COUNT]; /* List of isolated CPU MPIDs */
|
|
};
|
|
|
|
/* Function to read isolated CPU MPID list from SDS. */
|
|
void plat_arm_nrd_get_isolated_cpu_list(struct isolated_cpu_mpid_list *list)
|
|
{
|
|
int ret;
|
|
|
|
ret = sds_init(SDS_SCP_AP_REGION_ID);
|
|
if (ret != SDS_OK) {
|
|
ERROR("SDS initialization failed, error: %d\n", ret);
|
|
panic();
|
|
}
|
|
|
|
ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
|
|
SDS_ISOLATED_CPU_LIST_ID, 0, &list->num_entries,
|
|
sizeof(list->num_entries), SDS_ACCESS_MODE_CACHED);
|
|
if (ret != SDS_OK) {
|
|
INFO("SDS CPU num elements read failed, error: %d\n", ret);
|
|
list->num_entries = 0;
|
|
return;
|
|
}
|
|
|
|
if (list->num_entries > PLATFORM_CORE_COUNT) {
|
|
ERROR("Isolated CPU list count %ld greater than max"
|
|
" number supported %d\n",
|
|
list->num_entries, PLATFORM_CORE_COUNT);
|
|
panic();
|
|
} else if (list->num_entries == 0) {
|
|
INFO("SDS isolated CPU list is empty\n");
|
|
return;
|
|
}
|
|
|
|
ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
|
|
SDS_ISOLATED_CPU_LIST_ID,
|
|
sizeof(list->num_entries),
|
|
&list->mpid_list,
|
|
sizeof(list->mpid_list[0]) * list->num_entries,
|
|
SDS_ACCESS_MODE_CACHED);
|
|
if (ret != SDS_OK) {
|
|
ERROR("SDS CPU list read failed. error: %d\n", ret);
|
|
panic();
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* This function inserts Platform information via device tree nodes as,
|
|
* system-id {
|
|
* platform-id = <0>;
|
|
* config-id = <0>;
|
|
* isolated-cpu-list = <0>
|
|
* }
|
|
******************************************************************************/
|
|
static int plat_nrd_append_config_node(void)
|
|
{
|
|
bl_mem_params_node_t *mem_params;
|
|
void *fdt;
|
|
int nodeoffset, err;
|
|
unsigned int platid = 0, platcfg = 0;
|
|
struct isolated_cpu_mpid_list cpu_mpid_list = {0};
|
|
|
|
mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
|
|
if (mem_params == NULL) {
|
|
ERROR("NT_FW CONFIG base address is NULL");
|
|
return -1;
|
|
}
|
|
|
|
fdt = (void *)(mem_params->image_info.image_base);
|
|
|
|
/* Check the validity of the fdt */
|
|
if (fdt_check_header(fdt) != 0) {
|
|
ERROR("Invalid NT_FW_CONFIG DTB passed\n");
|
|
return -1;
|
|
}
|
|
|
|
nodeoffset = fdt_subnode_offset(fdt, 0, "system-id");
|
|
if (nodeoffset < 0) {
|
|
ERROR("Failed to get system-id node offset\n");
|
|
return -1;
|
|
}
|
|
|
|
platid = plat_arm_nrd_get_platform_id();
|
|
err = fdt_setprop_u32(fdt, nodeoffset, "platform-id", platid);
|
|
if (err < 0) {
|
|
ERROR("Failed to set platform-id\n");
|
|
return -1;
|
|
}
|
|
|
|
platcfg = plat_arm_nrd_get_config_id();
|
|
err = fdt_setprop_u32(fdt, nodeoffset, "config-id", platcfg);
|
|
if (err < 0) {
|
|
ERROR("Failed to set config-id\n");
|
|
return -1;
|
|
}
|
|
|
|
platcfg = plat_arm_nrd_get_multi_chip_mode();
|
|
err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg);
|
|
if (err < 0) {
|
|
ERROR("Failed to set multi-chip-mode\n");
|
|
return -1;
|
|
}
|
|
|
|
plat_arm_nrd_get_isolated_cpu_list(&cpu_mpid_list);
|
|
if (cpu_mpid_list.num_entries > 0) {
|
|
err = fdt_setprop(fdt, nodeoffset, "isolated-cpu-list",
|
|
&cpu_mpid_list,
|
|
(sizeof(cpu_mpid_list.num_entries) *
|
|
(cpu_mpid_list.num_entries + 1)));
|
|
if (err < 0) {
|
|
ERROR("Failed to set isolated-cpu-list, error: %d\n",
|
|
err);
|
|
}
|
|
}
|
|
|
|
flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* This function returns the list of executable images.
|
|
******************************************************************************/
|
|
bl_params_t *plat_get_next_bl_params(void)
|
|
{
|
|
struct bl_params *arm_bl_params;
|
|
int ret;
|
|
|
|
ret = plat_nrd_append_config_node();
|
|
if (ret != 0)
|
|
panic();
|
|
|
|
arm_bl_params = arm_get_next_bl_params();
|
|
|
|
#if !EL3_PAYLOAD_BASE
|
|
const struct dyn_cfg_dtb_info_t *fw_config_info;
|
|
bl_mem_params_node_t *param_node;
|
|
uintptr_t fw_config_base = 0UL;
|
|
|
|
/* Get BL31 image node */
|
|
param_node = get_bl_mem_params_node(BL31_IMAGE_ID);
|
|
assert(param_node != NULL);
|
|
|
|
/* Get fw_config load address */
|
|
fw_config_info = FCONF_GET_PROPERTY(dyn_cfg, dtb, FW_CONFIG_ID);
|
|
assert(fw_config_info != NULL);
|
|
|
|
fw_config_base = fw_config_info->config_addr;
|
|
assert(fw_config_base != 0UL);
|
|
|
|
/*
|
|
* Get the entry point info of next executable image and override
|
|
* arg1 of entry point info with fw_config base address
|
|
*/
|
|
param_node->ep_info.args.arg1 = (uint64_t)fw_config_base;
|
|
|
|
#endif
|
|
return arm_bl_params;
|
|
}
|