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