2 * Copyright (C) 2008 RuggedCom, Inc.
3 * Richard Retanubun <RichardRetanubun@RuggedCom.com>
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 * Problems with CONFIG_SYS_64BIT_LBA:
27 * struct disk_partition.start in include/part.h is sized as ulong.
28 * When CONFIG_SYS_64BIT_LBA is activated, lbaint_t changes from ulong to uint64_t.
29 * For now, it is cast back to ulong at assignment.
31 * This limits the maximum size of addressable storage to < 2 Terra Bytes
33 #include <linux/ctype.h>
39 #include "part_uefi.h"
41 #if defined(CONFIG_CMD_IDE) || \
42 defined(CONFIG_CMD_MG_DISK) || \
43 defined(CONFIG_CMD_SATA) || \
44 defined(CONFIG_CMD_SCSI) || \
45 defined(CONFIG_CMD_USB) || \
46 defined(CONFIG_MMC) || \
47 defined(CONFIG_SYSTEMACE)
49 /* Convert char[2] in little endian format to the host format integer
51 static inline unsigned short le16_to_int(unsigned char *le16)
53 return ((le16[1] << 8) + le16[0]);
56 /* Convert char[4] in little endian format to the host format integer
58 static inline unsigned long le32_to_int(unsigned char *le32)
60 return ((le32[3] << 24) + (le32[2] << 16) + (le32[1] << 8) + le32[0]);
63 /* Convert char[8] in little endian format to the host format integer
65 static inline unsigned long long le64_to_int(unsigned char *le64)
67 return (((unsigned long long)le64[7] << 56) +
68 ((unsigned long long)le64[6] << 48) +
69 ((unsigned long long)le64[5] << 40) +
70 ((unsigned long long)le64[4] << 32) +
71 ((unsigned long long)le64[3] << 24) +
72 ((unsigned long long)le64[2] << 16) +
73 ((unsigned long long)le64[1] << 8) +
74 (unsigned long long)le64[0]);
78 * efi_crc32() - EFI version of crc32 function
79 * @buf: buffer to calculate crc32 of
80 * @len - length of buf
82 * Description: Returns EFI-style CRC32 value for @buf
84 static inline unsigned long efi_crc32(const void *buf, unsigned long len)
86 return crc32(0, buf, len);
90 * Private function prototypes
93 static int pmbr_part_valid(struct partition *part);
94 static int is_pmbr_valid(legacy_mbr * mbr);
96 static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
97 gpt_header * pgpt_head, gpt_entry ** pgpt_pte);
98 #ifdef CONFIG_GPT_FORMAT_VALID
99 #ifdef CONFIG_EMMC_BOOT
100 static int format_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
101 gpt_header * pgpt_head, gpt_entry ** pgpt_pte);
103 #endif /* CONFIG_GPT_FORMAT_VALID */
104 static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
105 gpt_header * pgpt_head);
107 static int is_pte_valid(gpt_entry * pte);
109 #define PARTNAME_SZ (72 / sizeof(efi_char16_t))
110 static char *print_efiname(gpt_entry *pte)
112 static char name[PARTNAME_SZ + 1];
114 for (i = 0; i < PARTNAME_SZ; i++) {
116 c = pte->partition_name[i] & 0xff;
117 c = (c && !isprint(c)) ? '.' : c;
120 name[PARTNAME_SZ] = 0;
126 * Public Functions (include/part.h)
129 void print_part_efi(block_dev_desc_t * dev_desc)
132 gpt_entry *pgpt_pte = NULL;
136 debug("%s: Invalid Argument(s)\n", __FUNCTION__);
139 /* This function validates AND fills in the GPT header and PTE */
140 if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
141 &(gpt_head), &pgpt_pte) != 1) {
142 debug("%s: *** ERROR: Invalid GPT ***\n", __FUNCTION__);
146 debug("%s: gpt-entry at 0x%08X\n", __FUNCTION__, (unsigned int)pgpt_pte);
148 debug("Part Start LBA End LBA\n");
149 for (i = 0; i < le32_to_int(gpt_head.num_partition_entries); i++) {
151 if (is_pte_valid(&(pgpt_pte)[i])) {
152 debug("%s%d 0x%llX 0x%llX\n", GPT_ENTRY_NAME,
154 le64_to_int((pgpt_pte)[i].starting_lba),
155 le64_to_int((pgpt_pte)[i].ending_lba));
157 break; /* Stop at the first non valid PTE */
161 /* Remember to free pte */
162 if (pgpt_pte != NULL) {
163 debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
169 int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
170 disk_partition_t * info)
173 gpt_entry *pgpt_pte = NULL;
175 /* "part" argument must be at least 1 */
176 if (!dev_desc || !info || part < 1) {
177 debug("%s: Invalid Argument(s)\n", __FUNCTION__);
181 /* This function validates AND fills in the GPT header and PTE */
182 if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
183 &(gpt_head), &pgpt_pte) != 1) {
184 debug("%s: *** ERROR: Invalid Main GPT ***\n", __FUNCTION__);
185 if(is_gpt_valid(dev_desc, dev_desc->lba -1, &(gpt_head), &pgpt_pte) != 1){
186 debug("%s: *** ERROR: Invalid alternate GPT ***\n", __FUNCTION__);
192 /* The ulong casting limits the maximum disk size to 2 TB */
193 info->start = (ulong) le64_to_int((pgpt_pte)[part - 1].starting_lba);
194 /* The ending LBA is inclusive, to calculate size, add 1 to it */
195 info->size = ((ulong)le64_to_int((pgpt_pte)[part - 1].ending_lba) + 1)
197 info->blksz = GPT_BLOCK_SIZE;
199 sprintf((char *)info->name, "%s", print_efiname(&((pgpt_pte)[part - 1])));
200 sprintf((char *)info->type, "U-Boot");
202 debug("%s: start 0x%lX, size 0x%lX, name %s", __FUNCTION__,
203 info->start, info->size, info->name);
205 /* Remember to free pte */
206 if (pgpt_pte != NULL) {
207 debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
213 int get_partition_info_by_name_efi(block_dev_desc_t * dev_desc, wchar_t* partition_name,
214 disk_partition_t * info)
217 gpt_entry *pgpt_pte = NULL;
219 unsigned int i,j,partition_nums=0;
220 wchar_t disk_parition[MAX_UTF_PARTITION_NAME_LEN];
222 if (!dev_desc || !info || !partition_name) {
223 debug("%s: Invalid Argument(s)\n", __FUNCTION__);
227 /* This function validates AND fills in the GPT header and PTE */
228 if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
229 &(gpt_head), &pgpt_pte) != 1) {
230 debug("%s: *** ERROR: Invalid Main GPT ***\n", __FUNCTION__);
231 if(is_gpt_valid(dev_desc, dev_desc->lba -1, &(gpt_head), &pgpt_pte) != 1){
232 debug("%s: *** ERROR: Invalid alternate GPT ***\n", __FUNCTION__);
238 /*Get the partition info*/
239 partition_nums = le32_to_int(gpt_head.num_partition_entries);
240 for(i=0;i<partition_nums;i++)
242 for(j=0;j<MAX_UTF_PARTITION_NAME_LEN;j++)
244 disk_parition[j] = (wchar_t)pgpt_pte[i].partition_name[j];
247 if(0 == wcscmp(disk_parition, partition_name))
249 /* The ulong casting limits the maximum disk size to 2 TB */
250 info->start = (ulong) le64_to_int((pgpt_pte)[i].starting_lba);
251 /* The ending LBA is inclusive, to calculate size, add 1 to it */
252 info->size = ((ulong)le64_to_int((pgpt_pte)[i].ending_lba) + 1) - info->start;
253 info->blksz = GPT_BLOCK_SIZE;
255 sprintf((char *)info->name, "%s", print_efiname(&((pgpt_pte)[i])));
256 sprintf((char *)info->type, "U-Boot");
258 debug("%s: start 0x%lX, size 0x%lX, name %s", __FUNCTION__,
259 info->start, info->size, info->name);
265 /* Remember to free pte */
266 if (pgpt_pte != NULL) {
267 debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
274 int get_partition_num_by_name_efi(block_dev_desc_t *dev_desc, const char *partition_name)
277 gpt_entry *pgpt_pte = NULL;
279 unsigned int i, j, partition_nums = 0;
280 int part_name_len = (72 / sizeof(efi_char16_t));
282 if (!dev_desc || !partition_name) {
283 debug("%s: Invalid Argument(s)\n", __FUNCTION__);
287 /* This function validates AND fills in the GPT header and PTE */
288 if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
289 &(gpt_head), &pgpt_pte) != 1) {
290 debug("%s: *** ERROR: Invalid Main GPT ***\n", __FUNCTION__);
291 if (is_gpt_valid(dev_desc, dev_desc->lba -1, &(gpt_head), &pgpt_pte) != 1){
292 debug("%s: *** ERROR: Invalid alternate GPT ***\n", __FUNCTION__);
298 partition_nums = le32_to_int(gpt_head.num_partition_entries);
299 for (i = 0; i < partition_nums; i++) {
300 for (j = 0; j < part_name_len; j++) {
301 if (partition_name[j] != pgpt_pte[i].partition_name[j])
303 if (partition_name[j] == 0 && pgpt_pte[i].partition_name[j] == 0) {
311 /* Remember to free pte */
312 if (pgpt_pte != NULL) {
313 debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
320 int get_all_partition_info_efi(block_dev_desc_t * dev_desc, PARTITION_CFG * info, unsigned int *total_partition_num)
323 gpt_entry *pgpt_pte = NULL;
324 unsigned int i,j, partition_nums = 0;
326 if (!dev_desc || !info) {
327 debug("%s: Invalid Argument(s)\n", __FUNCTION__);
331 /* This function validates AND fills in the GPT header and PTE */
332 if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
333 &(gpt_head), &pgpt_pte) != 1) {
334 debug("%s: *** ERROR: Invalid Main GPT ***\n", __FUNCTION__);
335 if(is_gpt_valid(dev_desc, dev_desc->lba -1, &(gpt_head), &pgpt_pte) != 1){
336 debug("%s: *** ERROR: Invalid alternate GPT ***\n", __FUNCTION__);
342 partition_nums = le32_to_int(gpt_head.num_partition_entries);
344 //TODO:partitions shuld beyond MAX PARTITION NUM
345 for(i=0;i<partition_nums;i++)
347 /* The ulong casting limits the maximum disk size to 2 TB */
348 info[i].partition_offset = (ulong) le64_to_int((pgpt_pte)[i].starting_lba);
349 /* The ending LBA is inclusive, to calculate size, add 1 to it */
350 info[i].partition_size = ((ulong)le64_to_int((pgpt_pte)[i].ending_lba) + 1) - info[i].partition_offset;
351 //TODO: We write partition index at unique_partition_guid.b[15]
352 info[i].partition_index = pgpt_pte[i].unique_partition_guid.b[15];
354 for(j=0;j<MAX_UTF_PARTITION_NAME_LEN;j++)
356 info[i].partition_name[j] = (wchar_t)pgpt_pte[i].partition_name[j];
359 debug("%s: start 0x%lX, size 0x%lX, name %S", __FUNCTION__,
360 info[i].partition_offset, info[i].partition_size, info[i].partition_name);
363 *total_partition_num = partition_nums;
365 /* Remember to free pte */
366 if (pgpt_pte != NULL) {
367 debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
374 int get_partition_info_efi_with_partnum(block_dev_desc_t * dev_desc, int part,
375 disk_partition_t * info, unsigned long total, unsigned long sdidx, int sdpart, disk_partition_t *sdinfo)
378 gpt_entry *pgpt_pte = NULL;
380 /* "part" argument must be at least 1 */
381 if (!dev_desc || !info || part < 1) {
382 debug("%s: Invalid Argument(s)\n", __FUNCTION__);
386 /* This function validates AND fills in the GPT header and PTE */
387 if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA,
388 &(gpt_head), &pgpt_pte) != 1) {
389 debug("%s: *** ERROR: Invalid Main GPT ***\n", __FUNCTION__);
390 if(is_gpt_valid(dev_desc, dev_desc->lba -1, &(gpt_head), &pgpt_pte) != 1){
391 debug("%s: *** ERROR: Invalid alternate GPT ***\n", __FUNCTION__);
397 /* The ulong casting limits the maximum disk size to 2 TB */
398 info->start = (ulong) le64_to_int((pgpt_pte)[part - 1].starting_lba);
399 /* The ending LBA is inclusive, to calculate size, add 1 to it */
400 info->size = ((ulong)le64_to_int((pgpt_pte)[part - 1].ending_lba) + 1)
402 info->blksz = GPT_BLOCK_SIZE;
404 sprintf((char *)info->name, "%s",
405 print_efiname(&((pgpt_pte)[part - 1])));
406 sprintf((char *)info->type, "U-Boot");
408 debug("%s: start 0x%lX, size 0x%lX, name %s\n", __FUNCTION__,
409 info->start, info->size, info->name);
412 if (sdidx < (le32_to_int(gpt_head.num_partition_entries))) {
413 sdinfo->start = (ulong) le64_to_int((pgpt_pte)[sdpart - 1].starting_lba);
414 sdinfo->size = ((ulong)le64_to_int((pgpt_pte)[sdpart - 1].ending_lba) + 1) - sdinfo->start;
417 /* Remember to free pte */
418 if (pgpt_pte != NULL) {
419 debug("%s: Freeing pgpt_pte\n", __FUNCTION__);
425 else if (total != le32_to_int(gpt_head.num_partition_entries))
431 int test_part_efi(block_dev_desc_t * dev_desc)
433 legacy_mbr legacymbr;
435 /* Read legacy MBR from block 0 and validate it */
436 if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) & legacymbr) != 1)
437 || (is_pmbr_valid(&legacymbr) != 1)) {
447 * pmbr_part_valid(): Check for EFI partition signature
449 * Returns: 1 if EFI GPT partition type is found.
451 static int pmbr_part_valid(struct partition *part)
453 if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
454 le32_to_int(part->start_sect) == 1UL) {
462 * is_pmbr_valid(): test Protective MBR for validity
464 * Returns: 1 if PMBR is valid, 0 otherwise.
465 * Validity depends on two things:
466 * 1) MSDOS signature is in the last two bytes of the MBR
467 * 2) One partition of type 0xEE is found, checked by pmbr_part_valid()
469 static int is_pmbr_valid(legacy_mbr * mbr)
473 if (!mbr || le16_to_int(mbr->signature) != MSDOS_MBR_SIGNATURE) {
477 for (i = 0; i < 4; i++) {
478 if (pmbr_part_valid(&mbr->partition_record[i])) {
486 * is_gpt_valid() - tests one GPT header and PTEs for validity
488 * lba is the logical block address of the GPT header to test
489 * gpt is a GPT header ptr, filled on return.
490 * ptes is a PTEs ptr, filled on return.
492 * Description: returns 1 if valid, 0 on error.
493 * If valid, returns pointers to PTEs.
495 static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
496 gpt_header * pgpt_head, gpt_entry ** pgpt_pte)
498 unsigned char crc32_backup[4] = { 0 };
499 unsigned long calc_crc32;
500 unsigned long long lastlba;
501 //debug("Enter is_gpt_valid 0x%16Lx \n", lba);
502 if (!dev_desc || !pgpt_head) {
503 debug("%s: Invalid Argument(s)\n", __FUNCTION__);
507 /* Read GPT Header from device */
508 if (dev_desc->block_read(dev_desc->dev, lba, 1, pgpt_head) != 1) {
509 debug("*** ERROR: Can't read GPT header ***\n");
513 /* Check the GPT header signature */
514 if (le64_to_int(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
515 debug("GUID Partition Table Header signature is wrong:"
516 "0x%llX != 0x%llX\n",
517 (unsigned long long)le64_to_int(pgpt_head->signature),
518 (unsigned long long)GPT_HEADER_SIGNATURE);
522 /* Check the GUID Partition Table CRC */
523 memcpy(crc32_backup, pgpt_head->header_crc32, sizeof(crc32_backup));
524 memset(pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
526 calc_crc32 = efi_crc32((const unsigned char *)pgpt_head,
527 le32_to_int(pgpt_head->header_size));
529 memcpy(pgpt_head->header_crc32, crc32_backup, sizeof(crc32_backup));
531 if (calc_crc32 != le32_to_int(crc32_backup)) {
532 debug("GUID Partition Table Header CRC is wrong:"
533 "0x%08lX != 0x%08lX\n",
534 le32_to_int(crc32_backup), calc_crc32);
538 /* Check that the my_lba entry points to the LBA that contains the GPT */
539 if (le64_to_int(pgpt_head->my_lba) != lba) {
540 debug("GPT: my_lba incorrect: %llX != %llX\n",
541 (unsigned long long)le64_to_int(pgpt_head->my_lba),
542 (unsigned long long)lba);
546 /* Check the first_usable_lba and last_usable_lba are within the disk. */
547 lastlba = (unsigned long long)dev_desc->lba;
548 if (le64_to_int(pgpt_head->first_usable_lba) > lastlba) {
549 debug("GPT: first_usable_lba incorrect: %llX > %llX\n",
550 le64_to_int(pgpt_head->first_usable_lba), lastlba);
553 if (le64_to_int(pgpt_head->last_usable_lba) > lastlba) {
554 debug("GPT: last_usable_lba incorrect: %llX > %llX\n",
555 le64_to_int(pgpt_head->last_usable_lba), lastlba);
559 debug("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %llX\n",
560 le64_to_int(pgpt_head->first_usable_lba),
561 le64_to_int(pgpt_head->last_usable_lba), lastlba);
563 /* Read and allocate Partition Table Entries */
564 *pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
565 if (*pgpt_pte == NULL) {
566 debug("GPT: Failed to allocate memory for PTE\n");
570 /* Check the GUID Partition Table Entry Array CRC */
571 calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte,
572 le32_to_int(pgpt_head->num_partition_entries) *
573 le32_to_int(pgpt_head->sizeof_partition_entry));
575 if (calc_crc32 != le32_to_int(pgpt_head->partition_entry_array_crc32)) {
576 debug("GUID Partition Table Entry Array CRC is wrong:"
577 "0x%08lX != 0x%08lX\n",
578 le32_to_int(pgpt_head->partition_entry_array_crc32),
581 if (*pgpt_pte != NULL) {
587 /* We're done, all's well */
591 #ifdef CONFIG_GPT_FORMAT_VALID
592 #ifdef CONFIG_EMMC_BOOT
594 * format_gpt_valid() - tests one GPT header and PTEs for validity
596 * lba is the logical block address of the GPT header to test
597 * gpt is a GPT header ptr, filled on return.
598 * ptes is a PTEs ptr, filled on return.
600 * Description: returns 1 if valid, 0 on error.
601 * If valid, returns pointers to PTEs.
603 static int format_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
604 gpt_header * pgpt_head, gpt_entry ** pgpt_pte)
606 unsigned char crc32_backup[4] = { 0 };
607 unsigned long calc_crc32;
608 unsigned long long lastlba;
611 if (!dev_desc || !pgpt_head) {
612 debug("%s: Invalid Argument(s)\n", __FUNCTION__);
616 memset(pgpt_head, 0, sizeof(gpt_header));
618 /* set GPT Header from device */
619 for (idx = 0; idx < 8; idx ++) {
620 pgpt_head->signature[idx] = (GPT_HEADER_SIGNATURE >> (8 * idx)) & 0xff;
621 debug("signature[%d] = 0x%02x\n", idx, pgpt_head->signature[idx]);
624 if (dev_desc->block_write(dev_desc->dev, lba, 1, pgpt_head) != 1) {
625 debug("*** ERROR: Can't write GPT header ***\n");
630 /* Check the GPT header signature */
631 if (le64_to_int(pgpt_head->signature) != GPT_HEADER_SIGNATURE) {
632 debug("GUID Partition Table Header signature is wrong:"
633 "0x%llX != 0x%llX\n",
634 (unsigned long long)le64_to_int(pgpt_head->signature),
635 (unsigned long long)GPT_HEADER_SIGNATURE);
639 /* Check the GUID Partition Table CRC */
640 memcpy(crc32_backup, pgpt_head->header_crc32, sizeof(crc32_backup));
641 memset(pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32));
643 calc_crc32 = efi_crc32((const unsigned char *)pgpt_head,
644 le32_to_int(pgpt_head->header_size));
646 memcpy(pgpt_head->header_crc32, crc32_backup, sizeof(crc32_backup));
648 if (calc_crc32 != le32_to_int(crc32_backup)) {
649 debug("GUID Partition Table Header CRC is wrong:"
650 "0x%08lX != 0x%08lX\n",
651 le32_to_int(crc32_backup), calc_crc32);
655 /* Check that the my_lba entry points to the LBA that contains the GPT */
656 if (le64_to_int(pgpt_head->my_lba) != lba) {
657 debug("GPT: my_lba incorrect: %llX != %llX\n",
658 (unsigned long long)le64_to_int(pgpt_head->my_lba),
659 (unsigned long long)lba);
663 /* Check the first_usable_lba and last_usable_lba are within the disk. */
664 lastlba = (unsigned long long)dev_desc->lba;
665 if (le64_to_int(pgpt_head->first_usable_lba) > lastlba) {
666 debug("GPT: first_usable_lba incorrect: %llX > %llX\n",
667 le64_to_int(pgpt_head->first_usable_lba), lastlba);
670 if (le64_to_int(pgpt_head->last_usable_lba) > lastlba) {
671 debug("GPT: last_usable_lba incorrect: %llX > %llX\n",
672 le64_to_int(pgpt_head->last_usable_lba), lastlba);
676 debug("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %llX\n",
677 le64_to_int(pgpt_head->first_usable_lba),
678 le64_to_int(pgpt_head->last_usable_lba), lastlba);
680 /* Read and allocate Partition Table Entries */
681 *pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
682 if (*pgpt_pte == NULL) {
683 debug("GPT: Failed to allocate memory for PTE\n");
687 /* Check the GUID Partition Table Entry Array CRC */
688 calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte,
689 le32_to_int(pgpt_head->num_partition_entries) *
690 le32_to_int(pgpt_head->sizeof_partition_entry));
692 if (calc_crc32 != le32_to_int(pgpt_head->partition_entry_array_crc32)) {
693 debug("GUID Partition Table Entry Array CRC is wrong:"
694 "0x%08lX != 0x%08lX\n",
695 le32_to_int(pgpt_head->partition_entry_array_crc32),
698 if (*pgpt_pte != NULL) {
704 /* We're done, all's well */
708 #endif /* CONFIG_GPT_FORMAT_VALID */
711 * alloc_read_gpt_entries(): reads partition entries from disk
715 * Description: Returns ptes on success, NULL on error.
716 * Allocates space for PTEs based on information found in @gpt.
717 * Notes: remember to free pte when you're done!
719 static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
720 gpt_header * pgpt_head)
723 gpt_entry *pte = NULL;
725 if (!dev_desc || !pgpt_head) {
726 debug("%s: Invalid Argument(s)\n", __FUNCTION__);
730 count = le32_to_int(pgpt_head->num_partition_entries) *
731 le32_to_int(pgpt_head->sizeof_partition_entry);
733 debug("%s: count = %lu * %lu = %u\n", __FUNCTION__,
734 le32_to_int(pgpt_head->num_partition_entries),
735 le32_to_int(pgpt_head->sizeof_partition_entry), count);
736 if(count % GPT_BLOCK_SIZE){
738 ntemp = count/GPT_BLOCK_SIZE +1;
739 count = ntemp * GPT_BLOCK_SIZE;
741 /* Allocate memory for PTE, remember to FREE */
746 if (count == 0 || pte == NULL) {
747 debug("%s: ERROR: Can't allocate 0x%X bytes for GPT Entries\n",
748 __FUNCTION__, count);
752 /* Read GPT Entries from device */
753 if (dev_desc->block_read (dev_desc->dev,
754 (unsigned long)le64_to_int(pgpt_head->partition_entry_lba),
755 (lbaint_t) (count / GPT_BLOCK_SIZE), pte)
756 != (count / GPT_BLOCK_SIZE)) {
758 debug("*** ERROR: Can't read GPT Entries ***\n");
766 * is_pte_valid(): validates a single Partition Table Entry
767 * @gpt_entry - Pointer to a single Partition Table Entry
769 * Description: returns 1 if valid, 0 on error.
771 static int is_pte_valid(gpt_entry * pte)
773 efi_guid_t unused_guid;
776 debug("%s: Invalid Argument(s)\n", __FUNCTION__);
780 /* Only one validation for now:
781 * The GUID Partition Type != Unused Entry (ALL-ZERO)
783 memset(unused_guid.b, 0, sizeof(unused_guid.b));
785 if (memcmp(pte->partition_type_guid.b, unused_guid.b,
786 sizeof(unused_guid.b)) == 0) {
788 debug("%s: Found an unused PTE GUID at 0x%08X\n", __FUNCTION__,