]> git.sur5r.net Git - u-boot/blobdiff - disk/part_efi.c
Merge git://git.denx.de/u-boot-fsl-qoriq
[u-boot] / disk / part_efi.c
index 807d01de39d06ada737175962096f9449fb76f43..0abf48733d5d8fd731407ffb3a2db6c2d01adee1 100644 (file)
@@ -360,7 +360,7 @@ static int set_protective_mbr(struct blk_desc *dev_desc)
 
        /* Read MBR to backup boot code if it exists */
        if (blk_dread(dev_desc, 0, 1, p_mbr) != 1) {
-               error("** Can't read from device %d **\n", dev_desc->devnum);
+               pr_err("** Can't read from device %d **\n", dev_desc->devnum);
                return -1;
        }
 
@@ -445,24 +445,38 @@ int gpt_fill_pte(struct blk_desc *dev_desc,
        char *str_type_guid;
        unsigned char *bin_type_guid;
 #endif
+       size_t hdr_start = gpt_h->my_lba;
+       size_t hdr_end = hdr_start + 1;
+
+       size_t pte_start = gpt_h->partition_entry_lba;
+       size_t pte_end = pte_start +
+               gpt_h->num_partition_entries * gpt_h->sizeof_partition_entry /
+               dev_desc->blksz;
 
        for (i = 0; i < parts; i++) {
                /* partition starting lba */
                lbaint_t start = partitions[i].start;
                lbaint_t size = partitions[i].size;
 
-               if (start && (start < offset)) {
-                       printf("Partition overlap\n");
-                       return -1;
-               }
-
                if (start) {
-                       gpt_e[i].starting_lba = cpu_to_le64(start);
                        offset = start + size;
                } else {
-                       gpt_e[i].starting_lba = cpu_to_le64(offset);
+                       start = offset;
                        offset += size;
                }
+
+               /*
+                * If our partition overlaps with either the GPT
+                * header, or the partition entry, reject it.
+                */
+               if (((start <= hdr_end && hdr_start <= (start + size)) ||
+                    (start <= pte_end && pte_start <= (start + size)))) {
+                       printf("Partition overlap\n");
+                       return -1;
+               }
+
+               gpt_e[i].starting_lba = cpu_to_le64(start);
+
                if (offset > (last_usable_lba + 1)) {
                        printf("Partitions layout exceds disk size\n");
                        return -1;
@@ -702,7 +716,7 @@ int gpt_verify_partitions(struct blk_desc *dev_desc,
 
        for (i = 0; i < parts; i++) {
                if (i == gpt_head->num_partition_entries) {
-                       error("More partitions than allowed!\n");
+                       pr_err("More partitions than allowed!\n");
                        return -1;
                }
 
@@ -715,7 +729,7 @@ int gpt_verify_partitions(struct blk_desc *dev_desc,
 
                if (strncmp(efi_str, (char *)partitions[i].name,
                            sizeof(partitions->name))) {
-                       error("Partition name: %s does not match %s!\n",
+                       pr_err("Partition name: %s does not match %s!\n",
                              efi_str, (char *)partitions[i].name);
                        return -1;
                }
@@ -732,7 +746,7 @@ int gpt_verify_partitions(struct blk_desc *dev_desc,
                        if ((i == parts - 1) && (partitions[i].size == 0))
                                continue;
 
-                       error("Partition %s size: %llu does not match %llu!\n",
+                       pr_err("Partition %s size: %llu does not match %llu!\n",
                              efi_str, (unsigned long long)gpt_part_size,
                              (unsigned long long)partitions[i].size);
                        return -1;
@@ -753,7 +767,7 @@ int gpt_verify_partitions(struct blk_desc *dev_desc,
                      (unsigned long long)partitions[i].start);
 
                if (le64_to_cpu(gpt_e[i].starting_lba) != partitions[i].start) {
-                       error("Partition %s start: %llu does not match %llu!\n",
+                       pr_err("Partition %s start: %llu does not match %llu!\n",
                              efi_str, le64_to_cpu(gpt_e[i].starting_lba),
                              (unsigned long long)partitions[i].start);
                        return -1;
@@ -909,11 +923,19 @@ static int is_pmbr_valid(legacy_mbr * mbr)
 static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba,
                        gpt_header *pgpt_head, gpt_entry **pgpt_pte)
 {
+       ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, mbr, dev_desc->blksz);
+
        if (!dev_desc || !pgpt_head) {
                printf("%s: Invalid Argument(s)\n", __func__);
                return 0;
        }
 
+       /* Read MBR Header from device */
+       if (blk_dread(dev_desc, 0, 1, (ulong *)mbr) != 1) {
+               printf("*** ERROR: Can't read MBR header ***\n");
+               return 0;
+       }
+
        /* Read GPT Header from device */
        if (blk_dread(dev_desc, (lbaint_t)lba, 1, pgpt_head) != 1) {
                printf("*** ERROR: Can't read GPT header ***\n");
@@ -923,6 +945,18 @@ static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba,
        if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba))
                return 0;
 
+       if (dev_desc->sig_type == SIG_TYPE_NONE) {
+               efi_guid_t empty = {};
+               if (memcmp(&pgpt_head->disk_guid, &empty, sizeof(empty))) {
+                       dev_desc->sig_type = SIG_TYPE_GUID;
+                       memcpy(&dev_desc->guid_sig, &pgpt_head->disk_guid,
+                             sizeof(empty));
+               } else if (mbr->unique_mbr_signature != 0) {
+                       dev_desc->sig_type = SIG_TYPE_MBR;
+                       dev_desc->mbr_sig = mbr->unique_mbr_signature;
+               }
+       }
+
        /* Read and allocate Partition Table Entries */
        *pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head);
        if (*pgpt_pte == NULL) {