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