1 /* 2 * Copyright (c) 2022-2024, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch_helpers.h> 8 #include <common/debug.h> 9 #include <common/desc_image_load.h> 10 #include <drivers/arm/css/sds.h> 11 #include <libfdt.h> 12 #include <plat/common/platform.h> 13 14 #include "n1sdp_def.h" 15 #include <plat/arm/common/plat_arm.h> 16 #include <platform_def.h> 17 18 /* 19 * Platform information structure stored in SDS. 20 * This structure holds information about platform's DDR 21 * size which will be used to zero out the memory before 22 * enabling the ECC capability as well as information 23 * about multichip setup 24 * - multichip mode 25 * - secondary_count 26 * - Local DDR size in GB, DDR memory in master board 27 * - Remote DDR size in GB, DDR memory in secondary board 28 */ 29 struct n1sdp_plat_info { 30 bool multichip_mode; 31 uint8_t secondary_count; 32 uint8_t local_ddr_size; 33 uint8_t remote_ddr_size; 34 } __packed; 35 36 /******************************************************************************* 37 * This function inserts Platform information via device tree nodes as, 38 * platform-info { 39 * multichip-mode = <0x0>; 40 * secondary-chip-count = <0x0>; 41 * local-ddr-size = <0x0>; 42 * remote-ddr-size = <0x0>; 43 * }; 44 ******************************************************************************/ 45 static int plat_n1sdp_append_config_node(struct n1sdp_plat_info *plat_info) 46 { 47 bl_mem_params_node_t *mem_params; 48 void *fdt; 49 int nodeoffset, err; 50 51 mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID); 52 if (mem_params == NULL) { 53 ERROR("NT_FW CONFIG base address is NULL\n"); 54 return -1; 55 } 56 57 fdt = (void *)(mem_params->image_info.image_base); 58 59 /* Check the validity of the fdt */ 60 if (fdt_check_header(fdt) != 0) { 61 ERROR("Invalid NT_FW_CONFIG DTB passed\n"); 62 return -1; 63 } 64 65 nodeoffset = fdt_subnode_offset(fdt, 0, "platform-info"); 66 if (nodeoffset < 0) { 67 ERROR("NT_FW_CONFIG: Failed to get platform-info node offset\n"); 68 return -1; 69 } 70 71 err = fdt_setprop_u32(fdt, nodeoffset, "multichip-mode", 72 plat_info->multichip_mode); 73 if (err < 0) { 74 ERROR("NT_FW_CONFIG: Failed to set multichip-mode\n"); 75 return -1; 76 } 77 78 err = fdt_setprop_u32(fdt, nodeoffset, "secondary-chip-count", 79 plat_info->secondary_count); 80 if (err < 0) { 81 ERROR("NT_FW_CONFIG: Failed to set secondary-chip-count\n"); 82 return -1; 83 } 84 85 err = fdt_setprop_u32(fdt, nodeoffset, "local-ddr-size", 86 plat_info->local_ddr_size); 87 if (err < 0) { 88 ERROR("NT_FW_CONFIG: Failed to set local-ddr-size\n"); 89 return -1; 90 } 91 92 err = fdt_setprop_u32(fdt, nodeoffset, "remote-ddr-size", 93 plat_info->remote_ddr_size); 94 if (err < 0) { 95 ERROR("NT_FW_CONFIG: Failed to set remote-ddr-size\n"); 96 return -1; 97 } 98 99 flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size); 100 101 return 0; 102 } 103 104 /******************************************************************************* 105 * This function returns the list of executable images. 106 ******************************************************************************/ 107 bl_params_t *plat_get_next_bl_params(void) 108 { 109 int ret; 110 struct n1sdp_plat_info plat_info; 111 112 ret = sds_init(SDS_SCP_AP_REGION_ID); 113 if (ret != SDS_OK) { 114 ERROR("SDS initialization failed. ret:%d\n", ret); 115 panic(); 116 } 117 118 ret = sds_struct_read(SDS_SCP_AP_REGION_ID, 119 N1SDP_SDS_PLATFORM_INFO_STRUCT_ID, 120 N1SDP_SDS_PLATFORM_INFO_OFFSET, 121 &plat_info, 122 N1SDP_SDS_PLATFORM_INFO_SIZE, 123 SDS_ACCESS_MODE_NON_CACHED); 124 if (ret != SDS_OK) { 125 ERROR("Error getting platform info from SDS. ret:%d\n", ret); 126 panic(); 127 } 128 129 /* Validate plat_info SDS */ 130 if ((plat_info.local_ddr_size == 0U) 131 || (plat_info.local_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB) 132 || (plat_info.remote_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB) 133 || (plat_info.secondary_count > N1SDP_MAX_SECONDARY_COUNT) 134 ){ 135 ERROR("platform info SDS is corrupted\n"); 136 panic(); 137 } 138 139 ret = plat_n1sdp_append_config_node(&plat_info); 140 if (ret != 0) { 141 panic(); 142 } 143 144 return arm_get_next_bl_params(); 145 } 146