1 /*
2  * Copyright (c) 2021, 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 
13 #include "morello_def.h"
14 #include <plat/arm/common/plat_arm.h>
15 #include <plat/common/platform.h>
16 
17 #ifdef TARGET_PLATFORM_FVP
18 /*
19  * Platform information structure stored in SDS.
20  * This structure holds information about platform's DDR
21  * size which is an information about multichip setup
22  *	- Local DDR size in bytes, DDR memory in main board
23  */
24 struct morello_plat_info {
25 	uint64_t local_ddr_size;
26 } __packed;
27 #else
28 /*
29  * Platform information structure stored in SDS.
30  * This structure holds information about platform's DDR
31  * size which is an information about multichip setup
32  *	- Local DDR size in bytes, DDR memory in main board
33  *	- Remote DDR size in bytes, DDR memory in remote board
34  *	- remote_chip_count
35  *	- multichip mode
36  *	- scc configuration
37  */
38 struct morello_plat_info {
39 	uint64_t local_ddr_size;
40 	uint64_t remote_ddr_size;
41 	uint8_t remote_chip_count;
42 	bool multichip_mode;
43 	uint32_t scc_config;
44 } __packed;
45 #endif
46 
47 /* In client mode, a part of the DDR memory is reserved for Tag bits.
48  * Calculate the usable memory size after subtracting the Tag memory.
49  */
get_mem_client_mode(uint64_t size)50 static inline uint64_t get_mem_client_mode(uint64_t size)
51 {
52 	return (size - (size / 128ULL));
53 }
54 
55 /*******************************************************************************
56  * This function inserts Platform information via device tree nodes as,
57  *	platform-info {
58  *		local-ddr-size = <0x0 0x0>;
59  *#ifdef TARGET_PLATFORM_SOC
60  *		remote-ddr-size = <0x0 0x0>;
61  *		remote-chip-count = <0x0>;
62  *		multichip-mode = <0x0>;
63  *		scc-config = <0x0>;
64  *#endif
65  *	};
66  ******************************************************************************/
plat_morello_append_config_node(struct morello_plat_info * plat_info)67 static int plat_morello_append_config_node(struct morello_plat_info *plat_info)
68 {
69 	bl_mem_params_node_t *mem_params;
70 	void *fdt;
71 	int nodeoffset, err;
72 	uint64_t usable_mem_size;
73 
74 	usable_mem_size = plat_info->local_ddr_size;
75 
76 	mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
77 	if (mem_params == NULL) {
78 		ERROR("NT_FW CONFIG base address is NULL\n");
79 		return -1;
80 	}
81 
82 	fdt = (void *)(mem_params->image_info.image_base);
83 
84 	/* Check the validity of the fdt */
85 	if (fdt_check_header(fdt) != 0) {
86 		ERROR("Invalid NT_FW_CONFIG DTB passed\n");
87 		return -1;
88 	}
89 
90 	nodeoffset = fdt_subnode_offset(fdt, 0, "platform-info");
91 	if (nodeoffset < 0) {
92 		ERROR("NT_FW_CONFIG: Failed to get platform-info node offset\n");
93 		return -1;
94 	}
95 
96 #ifdef TARGET_PLATFORM_SOC
97 	err = fdt_setprop_u64(fdt, nodeoffset, "remote-ddr-size",
98 			plat_info->remote_ddr_size);
99 	if (err < 0) {
100 		ERROR("NT_FW_CONFIG: Failed to set remote-ddr-size\n");
101 		return -1;
102 	}
103 
104 	err = fdt_setprop_u32(fdt, nodeoffset, "remote-chip-count",
105 			plat_info->remote_chip_count);
106 	if (err < 0) {
107 		ERROR("NT_FW_CONFIG: Failed to set remote-chip-count\n");
108 		return -1;
109 	}
110 
111 	err = fdt_setprop_u32(fdt, nodeoffset, "multichip-mode",
112 			plat_info->multichip_mode);
113 	if (err < 0) {
114 		ERROR("NT_FW_CONFIG: Failed to set multichip-mode\n");
115 		return -1;
116 	}
117 
118 	err = fdt_setprop_u32(fdt, nodeoffset, "scc-config",
119 			plat_info->scc_config);
120 	if (err < 0) {
121 		ERROR("NT_FW_CONFIG: Failed to set scc-config\n");
122 		return -1;
123 	}
124 
125 	if (plat_info->scc_config & MORELLO_SCC_CLIENT_MODE_MASK) {
126 		usable_mem_size = get_mem_client_mode(plat_info->local_ddr_size);
127 	}
128 #endif
129 	err = fdt_setprop_u64(fdt, nodeoffset, "local-ddr-size",
130 			usable_mem_size);
131 	if (err < 0) {
132 		ERROR("NT_FW_CONFIG: Failed to set local-ddr-size\n");
133 		return -1;
134 	}
135 
136 	flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size);
137 
138 	return 0;
139 }
140 
141 /*******************************************************************************
142  * This function returns the list of executable images.
143  ******************************************************************************/
plat_get_next_bl_params(void)144 bl_params_t *plat_get_next_bl_params(void)
145 {
146 	int ret;
147 	struct morello_plat_info plat_info;
148 
149 	ret = sds_init();
150 	if (ret != SDS_OK) {
151 		ERROR("SDS initialization failed. ret:%d\n", ret);
152 		panic();
153 	}
154 
155 	ret = sds_struct_read(MORELLO_SDS_PLATFORM_INFO_STRUCT_ID,
156 				MORELLO_SDS_PLATFORM_INFO_OFFSET,
157 				&plat_info,
158 				MORELLO_SDS_PLATFORM_INFO_SIZE,
159 				SDS_ACCESS_MODE_NON_CACHED);
160 	if (ret != SDS_OK) {
161 		ERROR("Error getting platform info from SDS. ret:%d\n", ret);
162 		panic();
163 	}
164 
165 	/* Validate plat_info SDS */
166 #ifdef TARGET_PLATFORM_FVP
167 	if (plat_info.local_ddr_size == 0U) {
168 #else
169 	if ((plat_info.local_ddr_size == 0U)
170 		|| (plat_info.local_ddr_size > MORELLO_MAX_DDR_CAPACITY)
171 		|| (plat_info.remote_ddr_size > MORELLO_MAX_DDR_CAPACITY)
172 		|| (plat_info.remote_chip_count > MORELLO_MAX_REMOTE_CHIP_COUNT)
173 		){
174 #endif
175 		ERROR("platform info SDS is corrupted\n");
176 		panic();
177 	}
178 
179 	ret = plat_morello_append_config_node(&plat_info);
180 	if (ret != 0) {
181 		panic();
182 	}
183 
184 	return arm_get_next_bl_params();
185 }
186