1 /*
2  * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <errno.h>
9 #include <stdint.h>
10 #include <string.h>
11 
12 #include <platform_def.h>
13 
14 #include <common/debug.h>
15 #include <drivers/io/io_driver.h>
16 #include <drivers/io/io_storage.h>
17 #include <drivers/st/io_stm32image.h>
18 #include <lib/utils.h>
19 #include <plat/common/platform.h>
20 
21 static uintptr_t backend_dev_handle;
22 static uintptr_t backend_image_spec;
23 static uint32_t *stm32_img;
24 static uint8_t first_lba_buffer[MAX_LBA_SIZE] __aligned(4);
25 static struct stm32image_part_info *current_part;
26 
27 /* STM32 Image driver functions */
28 static int stm32image_dev_open(const uintptr_t init_params,
29 			       io_dev_info_t **dev_info);
30 static int stm32image_partition_open(io_dev_info_t *dev_info,
31 				     const uintptr_t spec, io_entity_t *entity);
32 static int stm32image_partition_size(io_entity_t *entity, size_t *length);
33 static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
34 				     size_t length, size_t *length_read);
35 static int stm32image_partition_close(io_entity_t *entity);
36 static int stm32image_dev_init(io_dev_info_t *dev_info,
37 			       const uintptr_t init_params);
38 static int stm32image_dev_close(io_dev_info_t *dev_info);
39 
40 /* Identify the device type as a virtual driver */
device_type_stm32image(void)41 static io_type_t device_type_stm32image(void)
42 {
43 	return IO_TYPE_STM32IMAGE;
44 }
45 
46 static const io_dev_connector_t stm32image_dev_connector = {
47 	.dev_open = stm32image_dev_open
48 };
49 
50 static const io_dev_funcs_t stm32image_dev_funcs = {
51 	.type = device_type_stm32image,
52 	.open = stm32image_partition_open,
53 	.size = stm32image_partition_size,
54 	.read = stm32image_partition_read,
55 	.close = stm32image_partition_close,
56 	.dev_init = stm32image_dev_init,
57 	.dev_close = stm32image_dev_close,
58 };
59 
60 static io_dev_info_t stm32image_dev_info = {
61 	.funcs = &stm32image_dev_funcs,
62 	.info = (uintptr_t)0,
63 };
64 
65 static struct stm32image_device_info stm32image_dev;
66 
get_part_idx_by_binary_type(uint32_t binary_type)67 static int get_part_idx_by_binary_type(uint32_t binary_type)
68 {
69 	int i;
70 
71 	for (i = 0; i < STM32_PART_NUM; i++) {
72 		if (stm32image_dev.part_info[i].binary_type == binary_type) {
73 			return i;
74 		}
75 	}
76 
77 	return -EINVAL;
78 }
79 
80 /* Open a connection to the STM32IMAGE device */
stm32image_dev_open(const uintptr_t init_params,io_dev_info_t ** dev_info)81 static int stm32image_dev_open(const uintptr_t init_params,
82 			       io_dev_info_t **dev_info)
83 {
84 	int i;
85 	struct stm32image_device_info *device_info =
86 		(struct stm32image_device_info *)init_params;
87 
88 	assert(dev_info != NULL);
89 	*dev_info = (io_dev_info_t *)&stm32image_dev_info;
90 
91 	stm32image_dev.device_size = device_info->device_size;
92 	stm32image_dev.lba_size = device_info->lba_size;
93 
94 	for (i = 0; i < STM32_PART_NUM; i++) {
95 		memcpy(stm32image_dev.part_info[i].name,
96 		       device_info->part_info[i].name, MAX_PART_NAME_SIZE);
97 		stm32image_dev.part_info[i].binary_type =
98 			device_info->part_info[i].binary_type;
99 		stm32image_dev.part_info[i].part_offset =
100 			device_info->part_info[i].part_offset;
101 		stm32image_dev.part_info[i].bkp_offset =
102 			device_info->part_info[i].bkp_offset;
103 	}
104 
105 	return 0;
106 }
107 
108 /* Do some basic package checks */
stm32image_dev_init(io_dev_info_t * dev_info,const uintptr_t init_params)109 static int stm32image_dev_init(io_dev_info_t *dev_info,
110 			       const uintptr_t init_params)
111 {
112 	int result;
113 
114 	if ((backend_dev_handle != 0U) || (backend_image_spec != 0U)) {
115 		ERROR("STM32 Image io supports only one session\n");
116 		return -ENOMEM;
117 	}
118 
119 	/* Obtain a reference to the image by querying the platform layer */
120 	result = plat_get_image_source(STM32_IMAGE_ID, &backend_dev_handle,
121 				       &backend_image_spec);
122 	if (result != 0) {
123 		ERROR("STM32 image error (%i)\n", result);
124 		return -EINVAL;
125 	}
126 
127 	return result;
128 }
129 
130 /* Close a connection to the STM32 Image device */
stm32image_dev_close(io_dev_info_t * dev_info)131 static int stm32image_dev_close(io_dev_info_t *dev_info)
132 {
133 	backend_dev_handle = 0U;
134 	backend_image_spec = 0U;
135 	stm32_img = NULL;
136 
137 	return 0;
138 }
139 
140 /* Open a partition */
stm32image_partition_open(io_dev_info_t * dev_info,const uintptr_t spec,io_entity_t * entity)141 static int stm32image_partition_open(io_dev_info_t *dev_info,
142 				     const uintptr_t spec, io_entity_t *entity)
143 {
144 	const struct stm32image_part_info *partition_spec;
145 	int idx;
146 
147 	assert(entity != NULL);
148 
149 	partition_spec = (struct stm32image_part_info *)spec;
150 	assert(partition_spec != NULL);
151 
152 	idx = get_part_idx_by_binary_type(partition_spec->binary_type);
153 	if ((idx < 0) || (idx > STM32_PART_NUM)) {
154 		ERROR("Wrong partition index (%d)\n", idx);
155 		return -EINVAL;
156 	}
157 
158 	current_part = &stm32image_dev.part_info[idx];
159 	stm32_img = (uint32_t *)&current_part->part_offset;
160 
161 	return 0;
162 }
163 
164 /* Return the size of a partition */
stm32image_partition_size(io_entity_t * entity,size_t * length)165 static int stm32image_partition_size(io_entity_t *entity, size_t *length)
166 {
167 	int result;
168 	uintptr_t backend_handle;
169 	size_t bytes_read;
170 	boot_api_image_header_t *header =
171 		(boot_api_image_header_t *)first_lba_buffer;
172 
173 	assert(entity != NULL);
174 	assert(length != NULL);
175 
176 	/* Attempt to access the image */
177 	result = io_open(backend_dev_handle, backend_image_spec,
178 			 &backend_handle);
179 
180 	if (result < 0) {
181 		ERROR("%s: io_open (%i)\n", __func__, result);
182 		return result;
183 	}
184 
185 	/* Reset magic header value */
186 	header->magic = 0;
187 
188 	while (header->magic == 0U) {
189 		result = io_seek(backend_handle, IO_SEEK_SET, *stm32_img);
190 		if (result != 0) {
191 			ERROR("%s: io_seek (%i)\n", __func__, result);
192 			break;
193 		}
194 
195 		result = io_read(backend_handle, (uintptr_t)header,
196 				 MAX_LBA_SIZE, (size_t *)&bytes_read);
197 		if (result != 0) {
198 			if (current_part->bkp_offset == 0U) {
199 				ERROR("%s: io_read (%i)\n", __func__, result);
200 			}
201 			header->magic = 0;
202 		}
203 
204 		if ((header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) ||
205 		    (header->binary_type != current_part->binary_type) ||
206 		    (header->image_length >= stm32image_dev.device_size)) {
207 			VERBOSE("%s: partition %s not found at %x\n",
208 				__func__, current_part->name, *stm32_img);
209 
210 			if (current_part->bkp_offset == 0U) {
211 				result = -ENOMEM;
212 				break;
213 			}
214 
215 			/* Header not correct, check next offset for backup */
216 			*stm32_img += current_part->bkp_offset;
217 			if (*stm32_img > stm32image_dev.device_size) {
218 				/* No backup found, end of device reached */
219 				WARN("%s : partition %s not found\n",
220 				     __func__, current_part->name);
221 				result = -ENOMEM;
222 				break;
223 			}
224 			header->magic = 0;
225 		}
226 	}
227 
228 	io_close(backend_handle);
229 
230 	if (result != 0) {
231 		return result;
232 	}
233 
234 	if (header->image_length < stm32image_dev.lba_size) {
235 		*length = stm32image_dev.lba_size;
236 	} else {
237 		*length = header->image_length;
238 	}
239 
240 	INFO("STM32 Image size : %lu\n", (unsigned long)*length);
241 
242 	return 0;
243 }
244 
245 /* Read data from a partition */
stm32image_partition_read(io_entity_t * entity,uintptr_t buffer,size_t length,size_t * length_read)246 static int stm32image_partition_read(io_entity_t *entity, uintptr_t buffer,
247 				     size_t length, size_t *length_read)
248 {
249 	int result = -EINVAL;
250 	uint8_t *local_buffer;
251 	boot_api_image_header_t *header =
252 		(boot_api_image_header_t *)first_lba_buffer;
253 	size_t hdr_sz = sizeof(boot_api_image_header_t);
254 
255 	assert(entity != NULL);
256 	assert(buffer != 0U);
257 	assert(length_read != NULL);
258 
259 	local_buffer = (uint8_t *)buffer;
260 	*length_read = 0U;
261 
262 	while (*length_read == 0U) {
263 		int offset;
264 		int local_length;
265 		uintptr_t backend_handle;
266 
267 		if (header->magic != BOOT_API_IMAGE_HEADER_MAGIC_NB) {
268 			/* Check for backup as image is corrupted */
269 			if (current_part->bkp_offset == 0U) {
270 				result = -ENOMEM;
271 				break;
272 			}
273 
274 			*stm32_img += current_part->bkp_offset;
275 			if (*stm32_img >= stm32image_dev.device_size) {
276 				/* End of device reached */
277 				result = -ENOMEM;
278 				break;
279 			}
280 
281 			local_buffer = (uint8_t *)buffer;
282 
283 			result = stm32image_partition_size(entity, &length);
284 			if (result != 0) {
285 				break;
286 			}
287 		}
288 
289 		/* Part of image already loaded with the header */
290 		memcpy(local_buffer, (uint8_t *)first_lba_buffer + hdr_sz,
291 		       MAX_LBA_SIZE - hdr_sz);
292 		local_buffer += MAX_LBA_SIZE - hdr_sz;
293 		offset = MAX_LBA_SIZE;
294 
295 		/* New image length to be read */
296 		local_length = round_up(length - ((MAX_LBA_SIZE) - hdr_sz),
297 					stm32image_dev.lba_size);
298 
299 		if ((header->load_address != 0U) &&
300 		    (header->load_address != buffer)) {
301 			ERROR("Wrong load address\n");
302 			panic();
303 		}
304 
305 		result = io_open(backend_dev_handle, backend_image_spec,
306 				 &backend_handle);
307 
308 		if (result != 0) {
309 			ERROR("%s: io_open (%i)\n", __func__, result);
310 			break;
311 		}
312 
313 		result = io_seek(backend_handle, IO_SEEK_SET,
314 				 *stm32_img + offset);
315 
316 		if (result != 0) {
317 			ERROR("%s: io_seek (%i)\n", __func__, result);
318 			*length_read = 0;
319 			io_close(backend_handle);
320 			break;
321 		}
322 
323 		result = io_read(backend_handle, (uintptr_t)local_buffer,
324 				 local_length, length_read);
325 
326 		/* Adding part of size already read from header */
327 		*length_read += MAX_LBA_SIZE - hdr_sz;
328 
329 		if (result != 0) {
330 			ERROR("%s: io_read (%i)\n", __func__, result);
331 			*length_read = 0;
332 			header->magic = 0;
333 			continue;
334 		}
335 
336 		result = stm32mp_check_header(header, buffer);
337 		if (result != 0) {
338 			ERROR("Header check failed\n");
339 			*length_read = 0;
340 			header->magic = 0;
341 		}
342 
343 		result = stm32mp_auth_image(header, buffer);
344 		if (result != 0) {
345 			ERROR("Authentication Failed (%i)\n", result);
346 			return result;
347 		}
348 
349 		inv_dcache_range(round_up((uintptr_t)(local_buffer + length - hdr_sz),
350 					  CACHE_WRITEBACK_GRANULE), *length_read - length + hdr_sz);
351 
352 		io_close(backend_handle);
353 	}
354 
355 	return result;
356 }
357 
358 /* Close a partition */
stm32image_partition_close(io_entity_t * entity)359 static int stm32image_partition_close(io_entity_t *entity)
360 {
361 	current_part = NULL;
362 
363 	return 0;
364 }
365 
366 /* Register the stm32image driver with the IO abstraction */
register_io_dev_stm32image(const io_dev_connector_t ** dev_con)367 int register_io_dev_stm32image(const io_dev_connector_t **dev_con)
368 {
369 	int result;
370 
371 	assert(dev_con != NULL);
372 
373 	result = io_register_device(&stm32image_dev_info);
374 	if (result == 0) {
375 		*dev_con = &stm32image_dev_connector;
376 	}
377 
378 	return result;
379 }
380