|
@@ -13,11 +13,13 @@
|
|
#include <asm/unaligned.h>
|
|
#include <asm/unaligned.h>
|
|
#include <common.h>
|
|
#include <common.h>
|
|
#include <command.h>
|
|
#include <command.h>
|
|
|
|
+#include <fdtdec.h>
|
|
#include <ide.h>
|
|
#include <ide.h>
|
|
#include <inttypes.h>
|
|
#include <inttypes.h>
|
|
#include <malloc.h>
|
|
#include <malloc.h>
|
|
#include <memalign.h>
|
|
#include <memalign.h>
|
|
#include <part_efi.h>
|
|
#include <part_efi.h>
|
|
|
|
+#include <linux/compiler.h>
|
|
#include <linux/ctype.h>
|
|
#include <linux/ctype.h>
|
|
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
@@ -373,8 +375,8 @@ int write_gpt_table(struct blk_desc *dev_desc,
|
|
if (blk_dwrite(dev_desc, 1, 1, gpt_h) != 1)
|
|
if (blk_dwrite(dev_desc, 1, 1, gpt_h) != 1)
|
|
goto err;
|
|
goto err;
|
|
|
|
|
|
- if (blk_dwrite(dev_desc, 2, pte_blk_cnt, gpt_e)
|
|
|
|
- != pte_blk_cnt)
|
|
|
|
|
|
+ if (blk_dwrite(dev_desc, le64_to_cpu(gpt_h->partition_entry_lba),
|
|
|
|
+ pte_blk_cnt, gpt_e) != pte_blk_cnt)
|
|
goto err;
|
|
goto err;
|
|
|
|
|
|
prepare_backup_gpt_header(gpt_h);
|
|
prepare_backup_gpt_header(gpt_h);
|
|
@@ -498,6 +500,49 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static uint32_t partition_entries_offset(struct blk_desc *dev_desc)
|
|
|
|
+{
|
|
|
|
+ uint32_t offset_blks = 2;
|
|
|
|
+ int __maybe_unused config_offset;
|
|
|
|
+
|
|
|
|
+#if defined(CONFIG_EFI_PARTITION_ENTRIES_OFF)
|
|
|
|
+ /*
|
|
|
|
+ * Some architectures require their SPL loader at a fixed
|
|
|
|
+ * address within the first 16KB of the disk. To avoid an
|
|
|
|
+ * overlap with the partition entries of the EFI partition
|
|
|
|
+ * table, the first safe offset (in bytes, from the start of
|
|
|
|
+ * the disk) for the entries can be set in
|
|
|
|
+ * CONFIG_EFI_PARTITION_ENTRIES_OFF.
|
|
|
|
+ */
|
|
|
|
+ offset_blks =
|
|
|
|
+ PAD_TO_BLOCKSIZE(CONFIG_EFI_PARTITION_ENTRIES_OFF, dev_desc);
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+#if defined(CONFIG_OF_CONTROL)
|
|
|
|
+ /*
|
|
|
|
+ * Allow the offset of the first partition entires (in bytes
|
|
|
|
+ * from the start of the device) to be specified as a property
|
|
|
|
+ * of the device tree '/config' node.
|
|
|
|
+ */
|
|
|
|
+ config_offset = fdtdec_get_config_int(gd->fdt_blob,
|
|
|
|
+ "u-boot,efi-partition-entries-offset",
|
|
|
|
+ -EINVAL);
|
|
|
|
+ if (config_offset != -EINVAL)
|
|
|
|
+ offset_blks = PAD_TO_BLOCKSIZE(config_offset, dev_desc);
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ debug("efi: partition entries offset (in blocks): %d\n", offset_blks);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * The earliest LBA this can be at is LBA#2 (i.e. right behind
|
|
|
|
+ * the (protective) MBR and the GPT header.
|
|
|
|
+ */
|
|
|
|
+ if (offset_blks < 2)
|
|
|
|
+ offset_blks = 2;
|
|
|
|
+
|
|
|
|
+ return offset_blks;
|
|
|
|
+}
|
|
|
|
+
|
|
int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h,
|
|
int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h,
|
|
char *str_guid, int parts_count)
|
|
char *str_guid, int parts_count)
|
|
{
|
|
{
|
|
@@ -506,9 +551,11 @@ int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h,
|
|
gpt_h->header_size = cpu_to_le32(sizeof(gpt_header));
|
|
gpt_h->header_size = cpu_to_le32(sizeof(gpt_header));
|
|
gpt_h->my_lba = cpu_to_le64(1);
|
|
gpt_h->my_lba = cpu_to_le64(1);
|
|
gpt_h->alternate_lba = cpu_to_le64(dev_desc->lba - 1);
|
|
gpt_h->alternate_lba = cpu_to_le64(dev_desc->lba - 1);
|
|
- gpt_h->first_usable_lba = cpu_to_le64(34);
|
|
|
|
gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
|
|
gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34);
|
|
- gpt_h->partition_entry_lba = cpu_to_le64(2);
|
|
|
|
|
|
+ gpt_h->partition_entry_lba =
|
|
|
|
+ cpu_to_le64(partition_entries_offset(dev_desc));
|
|
|
|
+ gpt_h->first_usable_lba =
|
|
|
|
+ cpu_to_le64(le64_to_cpu(gpt_h->partition_entry_lba) + 32);
|
|
gpt_h->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
|
|
gpt_h->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS);
|
|
gpt_h->sizeof_partition_entry = cpu_to_le32(sizeof(gpt_entry));
|
|
gpt_h->sizeof_partition_entry = cpu_to_le32(sizeof(gpt_entry));
|
|
gpt_h->header_crc32 = 0;
|
|
gpt_h->header_crc32 = 0;
|