]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - disk/part_efi.c
drivers/crypto/fsl: fix endianness issue in RNG
[people/ms/u-boot.git] / disk / part_efi.c
index 5856f9321118da1be38015d4bce89e8e498f1683..b1e01558a69f67a8a16b5bdf9a3fbe7454ba09a9 100644 (file)
@@ -16,6 +16,7 @@
 #include <ide.h>
 #include <inttypes.h>
 #include <malloc.h>
+#include <memalign.h>
 #include <part_efi.h>
 #include <linux/ctype.h>
 
@@ -222,6 +223,10 @@ void print_part_efi(block_dev_desc_t * dev_desc)
                uuid_bin = (unsigned char *)gpt_pte[i].partition_type_guid.b;
                uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
                printf("\ttype:\t%s\n", uuid);
+#ifdef CONFIG_PARTITION_TYPE_GUID
+               if (!uuid_guid_get_str(uuid_bin, uuid))
+                       printf("\ttype:\t%s\n", uuid);
+#endif
                uuid_bin = (unsigned char *)gpt_pte[i].unique_partition_guid.b;
                uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID);
                printf("\tguid:\t%s\n", uuid);
@@ -282,6 +287,10 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
        uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid,
                        UUID_STR_FORMAT_GUID);
 #endif
+#ifdef CONFIG_PARTITION_TYPE_GUID
+       uuid_bin_to_str(gpt_pte[part - 1].partition_type_guid.b,
+                       info->type_guid, UUID_STR_FORMAT_GUID);
+#endif
 
        debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__,
              info->start, info->size, info->name);
@@ -418,6 +427,10 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
        char *str_uuid;
        unsigned char *bin_uuid;
 #endif
+#ifdef CONFIG_PARTITION_TYPE_GUID
+       char *str_type_guid;
+       unsigned char *bin_type_guid;
+#endif
 
        for (i = 0; i < parts; i++) {
                /* partition starting lba */
@@ -444,9 +457,26 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
                else
                        gpt_e[i].ending_lba = cpu_to_le64(offset - 1);
 
+#ifdef CONFIG_PARTITION_TYPE_GUID
+               str_type_guid = partitions[i].type_guid;
+               bin_type_guid = gpt_e[i].partition_type_guid.b;
+               if (strlen(str_type_guid)) {
+                       if (uuid_str_to_bin(str_type_guid, bin_type_guid,
+                                           UUID_STR_FORMAT_GUID)) {
+                               printf("Partition no. %d: invalid type guid: %s\n",
+                                      i, str_type_guid);
+                               return -1;
+                       }
+               } else {
+                       /* default partition type GUID */
+                       memcpy(bin_type_guid,
+                              &PARTITION_BASIC_DATA_GUID, 16);
+               }
+#else
                /* partition type GUID */
                memcpy(gpt_e[i].partition_type_guid.b,
                        &PARTITION_BASIC_DATA_GUID, 16);
+#endif
 
 #ifdef CONFIG_PARTITION_UUIDS
                str_uuid = partitions[i].uuid;
@@ -463,6 +493,9 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
                memset(&gpt_e[i].attributes, 0,
                       sizeof(gpt_entry_attributes));
 
+               if (partitions[i].bootable)
+                       gpt_e[i].attributes.fields.legacy_bios_bootable = 1;
+
                /* partition name */
                efiname_len = sizeof(gpt_e[i].partition_name)
                        / sizeof(efi_char16_t);
@@ -548,6 +581,116 @@ err:
        return ret;
 }
 
+static void gpt_convert_efi_name_to_char(char *s, efi_char16_t *es, int n)
+{
+       char *ess = (char *)es;
+       int i, j;
+
+       memset(s, '\0', n);
+
+       for (i = 0, j = 0; j < n; i += 2, j++) {
+               s[j] = ess[i];
+               if (!ess[i])
+                       return;
+       }
+}
+
+int gpt_verify_headers(block_dev_desc_t *dev_desc, gpt_header *gpt_head,
+                      gpt_entry **gpt_pte)
+{
+       /*
+        * This function validates AND
+        * fills in the GPT header and PTE
+        */
+       if (is_gpt_valid(dev_desc,
+                        GPT_PRIMARY_PARTITION_TABLE_LBA,
+                        gpt_head, gpt_pte) != 1) {
+               printf("%s: *** ERROR: Invalid GPT ***\n",
+                      __func__);
+               return -1;
+       }
+       if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
+                        gpt_head, gpt_pte) != 1) {
+               printf("%s: *** ERROR: Invalid Backup GPT ***\n",
+                      __func__);
+               return -1;
+       }
+
+       return 0;
+}
+
+int gpt_verify_partitions(block_dev_desc_t *dev_desc,
+                         disk_partition_t *partitions, int parts,
+                         gpt_header *gpt_head, gpt_entry **gpt_pte)
+{
+       char efi_str[PARTNAME_SZ + 1];
+       u64 gpt_part_size;
+       gpt_entry *gpt_e;
+       int ret, i;
+
+       ret = gpt_verify_headers(dev_desc, gpt_head, gpt_pte);
+       if (ret)
+               return ret;
+
+       gpt_e = *gpt_pte;
+
+       for (i = 0; i < parts; i++) {
+               if (i == gpt_head->num_partition_entries) {
+                       error("More partitions than allowed!\n");
+                       return -1;
+               }
+
+               /* Check if GPT and ENV partition names match */
+               gpt_convert_efi_name_to_char(efi_str, gpt_e[i].partition_name,
+                                            PARTNAME_SZ + 1);
+
+               debug("%s: part: %2d name - GPT: %16s, ENV: %16s ",
+                     __func__, i, efi_str, partitions[i].name);
+
+               if (strncmp(efi_str, (char *)partitions[i].name,
+                           sizeof(partitions->name))) {
+                       error("Partition name: %s does not match %s!\n",
+                             efi_str, (char *)partitions[i].name);
+                       return -1;
+               }
+
+               /* Check if GPT and ENV sizes match */
+               gpt_part_size = le64_to_cpu(gpt_e[i].ending_lba) -
+                       le64_to_cpu(gpt_e[i].starting_lba) + 1;
+               debug("size(LBA) - GPT: %8llu, ENV: %8llu ",
+                     gpt_part_size, (u64) partitions[i].size);
+
+               if (le64_to_cpu(gpt_part_size) != partitions[i].size) {
+                       error("Partition %s size: %llu does not match %llu!\n",
+                             efi_str, gpt_part_size, (u64) partitions[i].size);
+                       return -1;
+               }
+
+               /*
+                * Start address is optional - check only if provided
+                * in '$partition' variable
+                */
+               if (!partitions[i].start) {
+                       debug("\n");
+                       continue;
+               }
+
+               /* Check if GPT and ENV start LBAs match */
+               debug("start LBA - GPT: %8llu, ENV: %8llu\n",
+                     le64_to_cpu(gpt_e[i].starting_lba),
+                     (u64) 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",
+                             efi_str, le64_to_cpu(gpt_e[i].starting_lba),
+                             (u64) partitions[i].start);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
 int is_valid_gpt_buf(block_dev_desc_t *dev_desc, void *buf)
 {
        gpt_header *gpt_h;