summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEgbert Eich <eich@suse.com>2013-04-09 06:03:36 +0000
committerTom Rini <trini@ti.com>2013-05-01 16:24:02 -0400
commitae1768a72cf70c00eec6824a5cc9079b0a247640 (patch)
treef39da7d478d7208b2603d0466c258dd9e710c30f
parent9d956e0fefa39ba49250f61e3c7aa3dadafdb7fd (diff)
disk/gpt: Fix GPT partition handling for blocksize != 512
Disks beyond 2T in size use blocksizes of 4096 bytes. However a lot of code in u-boot still assumes a 512 byte blocksize. This patch fixes the handling of GPTs. Signed-off-by: Egbert Eich <eich@suse.com>
-rw-r--r--disk/part_efi.c38
-rw-r--r--include/common.h11
-rw-r--r--include/part.h4
-rw-r--r--include/part_efi.h2
4 files changed, 35 insertions, 20 deletions
diff --git a/disk/part_efi.c b/disk/part_efi.c
index e9987f055cb..59865897085 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -115,7 +115,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];
@@ -162,7 +162,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 */
@@ -190,7 +190,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]));
@@ -210,7 +210,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)
@@ -311,9 +311,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;
@@ -336,8 +335,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 */
@@ -352,7 +351,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,
@@ -462,13 +461,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);
@@ -652,7 +656,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) {
@@ -669,7 +673,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) {
@@ -680,10 +685,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);
diff --git a/include/common.h b/include/common.h
index 28aa4b9d603..84315a0b431 100644
--- a/include/common.h
+++ b/include/common.h
@@ -1011,10 +1011,17 @@ static inline phys_addr_t map_to_sysmem(void *ptr)
* of a function scoped static buffer. It can not be used to create a cache
* line aligned global buffer.
*/
-#define ALLOC_ALIGN_BUFFER(type, name, size, align) \
- char __##name[ROUND(size * sizeof(type), align) + (align - 1)]; \
+#define PAD_COUNT(s, pad) ((s - 1) / pad + 1)
+#define PAD_SIZE(s, pad) (PAD_COUNT(s, pad) * pad)
+#define ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad) \
+ char __##name[ROUND(PAD_SIZE(size * sizeof(type), pad), align) \
+ + (align - 1)]; \
\
type *name = (type *) ALIGN((uintptr_t)__##name, align)
+#define ALLOC_ALIGN_BUFFER(type, name, size, align) \
+ ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, 1)
+#define ALLOC_CACHE_ALIGN_BUFFER_PAD(type, name, size, pad) \
+ ALLOC_ALIGN_BUFFER_PAD(type, name, size, ARCH_DMA_MINALIGN, pad)
#define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \
ALLOC_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN)
diff --git a/include/part.h b/include/part.h
index c58a734ada0..12e9b056e46 100644
--- a/include/part.h
+++ b/include/part.h
@@ -55,6 +55,10 @@ typedef struct block_dev_desc {
void *priv; /* driver private struct pointer */
}block_dev_desc_t;
+#define BLOCK_CNT(size, block_dev_desc) (PAD_COUNT(size, block_dev_desc->blksz))
+#define PAD_TO_BLOCKSIZE(size, block_dev_desc) \
+ (PAD_SIZE(size, block_dev_desc->blksz))
+
/* Interface types: */
#define IF_TYPE_UNKNOWN 0
#define IF_TYPE_IDE 1
diff --git a/include/part_efi.h b/include/part_efi.h
index 6de0a3258aa..95e4c8f61e4 100644
--- a/include/part_efi.h
+++ b/include/part_efi.h
@@ -38,7 +38,6 @@
#define EFI_PMBR_OSTYPE_EFI 0xEF
#define EFI_PMBR_OSTYPE_EFI_GPT 0xEE
-#define GPT_BLOCK_SIZE 512
#define GPT_HEADER_SIGNATURE 0x5452415020494645ULL
#define GPT_HEADER_REVISION_V1 0x00010000
#define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL
@@ -112,7 +111,6 @@ typedef struct _gpt_header {
__le32 num_partition_entries;
__le32 sizeof_partition_entry;
__le32 partition_entry_array_crc32;
- u8 reserved2[GPT_BLOCK_SIZE - 92];
} __packed gpt_header;
typedef union _gpt_entry_attributes {