Merge branch 'master' of git://git.denx.de/u-boot-net
[oweals/u-boot.git] / disk / part_efi.c
index 0abf48733d5d8fd731407ffb3a2db6c2d01adee1..3e026697dbe9911002db37635fa610dc75338ba5 100644 (file)
@@ -1,8 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (C) 2008 RuggedCom, Inc.
  * Richard Retanubun <RichardRetanubun@RuggedCom.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 /*
@@ -15,7 +14,6 @@
 #include <command.h>
 #include <fdtdec.h>
 #include <ide.h>
-#include <inttypes.h>
 #include <malloc.h>
 #include <memalign.h>
 #include <part_efi.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#ifdef HAVE_BLOCK_DEVICE
+/*
+ * GUID for basic data partions.
+ */
+static const efi_guid_t partition_basic_data_guid = PARTITION_BASIC_DATA_GUID;
+
+#ifdef CONFIG_HAVE_BLOCK_DEVICE
 /**
  * efi_crc32() - EFI version of crc32 function
  * @buf: buffer to calculate crc32 of
@@ -63,7 +66,7 @@ static char *print_efiname(gpt_entry *pte)
        return name;
 }
 
-static efi_guid_t system_guid = PARTITION_SYSTEM_GUID;
+static const efi_guid_t system_guid = PARTITION_SYSTEM_GUID;
 
 static inline int is_bootable(gpt_entry *p)
 {
@@ -79,11 +82,11 @@ static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba,
        uint32_t calc_crc32;
 
        /* Check the GPT header signature */
-       if (le64_to_cpu(gpt_h->signature) != GPT_HEADER_SIGNATURE) {
+       if (le64_to_cpu(gpt_h->signature) != GPT_HEADER_SIGNATURE_UBOOT) {
                printf("%s signature is wrong: 0x%llX != 0x%llX\n",
                       "GUID Partition Table Header",
                       le64_to_cpu(gpt_h->signature),
-                      GPT_HEADER_SIGNATURE);
+                      GPT_HEADER_SIGNATURE_UBOOT);
                return -1;
        }
 
@@ -206,6 +209,8 @@ int get_disk_guid(struct blk_desc * dev_desc, char *guid)
        guid_bin = gpt_head->disk_guid.b;
        uuid_bin_to_str(guid_bin, guid, UUID_STR_FORMAT_GUID);
 
+       /* Remember to free pte */
+       free(gpt_pte);
        return 0;
 }
 
@@ -308,8 +313,8 @@ int part_get_info_efi(struct blk_desc *dev_desc, int part,
                     - info->start;
        info->blksz = dev_desc->blksz;
 
-       sprintf((char *)info->name, "%s",
-                       print_efiname(&gpt_pte[part - 1]));
+       snprintf((char *)info->name, sizeof(info->name), "%s",
+                print_efiname(&gpt_pte[part - 1]));
        strcpy((char *)info->type, "U-Boot");
        info->bootable = is_bootable(&gpt_pte[part - 1]);
 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
@@ -350,9 +355,7 @@ static int part_test_efi(struct blk_desc *dev_desc)
 static int set_protective_mbr(struct blk_desc *dev_desc)
 {
        /* Setup the Protective MBR */
-       ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, p_mbr, 1);
-       memset(p_mbr, 0, sizeof(*p_mbr));
-
+       ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, p_mbr, 1, dev_desc->blksz);
        if (p_mbr == NULL) {
                printf("%s: calloc failed!\n", __func__);
                return -1;
@@ -364,6 +367,10 @@ static int set_protective_mbr(struct blk_desc *dev_desc)
                return -1;
        }
 
+       /* Clear all data in MBR except of backed up boot code */
+       memset((char *)p_mbr + MSDOS_MBR_BOOT_CODE_SIZE, 0, sizeof(*p_mbr) -
+                       MSDOS_MBR_BOOT_CODE_SIZE);
+
        /* Append signature */
        p_mbr->signature = MSDOS_MBR_SIGNATURE;
        p_mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
@@ -469,8 +476,8 @@ int gpt_fill_pte(struct blk_desc *dev_desc,
                 * 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)))) {
+               if (((start < hdr_end && hdr_start < (start + size)) ||
+                    (start < pte_end && pte_start < (start + size)))) {
                        printf("Partition overlap\n");
                        return -1;
                }
@@ -501,12 +508,12 @@ int gpt_fill_pte(struct blk_desc *dev_desc,
                } else {
                        /* default partition type GUID */
                        memcpy(bin_type_guid,
-                              &PARTITION_BASIC_DATA_GUID, 16);
+                              &partition_basic_data_guid, 16);
                }
 #else
                /* partition type GUID */
                memcpy(gpt_e[i].partition_type_guid.b,
-                       &PARTITION_BASIC_DATA_GUID, 16);
+                       &partition_basic_data_guid, 16);
 #endif
 
 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
@@ -598,7 +605,7 @@ static uint32_t partition_entries_offset(struct blk_desc *dev_desc)
 int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h,
                char *str_guid, int parts_count)
 {
-       gpt_h->signature = cpu_to_le64(GPT_HEADER_SIGNATURE);
+       gpt_h->signature = cpu_to_le64(GPT_HEADER_SIGNATURE_UBOOT);
        gpt_h->revision = cpu_to_le32(GPT_HEADER_REVISION_V1);
        gpt_h->header_size = cpu_to_le32(sizeof(gpt_header));
        gpt_h->my_lba = cpu_to_le64(1);
@@ -622,25 +629,27 @@ int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h,
 int gpt_restore(struct blk_desc *dev_desc, char *str_disk_guid,
                disk_partition_t *partitions, int parts_count)
 {
-       int ret;
-
-       gpt_header *gpt_h = calloc(1, PAD_TO_BLOCKSIZE(sizeof(gpt_header),
-                                                      dev_desc));
+       gpt_header *gpt_h;
        gpt_entry *gpt_e;
+       int ret, size;
 
+       size = PAD_TO_BLOCKSIZE(sizeof(gpt_header), dev_desc);
+       gpt_h = malloc_cache_aligned(size);
        if (gpt_h == NULL) {
                printf("%s: calloc failed!\n", __func__);
                return -1;
        }
+       memset(gpt_h, 0, size);
 
-       gpt_e = calloc(1, PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS
-                                              * sizeof(gpt_entry),
-                                              dev_desc));
+       size = PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
+                               dev_desc);
+       gpt_e = malloc_cache_aligned(size);
        if (gpt_e == NULL) {
                printf("%s: calloc failed!\n", __func__);
                free(gpt_h);
                return -1;
        }
+       memset(gpt_e, 0, size);
 
        /* Generate Primary GPT header (LBA1) */
        ret = gpt_fill_header(dev_desc, gpt_h, str_disk_guid, parts_count);
@@ -689,6 +698,10 @@ int gpt_verify_headers(struct blk_desc *dev_desc, gpt_header *gpt_head,
                       __func__);
                return -1;
        }
+
+       /* Free pte before allocating again */
+       free(*gpt_pte);
+
        if (is_gpt_valid(dev_desc, (dev_desc->lba - 1),
                         gpt_head, gpt_pte) != 1) {
                printf("%s: *** ERROR: Invalid Backup GPT ***\n",
@@ -923,13 +936,14 @@ 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);
-
+       /* Confirm valid arguments prior to allocation. */
        if (!dev_desc || !pgpt_head) {
                printf("%s: Invalid Argument(s)\n", __func__);
                return 0;
        }
 
+       ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, mbr, 1, dev_desc->blksz);
+
        /* Read MBR Header from device */
        if (blk_dread(dev_desc, 0, 1, (ulong *)mbr) != 1) {
                printf("*** ERROR: Can't read MBR header ***\n");