]> git.sur5r.net Git - u-boot/blob - disk/part_efi.c
db410c: Added pre-relocation attribute to pinctrl
[u-boot] / disk / part_efi.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2008 RuggedCom, Inc.
4  * Richard Retanubun <RichardRetanubun@RuggedCom.com>
5  */
6
7 /*
8  * NOTE:
9  *   when CONFIG_SYS_64BIT_LBA is not defined, lbaint_t is 32 bits; this
10  *   limits the maximum size of addressable storage to < 2 Terra Bytes
11  */
12 #include <asm/unaligned.h>
13 #include <common.h>
14 #include <command.h>
15 #include <fdtdec.h>
16 #include <ide.h>
17 #include <inttypes.h>
18 #include <malloc.h>
19 #include <memalign.h>
20 #include <part_efi.h>
21 #include <linux/compiler.h>
22 #include <linux/ctype.h>
23
24 DECLARE_GLOBAL_DATA_PTR;
25
26 #ifdef CONFIG_HAVE_BLOCK_DEVICE
27 /**
28  * efi_crc32() - EFI version of crc32 function
29  * @buf: buffer to calculate crc32 of
30  * @len - length of buf
31  *
32  * Description: Returns EFI-style CRC32 value for @buf
33  */
34 static inline u32 efi_crc32(const void *buf, u32 len)
35 {
36         return crc32(0, buf, len);
37 }
38
39 /*
40  * Private function prototypes
41  */
42
43 static int pmbr_part_valid(struct partition *part);
44 static int is_pmbr_valid(legacy_mbr * mbr);
45 static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba,
46                                 gpt_header *pgpt_head, gpt_entry **pgpt_pte);
47 static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc,
48                                          gpt_header *pgpt_head);
49 static int is_pte_valid(gpt_entry * pte);
50
51 static char *print_efiname(gpt_entry *pte)
52 {
53         static char name[PARTNAME_SZ + 1];
54         int i;
55         for (i = 0; i < PARTNAME_SZ; i++) {
56                 u8 c;
57                 c = pte->partition_name[i] & 0xff;
58                 c = (c && !isprint(c)) ? '.' : c;
59                 name[i] = c;
60         }
61         name[PARTNAME_SZ] = 0;
62         return name;
63 }
64
65 static efi_guid_t system_guid = PARTITION_SYSTEM_GUID;
66
67 static inline int is_bootable(gpt_entry *p)
68 {
69         return p->attributes.fields.legacy_bios_bootable ||
70                 !memcmp(&(p->partition_type_guid), &system_guid,
71                         sizeof(efi_guid_t));
72 }
73
74 static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba,
75                 lbaint_t lastlba)
76 {
77         uint32_t crc32_backup = 0;
78         uint32_t calc_crc32;
79
80         /* Check the GPT header signature */
81         if (le64_to_cpu(gpt_h->signature) != GPT_HEADER_SIGNATURE) {
82                 printf("%s signature is wrong: 0x%llX != 0x%llX\n",
83                        "GUID Partition Table Header",
84                        le64_to_cpu(gpt_h->signature),
85                        GPT_HEADER_SIGNATURE);
86                 return -1;
87         }
88
89         /* Check the GUID Partition Table CRC */
90         memcpy(&crc32_backup, &gpt_h->header_crc32, sizeof(crc32_backup));
91         memset(&gpt_h->header_crc32, 0, sizeof(gpt_h->header_crc32));
92
93         calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
94                 le32_to_cpu(gpt_h->header_size));
95
96         memcpy(&gpt_h->header_crc32, &crc32_backup, sizeof(crc32_backup));
97
98         if (calc_crc32 != le32_to_cpu(crc32_backup)) {
99                 printf("%s CRC is wrong: 0x%x != 0x%x\n",
100                        "GUID Partition Table Header",
101                        le32_to_cpu(crc32_backup), calc_crc32);
102                 return -1;
103         }
104
105         /*
106          * Check that the my_lba entry points to the LBA that contains the GPT
107          */
108         if (le64_to_cpu(gpt_h->my_lba) != lba) {
109                 printf("GPT: my_lba incorrect: %llX != " LBAF "\n",
110                        le64_to_cpu(gpt_h->my_lba),
111                        lba);
112                 return -1;
113         }
114
115         /*
116          * Check that the first_usable_lba and that the last_usable_lba are
117          * within the disk.
118          */
119         if (le64_to_cpu(gpt_h->first_usable_lba) > lastlba) {
120                 printf("GPT: first_usable_lba incorrect: %llX > " LBAF "\n",
121                        le64_to_cpu(gpt_h->first_usable_lba), lastlba);
122                 return -1;
123         }
124         if (le64_to_cpu(gpt_h->last_usable_lba) > lastlba) {
125                 printf("GPT: last_usable_lba incorrect: %llX > " LBAF "\n",
126                        le64_to_cpu(gpt_h->last_usable_lba), lastlba);
127                 return -1;
128         }
129
130         debug("GPT: first_usable_lba: %llX last_usable_lba: %llX last lba: "
131               LBAF "\n", le64_to_cpu(gpt_h->first_usable_lba),
132               le64_to_cpu(gpt_h->last_usable_lba), lastlba);
133
134         return 0;
135 }
136
137 static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e)
138 {
139         uint32_t calc_crc32;
140
141         /* Check the GUID Partition Table Entry Array CRC */
142         calc_crc32 = efi_crc32((const unsigned char *)gpt_e,
143                 le32_to_cpu(gpt_h->num_partition_entries) *
144                 le32_to_cpu(gpt_h->sizeof_partition_entry));
145
146         if (calc_crc32 != le32_to_cpu(gpt_h->partition_entry_array_crc32)) {
147                 printf("%s: 0x%x != 0x%x\n",
148                        "GUID Partition Table Entry Array CRC is wrong",
149                        le32_to_cpu(gpt_h->partition_entry_array_crc32),
150                        calc_crc32);
151                 return -1;
152         }
153
154         return 0;
155 }
156
157 static void prepare_backup_gpt_header(gpt_header *gpt_h)
158 {
159         uint32_t calc_crc32;
160         uint64_t val;
161
162         /* recalculate the values for the Backup GPT Header */
163         val = le64_to_cpu(gpt_h->my_lba);
164         gpt_h->my_lba = gpt_h->alternate_lba;
165         gpt_h->alternate_lba = cpu_to_le64(val);
166         gpt_h->partition_entry_lba =
167                         cpu_to_le64(le64_to_cpu(gpt_h->last_usable_lba) + 1);
168         gpt_h->header_crc32 = 0;
169
170         calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
171                                le32_to_cpu(gpt_h->header_size));
172         gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
173 }
174
175 #if CONFIG_IS_ENABLED(EFI_PARTITION)
176 /*
177  * Public Functions (include/part.h)
178  */
179
180 /*
181  * UUID is displayed as 32 hexadecimal digits, in 5 groups,
182  * separated by hyphens, in the form 8-4-4-4-12 for a total of 36 characters
183  */
184 int get_disk_guid(struct blk_desc * dev_desc, char *guid)
185 {
186         ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
187         gpt_entry *gpt_pte = NULL;
188         unsigned char *guid_bin;
189
190         /* This function validates AND fills in the GPT header and PTE */
191         if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
192                          gpt_head, &gpt_pte) != 1) {
193                 printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
194                 if (is_gpt_valid(dev_desc, dev_desc->lba - 1,
195                                  gpt_head, &gpt_pte) != 1) {
196                         printf("%s: *** ERROR: Invalid Backup GPT ***\n",
197                                __func__);
198                         return -EINVAL;
199                 } else {
200                         printf("%s: ***        Using Backup GPT ***\n",
201                                __func__);
202                 }
203         }
204
205         guid_bin = gpt_head->disk_guid.b;
206         uuid_bin_to_str(guid_bin, guid, UUID_STR_FORMAT_GUID);
207
208         return 0;
209 }
210
211 void part_print_efi(struct blk_desc *dev_desc)
212 {
213         ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
214         gpt_entry *gpt_pte = NULL;
215         int i = 0;
216         char uuid[UUID_STR_LEN + 1];
217         unsigned char *uuid_bin;
218
219         /* This function validates AND fills in the GPT header and PTE */
220         if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
221                          gpt_head, &gpt_pte) != 1) {
222                 printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
223                 if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
224                                  gpt_head, &gpt_pte) != 1) {
225                         printf("%s: *** ERROR: Invalid Backup GPT ***\n",
226                                __func__);
227                         return;
228                 } else {
229                         printf("%s: ***        Using Backup GPT ***\n",
230                                __func__);
231                 }
232         }
233
234         debug("%s: gpt-entry at %p\n", __func__, gpt_pte);
235
236         printf("Part\tStart LBA\tEnd LBA\t\tName\n");
237         printf("\tAttributes\n");
238         printf("\tType GUID\n");
239         printf("\tPartition GUID\n");
240
241         for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) {
242                 /* Stop at the first non valid PTE */
243                 if (!is_pte_valid(&gpt_pte[i]))
244                         break;
245
246                 printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"\n", (i + 1),
247                         le64_to_cpu(gpt_pte[i].starting_lba),
248                         le64_to_cpu(gpt_pte[i].ending_lba),
249                         print_efiname(&gpt_pte[i]));
250                 printf("\tattrs:\t0x%016llx\n", gpt_pte[i].attributes.raw);
251                 uuid_bin = (unsigned char *)gpt_pte[i].partition_type_guid.b;
252                 uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
253                 printf("\ttype:\t%s\n", uuid);
254 #ifdef CONFIG_PARTITION_TYPE_GUID
255                 if (!uuid_guid_get_str(uuid_bin, uuid))
256                         printf("\ttype:\t%s\n", uuid);
257 #endif
258                 uuid_bin = (unsigned char *)gpt_pte[i].unique_partition_guid.b;
259                 uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
260                 printf("\tguid:\t%s\n", uuid);
261         }
262
263         /* Remember to free pte */
264         free(gpt_pte);
265         return;
266 }
267
268 int part_get_info_efi(struct blk_desc *dev_desc, int part,
269                       disk_partition_t *info)
270 {
271         ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
272         gpt_entry *gpt_pte = NULL;
273
274         /* "part" argument must be at least 1 */
275         if (part < 1) {
276                 printf("%s: Invalid Argument(s)\n", __func__);
277                 return -1;
278         }
279
280         /* This function validates AND fills in the GPT header and PTE */
281         if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
282                         gpt_head, &gpt_pte) != 1) {
283                 printf("%s: *** ERROR: Invalid GPT ***\n", __func__);
284                 if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
285                                  gpt_head, &gpt_pte) != 1) {
286                         printf("%s: *** ERROR: Invalid Backup GPT ***\n",
287                                __func__);
288                         return -1;
289                 } else {
290                         printf("%s: ***        Using Backup GPT ***\n",
291                                __func__);
292                 }
293         }
294
295         if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
296             !is_pte_valid(&gpt_pte[part - 1])) {
297                 debug("%s: *** ERROR: Invalid partition number %d ***\n",
298                         __func__, part);
299                 free(gpt_pte);
300                 return -1;
301         }
302
303         /* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */
304         info->start = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].starting_lba);
305         /* The ending LBA is inclusive, to calculate size, add 1 to it */
306         info->size = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1
307                      - info->start;
308         info->blksz = dev_desc->blksz;
309
310         sprintf((char *)info->name, "%s",
311                         print_efiname(&gpt_pte[part - 1]));
312         strcpy((char *)info->type, "U-Boot");
313         info->bootable = is_bootable(&gpt_pte[part - 1]);
314 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
315         uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid,
316                         UUID_STR_FORMAT_GUID);
317 #endif
318 #ifdef CONFIG_PARTITION_TYPE_GUID
319         uuid_bin_to_str(gpt_pte[part - 1].partition_type_guid.b,
320                         info->type_guid, UUID_STR_FORMAT_GUID);
321 #endif
322
323         debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__,
324               info->start, info->size, info->name);
325
326         /* Remember to free pte */
327         free(gpt_pte);
328         return 0;
329 }
330
331 static int part_test_efi(struct blk_desc *dev_desc)
332 {
333         ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz);
334
335         /* Read legacy MBR from block 0 and validate it */
336         if ((blk_dread(dev_desc, 0, 1, (ulong *)legacymbr) != 1)
337                 || (is_pmbr_valid(legacymbr) != 1)) {
338                 return -1;
339         }
340         return 0;
341 }
342
343 /**
344  * set_protective_mbr(): Set the EFI protective MBR
345  * @param dev_desc - block device descriptor
346  *
347  * @return - zero on success, otherwise error
348  */
349 static int set_protective_mbr(struct blk_desc *dev_desc)
350 {
351         /* Setup the Protective MBR */
352         ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, p_mbr, 1, dev_desc->blksz);
353         memset(p_mbr, 0, sizeof(*p_mbr));
354
355         if (p_mbr == NULL) {
356                 printf("%s: calloc failed!\n", __func__);
357                 return -1;
358         }
359
360         /* Read MBR to backup boot code if it exists */
361         if (blk_dread(dev_desc, 0, 1, p_mbr) != 1) {
362                 pr_err("** Can't read from device %d **\n", dev_desc->devnum);
363                 return -1;
364         }
365
366         /* Append signature */
367         p_mbr->signature = MSDOS_MBR_SIGNATURE;
368         p_mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
369         p_mbr->partition_record[0].start_sect = 1;
370         p_mbr->partition_record[0].nr_sects = (u32) dev_desc->lba - 1;
371
372         /* Write MBR sector to the MMC device */
373         if (blk_dwrite(dev_desc, 0, 1, p_mbr) != 1) {
374                 printf("** Can't write to device %d **\n",
375                         dev_desc->devnum);
376                 return -1;
377         }
378
379         return 0;
380 }
381
382 int write_gpt_table(struct blk_desc *dev_desc,
383                 gpt_header *gpt_h, gpt_entry *gpt_e)
384 {
385         const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries
386                                            * sizeof(gpt_entry)), dev_desc);
387         u32 calc_crc32;
388
389         debug("max lba: %x\n", (u32) dev_desc->lba);
390         /* Setup the Protective MBR */
391         if (set_protective_mbr(dev_desc) < 0)
392                 goto err;
393
394         /* Generate CRC for the Primary GPT Header */
395         calc_crc32 = efi_crc32((const unsigned char *)gpt_e,
396                               le32_to_cpu(gpt_h->num_partition_entries) *
397                               le32_to_cpu(gpt_h->sizeof_partition_entry));
398         gpt_h->partition_entry_array_crc32 = cpu_to_le32(calc_crc32);
399
400         calc_crc32 = efi_crc32((const unsigned char *)gpt_h,
401                               le32_to_cpu(gpt_h->header_size));
402         gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
403
404         /* Write the First GPT to the block right after the Legacy MBR */
405         if (blk_dwrite(dev_desc, 1, 1, gpt_h) != 1)
406                 goto err;
407
408         if (blk_dwrite(dev_desc, le64_to_cpu(gpt_h->partition_entry_lba),
409                        pte_blk_cnt, gpt_e) != pte_blk_cnt)
410                 goto err;
411
412         prepare_backup_gpt_header(gpt_h);
413
414         if (blk_dwrite(dev_desc, (lbaint_t)le64_to_cpu(gpt_h->last_usable_lba)
415                        + 1, pte_blk_cnt, gpt_e) != pte_blk_cnt)
416                 goto err;
417
418         if (blk_dwrite(dev_desc, (lbaint_t)le64_to_cpu(gpt_h->my_lba), 1,
419                        gpt_h) != 1)
420                 goto err;
421
422         debug("GPT successfully written to block device!\n");
423         return 0;
424
425  err:
426         printf("** Can't write to device %d **\n", dev_desc->devnum);
427         return -1;
428 }
429
430 int gpt_fill_pte(struct blk_desc *dev_desc,
431                  gpt_header *gpt_h, gpt_entry *gpt_e,
432                  disk_partition_t *partitions, int parts)
433 {
434         lbaint_t offset = (lbaint_t)le64_to_cpu(gpt_h->first_usable_lba);
435         lbaint_t last_usable_lba = (lbaint_t)
436                         le64_to_cpu(gpt_h->last_usable_lba);
437         int i, k;
438         size_t efiname_len, dosname_len;
439 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
440         char *str_uuid;
441         unsigned char *bin_uuid;
442 #endif
443 #ifdef CONFIG_PARTITION_TYPE_GUID
444         char *str_type_guid;
445         unsigned char *bin_type_guid;
446 #endif
447         size_t hdr_start = gpt_h->my_lba;
448         size_t hdr_end = hdr_start + 1;
449
450         size_t pte_start = gpt_h->partition_entry_lba;
451         size_t pte_end = pte_start +
452                 gpt_h->num_partition_entries * gpt_h->sizeof_partition_entry /
453                 dev_desc->blksz;
454
455         for (i = 0; i < parts; i++) {
456                 /* partition starting lba */
457                 lbaint_t start = partitions[i].start;
458                 lbaint_t size = partitions[i].size;
459
460                 if (start) {
461                         offset = start + size;
462                 } else {
463                         start = offset;
464                         offset += size;
465                 }
466
467                 /*
468                  * If our partition overlaps with either the GPT
469                  * header, or the partition entry, reject it.
470                  */
471                 if (((start < hdr_end && hdr_start < (start + size)) ||
472                      (start < pte_end && pte_start < (start + size)))) {
473                         printf("Partition overlap\n");
474                         return -1;
475                 }
476
477                 gpt_e[i].starting_lba = cpu_to_le64(start);
478
479                 if (offset > (last_usable_lba + 1)) {
480                         printf("Partitions layout exceds disk size\n");
481                         return -1;
482                 }
483                 /* partition ending lba */
484                 if ((i == parts - 1) && (size == 0))
485                         /* extend the last partition to maximuim */
486                         gpt_e[i].ending_lba = gpt_h->last_usable_lba;
487                 else
488                         gpt_e[i].ending_lba = cpu_to_le64(offset - 1);
489
490 #ifdef CONFIG_PARTITION_TYPE_GUID
491                 str_type_guid = partitions[i].type_guid;
492                 bin_type_guid = gpt_e[i].partition_type_guid.b;
493                 if (strlen(str_type_guid)) {
494                         if (uuid_str_to_bin(str_type_guid, bin_type_guid,
495                                             UUID_STR_FORMAT_GUID)) {
496                                 printf("Partition no. %d: invalid type guid: %s\n",
497                                        i, str_type_guid);
498                                 return -1;
499                         }
500                 } else {
501                         /* default partition type GUID */
502                         memcpy(bin_type_guid,
503                                &PARTITION_BASIC_DATA_GUID, 16);
504                 }
505 #else
506                 /* partition type GUID */
507                 memcpy(gpt_e[i].partition_type_guid.b,
508                         &PARTITION_BASIC_DATA_GUID, 16);
509 #endif
510
511 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
512                 str_uuid = partitions[i].uuid;
513                 bin_uuid = gpt_e[i].unique_partition_guid.b;
514
515                 if (uuid_str_to_bin(str_uuid, bin_uuid, UUID_STR_FORMAT_GUID)) {
516                         printf("Partition no. %d: invalid guid: %s\n",
517                                 i, str_uuid);
518                         return -1;
519                 }
520 #endif
521
522                 /* partition attributes */
523                 memset(&gpt_e[i].attributes, 0,
524                        sizeof(gpt_entry_attributes));
525
526                 if (partitions[i].bootable)
527                         gpt_e[i].attributes.fields.legacy_bios_bootable = 1;
528
529                 /* partition name */
530                 efiname_len = sizeof(gpt_e[i].partition_name)
531                         / sizeof(efi_char16_t);
532                 dosname_len = sizeof(partitions[i].name);
533
534                 memset(gpt_e[i].partition_name, 0,
535                        sizeof(gpt_e[i].partition_name));
536
537                 for (k = 0; k < min(dosname_len, efiname_len); k++)
538                         gpt_e[i].partition_name[k] =
539                                 (efi_char16_t)(partitions[i].name[k]);
540
541                 debug("%s: name: %s offset[%d]: 0x" LBAF
542                       " size[%d]: 0x" LBAF "\n",
543                       __func__, partitions[i].name, i,
544                       offset, i, size);
545         }
546
547         return 0;
548 }
549
550 static uint32_t partition_entries_offset(struct blk_desc *dev_desc)
551 {
552         uint32_t offset_blks = 2;
553         uint32_t __maybe_unused offset_bytes;
554         int __maybe_unused config_offset;
555
556 #if defined(CONFIG_EFI_PARTITION_ENTRIES_OFF)
557         /*
558          * Some architectures require their SPL loader at a fixed
559          * address within the first 16KB of the disk.  To avoid an
560          * overlap with the partition entries of the EFI partition
561          * table, the first safe offset (in bytes, from the start of
562          * the disk) for the entries can be set in
563          * CONFIG_EFI_PARTITION_ENTRIES_OFF.
564          */
565         offset_bytes =
566                 PAD_TO_BLOCKSIZE(CONFIG_EFI_PARTITION_ENTRIES_OFF, dev_desc);
567         offset_blks = offset_bytes / dev_desc->blksz;
568 #endif
569
570 #if defined(CONFIG_OF_CONTROL)
571         /*
572          * Allow the offset of the first partition entires (in bytes
573          * from the start of the device) to be specified as a property
574          * of the device tree '/config' node.
575          */
576         config_offset = fdtdec_get_config_int(gd->fdt_blob,
577                                               "u-boot,efi-partition-entries-offset",
578                                               -EINVAL);
579         if (config_offset != -EINVAL) {
580                 offset_bytes = PAD_TO_BLOCKSIZE(config_offset, dev_desc);
581                 offset_blks = offset_bytes / dev_desc->blksz;
582         }
583 #endif
584
585         debug("efi: partition entries offset (in blocks): %d\n", offset_blks);
586
587         /*
588          * The earliest LBA this can be at is LBA#2 (i.e. right behind
589          * the (protective) MBR and the GPT header.
590          */
591         if (offset_blks < 2)
592                 offset_blks = 2;
593
594         return offset_blks;
595 }
596
597 int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h,
598                 char *str_guid, int parts_count)
599 {
600         gpt_h->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
601         gpt_h->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
602         gpt_h->header_size = cpu_to_le32(sizeof(gpt_header));
603         gpt_h->my_lba = cpu_to_le64(1);
604         gpt_h->alternate_lba = cpu_to_le64(dev_desc->lba - 1);
605         gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
606         gpt_h->partition_entry_lba =
607                 cpu_to_le64(partition_entries_offset(dev_desc));
608         gpt_h->first_usable_lba =
609                 cpu_to_le64(le64_to_cpu(gpt_h->partition_entry_lba) + 32);
610         gpt_h->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
611         gpt_h->sizeof_partition_entry = cpu_to_le32(sizeof(gpt_entry));
612         gpt_h->header_crc32 = 0;
613         gpt_h->partition_entry_array_crc32 = 0;
614
615         if (uuid_str_to_bin(str_guid, gpt_h->disk_guid.b, UUID_STR_FORMAT_GUID))
616                 return -1;
617
618         return 0;
619 }
620
621 int gpt_restore(struct blk_desc *dev_desc, char *str_disk_guid,
622                 disk_partition_t *partitions, int parts_count)
623 {
624         gpt_header *gpt_h;
625         gpt_entry *gpt_e;
626         int ret, size;
627
628         size = PAD_TO_BLOCKSIZE(sizeof(gpt_header), dev_desc);
629         gpt_h = malloc_cache_aligned(size);
630         if (gpt_h == NULL) {
631                 printf("%s: calloc failed!\n", __func__);
632                 return -1;
633         }
634         memset(gpt_h, 0, size);
635
636         size = PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
637                                 dev_desc);
638         gpt_e = malloc_cache_aligned(size);
639         if (gpt_e == NULL) {
640                 printf("%s: calloc failed!\n", __func__);
641                 free(gpt_h);
642                 return -1;
643         }
644         memset(gpt_e, 0, size);
645
646         /* Generate Primary GPT header (LBA1) */
647         ret = gpt_fill_header(dev_desc, gpt_h, str_disk_guid, parts_count);
648         if (ret)
649                 goto err;
650
651         /* Generate partition entries */
652         ret = gpt_fill_pte(dev_desc, gpt_h, gpt_e, partitions, parts_count);
653         if (ret)
654                 goto err;
655
656         /* Write GPT partition table */
657         ret = write_gpt_table(dev_desc, gpt_h, gpt_e);
658
659 err:
660         free(gpt_e);
661         free(gpt_h);
662         return ret;
663 }
664
665 static void gpt_convert_efi_name_to_char(char *s, efi_char16_t *es, int n)
666 {
667         char *ess = (char *)es;
668         int i, j;
669
670         memset(s, '\0', n);
671
672         for (i = 0, j = 0; j < n; i += 2, j++) {
673                 s[j] = ess[i];
674                 if (!ess[i])
675                         return;
676         }
677 }
678
679 int gpt_verify_headers(struct blk_desc *dev_desc, gpt_header *gpt_head,
680                        gpt_entry **gpt_pte)
681 {
682         /*
683          * This function validates AND
684          * fills in the GPT header and PTE
685          */
686         if (is_gpt_valid(dev_desc,
687                          GPT_PRIMARY_PARTITION_TABLE_LBA,
688                          gpt_head, gpt_pte) != 1) {
689                 printf("%s: *** ERROR: Invalid GPT ***\n",
690                        __func__);
691                 return -1;
692         }
693         if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
694                          gpt_head, gpt_pte) != 1) {
695                 printf("%s: *** ERROR: Invalid Backup GPT ***\n",
696                        __func__);
697                 return -1;
698         }
699
700         return 0;
701 }
702
703 int gpt_verify_partitions(struct blk_desc *dev_desc,
704                           disk_partition_t *partitions, int parts,
705                           gpt_header *gpt_head, gpt_entry **gpt_pte)
706 {
707         char efi_str[PARTNAME_SZ + 1];
708         u64 gpt_part_size;
709         gpt_entry *gpt_e;
710         int ret, i;
711
712         ret = gpt_verify_headers(dev_desc, gpt_head, gpt_pte);
713         if (ret)
714                 return ret;
715
716         gpt_e = *gpt_pte;
717
718         for (i = 0; i < parts; i++) {
719                 if (i == gpt_head->num_partition_entries) {
720                         pr_err("More partitions than allowed!\n");
721                         return -1;
722                 }
723
724                 /* Check if GPT and ENV partition names match */
725                 gpt_convert_efi_name_to_char(efi_str, gpt_e[i].partition_name,
726                                              PARTNAME_SZ + 1);
727
728                 debug("%s: part: %2d name - GPT: %16s, ENV: %16s ",
729                       __func__, i, efi_str, partitions[i].name);
730
731                 if (strncmp(efi_str, (char *)partitions[i].name,
732                             sizeof(partitions->name))) {
733                         pr_err("Partition name: %s does not match %s!\n",
734                               efi_str, (char *)partitions[i].name);
735                         return -1;
736                 }
737
738                 /* Check if GPT and ENV sizes match */
739                 gpt_part_size = le64_to_cpu(gpt_e[i].ending_lba) -
740                         le64_to_cpu(gpt_e[i].starting_lba) + 1;
741                 debug("size(LBA) - GPT: %8llu, ENV: %8llu ",
742                       (unsigned long long)gpt_part_size,
743                       (unsigned long long)partitions[i].size);
744
745                 if (le64_to_cpu(gpt_part_size) != partitions[i].size) {
746                         /* We do not check the extend partition size */
747                         if ((i == parts - 1) && (partitions[i].size == 0))
748                                 continue;
749
750                         pr_err("Partition %s size: %llu does not match %llu!\n",
751                               efi_str, (unsigned long long)gpt_part_size,
752                               (unsigned long long)partitions[i].size);
753                         return -1;
754                 }
755
756                 /*
757                  * Start address is optional - check only if provided
758                  * in '$partition' variable
759                  */
760                 if (!partitions[i].start) {
761                         debug("\n");
762                         continue;
763                 }
764
765                 /* Check if GPT and ENV start LBAs match */
766                 debug("start LBA - GPT: %8llu, ENV: %8llu\n",
767                       le64_to_cpu(gpt_e[i].starting_lba),
768                       (unsigned long long)partitions[i].start);
769
770                 if (le64_to_cpu(gpt_e[i].starting_lba) != partitions[i].start) {
771                         pr_err("Partition %s start: %llu does not match %llu!\n",
772                               efi_str, le64_to_cpu(gpt_e[i].starting_lba),
773                               (unsigned long long)partitions[i].start);
774                         return -1;
775                 }
776         }
777
778         return 0;
779 }
780
781 int is_valid_gpt_buf(struct blk_desc *dev_desc, void *buf)
782 {
783         gpt_header *gpt_h;
784         gpt_entry *gpt_e;
785
786         /* determine start of GPT Header in the buffer */
787         gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA *
788                        dev_desc->blksz);
789         if (validate_gpt_header(gpt_h, GPT_PRIMARY_PARTITION_TABLE_LBA,
790                                 dev_desc->lba))
791                 return -1;
792
793         /* determine start of GPT Entries in the buffer */
794         gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) *
795                        dev_desc->blksz);
796         if (validate_gpt_entries(gpt_h, gpt_e))
797                 return -1;
798
799         return 0;
800 }
801
802 int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf)
803 {
804         gpt_header *gpt_h;
805         gpt_entry *gpt_e;
806         int gpt_e_blk_cnt;
807         lbaint_t lba;
808         int cnt;
809
810         if (is_valid_gpt_buf(dev_desc, buf))
811                 return -1;
812
813         /* determine start of GPT Header in the buffer */
814         gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA *
815                        dev_desc->blksz);
816
817         /* determine start of GPT Entries in the buffer */
818         gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) *
819                        dev_desc->blksz);
820         gpt_e_blk_cnt = BLOCK_CNT((le32_to_cpu(gpt_h->num_partition_entries) *
821                                    le32_to_cpu(gpt_h->sizeof_partition_entry)),
822                                   dev_desc);
823
824         /* write MBR */
825         lba = 0;        /* MBR is always at 0 */
826         cnt = 1;        /* MBR (1 block) */
827         if (blk_dwrite(dev_desc, lba, cnt, buf) != cnt) {
828                 printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
829                        __func__, "MBR", cnt, lba);
830                 return 1;
831         }
832
833         /* write Primary GPT */
834         lba = GPT_PRIMARY_PARTITION_TABLE_LBA;
835         cnt = 1;        /* GPT Header (1 block) */
836         if (blk_dwrite(dev_desc, lba, cnt, gpt_h) != cnt) {
837                 printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
838                        __func__, "Primary GPT Header", cnt, lba);
839                 return 1;
840         }
841
842         lba = le64_to_cpu(gpt_h->partition_entry_lba);
843         cnt = gpt_e_blk_cnt;
844         if (blk_dwrite(dev_desc, lba, cnt, gpt_e) != cnt) {
845                 printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
846                        __func__, "Primary GPT Entries", cnt, lba);
847                 return 1;
848         }
849
850         prepare_backup_gpt_header(gpt_h);
851
852         /* write Backup GPT */
853         lba = le64_to_cpu(gpt_h->partition_entry_lba);
854         cnt = gpt_e_blk_cnt;
855         if (blk_dwrite(dev_desc, lba, cnt, gpt_e) != cnt) {
856                 printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
857                        __func__, "Backup GPT Entries", cnt, lba);
858                 return 1;
859         }
860
861         lba = le64_to_cpu(gpt_h->my_lba);
862         cnt = 1;        /* GPT Header (1 block) */
863         if (blk_dwrite(dev_desc, lba, cnt, gpt_h) != cnt) {
864                 printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n",
865                        __func__, "Backup GPT Header", cnt, lba);
866                 return 1;
867         }
868
869         return 0;
870 }
871 #endif
872
873 /*
874  * Private functions
875  */
876 /*
877  * pmbr_part_valid(): Check for EFI partition signature
878  *
879  * Returns: 1 if EFI GPT partition type is found.
880  */
881 static int pmbr_part_valid(struct partition *part)
882 {
883         if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
884                 get_unaligned_le32(&part->start_sect) == 1UL) {
885                 return 1;
886         }
887
888         return 0;
889 }
890
891 /*
892  * is_pmbr_valid(): test Protective MBR for validity
893  *
894  * Returns: 1 if PMBR is valid, 0 otherwise.
895  * Validity depends on two things:
896  *  1) MSDOS signature is in the last two bytes of the MBR
897  *  2) One partition of type 0xEE is found, checked by pmbr_part_valid()
898  */
899 static int is_pmbr_valid(legacy_mbr * mbr)
900 {
901         int i = 0;
902
903         if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
904                 return 0;
905
906         for (i = 0; i < 4; i++) {
907                 if (pmbr_part_valid(&mbr->partition_record[i])) {
908                         return 1;
909                 }
910         }
911         return 0;
912 }
913
914 /**
915  * is_gpt_valid() - tests one GPT header and PTEs for validity
916  *
917  * lba is the logical block address of the GPT header to test
918  * gpt is a GPT header ptr, filled on return.
919  * ptes is a PTEs ptr, filled on return.
920  *
921  * Description: returns 1 if valid,  0 on error.
922  * If valid, returns pointers to PTEs.
923  */
924 static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba,
925                         gpt_header *pgpt_head, gpt_entry **pgpt_pte)
926 {
927         /* Confirm valid arguments prior to allocation. */
928         if (!dev_desc || !pgpt_head) {
929                 printf("%s: Invalid Argument(s)\n", __func__);
930                 return 0;
931         }
932
933         ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, mbr, 1, dev_desc->blksz);
934
935         /* Read MBR Header from device */
936         if (blk_dread(dev_desc, 0, 1, (ulong *)mbr) != 1) {
937                 printf("*** ERROR: Can't read MBR header ***\n");
938                 return 0;
939         }
940
941         /* Read GPT Header from device */
942         if (blk_dread(dev_desc, (lbaint_t)lba, 1, pgpt_head) != 1) {
943                 printf("*** ERROR: Can't read GPT header ***\n");
944                 return 0;
945         }
946
947         if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba))
948                 return 0;
949
950         if (dev_desc->sig_type == SIG_TYPE_NONE) {
951                 efi_guid_t empty = {};
952                 if (memcmp(&pgpt_head->disk_guid, &empty, sizeof(empty))) {
953                         dev_desc->sig_type = SIG_TYPE_GUID;
954                         memcpy(&dev_desc->guid_sig, &pgpt_head->disk_guid,
955                               sizeof(empty));
956                 } else if (mbr->unique_mbr_signature != 0) {
957                         dev_desc->sig_type = SIG_TYPE_MBR;
958                         dev_desc->mbr_sig = mbr->unique_mbr_signature;
959                 }
960         }
961
962         /* Read and allocate Partition Table Entries */
963         *pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
964         if (*pgpt_pte == NULL) {
965                 printf("GPT: Failed to allocate memory for PTE\n");
966                 return 0;
967         }
968
969         if (validate_gpt_entries(pgpt_head, *pgpt_pte)) {
970                 free(*pgpt_pte);
971                 return 0;
972         }
973
974         /* We're done, all's well */
975         return 1;
976 }
977
978 /**
979  * alloc_read_gpt_entries(): reads partition entries from disk
980  * @dev_desc
981  * @gpt - GPT header
982  *
983  * Description: Returns ptes on success,  NULL on error.
984  * Allocates space for PTEs based on information found in @gpt.
985  * Notes: remember to free pte when you're done!
986  */
987 static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc,
988                                          gpt_header *pgpt_head)
989 {
990         size_t count = 0, blk_cnt;
991         lbaint_t blk;
992         gpt_entry *pte = NULL;
993
994         if (!dev_desc || !pgpt_head) {
995                 printf("%s: Invalid Argument(s)\n", __func__);
996                 return NULL;
997         }
998
999         count = le32_to_cpu(pgpt_head->num_partition_entries) *
1000                 le32_to_cpu(pgpt_head->sizeof_partition_entry);
1001
1002         debug("%s: count = %u * %u = %lu\n", __func__,
1003               (u32) le32_to_cpu(pgpt_head->num_partition_entries),
1004               (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry),
1005               (ulong)count);
1006
1007         /* Allocate memory for PTE, remember to FREE */
1008         if (count != 0) {
1009                 pte = memalign(ARCH_DMA_MINALIGN,
1010                                PAD_TO_BLOCKSIZE(count, dev_desc));
1011         }
1012
1013         if (count == 0 || pte == NULL) {
1014                 printf("%s: ERROR: Can't allocate %#lX bytes for GPT Entries\n",
1015                        __func__, (ulong)count);
1016                 return NULL;
1017         }
1018
1019         /* Read GPT Entries from device */
1020         blk = le64_to_cpu(pgpt_head->partition_entry_lba);
1021         blk_cnt = BLOCK_CNT(count, dev_desc);
1022         if (blk_dread(dev_desc, blk, (lbaint_t)blk_cnt, pte) != blk_cnt) {
1023                 printf("*** ERROR: Can't read GPT Entries ***\n");
1024                 free(pte);
1025                 return NULL;
1026         }
1027         return pte;
1028 }
1029
1030 /**
1031  * is_pte_valid(): validates a single Partition Table Entry
1032  * @gpt_entry - Pointer to a single Partition Table Entry
1033  *
1034  * Description: returns 1 if valid,  0 on error.
1035  */
1036 static int is_pte_valid(gpt_entry * pte)
1037 {
1038         efi_guid_t unused_guid;
1039
1040         if (!pte) {
1041                 printf("%s: Invalid Argument(s)\n", __func__);
1042                 return 0;
1043         }
1044
1045         /* Only one validation for now:
1046          * The GUID Partition Type != Unused Entry (ALL-ZERO)
1047          */
1048         memset(unused_guid.b, 0, sizeof(unused_guid.b));
1049
1050         if (memcmp(pte->partition_type_guid.b, unused_guid.b,
1051                 sizeof(unused_guid.b)) == 0) {
1052
1053                 debug("%s: Found an unused PTE GUID at 0x%08X\n", __func__,
1054                       (unsigned int)(uintptr_t)pte);
1055
1056                 return 0;
1057         } else {
1058                 return 1;
1059         }
1060 }
1061
1062 /*
1063  * Add an 'a_' prefix so it comes before 'dos' in the linker list. We need to
1064  * check EFI first, since a DOS partition is often used as a 'protective MBR'
1065  * with EFI.
1066  */
1067 U_BOOT_PART_TYPE(a_efi) = {
1068         .name           = "EFI",
1069         .part_type      = PART_TYPE_EFI,
1070         .max_entries    = GPT_ENTRY_NUMBERS,
1071         .get_info       = part_get_info_ptr(part_get_info_efi),
1072         .print          = part_print_ptr(part_print_efi),
1073         .test           = part_test_efi,
1074 };
1075 #endif