1 /*
2 * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "fip_parser.h"
9
10 #include "flash_layout.h"
11 #include "Driver_Flash.h"
12
13 #include <string.h>
14
15 extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
16
fip_get_entry_by_uuid(uint32_t fip_base,uint32_t atu_slot_size,uuid_t uuid,uint64_t * offset,size_t * size)17 int fip_get_entry_by_uuid(uint32_t fip_base, uint32_t atu_slot_size, uuid_t uuid,
18 uint64_t *offset, size_t *size)
19 {
20 ARM_FLASH_CAPABILITIES DriverCapabilities = FLASH_DEV_NAME.GetCapabilities();
21 /* Valid entries for data item width */
22 uint32_t data_width_byte[] = {
23 sizeof(uint8_t),
24 sizeof(uint16_t),
25 sizeof(uint32_t),
26 };
27 size_t data_width = data_width_byte[DriverCapabilities.data_width];
28 int rc;
29 uint32_t idx = 0;
30 fip_toc_header_t toc_header;
31 fip_toc_entry_t toc_entry;
32 uuid_t null_uuid;
33
34 /* The NULL UUID is all-zeroes */
35 memset(&null_uuid, 0, sizeof(null_uuid));
36
37 rc = FLASH_DEV_NAME.ReadData(fip_base - FLASH_BASE_ADDRESS, &toc_header,
38 sizeof(toc_header) / data_width);
39 if (rc != sizeof(toc_header) / data_width) {
40 return rc;
41 }
42
43 if (toc_header.name != TOC_HEADER_NAME) {
44 return 2;
45 }
46
47 idx += sizeof(toc_header);
48
49 do {
50 /* Prevent reading out of bounds */
51 if (idx + sizeof(toc_entry) > atu_slot_size) {
52 return 3;
53 }
54
55 rc = FLASH_DEV_NAME.ReadData(fip_base + idx - FLASH_BASE_ADDRESS,
56 &toc_entry, sizeof(toc_entry) / data_width);
57 if (rc != sizeof(toc_entry) / data_width) {
58 return rc;
59 }
60
61 if (!memcmp(&uuid, &toc_entry.uuid, sizeof(uuid))) {
62 *offset = toc_entry.offset_address;
63
64 /* We can't deal with partitions that are greater than UINT32_MAX,
65 * since they aren't wholly mappable into the RSE memory space. This
66 * is in reality bounded by the ATU mappable size, but that'll be
67 * checked once the ATU region is set up, this just allows us to
68 * perform safe type-conversion.
69 */
70 if (toc_entry.size > UINT32_MAX) {
71 return 1;
72 }
73
74 *size = (uint32_t)toc_entry.size;
75
76 return 0;
77 }
78
79 idx += sizeof(toc_entry);
80 /* The FIP's TOC ends in an entry with a NULL UUID. This entry's size is
81 * the size of the whole FIP. */
82 } while (memcmp(&null_uuid, &toc_entry.uuid, sizeof(uuid_t)));
83
84 /* UUID not found, return error. */
85 return 3;
86 }
87