1 /* 2 * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 9 #include <common/debug.h> 10 #include <common/fdt_wrappers.h> 11 #include <drivers/io/io_storage.h> 12 #include <lib/object_pool.h> 13 #include <libfdt.h> 14 #include <plat/arm/common/arm_fconf_getter.h> 15 #include <plat/arm/common/arm_fconf_io_storage.h> 16 #include <plat/arm/common/fconf_arm_sp_getter.h> 17 #include <platform_def.h> 18 #include <tools_share/firmware_image_package.h> 19 20 #ifdef IMAGE_BL2 21 22 struct arm_sp_t arm_sp; 23 24 int fconf_populate_arm_sp(uintptr_t config) 25 { 26 int sp_node, node, err; 27 union uuid_helper_t uuid_helper; 28 29 /* As libfdt use void *, we can't avoid this cast */ 30 const void *dtb = (void *)config; 31 32 /* Assert the node offset point to "arm,sp" compatible property */ 33 const char *compatible_str = "arm,sp"; 34 35 node = fdt_node_offset_by_compatible(dtb, -1, compatible_str); 36 if (node < 0) { 37 ERROR("FCONF: Can't find %s in dtb\n", compatible_str); 38 return node; 39 } 40 41 fdt_for_each_subnode(sp_node, dtb, node) { 42 err = fdtw_read_array(dtb, sp_node, "uuid", 4, 43 &uuid_helper.word); 44 if (err < 0) { 45 ERROR("FCONF: cannot read SP uuid\n"); 46 return -1; 47 } 48 49 arm_sp.uuids[arm_sp.number_of_sp] = uuid_helper; 50 51 err = fdtw_read_cells(dtb, sp_node, "load-address", 1, 52 &arm_sp.load_addr[arm_sp.number_of_sp]); 53 if (err < 0) { 54 ERROR("FCONF: cannot read SP load address\n"); 55 return -1; 56 } 57 58 VERBOSE("FCONF: %s UUID %x-%x-%x-%x load_addr=%lx\n", 59 __func__, 60 uuid_helper.word[0], 61 uuid_helper.word[1], 62 uuid_helper.word[2], 63 uuid_helper.word[3], 64 arm_sp.load_addr[arm_sp.number_of_sp]); 65 66 arm_sp.number_of_sp++; 67 68 if (arm_sp.number_of_sp >= MAX_SP_IDS) { 69 ERROR("FCONF: reached max number of SPs\n"); 70 return -1; 71 } 72 } 73 74 if ((sp_node < 0) && (sp_node != -FDT_ERR_NOTFOUND)) { 75 ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node); 76 return sp_node; 77 } 78 79 return 0; 80 } 81 82 FCONF_REGISTER_POPULATOR(arm_sp, fconf_populate_arm_sp); 83 84 #endif /* IMAGE_BL2 */ 85