1 /* 2 * Copyright (c) 2018-2022, 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 16 #include <platform_def.h> 17 #include <sgi_base_platform_def.h> 18 #include <sgi_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_sgi_get_isolated_cpu_list(struct isolated_cpu_mpid_list *list) 30 { 31 int ret; 32 33 ret = sds_init(); 34 if (ret != SDS_OK) { 35 ERROR("SDS initialization failed, error: %d\n", ret); 36 panic(); 37 } 38 39 ret = sds_struct_read(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_ISOLATED_CPU_LIST_ID, 58 sizeof(list->num_entries), 59 &list->mpid_list, 60 sizeof(list->mpid_list[0]) * list->num_entries, 61 SDS_ACCESS_MODE_CACHED); 62 if (ret != SDS_OK) { 63 ERROR("SDS CPU list read failed. error: %d\n", ret); 64 panic(); 65 } 66 } 67 68 /******************************************************************************* 69 * This function inserts Platform information via device tree nodes as, 70 * system-id { 71 * platform-id = <0>; 72 * config-id = <0>; 73 * isolated-cpu-list = <0> 74 * } 75 ******************************************************************************/ 76 static int plat_sgi_append_config_node(void) 77 { 78 bl_mem_params_node_t *mem_params; 79 void *fdt; 80 int nodeoffset, err; 81 unsigned int platid = 0, platcfg = 0; 82 struct isolated_cpu_mpid_list cpu_mpid_list = {0}; 83 84 mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID); 85 if (mem_params == NULL) { 86 ERROR("NT_FW CONFIG base address is NULL"); 87 return -1; 88 } 89 90 fdt = (void *)(mem_params->image_info.image_base); 91 92 /* Check the validity of the fdt */ 93 if (fdt_check_header(fdt) != 0) { 94 ERROR("Invalid NT_FW_CONFIG DTB passed\n"); 95 return -1; 96 } 97 98 nodeoffset = fdt_subnode_offset(fdt, 0, "system-id"); 99 if (nodeoffset < 0) { 100 ERROR("Failed to get system-id node offset\n"); 101 return -1; 102 } 103 104 platid = plat_arm_sgi_get_platform_id(); 105 err = fdt_setprop_u32(fdt, nodeoffset, "platform-id", platid); 106 if (err < 0) { 107 ERROR("Failed to set platform-id\n"); 108 return -1; 109 } 110 111 platcfg = plat_arm_sgi_get_config_id(); 112 err = fdt_setprop_u32(fdt, nodeoffset, "config-id", platcfg); 113 if (err < 0) { 114 ERROR("Failed to set config-id\n"); 115 return -1; 116 } 117 118 platcfg = plat_arm_sgi_get_multi_chip_mode(); 119 err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg); 120 if (err < 0) { 121 ERROR("Failed to set multi-chip-mode\n"); 122 return -1; 123 } 124 125 plat_arm_sgi_get_isolated_cpu_list(&cpu_mpid_list); 126 if (cpu_mpid_list.num_entries > 0) { 127 err = fdt_setprop(fdt, nodeoffset, "isolated-cpu-list", 128 &cpu_mpid_list, 129 (sizeof(cpu_mpid_list.num_entries) * 130 (cpu_mpid_list.num_entries + 1))); 131 if (err < 0) { 132 ERROR("Failed to set isolated-cpu-list, error: %d\n", 133 err); 134 } 135 } 136 137 flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size); 138 139 return 0; 140 } 141 142 /******************************************************************************* 143 * This function returns the list of executable images. 144 ******************************************************************************/ 145 bl_params_t *plat_get_next_bl_params(void) 146 { 147 int ret; 148 149 ret = plat_sgi_append_config_node(); 150 if (ret != 0) 151 panic(); 152 153 return arm_get_next_bl_params(); 154 } 155 156