1 /* 2 * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <libfdt.h> 8 9 #include <arch_helpers.h> 10 #include <common/debug.h> 11 #include <common/desc_image_load.h> 12 #include <drivers/arm/css/sds.h> 13 #include <plat/arm/common/plat_arm.h> 14 #include <plat/common/platform.h> 15 #include <platform_def.h> 16 17 #include <nrd_variant.h> 18 19 /* 20 * Information about the isolated CPUs obtained from SDS. 21 */ 22 struct isolated_cpu_mpid_list { 23 uint64_t num_entries; /* Number of entries in the list */ 24 uint64_t mpid_list[PLATFORM_CORE_COUNT]; /* List of isolated CPU MPIDs */ 25 }; 26 27 /* Function to read isolated CPU MPID list from SDS. */ 28 void plat_arm_nrd_get_isolated_cpu_list(struct isolated_cpu_mpid_list *list) 29 { 30 int ret; 31 32 ret = sds_init(SDS_SCP_AP_REGION_ID); 33 if (ret != SDS_OK) { 34 ERROR("SDS initialization failed, error: %d\n", ret); 35 panic(); 36 } 37 38 ret = sds_struct_read(SDS_SCP_AP_REGION_ID, 39 SDS_ISOLATED_CPU_LIST_ID, 0, &list->num_entries, 40 sizeof(list->num_entries), SDS_ACCESS_MODE_CACHED); 41 if (ret != SDS_OK) { 42 INFO("SDS CPU num elements read failed, error: %d\n", ret); 43 list->num_entries = 0; 44 return; 45 } 46 47 if (list->num_entries > PLATFORM_CORE_COUNT) { 48 ERROR("Isolated CPU list count %ld greater than max" 49 " number supported %d\n", 50 list->num_entries, PLATFORM_CORE_COUNT); 51 panic(); 52 } else if (list->num_entries == 0) { 53 INFO("SDS isolated CPU list is empty\n"); 54 return; 55 } 56 57 ret = sds_struct_read(SDS_SCP_AP_REGION_ID, 58 SDS_ISOLATED_CPU_LIST_ID, 59 sizeof(list->num_entries), 60 &list->mpid_list, 61 sizeof(list->mpid_list[0]) * list->num_entries, 62 SDS_ACCESS_MODE_CACHED); 63 if (ret != SDS_OK) { 64 ERROR("SDS CPU list read failed. error: %d\n", ret); 65 panic(); 66 } 67 } 68 69 /******************************************************************************* 70 * This function inserts Platform information via device tree nodes as, 71 * system-id { 72 * platform-id = <0>; 73 * config-id = <0>; 74 * isolated-cpu-list = <0> 75 * } 76 ******************************************************************************/ 77 static int plat_nrd_append_config_node(void) 78 { 79 bl_mem_params_node_t *mem_params; 80 void *fdt; 81 int nodeoffset, err; 82 unsigned int platid = 0, platcfg = 0; 83 struct isolated_cpu_mpid_list cpu_mpid_list = {0}; 84 85 mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID); 86 if (mem_params == NULL) { 87 ERROR("NT_FW CONFIG base address is NULL"); 88 return -1; 89 } 90 91 fdt = (void *)(mem_params->image_info.image_base); 92 93 /* Check the validity of the fdt */ 94 if (fdt_check_header(fdt) != 0) { 95 ERROR("Invalid NT_FW_CONFIG DTB passed\n"); 96 return -1; 97 } 98 99 nodeoffset = fdt_subnode_offset(fdt, 0, "system-id"); 100 if (nodeoffset < 0) { 101 ERROR("Failed to get system-id node offset\n"); 102 return -1; 103 } 104 105 platid = plat_arm_nrd_get_platform_id(); 106 err = fdt_setprop_u32(fdt, nodeoffset, "platform-id", platid); 107 if (err < 0) { 108 ERROR("Failed to set platform-id\n"); 109 return -1; 110 } 111 112 platcfg = plat_arm_nrd_get_config_id(); 113 err = fdt_setprop_u32(fdt, nodeoffset, "config-id", platcfg); 114 if (err < 0) { 115 ERROR("Failed to set config-id\n"); 116 return -1; 117 } 118 119 platcfg = plat_arm_nrd_get_multi_chip_mode(); 120 err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg); 121 if (err < 0) { 122 ERROR("Failed to set multi-chip-mode\n"); 123 return -1; 124 } 125 126 plat_arm_nrd_get_isolated_cpu_list(&cpu_mpid_list); 127 if (cpu_mpid_list.num_entries > 0) { 128 err = fdt_setprop(fdt, nodeoffset, "isolated-cpu-list", 129 &cpu_mpid_list, 130 (sizeof(cpu_mpid_list.num_entries) * 131 (cpu_mpid_list.num_entries + 1))); 132 if (err < 0) { 133 ERROR("Failed to set isolated-cpu-list, error: %d\n", 134 err); 135 } 136 } 137 138 flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size); 139 140 return 0; 141 } 142 143 /******************************************************************************* 144 * This function returns the list of executable images. 145 ******************************************************************************/ 146 bl_params_t *plat_get_next_bl_params(void) 147 { 148 int ret; 149 150 ret = plat_nrd_append_config_node(); 151 if (ret != 0) 152 panic(); 153 154 return arm_get_next_bl_params(); 155 } 156