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