1 /*
2 * Copyright 2018-2020 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include <assert.h>
9 #include <string.h>
10
11 #include <io_block.h>
12 #include <io_driver.h>
13 #include <io_fip.h>
14 #include <io_memmap.h>
15 #include <io_storage.h>
16 #include <lib/utils.h>
17 #include <tools_share/firmware_image_package.h>
18 #include "ddr_io_storage.h"
19 #include "plat_common.h"
20 #include "platform_def.h"
21
22
23 /* TBD - Move these defined to the platform_def.h file.
24 * Keeping them for reference here
25 */
26 extern uintptr_t backend_dev_handle;
27
28 static uint32_t ddr_fip;
29
30 static uintptr_t ddr_fip_dev_handle;
31
32 static io_block_spec_t ddr_fip_block_spec = {
33 .offset = PLAT_DDR_FIP_OFFSET,
34 .length = PLAT_DDR_FIP_MAX_SIZE
35 };
36
37 static const io_uuid_spec_t ddr_imem_udimm_1d_uuid_spec = {
38 .uuid = UUID_DDR_IMEM_UDIMM_1D,
39 };
40
41 static const io_uuid_spec_t ddr_imem_udimm_2d_uuid_spec = {
42 .uuid = UUID_DDR_IMEM_UDIMM_2D,
43 };
44
45 static const io_uuid_spec_t ddr_dmem_udimm_1d_uuid_spec = {
46 .uuid = UUID_DDR_DMEM_UDIMM_1D,
47 };
48
49 static const io_uuid_spec_t ddr_dmem_udimm_2d_uuid_spec = {
50 .uuid = UUID_DDR_DMEM_UDIMM_2D,
51 };
52
53 static const io_uuid_spec_t ddr_imem_rdimm_1d_uuid_spec = {
54 .uuid = UUID_DDR_IMEM_RDIMM_1D,
55 };
56
57 static const io_uuid_spec_t ddr_imem_rdimm_2d_uuid_spec = {
58 .uuid = UUID_DDR_IMEM_RDIMM_2D,
59 };
60
61 static const io_uuid_spec_t ddr_dmem_rdimm_1d_uuid_spec = {
62 .uuid = UUID_DDR_DMEM_RDIMM_1D,
63 };
64
65 static const io_uuid_spec_t ddr_dmem_rdimm_2d_uuid_spec = {
66 .uuid = UUID_DDR_DMEM_RDIMM_2D,
67 };
68
69 #if TRUSTED_BOARD_BOOT
70 static const io_uuid_spec_t ddr_fw_key_cert_uuid_spec = {
71 .uuid = UUID_DDR_FW_KEY_CERT,
72 };
73 static const io_uuid_spec_t ddr_udimm_fw_cert_uuid_spec = {
74 .uuid = UUID_DDR_UDIMM_FW_CONTENT_CERT,
75 };
76 static const io_uuid_spec_t ddr_rdimm_fw_cert_uuid_spec = {
77 .uuid = UUID_DDR_RDIMM_FW_CONTENT_CERT,
78 };
79 #endif
80
81 static int open_ddr_fip(const uintptr_t spec);
82
83 struct plat_io_policy {
84 uintptr_t *dev_handle;
85 uintptr_t image_spec;
86 int (*check)(const uintptr_t spec);
87 };
88
89 /* By default, ARM platforms load images from the FIP */
90 static const struct plat_io_policy ddr_policies[] = {
91 [DDR_FIP_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
92 &backend_dev_handle,
93 (uintptr_t)&ddr_fip_block_spec,
94 NULL
95 },
96 [DDR_IMEM_UDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
97 &ddr_fip_dev_handle,
98 (uintptr_t)&ddr_imem_udimm_1d_uuid_spec,
99 open_ddr_fip
100 },
101 [DDR_IMEM_UDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
102 &ddr_fip_dev_handle,
103 (uintptr_t)&ddr_imem_udimm_2d_uuid_spec,
104 open_ddr_fip
105 },
106 [DDR_DMEM_UDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
107 &ddr_fip_dev_handle,
108 (uintptr_t)&ddr_dmem_udimm_1d_uuid_spec,
109 open_ddr_fip
110 },
111 [DDR_DMEM_UDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
112 &ddr_fip_dev_handle,
113 (uintptr_t)&ddr_dmem_udimm_2d_uuid_spec,
114 open_ddr_fip
115 },
116 [DDR_IMEM_RDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
117 &ddr_fip_dev_handle,
118 (uintptr_t)&ddr_imem_rdimm_1d_uuid_spec,
119 open_ddr_fip
120 },
121 [DDR_IMEM_RDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
122 &ddr_fip_dev_handle,
123 (uintptr_t)&ddr_imem_rdimm_2d_uuid_spec,
124 open_ddr_fip
125 },
126 [DDR_DMEM_RDIMM_1D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
127 &ddr_fip_dev_handle,
128 (uintptr_t)&ddr_dmem_rdimm_1d_uuid_spec,
129 open_ddr_fip
130 },
131 [DDR_DMEM_RDIMM_2D_IMAGE_ID - DDR_FIP_IMAGE_ID] = {
132 &ddr_fip_dev_handle,
133 (uintptr_t)&ddr_dmem_rdimm_2d_uuid_spec,
134 open_ddr_fip
135 },
136 #if TRUSTED_BOARD_BOOT
137 [DDR_FW_KEY_CERT_ID - DDR_FIP_IMAGE_ID] = {
138 &ddr_fip_dev_handle,
139 (uintptr_t)&ddr_fw_key_cert_uuid_spec,
140 open_ddr_fip
141 },
142 [DDR_UDIMM_FW_CONTENT_CERT_ID - DDR_FIP_IMAGE_ID] = {
143 &ddr_fip_dev_handle,
144 (uintptr_t)&ddr_udimm_fw_cert_uuid_spec,
145 open_ddr_fip
146 },
147 [DDR_RDIMM_FW_CONTENT_CERT_ID - DDR_FIP_IMAGE_ID] = {
148 &ddr_fip_dev_handle,
149 (uintptr_t)&ddr_rdimm_fw_cert_uuid_spec,
150 open_ddr_fip
151 },
152 #endif
153 };
154
open_ddr_fip(const uintptr_t spec)155 static int open_ddr_fip(const uintptr_t spec)
156 {
157 int result;
158 uintptr_t local_image_handle;
159
160 /* See if a Firmware Image Package is available */
161 result = io_dev_init(ddr_fip_dev_handle, (uintptr_t)DDR_FIP_IMAGE_ID);
162 if (result == 0) {
163 result = io_open(ddr_fip_dev_handle, spec, &local_image_handle);
164 if (result == 0) {
165 VERBOSE("Using FIP\n");
166 io_close(local_image_handle);
167 }
168 }
169 return result;
170 }
171
172 /* The image can be one of the DDR PHY images, which can be sleected via DDR
173 * policies
174 */
plat_get_ddr_fip_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec,int (* check)(const uintptr_t spec))175 int plat_get_ddr_fip_image_source(unsigned int image_id, uintptr_t *dev_handle,
176 uintptr_t *image_spec,
177 int (*check)(const uintptr_t spec))
178 {
179 int result = -1;
180 const struct plat_io_policy *policy;
181
182 if (image_id >= (DDR_FIP_IMAGE_ID + ARRAY_SIZE(ddr_policies))) {
183 return result;
184 }
185
186 policy = &ddr_policies[image_id - DDR_FIP_IMAGE_ID];
187 if (image_id == DDR_FIP_IMAGE_ID) {
188 result = check(policy->image_spec);
189 } else {
190 result = policy->check(policy->image_spec);
191 }
192 if (result == 0) {
193 *image_spec = policy->image_spec;
194 *dev_handle = *(policy->dev_handle);
195 }
196 return result;
197 }
198
ddr_fip_setup(const io_dev_connector_t * fip_dev_con,unsigned int boot_dev)199 int ddr_fip_setup(const io_dev_connector_t *fip_dev_con, unsigned int boot_dev)
200 {
201 int io_result;
202 size_t ddr_fip_offset = PLAT_DDR_FIP_OFFSET;
203
204 /* Open connections to ddr fip and cache the handles */
205 io_result = io_dev_open(fip_dev_con, (uintptr_t)&ddr_fip,
206 &ddr_fip_dev_handle);
207 assert(io_result == 0);
208
209 switch (boot_dev) {
210 #if QSPI_BOOT
211 case BOOT_DEVICE_QSPI:
212 ddr_fip_offset += NXP_QSPI_FLASH_ADDR;
213 break;
214 #endif
215 #if NOR_BOOT
216 case BOOT_DEVICE_IFC_NOR:
217 ddr_fip_offset += NXP_NOR_FLASH_ADDR;
218 break;
219 #endif
220 #if FLEXSPI_NOR_BOOT
221 case BOOT_DEVICE_FLEXSPI_NOR:
222 ddr_fip_offset += NXP_FLEXSPI_FLASH_ADDR;
223 break;
224 #endif
225 default:
226 break;
227 }
228
229 ddr_fip_block_spec.offset = ddr_fip_offset;
230
231 return io_result;
232 }
233