blob: 418c533af0ddea0b6a273fe84ddff7babeaa0a35 [file] [log] [blame]
Andrew Geissler2daf84b2023-03-31 09:57:23 -05001From 1fdc3000f1ab6f9c1bb792cb8baff16a7517c03a Mon Sep 17 00:00:00 2001
2From: Mohamed Omar Asaker <mohamed.omarasaker@arm.com>
3Date: Thu, 22 Dec 2022 14:27:41 +0000
4Subject: [PATCH 7/10] Platform:corstone1000: Introduce GPT parser
5
6Adding GPT parser
7Side changes required:
8Includes the implementation of the `plat_get_image_source` function
9in the platform.c file.
10
11The GPT parser requires the function. Given the image id, it should
12return handle to the IO device contains the image and image
13specification that allows IO storage access to the image.
14
15Signed-off-by: Mohamed Omar Asaker <mohamed.omarasaker@arm.com>
16Upstream-Status: Pending [Not submitted to upstream yet]
17---
18 .../target/arm/corstone1000/partition/efi.h | 36 ++
19 .../target/arm/corstone1000/partition/gpt.c | 58 ++++
20 .../target/arm/corstone1000/partition/gpt.h | 51 +++
21 .../target/arm/corstone1000/partition/mbr.h | 29 ++
22 .../arm/corstone1000/partition/partition.c | 310 ++++++++++++++++++
23 .../arm/corstone1000/partition/partition.h | 47 +++
24 .../target/arm/corstone1000/partition/uuid.h | 76 +++++
25 .../ext/target/arm/corstone1000/platform.c | 20 ++
26 .../ext/target/arm/corstone1000/platform.h | 14 +
27 9 files changed, 641 insertions(+)
28 create mode 100644 platform/ext/target/arm/corstone1000/partition/efi.h
29 create mode 100644 platform/ext/target/arm/corstone1000/partition/gpt.c
30 create mode 100644 platform/ext/target/arm/corstone1000/partition/gpt.h
31 create mode 100644 platform/ext/target/arm/corstone1000/partition/mbr.h
32 create mode 100644 platform/ext/target/arm/corstone1000/partition/partition.c
33 create mode 100644 platform/ext/target/arm/corstone1000/partition/partition.h
34 create mode 100644 platform/ext/target/arm/corstone1000/partition/uuid.h
35 create mode 100644 platform/ext/target/arm/corstone1000/platform.c
36 create mode 100644 platform/ext/target/arm/corstone1000/platform.h
37
38diff --git a/platform/ext/target/arm/corstone1000/partition/efi.h b/platform/ext/target/arm/corstone1000/partition/efi.h
39new file mode 100644
40index 0000000000..f66daffb32
41--- /dev/null
42+++ b/platform/ext/target/arm/corstone1000/partition/efi.h
43@@ -0,0 +1,36 @@
44+/*
45+ * Copyright (c) 2021, Linaro Limited
46+ *
47+ * SPDX-License-Identifier: BSD-3-Clause
48+ *
49+ */
50+
51+#ifndef DRIVERS_PARTITION_EFI_H
52+#define DRIVERS_PARTITION_EFI_H
53+
54+#include <string.h>
55+
56+#include "uuid.h"
57+
58+#define EFI_NAMELEN 36
59+
60+static inline int guidcmp(const void *g1, const void *g2) {
61+ return memcmp(g1, g2, sizeof(struct efi_guid));
62+}
63+
64+static inline void *guidcpy(void *dst, const void *src) {
65+ return memcpy(dst, src, sizeof(struct efi_guid));
66+}
67+
68+#define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
69+ { \
70+ (a) & 0xffffffff, (b)&0xffff, (c)&0xffff, { \
71+ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) \
72+ } \
73+ }
74+
75+#define NULL_GUID \
76+ EFI_GUID(0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
77+ 0x00, 0x00)
78+
79+#endif /* DRIVERS_PARTITION_EFI_H */
80diff --git a/platform/ext/target/arm/corstone1000/partition/gpt.c b/platform/ext/target/arm/corstone1000/partition/gpt.c
81new file mode 100644
82index 0000000000..8549785e3b
83--- /dev/null
84+++ b/platform/ext/target/arm/corstone1000/partition/gpt.c
85@@ -0,0 +1,58 @@
86+/*
87+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
88+ *
89+ * SPDX-License-Identifier: BSD-3-Clause
90+ */
91+
92+#include "gpt.h"
93+
94+#include <assert.h>
95+#include <errno.h>
96+#include <string.h>
97+
98+#include "efi.h"
99+
100+static int unicode_to_ascii(unsigned short *str_in, unsigned char *str_out) {
101+ uint8_t *name;
102+ int i;
103+
104+ assert((str_in != NULL) && (str_out != NULL));
105+
106+ name = (uint8_t *)str_in;
107+
108+ assert(name[0] != '\0');
109+
110+ /* check whether the unicode string is valid */
111+ for (i = 1; i < (EFI_NAMELEN << 1); i += 2) {
112+ if (name[i] != '\0') return -EINVAL;
113+ }
114+ /* convert the unicode string to ascii string */
115+ for (i = 0; i < (EFI_NAMELEN << 1); i += 2) {
116+ str_out[i >> 1] = name[i];
117+ if (name[i] == '\0') break;
118+ }
119+ return 0;
120+}
121+
122+int parse_gpt_entry(gpt_entry_t *gpt_entry, partition_entry_t *entry) {
123+ int result;
124+
125+ assert((gpt_entry != NULL) && (entry != NULL));
126+
127+ if ((gpt_entry->first_lba == 0) && (gpt_entry->last_lba == 0)) {
128+ return -EINVAL;
129+ }
130+
131+ memset(entry, 0, sizeof(partition_entry_t));
132+ result = unicode_to_ascii(gpt_entry->name, (uint8_t *)entry->name);
133+ if (result != 0) {
134+ return result;
135+ }
136+ entry->start = (uint64_t)gpt_entry->first_lba * PLAT_PARTITION_BLOCK_SIZE;
137+ entry->length = (uint64_t)(gpt_entry->last_lba - gpt_entry->first_lba + 1) *
138+ PLAT_PARTITION_BLOCK_SIZE;
139+ guidcpy(&entry->part_guid, &gpt_entry->unique_uuid);
140+ guidcpy(&entry->type_guid, &gpt_entry->type_uuid);
141+
142+ return 0;
143+}
144diff --git a/platform/ext/target/arm/corstone1000/partition/gpt.h b/platform/ext/target/arm/corstone1000/partition/gpt.h
145new file mode 100644
146index 0000000000..b528fc05c0
147--- /dev/null
148+++ b/platform/ext/target/arm/corstone1000/partition/gpt.h
149@@ -0,0 +1,51 @@
150+/*
151+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
152+ *
153+ * SPDX-License-Identifier: BSD-3-Clause
154+ */
155+
156+#ifndef GPT_H
157+#define GPT_H
158+
159+#include "efi.h"
160+#include "partition.h"
161+#include "uuid.h"
162+
163+#define PARTITION_TYPE_GPT 0xee
164+#define GPT_HEADER_OFFSET PLAT_PARTITION_BLOCK_SIZE
165+#define GPT_ENTRY_OFFSET (GPT_HEADER_OFFSET + PLAT_PARTITION_BLOCK_SIZE)
166+
167+#define GPT_SIGNATURE "EFI PART"
168+
169+typedef struct gpt_entry {
170+ struct efi_guid type_uuid;
171+ struct efi_guid unique_uuid;
172+ unsigned long long first_lba;
173+ unsigned long long last_lba;
174+ unsigned long long attr;
175+ unsigned short name[EFI_NAMELEN];
176+} gpt_entry_t;
177+
178+typedef struct gpt_header {
179+ unsigned char signature[8];
180+ unsigned int revision;
181+ unsigned int size;
182+ unsigned int header_crc;
183+ unsigned int reserved;
184+ unsigned long long current_lba;
185+ unsigned long long backup_lba;
186+ unsigned long long first_lba;
187+ unsigned long long last_lba;
188+ struct efi_guid disk_uuid;
189+ /* starting LBA of array of partition entries */
190+ unsigned long long part_lba;
191+ /* number of partition entries in array */
192+ unsigned int list_num;
193+ /* size of a single partition entry (usually 128) */
194+ unsigned int part_size;
195+ unsigned int part_crc;
196+} gpt_header_t;
197+
198+int parse_gpt_entry(gpt_entry_t *gpt_entry, partition_entry_t *entry);
199+
200+#endif /* GPT_H */
201diff --git a/platform/ext/target/arm/corstone1000/partition/mbr.h b/platform/ext/target/arm/corstone1000/partition/mbr.h
202new file mode 100644
203index 0000000000..e77f367016
204--- /dev/null
205+++ b/platform/ext/target/arm/corstone1000/partition/mbr.h
206@@ -0,0 +1,29 @@
207+/*
208+ * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
209+ *
210+ * SPDX-License-Identifier: BSD-3-Clause
211+ */
212+
213+#ifndef MBR_H
214+#define MBR_H
215+
216+#define MBR_OFFSET 0
217+
218+#define MBR_PRIMARY_ENTRY_OFFSET 0x1be
219+#define MBR_PRIMARY_ENTRY_SIZE 0x10
220+#define MBR_PRIMARY_ENTRY_NUMBER 4
221+#define MBR_CHS_ADDRESS_LEN 3
222+
223+#define MBR_SIGNATURE_FIRST 0x55
224+#define MBR_SIGNATURE_SECOND 0xAA
225+
226+typedef struct mbr_entry {
227+ unsigned char status;
228+ unsigned char first_sector[MBR_CHS_ADDRESS_LEN];
229+ unsigned char type;
230+ unsigned char last_sector[MBR_CHS_ADDRESS_LEN];
231+ unsigned int first_lba;
232+ unsigned int sector_nums;
233+} mbr_entry_t;
234+
235+#endif /* MBR_H */
236diff --git a/platform/ext/target/arm/corstone1000/partition/partition.c b/platform/ext/target/arm/corstone1000/partition/partition.c
237new file mode 100644
238index 0000000000..afc6aa1c5c
239--- /dev/null
240+++ b/platform/ext/target/arm/corstone1000/partition/partition.c
241@@ -0,0 +1,310 @@
242+/*
243+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
244+ *
245+ * SPDX-License-Identifier: BSD-3-Clause
246+ */
247+
248+#include "partition.h"
249+
250+#include <assert.h>
251+#include <errno.h>
252+#include <inttypes.h>
253+#include <stdio.h>
254+#include <string.h>
255+
256+#include "efi.h"
257+#include "gpt.h"
258+#include "mbr.h"
259+
260+#include "io_storage.h"
261+#include "platform.h"
262+#include "soft_crc.h"
263+
264+#define PLAT_LOG_MODULE_NAME "partition"
265+#include "platform_log.h"
266+
267+static uint8_t mbr_sector[PLAT_PARTITION_BLOCK_SIZE];
268+static partition_entry_list_t list;
269+
270+#if LOG_LEVEL >= LOG_LEVEL_DEBUG
271+static void dump_entries(int num) {
272+ char name[EFI_NAMELEN];
273+ int i, j, len;
274+
275+ VERBOSE("Partition table with %d entries:", num);
276+ for (i = 0; i < num; i++) {
277+ len = snprintf(name, EFI_NAMELEN, "%s", list.list[i].name);
278+ for (j = 0; j < EFI_NAMELEN - len - 1; j++) {
279+ name[len + j] = ' ';
280+ }
281+ name[EFI_NAMELEN - 1] = '\0';
282+ VERBOSE("%d: %s %x%x %d", i + 1, name,
283+ (uint32_t)(list.list[i].start >> 32),
284+ (uint32_t)list.list[i].start,
285+ (uint32_t)(list.list[i].start + list.list[i].length - 4));
286+ }
287+}
288+#else
289+#define dump_entries(num) ((void)num)
290+#endif
291+
292+/*
293+ * Load the first sector that carries MBR header.
294+ * The MBR boot signature should be always valid whether it's MBR or GPT.
295+ */
296+static int load_mbr_header(uintptr_t image_handle, mbr_entry_t *mbr_entry) {
297+ size_t bytes_read;
298+ uintptr_t offset;
299+ int result;
300+
301+ assert(mbr_entry != NULL);
302+ /* MBR partition table is in LBA0. */
303+ result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET);
304+ if (result != 0) {
305+ WARN("Failed to seek (%i)\n", result);
306+ return result;
307+ }
308+ result = io_read(image_handle, (uintptr_t)&mbr_sector,
309+ PLAT_PARTITION_BLOCK_SIZE, &bytes_read);
310+ if (result != 0) {
311+ WARN("Failed to read data (%i)\n", result);
312+ return result;
313+ }
314+
315+ /* Check MBR boot signature. */
316+ if ((mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) ||
317+ (mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) {
318+ ERROR("MBR signature isn't correct");
319+ return -ENOENT;
320+ }
321+ offset = (uintptr_t)&mbr_sector + MBR_PRIMARY_ENTRY_OFFSET;
322+ memcpy(mbr_entry, (void *)offset, sizeof(mbr_entry_t));
323+ return 0;
324+}
325+
326+/*
327+ * Load GPT header and check the GPT signature and header CRC.
328+ * If partition numbers could be found, check & update it.
329+ */
330+static int load_gpt_header(uintptr_t image_handle) {
331+ gpt_header_t header;
332+ size_t bytes_read;
333+ int result;
334+ uint32_t header_crc, calc_crc;
335+
336+ result = io_seek(image_handle, IO_SEEK_SET, GPT_HEADER_OFFSET);
337+ if (result != 0) {
338+ return result;
339+ }
340+ result = io_read(image_handle, (uintptr_t)&header, sizeof(gpt_header_t),
341+ &bytes_read);
342+ if ((result != 0) || (sizeof(gpt_header_t) != bytes_read)) {
343+ return result;
344+ }
345+ if (memcmp(header.signature, GPT_SIGNATURE, sizeof(header.signature)) !=
346+ 0) {
347+ return -EINVAL;
348+ }
349+
350+ /*
351+ * UEFI Spec 2.8 March 2019 Page 119: HeaderCRC32 value is
352+ * computed by setting this field to 0, and computing the
353+ * 32-bit CRC for HeaderSize bytes.
354+ */
355+ header_crc = header.header_crc;
356+ header.header_crc = 0U;
357+
358+ calc_crc = crc32((uint8_t *)&header, DEFAULT_GPT_HEADER_SIZE);
359+ if (header_crc != calc_crc) {
360+ ERROR("Invalid GPT Header CRC: Expected 0x%x but got 0x%x.\n",
361+ header_crc, calc_crc);
362+ return -EINVAL;
363+ }
364+
365+ header.header_crc = header_crc;
366+
367+ /* partition numbers can't exceed PLAT_PARTITION_MAX_ENTRIES */
368+ list.entry_count = header.list_num;
369+ if (list.entry_count > PLAT_PARTITION_MAX_ENTRIES) {
370+ list.entry_count = PLAT_PARTITION_MAX_ENTRIES;
371+ }
372+ return 0;
373+}
374+
375+static int load_mbr_entry(uintptr_t image_handle, mbr_entry_t *mbr_entry,
376+ int part_number) {
377+ size_t bytes_read;
378+ uintptr_t offset;
379+ int result;
380+
381+ assert(mbr_entry != NULL);
382+ /* MBR partition table is in LBA0. */
383+ result = io_seek(image_handle, IO_SEEK_SET, MBR_OFFSET);
384+ if (result != 0) {
385+ WARN("Failed to seek (%i)\n", result);
386+ return result;
387+ }
388+ result = io_read(image_handle, (uintptr_t)&mbr_sector,
389+ PLAT_PARTITION_BLOCK_SIZE, &bytes_read);
390+ if (result != 0) {
391+ WARN("Failed to read data (%i)\n", result);
392+ return result;
393+ }
394+
395+ /* Check MBR boot signature. */
396+ if ((mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 2] != MBR_SIGNATURE_FIRST) ||
397+ (mbr_sector[LEGACY_PARTITION_BLOCK_SIZE - 1] != MBR_SIGNATURE_SECOND)) {
398+ return -ENOENT;
399+ }
400+ offset = (uintptr_t)&mbr_sector + MBR_PRIMARY_ENTRY_OFFSET +
401+ MBR_PRIMARY_ENTRY_SIZE * part_number;
402+ memcpy(mbr_entry, (void *)offset, sizeof(mbr_entry_t));
403+
404+ return 0;
405+}
406+
407+static int load_mbr_entries(uintptr_t image_handle) {
408+ mbr_entry_t mbr_entry;
409+ int i;
410+
411+ list.entry_count = MBR_PRIMARY_ENTRY_NUMBER;
412+
413+ for (i = 0; i < list.entry_count; i++) {
414+ load_mbr_entry(image_handle, &mbr_entry, i);
415+ list.list[i].start = mbr_entry.first_lba * 512;
416+ list.list[i].length = mbr_entry.sector_nums * 512;
417+ list.list[i].name[0] = mbr_entry.type;
418+ }
419+
420+ return 0;
421+}
422+
423+static int load_gpt_entry(uintptr_t image_handle, gpt_entry_t *entry) {
424+ size_t bytes_read;
425+ int result;
426+
427+ assert(entry != NULL);
428+ result = io_read(image_handle, (uintptr_t)entry, sizeof(gpt_entry_t),
429+ &bytes_read);
430+ if (sizeof(gpt_entry_t) != bytes_read) return -EINVAL;
431+ return result;
432+}
433+
434+static int verify_partition_gpt(uintptr_t image_handle) {
435+ gpt_entry_t entry;
436+ int result, i;
437+
438+ for (i = 0; i < list.entry_count; i++) {
439+ result = load_gpt_entry(image_handle, &entry);
440+ assert(result == 0);
441+ if (result != 0) {
442+ break;
443+ }
444+ result = parse_gpt_entry(&entry, &list.list[i]);
445+ if (result != 0) {
446+ break;
447+ }
448+ }
449+ if (i == 0) {
450+ return -EINVAL;
451+ }
452+ /*
453+ * Only records the valid partition number that is loaded from
454+ * partition table.
455+ */
456+ list.entry_count = i;
457+ dump_entries(list.entry_count);
458+
459+ return 0;
460+}
461+
462+int load_partition_table(unsigned int image_id) {
463+ uintptr_t dev_handle, image_handle, image_spec = 0;
464+ mbr_entry_t mbr_entry;
465+ int result;
466+
467+ result = plat_get_image_source(image_id, &dev_handle, &image_spec);
468+ if (result != 0) {
469+ WARN("Failed to obtain reference to image id=%u (%i)\n", image_id,
470+ result);
471+ return result;
472+ }
473+
474+ result = io_open(dev_handle, image_spec, &image_handle);
475+ if (result != 0) {
476+ WARN("Failed to open image id=%u (%i)\n", image_id, result);
477+ return result;
478+ }
479+
480+ result = load_mbr_header(image_handle, &mbr_entry);
481+ if (result != 0) {
482+ ERROR("Loading mbr header failed with image id=%u (%i)\n", image_id,
483+ result);
484+ return result;
485+ }
486+ if (mbr_entry.type == PARTITION_TYPE_GPT) {
487+ INFO("Loading gpt header");
488+ result = load_gpt_header(image_handle);
489+ assert(result == 0);
490+ if (result != 0) {
491+ ERROR("Failed load gpt header! %i", result);
492+ goto load_partition_table_exit;
493+ }
494+ result = io_seek(image_handle, IO_SEEK_SET, GPT_ENTRY_OFFSET);
495+ assert(result == 0);
496+ if (result != 0) {
497+ ERROR("Failed seek gpt header! %i", result);
498+ goto load_partition_table_exit;
499+ }
500+ result = verify_partition_gpt(image_handle);
501+ if (result != 0) {
502+ ERROR("Failed verify gpt partition %i", result);
503+ goto load_partition_table_exit;
504+ }
505+ } else {
506+ result = load_mbr_entries(image_handle);
507+ }
508+
509+load_partition_table_exit:
510+ io_close(image_handle);
511+ return result;
512+}
513+
514+const partition_entry_t *get_partition_entry(const char *name) {
515+ int i;
516+
517+ for (i = 0; i < list.entry_count; i++) {
518+ if (strcmp(name, list.list[i].name) == 0) {
519+ return &list.list[i];
520+ }
521+ }
522+ return NULL;
523+}
524+
525+const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_uuid) {
526+ int i;
527+
528+ for (i = 0; i < list.entry_count; i++) {
529+ if (guidcmp(type_uuid, &list.list[i].type_guid) == 0) {
530+ return &list.list[i];
531+ }
532+ }
533+
534+ return NULL;
535+}
536+
537+const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid) {
538+ int i;
539+
540+ for (i = 0; i < list.entry_count; i++) {
541+ if (guidcmp(part_uuid, &list.list[i].part_guid) == 0) {
542+ return &list.list[i];
543+ }
544+ }
545+
546+ return NULL;
547+}
548+
549+const partition_entry_list_t *get_partition_entry_list(void) { return &list; }
550+
551+void partition_init(unsigned int image_id) { load_partition_table(image_id); }
552diff --git a/platform/ext/target/arm/corstone1000/partition/partition.h b/platform/ext/target/arm/corstone1000/partition/partition.h
553new file mode 100644
554index 0000000000..54af47aca4
555--- /dev/null
556+++ b/platform/ext/target/arm/corstone1000/partition/partition.h
557@@ -0,0 +1,47 @@
558+/*
559+ * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
560+ *
561+ * SPDX-License-Identifier: BSD-3-Clause
562+ */
563+
564+#ifndef PARTITION_H
565+#define PARTITION_H
566+
567+#include <stdint.h>
568+
569+#include "efi.h"
570+#include "uuid.h"
571+
572+#if !PLAT_PARTITION_MAX_ENTRIES
573+#define PLAT_PARTITION_MAX_ENTRIES 16
574+#endif /* PLAT_PARTITION_MAX_ENTRIES */
575+
576+#if !PLAT_PARTITION_BLOCK_SIZE
577+#define PLAT_PARTITION_BLOCK_SIZE 512
578+#endif /* PLAT_PARTITION_BLOCK_SIZE */
579+
580+#define LEGACY_PARTITION_BLOCK_SIZE 512
581+
582+#define DEFAULT_GPT_HEADER_SIZE 92
583+
584+typedef struct partition_entry {
585+ uint64_t start;
586+ uint64_t length;
587+ char name[EFI_NAMELEN];
588+ struct efi_guid part_guid;
589+ struct efi_guid type_guid;
590+} partition_entry_t;
591+
592+typedef struct partition_entry_list {
593+ partition_entry_t list[PLAT_PARTITION_MAX_ENTRIES];
594+ int entry_count;
595+} partition_entry_list_t;
596+
597+int load_partition_table(unsigned int image_id);
598+const partition_entry_t *get_partition_entry(const char *name);
599+const partition_entry_t *get_partition_entry_by_type(const uuid_t *type_guid);
600+const partition_entry_t *get_partition_entry_by_uuid(const uuid_t *part_uuid);
601+const partition_entry_list_t *get_partition_entry_list(void);
602+void partition_init(unsigned int image_id);
603+
604+#endif /* PARTITION_H */
605diff --git a/platform/ext/target/arm/corstone1000/partition/uuid.h b/platform/ext/target/arm/corstone1000/partition/uuid.h
606new file mode 100644
607index 0000000000..06fec5a3c0
608--- /dev/null
609+++ b/platform/ext/target/arm/corstone1000/partition/uuid.h
610@@ -0,0 +1,76 @@
611+/*-
612+ * Copyright (c) 2002 Marcel Moolenaar
613+ * All rights reserved.
614+ *
615+ * Redistribution and use in source and binary forms, with or without
616+ * modification, are permitted provided that the following conditions
617+ * are met:
618+ *
619+ * 1. Redistributions of source code must retain the above copyright
620+ * notice, this list of conditions and the following disclaimer.
621+ * 2. Redistributions in binary form must reproduce the above copyright
622+ * notice, this list of conditions and the following disclaimer in the
623+ * documentation and/or other materials provided with the distribution.
624+ *
625+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
626+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
627+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
628+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
629+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
630+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
631+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
632+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
633+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
634+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
635+ *
636+ * $FreeBSD$
637+ */
638+
639+/*
640+ * Portions copyright (c) 2014-2020, ARM Limited and Contributors.
641+ * All rights reserved.
642+ */
643+
644+#ifndef UUID_H
645+#define UUID_H
646+
647+#include <stdint.h>
648+
649+/* Length of a node address (an IEEE 802 address). */
650+#define _UUID_NODE_LEN 6
651+
652+/* Length of UUID string including dashes. */
653+#define _UUID_STR_LEN 36
654+
655+/*
656+ * See also:
657+ * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
658+ * http://www.opengroup.org/onlinepubs/009629399/apdxa.htm
659+ *
660+ * A DCE 1.1 compatible source representation of UUIDs.
661+ */
662+struct uuid {
663+ uint8_t time_low[4];
664+ uint8_t time_mid[2];
665+ uint8_t time_hi_and_version[2];
666+ uint8_t clock_seq_hi_and_reserved;
667+ uint8_t clock_seq_low;
668+ uint8_t node[_UUID_NODE_LEN];
669+};
670+
671+struct efi_guid {
672+ uint32_t time_low;
673+ uint16_t time_mid;
674+ uint16_t time_hi_and_version;
675+ uint8_t clock_seq_and_node[8];
676+};
677+
678+union uuid_helper_t {
679+ struct uuid uuid_struct;
680+ struct efi_guid efi_guid;
681+};
682+
683+/* XXX namespace pollution? */
684+typedef struct uuid uuid_t;
685+
686+#endif /* UUID_H */
687diff --git a/platform/ext/target/arm/corstone1000/platform.c b/platform/ext/target/arm/corstone1000/platform.c
688new file mode 100644
689index 0000000000..908b66b7ac
690--- /dev/null
691+++ b/platform/ext/target/arm/corstone1000/platform.c
692@@ -0,0 +1,20 @@
693+/*
694+ * Copyright (c) 2023, Arm Limited. All rights reserved.
695+ *
696+ * SPDX-License-Identifier: BSD-3-Clause
697+ *
698+ */
699+
700+#include "platform.h"
701+
702+#include <stdint.h>
703+
704+/* Return an IO device handle and specification which can be used to access
705+ * an image. This has to be implemented for the GPT parser. */
706+int32_t plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
707+ uintptr_t *image_spec) {
708+ (void)image_id;
709+ *dev_handle = NULL;
710+ *image_spec = NULL;
711+ return 0;
712+}
713diff --git a/platform/ext/target/arm/corstone1000/platform.h b/platform/ext/target/arm/corstone1000/platform.h
714new file mode 100644
715index 0000000000..250f9cd9f5
716--- /dev/null
717+++ b/platform/ext/target/arm/corstone1000/platform.h
718@@ -0,0 +1,14 @@
719+/*
720+ * Copyright (c) 2023, Arm Limited. All rights reserved.
721+ *
722+ * SPDX-License-Identifier: BSD-3-Clause
723+ *
724+ */
725+
726+#ifndef __PLATFORM_H__
727+#define __PLATFORM_H__
728+
729+int32_t plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
730+ uintptr_t *image_spec);
731+
732+#endif /*__PLATFORM_H__*/
733--
7342.25.1
735