]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - disk/part_efi.c
part_efi: fix protective mbr struct allocation
[karo-tx-uboot.git] / disk / part_efi.c
index 76650173309624ed21eaa98a2b7a0dd3b7ef2fe3..733d5bde94ed416e0831d326a0e865c56edc02b8 100644 (file)
@@ -2,23 +2,7 @@
  * Copyright (C) 2008 RuggedCom, Inc.
  * Richard Retanubun <RichardRetanubun@RuggedCom.com>
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 /*
@@ -30,6 +14,7 @@
  *
  * This limits the maximum size of addressable storage to < 2 Terra Bytes
  */
+#include <asm/unaligned.h>
 #include <common.h>
 #include <command.h>
 #include <ide.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if defined(CONFIG_CMD_IDE) || \
-    defined(CONFIG_CMD_SATA) || \
-    defined(CONFIG_CMD_SCSI) || \
-    defined(CONFIG_CMD_USB) || \
-    defined(CONFIG_MMC) || \
-    defined(CONFIG_SYSTEMACE)
-
+#ifdef HAVE_BLOCK_DEVICE
 /**
  * efi_crc32() - EFI version of crc32 function
  * @buf: buffer to calculate crc32 of
@@ -120,7 +99,7 @@ static inline int is_bootable(gpt_entry *p)
 
 void print_part_efi(block_dev_desc_t * dev_desc)
 {
-       ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1);
+       ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
        gpt_entry *gpt_pte = NULL;
        int i = 0;
        char uuid[37];
@@ -167,7 +146,7 @@ void print_part_efi(block_dev_desc_t * dev_desc)
 int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
                                disk_partition_t * info)
 {
-       ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1);
+       ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
        gpt_entry *gpt_pte = NULL;
 
        /* "part" argument must be at least 1 */
@@ -185,8 +164,9 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 
        if (part > le32_to_cpu(gpt_head->num_partition_entries) ||
            !is_pte_valid(&gpt_pte[part - 1])) {
-               printf("%s: *** ERROR: Invalid partition number %d ***\n",
+               debug("%s: *** ERROR: Invalid partition number %d ***\n",
                        __func__, part);
+               free(gpt_pte);
                return -1;
        }
 
@@ -195,7 +175,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
        /* The ending LBA is inclusive, to calculate size, add 1 to it */
        info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1)
                     - info->start;
-       info->blksz = GPT_BLOCK_SIZE;
+       info->blksz = dev_desc->blksz;
 
        sprintf((char *)info->name, "%s",
                        print_efiname(&gpt_pte[part - 1]));
@@ -205,8 +185,8 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
        uuid_string(gpt_pte[part - 1].unique_partition_guid.b, info->uuid);
 #endif
 
-       debug("%s: start 0x%lX, size 0x%lX, name %s", __func__,
-               info->start, info->size, info->name);
+       debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s", __func__,
+             info->start, info->size, info->name);
 
        /* Remember to free pte */
        free(gpt_pte);
@@ -215,7 +195,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 
 int test_part_efi(block_dev_desc_t * dev_desc)
 {
-       ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, legacymbr, 1);
+       ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz);
 
        /* Read legacy MBR from block 0 and validate it */
        if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)legacymbr) != 1)
@@ -233,10 +213,10 @@ int test_part_efi(block_dev_desc_t * dev_desc)
  */
 static int set_protective_mbr(block_dev_desc_t *dev_desc)
 {
-       legacy_mbr *p_mbr;
-
        /* Setup the Protective MBR */
-       p_mbr = calloc(1, sizeof(p_mbr));
+       ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, p_mbr, 1);
+       memset(p_mbr, 0, sizeof(*p_mbr));
+
        if (p_mbr == NULL) {
                printf("%s: calloc failed!\n", __func__);
                return -1;
@@ -251,11 +231,9 @@ static int set_protective_mbr(block_dev_desc_t *dev_desc)
        if (dev_desc->block_write(dev_desc->dev, 0, 1, p_mbr) != 1) {
                printf("** Can't write to device %d **\n",
                        dev_desc->dev);
-               free(p_mbr);
                return -1;
        }
 
-       free(p_mbr);
        return 0;
 }
 
@@ -316,9 +294,8 @@ static int string_uuid(char *uuid, u8 *dst)
 int write_gpt_table(block_dev_desc_t *dev_desc,
                gpt_header *gpt_h, gpt_entry *gpt_e)
 {
-       const int pte_blk_num = (gpt_h->num_partition_entries
-               * sizeof(gpt_entry)) / dev_desc->blksz;
-
+       const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries
+                                          * sizeof(gpt_entry)), dev_desc);
        u32 calc_crc32;
        u64 val;
 
@@ -341,8 +318,8 @@ int write_gpt_table(block_dev_desc_t *dev_desc,
        if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1)
                goto err;
 
-       if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e)
-           != pte_blk_num)
+       if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_cnt, gpt_e)
+           != pte_blk_cnt)
                goto err;
 
        /* recalculate the values for the Second GPT Header */
@@ -357,7 +334,7 @@ int write_gpt_table(block_dev_desc_t *dev_desc,
 
        if (dev_desc->block_write(dev_desc->dev,
                                  le32_to_cpu(gpt_h->last_usable_lba + 1),
-                                 pte_blk_num, gpt_e) != pte_blk_num)
+                                 pte_blk_cnt, gpt_e) != pte_blk_cnt)
                goto err;
 
        if (dev_desc->block_write(dev_desc->dev,
@@ -378,7 +355,7 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
        u32 offset = (u32)le32_to_cpu(gpt_h->first_usable_lba);
        ulong start;
        int i, k;
-       size_t name_len;
+       size_t efiname_len, dosname_len;
 #ifdef CONFIG_PARTITION_UUIDS
        char *str_uuid;
 #endif
@@ -426,13 +403,18 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
                       sizeof(gpt_entry_attributes));
 
                /* partition name */
-               name_len = sizeof(gpt_e[i].partition_name)
+               efiname_len = sizeof(gpt_e[i].partition_name)
                        / sizeof(efi_char16_t);
-               for (k = 0; k < name_len; k++)
+               dosname_len = sizeof(partitions[i].name);
+
+               memset(gpt_e[i].partition_name, 0,
+                      sizeof(gpt_e[i].partition_name));
+
+               for (k = 0; k < min(dosname_len, efiname_len); k++)
                        gpt_e[i].partition_name[k] =
                                (efi_char16_t)(partitions[i].name[k]);
 
-               debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x%lx\n",
+               debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x" LBAF "\n",
                      __func__, partitions[i].name, i,
                      offset, i, partitions[i].size);
        }
@@ -467,13 +449,18 @@ int gpt_restore(block_dev_desc_t *dev_desc, char *str_disk_guid,
 {
        int ret;
 
-       gpt_header *gpt_h = calloc(1, sizeof(gpt_header));
+       gpt_header *gpt_h = calloc(1, PAD_TO_BLOCKSIZE(sizeof(gpt_header),
+                                                      dev_desc));
+       gpt_entry *gpt_e;
+
        if (gpt_h == NULL) {
                printf("%s: calloc failed!\n", __func__);
                return -1;
        }
 
-       gpt_entry *gpt_e = calloc(GPT_ENTRY_NUMBERS, sizeof(gpt_entry));
+       gpt_e = calloc(1, PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS
+                                              * sizeof(gpt_entry),
+                                              dev_desc));
        if (gpt_e == NULL) {
                printf("%s: calloc failed!\n", __func__);
                free(gpt_h);
@@ -511,7 +498,7 @@ err:
 static int pmbr_part_valid(struct partition *part)
 {
        if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT &&
-               le32_to_cpu(part->start_sect) == 1UL) {
+               get_unaligned_le32(&part->start_sect) == 1UL) {
                return 1;
        }
 
@@ -657,7 +644,7 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
                                         gpt_header * pgpt_head)
 {
-       size_t count = 0;
+       size_t count = 0, blk_cnt;
        gpt_entry *pte = NULL;
 
        if (!dev_desc || !pgpt_head) {
@@ -674,7 +661,8 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 
        /* Allocate memory for PTE, remember to FREE */
        if (count != 0) {
-               pte = memalign(ARCH_DMA_MINALIGN, count);
+               pte = memalign(ARCH_DMA_MINALIGN,
+                              PAD_TO_BLOCKSIZE(count, dev_desc));
        }
 
        if (count == 0 || pte == NULL) {
@@ -685,10 +673,11 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
        }
 
        /* Read GPT Entries from device */
+       blk_cnt = BLOCK_CNT(count, dev_desc);
        if (dev_desc->block_read (dev_desc->dev,
                le64_to_cpu(pgpt_head->partition_entry_lba),
-               (lbaint_t) (count / GPT_BLOCK_SIZE), pte)
-               != (count / GPT_BLOCK_SIZE)) {
+               (lbaint_t) (blk_cnt), pte)
+               != blk_cnt) {
 
                printf("*** ERROR: Can't read GPT Entries ***\n");
                free(pte);