Commit ae1768a72cf70c00eec6824a5cc9079b0a247640
Committed by
Tom Rini
1 parent
9d956e0fef
Exists in
master
and in
53 other branches
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>
Showing 4 changed files with 35 additions and 20 deletions Side-by-side Diff
disk/part_efi.c
... | ... | @@ -115,7 +115,7 @@ |
115 | 115 | |
116 | 116 | void print_part_efi(block_dev_desc_t * dev_desc) |
117 | 117 | { |
118 | - ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1); | |
118 | + ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz); | |
119 | 119 | gpt_entry *gpt_pte = NULL; |
120 | 120 | int i = 0; |
121 | 121 | char uuid[37]; |
... | ... | @@ -162,7 +162,7 @@ |
162 | 162 | int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, |
163 | 163 | disk_partition_t * info) |
164 | 164 | { |
165 | - ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1); | |
165 | + ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz); | |
166 | 166 | gpt_entry *gpt_pte = NULL; |
167 | 167 | |
168 | 168 | /* "part" argument must be at least 1 */ |
... | ... | @@ -190,7 +190,7 @@ |
190 | 190 | /* The ending LBA is inclusive, to calculate size, add 1 to it */ |
191 | 191 | info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1) |
192 | 192 | - info->start; |
193 | - info->blksz = GPT_BLOCK_SIZE; | |
193 | + info->blksz = dev_desc->blksz; | |
194 | 194 | |
195 | 195 | sprintf((char *)info->name, "%s", |
196 | 196 | print_efiname(&gpt_pte[part - 1])); |
... | ... | @@ -210,7 +210,7 @@ |
210 | 210 | |
211 | 211 | int test_part_efi(block_dev_desc_t * dev_desc) |
212 | 212 | { |
213 | - ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, legacymbr, 1); | |
213 | + ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz); | |
214 | 214 | |
215 | 215 | /* Read legacy MBR from block 0 and validate it */ |
216 | 216 | if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)legacymbr) != 1) |
... | ... | @@ -311,9 +311,8 @@ |
311 | 311 | int write_gpt_table(block_dev_desc_t *dev_desc, |
312 | 312 | gpt_header *gpt_h, gpt_entry *gpt_e) |
313 | 313 | { |
314 | - const int pte_blk_num = (gpt_h->num_partition_entries | |
315 | - * sizeof(gpt_entry)) / dev_desc->blksz; | |
316 | - | |
314 | + const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries | |
315 | + * sizeof(gpt_entry)), dev_desc); | |
317 | 316 | u32 calc_crc32; |
318 | 317 | u64 val; |
319 | 318 | |
... | ... | @@ -336,8 +335,8 @@ |
336 | 335 | if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1) |
337 | 336 | goto err; |
338 | 337 | |
339 | - if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e) | |
340 | - != pte_blk_num) | |
338 | + if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_cnt, gpt_e) | |
339 | + != pte_blk_cnt) | |
341 | 340 | goto err; |
342 | 341 | |
343 | 342 | /* recalculate the values for the Second GPT Header */ |
... | ... | @@ -352,7 +351,7 @@ |
352 | 351 | |
353 | 352 | if (dev_desc->block_write(dev_desc->dev, |
354 | 353 | le32_to_cpu(gpt_h->last_usable_lba + 1), |
355 | - pte_blk_num, gpt_e) != pte_blk_num) | |
354 | + pte_blk_cnt, gpt_e) != pte_blk_cnt) | |
356 | 355 | goto err; |
357 | 356 | |
358 | 357 | if (dev_desc->block_write(dev_desc->dev, |
359 | 358 | |
... | ... | @@ -462,13 +461,18 @@ |
462 | 461 | { |
463 | 462 | int ret; |
464 | 463 | |
465 | - gpt_header *gpt_h = calloc(1, sizeof(gpt_header)); | |
464 | + gpt_header *gpt_h = calloc(1, PAD_TO_BLOCKSIZE(sizeof(gpt_header), | |
465 | + dev_desc)); | |
466 | + gpt_entry *gpt_e; | |
467 | + | |
466 | 468 | if (gpt_h == NULL) { |
467 | 469 | printf("%s: calloc failed!\n", __func__); |
468 | 470 | return -1; |
469 | 471 | } |
470 | 472 | |
471 | - gpt_entry *gpt_e = calloc(GPT_ENTRY_NUMBERS, sizeof(gpt_entry)); | |
473 | + gpt_e = calloc(1, PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS | |
474 | + * sizeof(gpt_entry), | |
475 | + dev_desc)); | |
472 | 476 | if (gpt_e == NULL) { |
473 | 477 | printf("%s: calloc failed!\n", __func__); |
474 | 478 | free(gpt_h); |
... | ... | @@ -652,7 +656,7 @@ |
652 | 656 | static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc, |
653 | 657 | gpt_header * pgpt_head) |
654 | 658 | { |
655 | - size_t count = 0; | |
659 | + size_t count = 0, blk_cnt; | |
656 | 660 | gpt_entry *pte = NULL; |
657 | 661 | |
658 | 662 | if (!dev_desc || !pgpt_head) { |
... | ... | @@ -669,7 +673,8 @@ |
669 | 673 | |
670 | 674 | /* Allocate memory for PTE, remember to FREE */ |
671 | 675 | if (count != 0) { |
672 | - pte = memalign(ARCH_DMA_MINALIGN, count); | |
676 | + pte = memalign(ARCH_DMA_MINALIGN, | |
677 | + PAD_TO_BLOCKSIZE(count, dev_desc)); | |
673 | 678 | } |
674 | 679 | |
675 | 680 | if (count == 0 || pte == NULL) { |
676 | 681 | |
... | ... | @@ -680,10 +685,11 @@ |
680 | 685 | } |
681 | 686 | |
682 | 687 | /* Read GPT Entries from device */ |
688 | + blk_cnt = BLOCK_CNT(count, dev_desc); | |
683 | 689 | if (dev_desc->block_read (dev_desc->dev, |
684 | 690 | le64_to_cpu(pgpt_head->partition_entry_lba), |
685 | - (lbaint_t) (count / GPT_BLOCK_SIZE), pte) | |
686 | - != (count / GPT_BLOCK_SIZE)) { | |
691 | + (lbaint_t) (blk_cnt), pte) | |
692 | + != blk_cnt) { | |
687 | 693 | |
688 | 694 | printf("*** ERROR: Can't read GPT Entries ***\n"); |
689 | 695 | free(pte); |
include/common.h
... | ... | @@ -1011,10 +1011,17 @@ |
1011 | 1011 | * of a function scoped static buffer. It can not be used to create a cache |
1012 | 1012 | * line aligned global buffer. |
1013 | 1013 | */ |
1014 | -#define ALLOC_ALIGN_BUFFER(type, name, size, align) \ | |
1015 | - char __##name[ROUND(size * sizeof(type), align) + (align - 1)]; \ | |
1014 | +#define PAD_COUNT(s, pad) ((s - 1) / pad + 1) | |
1015 | +#define PAD_SIZE(s, pad) (PAD_COUNT(s, pad) * pad) | |
1016 | +#define ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad) \ | |
1017 | + char __##name[ROUND(PAD_SIZE(size * sizeof(type), pad), align) \ | |
1018 | + + (align - 1)]; \ | |
1016 | 1019 | \ |
1017 | 1020 | type *name = (type *) ALIGN((uintptr_t)__##name, align) |
1021 | +#define ALLOC_ALIGN_BUFFER(type, name, size, align) \ | |
1022 | + ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, 1) | |
1023 | +#define ALLOC_CACHE_ALIGN_BUFFER_PAD(type, name, size, pad) \ | |
1024 | + ALLOC_ALIGN_BUFFER_PAD(type, name, size, ARCH_DMA_MINALIGN, pad) | |
1018 | 1025 | #define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \ |
1019 | 1026 | ALLOC_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN) |
1020 | 1027 |
include/part.h
... | ... | @@ -55,6 +55,10 @@ |
55 | 55 | void *priv; /* driver private struct pointer */ |
56 | 56 | }block_dev_desc_t; |
57 | 57 | |
58 | +#define BLOCK_CNT(size, block_dev_desc) (PAD_COUNT(size, block_dev_desc->blksz)) | |
59 | +#define PAD_TO_BLOCKSIZE(size, block_dev_desc) \ | |
60 | + (PAD_SIZE(size, block_dev_desc->blksz)) | |
61 | + | |
58 | 62 | /* Interface types: */ |
59 | 63 | #define IF_TYPE_UNKNOWN 0 |
60 | 64 | #define IF_TYPE_IDE 1 |
include/part_efi.h
... | ... | @@ -38,7 +38,6 @@ |
38 | 38 | #define EFI_PMBR_OSTYPE_EFI 0xEF |
39 | 39 | #define EFI_PMBR_OSTYPE_EFI_GPT 0xEE |
40 | 40 | |
41 | -#define GPT_BLOCK_SIZE 512 | |
42 | 41 | #define GPT_HEADER_SIGNATURE 0x5452415020494645ULL |
43 | 42 | #define GPT_HEADER_REVISION_V1 0x00010000 |
44 | 43 | #define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL |
... | ... | @@ -112,7 +111,6 @@ |
112 | 111 | __le32 num_partition_entries; |
113 | 112 | __le32 sizeof_partition_entry; |
114 | 113 | __le32 partition_entry_array_crc32; |
115 | - u8 reserved2[GPT_BLOCK_SIZE - 92]; | |
116 | 114 | } __packed gpt_header; |
117 | 115 | |
118 | 116 | typedef union _gpt_entry_attributes { |