/* * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include #include #include #include #include #include #include #include /* * 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) { int ret; ret = plat_nrd_append_config_node(); if (ret != 0) panic(); return arm_get_next_bl_params(); }