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