2 * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
4 * SPDX-License-Identifier: BSD-3-Clause
12 #include <platform_def.h>
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>
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
;
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
);
40 /* Identify the device type as a virtual driver */
41 static io_type_t
device_type_stm32image(void)
43 return IO_TYPE_STM32IMAGE
;
46 static const io_dev_connector_t stm32image_dev_connector
= {
47 .dev_open
= stm32image_dev_open
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
,
60 static io_dev_info_t stm32image_dev_info
= {
61 .funcs
= &stm32image_dev_funcs
,
65 static struct stm32image_device_info stm32image_dev
;
67 static int get_part_idx_by_binary_type(uint32_t binary_type
)
71 for (i
= 0; i
< STM32_PART_NUM
; i
++) {
72 if (stm32image_dev
.part_info
[i
].binary_type
== binary_type
) {
80 /* Open a connection to the STM32IMAGE device */
81 static int stm32image_dev_open(const uintptr_t init_params
,
82 io_dev_info_t
**dev_info
)
85 struct stm32image_device_info
*device_info
=
86 (struct stm32image_device_info
*)init_params
;
88 assert(dev_info
!= NULL
);
89 *dev_info
= (io_dev_info_t
*)&stm32image_dev_info
;
91 stm32image_dev
.device_size
= device_info
->device_size
;
92 stm32image_dev
.lba_size
= device_info
->lba_size
;
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
].part_offset
=
98 device_info
->part_info
[i
].part_offset
;
99 stm32image_dev
.part_info
[i
].bkp_offset
=
100 device_info
->part_info
[i
].bkp_offset
;
106 /* Do some basic package checks */
107 static int stm32image_dev_init(io_dev_info_t
*dev_info
,
108 const uintptr_t init_params
)
112 if ((backend_dev_handle
!= 0U) || (backend_image_spec
!= 0U)) {
113 ERROR("STM32 Image io supports only one session\n");
117 /* Obtain a reference to the image by querying the platform layer */
118 result
= plat_get_image_source(STM32_IMAGE_ID
, &backend_dev_handle
,
119 &backend_image_spec
);
121 ERROR("STM32 image error (%i)\n", result
);
128 /* Close a connection to the STM32 Image device */
129 static int stm32image_dev_close(io_dev_info_t
*dev_info
)
131 backend_dev_handle
= 0U;
132 backend_image_spec
= 0U;
138 /* Open a partition */
139 static int stm32image_partition_open(io_dev_info_t
*dev_info
,
140 const uintptr_t spec
, io_entity_t
*entity
)
142 const struct stm32image_part_info
*partition_spec
;
145 assert(entity
!= NULL
);
147 partition_spec
= (struct stm32image_part_info
*)spec
;
148 assert(partition_spec
!= NULL
);
150 idx
= get_part_idx_by_binary_type(partition_spec
->binary_type
);
151 if ((idx
< 0) || (idx
> STM32_PART_NUM
)) {
152 ERROR("Wrong partition index (%d)\n", idx
);
156 current_part
= &stm32image_dev
.part_info
[idx
];
157 stm32_img
= (uint32_t *)¤t_part
->part_offset
;
162 /* Return the size of a partition */
163 static int stm32image_partition_size(io_entity_t
*entity
, size_t *length
)
166 uintptr_t backend_handle
;
168 boot_api_image_header_t
*header
=
169 (boot_api_image_header_t
*)first_lba_buffer
;
171 assert(entity
!= NULL
);
172 assert(length
!= NULL
);
174 /* Attempt to access the image */
175 result
= io_open(backend_dev_handle
, backend_image_spec
,
179 ERROR("%s: io_open (%i)\n", __func__
, result
);
183 /* Reset magic header value */
186 while (header
->magic
== 0U) {
187 result
= io_seek(backend_handle
, IO_SEEK_SET
, *stm32_img
);
189 ERROR("%s: io_seek (%i)\n", __func__
, result
);
193 result
= io_read(backend_handle
, (uintptr_t)header
,
194 MAX_LBA_SIZE
, (size_t *)&bytes_read
);
196 ERROR("%s: io_read (%i)\n", __func__
, result
);
200 if ((header
->magic
!= BOOT_API_IMAGE_HEADER_MAGIC_NB
) ||
201 (header
->binary_type
!= current_part
->binary_type
) ||
202 (header
->image_length
>= stm32image_dev
.device_size
)) {
203 WARN("%s: partition %s wrong header\n",
204 __func__
, current_part
->name
);
206 /* Header not correct, check next offset for backup */
207 *stm32_img
+= current_part
->bkp_offset
;
208 if (*stm32_img
> stm32image_dev
.device_size
) {
209 /* No backup found, end of device reached */
210 WARN("Out of memory\n");
218 io_close(backend_handle
);
224 *length
= header
->image_length
;
226 INFO("STM32 Image size : %i\n", *length
);
231 static int check_header(boot_api_image_header_t
*header
, uintptr_t buffer
)
234 uint32_t img_checksum
= 0;
237 * Check header/payload validity:
242 if (header
->magic
!= BOOT_API_IMAGE_HEADER_MAGIC_NB
) {
243 ERROR("Header magic\n");
247 if (header
->header_version
!= BOOT_API_HEADER_VERSION
) {
248 ERROR("Header version\n");
252 for (i
= 0; i
< header
->image_length
; i
++) {
253 img_checksum
+= *(uint8_t *)(buffer
+ i
);
256 if (header
->payload_checksum
!= img_checksum
) {
257 ERROR("Checksum: 0x%x (awaited: 0x%x)\n", img_checksum
,
258 header
->payload_checksum
);
265 /* Read data from a partition */
266 static int stm32image_partition_read(io_entity_t
*entity
, uintptr_t buffer
,
267 size_t length
, size_t *length_read
)
269 int result
= 0, offset
, local_length
= 0;
270 uint8_t *local_buffer
= (uint8_t *)buffer
;
271 boot_api_image_header_t
*header
=
272 (boot_api_image_header_t
*)first_lba_buffer
;
273 uintptr_t backend_handle
;
275 assert(entity
!= NULL
);
276 assert(buffer
!= 0U);
277 assert(length_read
!= NULL
);
281 while (*length_read
== 0U) {
282 if (header
->magic
!= BOOT_API_IMAGE_HEADER_MAGIC_NB
) {
283 /* Check for backup as image is corrupted */
284 *stm32_img
+= current_part
->bkp_offset
;
285 if (*stm32_img
>= stm32image_dev
.device_size
) {
286 /* End of device reached */
291 local_buffer
= (uint8_t *)buffer
;
293 result
= stm32image_partition_size(entity
, &length
);
299 /* Part of image already loaded with the header */
300 memcpy(local_buffer
, (uint8_t *)first_lba_buffer
+
301 sizeof(boot_api_image_header_t
),
302 MAX_LBA_SIZE
- sizeof(boot_api_image_header_t
));
303 local_buffer
+= MAX_LBA_SIZE
- sizeof(boot_api_image_header_t
);
304 offset
= MAX_LBA_SIZE
;
306 /* New image length to be read */
307 local_length
= round_up(length
-
309 sizeof(boot_api_image_header_t
)),
310 stm32image_dev
.lba_size
);
312 if ((header
->load_address
!= 0U) &&
313 (header
->load_address
!= buffer
)) {
314 ERROR("Wrong load address\n");
318 result
= io_open(backend_dev_handle
, backend_image_spec
,
322 ERROR("%s: io_open (%i)\n", __func__
, result
);
326 result
= io_seek(backend_handle
, IO_SEEK_SET
,
327 *stm32_img
+ offset
);
330 ERROR("%s: io_seek (%i)\n", __func__
, result
);
332 io_close(backend_handle
);
336 result
= io_read(backend_handle
, (uintptr_t)local_buffer
,
337 local_length
, length_read
);
339 /* Adding part of size already read from header */
340 *length_read
+= MAX_LBA_SIZE
- sizeof(boot_api_image_header_t
);
343 ERROR("%s: io_read (%i)\n", __func__
, result
);
345 io_close(backend_handle
);
349 result
= check_header(header
, buffer
);
351 ERROR("Header check failed\n");
354 io_close(backend_handle
);
358 io_close(backend_handle
);
364 /* Close a partition */
365 static int stm32image_partition_close(io_entity_t
*entity
)
372 /* Register the stm32image driver with the IO abstraction */
373 int register_io_dev_stm32image(const io_dev_connector_t
**dev_con
)
377 assert(dev_con
!= NULL
);
379 result
= io_register_device(&stm32image_dev_info
);
381 *dev_con
= &stm32image_dev_connector
;