1 /* 2 * Copyright (C) 2008 RuggedCom, Inc. 3 * Richard Retanubun <RichardRetanubun@RuggedCom.com> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 /* 9 * NOTE: 10 * when CONFIG_SYS_64BIT_LBA is not defined, lbaint_t is 32 bits; this 11 * limits the maximum size of addressable storage to < 2 Terra Bytes 12 */ 13 #include <asm/unaligned.h> 14 #include <common.h> 15 #include <command.h> 16 #include <fdtdec.h> 17 #include <ide.h> 18 #include <inttypes.h> 19 #include <malloc.h> 20 #include <memalign.h> 21 #include <part_efi.h> 22 #include <linux/compiler.h> 23 #include <linux/ctype.h> 24 25 DECLARE_GLOBAL_DATA_PTR; 26 27 #ifdef HAVE_BLOCK_DEVICE 28 /** 29 * efi_crc32() - EFI version of crc32 function 30 * @buf: buffer to calculate crc32 of 31 * @len - length of buf 32 * 33 * Description: Returns EFI-style CRC32 value for @buf 34 */ 35 static inline u32 efi_crc32(const void *buf, u32 len) 36 { 37 return crc32(0, buf, len); 38 } 39 40 /* 41 * Private function prototypes 42 */ 43 44 static int pmbr_part_valid(struct partition *part); 45 static int is_pmbr_valid(legacy_mbr * mbr); 46 static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba, 47 gpt_header *pgpt_head, gpt_entry **pgpt_pte); 48 static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc, 49 gpt_header *pgpt_head); 50 static int is_pte_valid(gpt_entry * pte); 51 52 static char *print_efiname(gpt_entry *pte) 53 { 54 static char name[PARTNAME_SZ + 1]; 55 int i; 56 for (i = 0; i < PARTNAME_SZ; i++) { 57 u8 c; 58 c = pte->partition_name[i] & 0xff; 59 c = (c && !isprint(c)) ? '.' : c; 60 name[i] = c; 61 } 62 name[PARTNAME_SZ] = 0; 63 return name; 64 } 65 66 static efi_guid_t system_guid = PARTITION_SYSTEM_GUID; 67 68 static inline int is_bootable(gpt_entry *p) 69 { 70 return p->attributes.fields.legacy_bios_bootable || 71 !memcmp(&(p->partition_type_guid), &system_guid, 72 sizeof(efi_guid_t)); 73 } 74 75 static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba, 76 lbaint_t lastlba) 77 { 78 uint32_t crc32_backup = 0; 79 uint32_t calc_crc32; 80 81 /* Check the GPT header signature */ 82 if (le64_to_cpu(gpt_h->signature) != GPT_HEADER_SIGNATURE) { 83 printf("%s signature is wrong: 0x%llX != 0x%llX\n", 84 "GUID Partition Table Header", 85 le64_to_cpu(gpt_h->signature), 86 GPT_HEADER_SIGNATURE); 87 return -1; 88 } 89 90 /* Check the GUID Partition Table CRC */ 91 memcpy(&crc32_backup, &gpt_h->header_crc32, sizeof(crc32_backup)); 92 memset(&gpt_h->header_crc32, 0, sizeof(gpt_h->header_crc32)); 93 94 calc_crc32 = efi_crc32((const unsigned char *)gpt_h, 95 le32_to_cpu(gpt_h->header_size)); 96 97 memcpy(&gpt_h->header_crc32, &crc32_backup, sizeof(crc32_backup)); 98 99 if (calc_crc32 != le32_to_cpu(crc32_backup)) { 100 printf("%s CRC is wrong: 0x%x != 0x%x\n", 101 "GUID Partition Table Header", 102 le32_to_cpu(crc32_backup), calc_crc32); 103 return -1; 104 } 105 106 /* 107 * Check that the my_lba entry points to the LBA that contains the GPT 108 */ 109 if (le64_to_cpu(gpt_h->my_lba) != lba) { 110 printf("GPT: my_lba incorrect: %llX != " LBAF "\n", 111 le64_to_cpu(gpt_h->my_lba), 112 lba); 113 return -1; 114 } 115 116 /* 117 * Check that the first_usable_lba and that the last_usable_lba are 118 * within the disk. 119 */ 120 if (le64_to_cpu(gpt_h->first_usable_lba) > lastlba) { 121 printf("GPT: first_usable_lba incorrect: %llX > " LBAF "\n", 122 le64_to_cpu(gpt_h->first_usable_lba), lastlba); 123 return -1; 124 } 125 if (le64_to_cpu(gpt_h->last_usable_lba) > lastlba) { 126 printf("GPT: last_usable_lba incorrect: %llX > " LBAF "\n", 127 le64_to_cpu(gpt_h->last_usable_lba), lastlba); 128 return -1; 129 } 130 131 debug("GPT: first_usable_lba: %llX last_usable_lba: %llX last lba: " 132 LBAF "\n", le64_to_cpu(gpt_h->first_usable_lba), 133 le64_to_cpu(gpt_h->last_usable_lba), lastlba); 134 135 return 0; 136 } 137 138 static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e) 139 { 140 uint32_t calc_crc32; 141 142 /* Check the GUID Partition Table Entry Array CRC */ 143 calc_crc32 = efi_crc32((const unsigned char *)gpt_e, 144 le32_to_cpu(gpt_h->num_partition_entries) * 145 le32_to_cpu(gpt_h->sizeof_partition_entry)); 146 147 if (calc_crc32 != le32_to_cpu(gpt_h->partition_entry_array_crc32)) { 148 printf("%s: 0x%x != 0x%x\n", 149 "GUID Partition Table Entry Array CRC is wrong", 150 le32_to_cpu(gpt_h->partition_entry_array_crc32), 151 calc_crc32); 152 return -1; 153 } 154 155 return 0; 156 } 157 158 static void prepare_backup_gpt_header(gpt_header *gpt_h) 159 { 160 uint32_t calc_crc32; 161 uint64_t val; 162 163 /* recalculate the values for the Backup GPT Header */ 164 val = le64_to_cpu(gpt_h->my_lba); 165 gpt_h->my_lba = gpt_h->alternate_lba; 166 gpt_h->alternate_lba = cpu_to_le64(val); 167 gpt_h->partition_entry_lba = 168 cpu_to_le64(le64_to_cpu(gpt_h->last_usable_lba) + 1); 169 gpt_h->header_crc32 = 0; 170 171 calc_crc32 = efi_crc32((const unsigned char *)gpt_h, 172 le32_to_cpu(gpt_h->header_size)); 173 gpt_h->header_crc32 = cpu_to_le32(calc_crc32); 174 } 175 176 #if CONFIG_IS_ENABLED(EFI_PARTITION) 177 /* 178 * Public Functions (include/part.h) 179 */ 180 181 void part_print_efi(struct blk_desc *dev_desc) 182 { 183 ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz); 184 gpt_entry *gpt_pte = NULL; 185 int i = 0; 186 char uuid[37]; 187 unsigned char *uuid_bin; 188 189 /* This function validates AND fills in the GPT header and PTE */ 190 if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA, 191 gpt_head, &gpt_pte) != 1) { 192 printf("%s: *** ERROR: Invalid GPT ***\n", __func__); 193 if (is_gpt_valid(dev_desc, (dev_desc->lba - 1), 194 gpt_head, &gpt_pte) != 1) { 195 printf("%s: *** ERROR: Invalid Backup GPT ***\n", 196 __func__); 197 return; 198 } else { 199 printf("%s: *** Using Backup GPT ***\n", 200 __func__); 201 } 202 } 203 204 debug("%s: gpt-entry at %p\n", __func__, gpt_pte); 205 206 printf("Part\tStart LBA\tEnd LBA\t\tName\n"); 207 printf("\tAttributes\n"); 208 printf("\tType GUID\n"); 209 printf("\tPartition GUID\n"); 210 211 for (i = 0; i < le32_to_cpu(gpt_head->num_partition_entries); i++) { 212 /* Stop at the first non valid PTE */ 213 if (!is_pte_valid(&gpt_pte[i])) 214 break; 215 216 printf("%3d\t0x%08llx\t0x%08llx\t\"%s\"\n", (i + 1), 217 le64_to_cpu(gpt_pte[i].starting_lba), 218 le64_to_cpu(gpt_pte[i].ending_lba), 219 print_efiname(&gpt_pte[i])); 220 printf("\tattrs:\t0x%016llx\n", gpt_pte[i].attributes.raw); 221 uuid_bin = (unsigned char *)gpt_pte[i].partition_type_guid.b; 222 uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID); 223 printf("\ttype:\t%s\n", uuid); 224 #ifdef CONFIG_PARTITION_TYPE_GUID 225 if (!uuid_guid_get_str(uuid_bin, uuid)) 226 printf("\ttype:\t%s\n", uuid); 227 #endif 228 uuid_bin = (unsigned char *)gpt_pte[i].unique_partition_guid.b; 229 uuid_bin_to_str(uuid_bin, uuid, UUID_STR_FORMAT_GUID); 230 printf("\tguid:\t%s\n", uuid); 231 } 232 233 /* Remember to free pte */ 234 free(gpt_pte); 235 return; 236 } 237 238 int part_get_info_efi(struct blk_desc *dev_desc, int part, 239 disk_partition_t *info) 240 { 241 ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz); 242 gpt_entry *gpt_pte = NULL; 243 244 /* "part" argument must be at least 1 */ 245 if (part < 1) { 246 printf("%s: Invalid Argument(s)\n", __func__); 247 return -1; 248 } 249 250 /* This function validates AND fills in the GPT header and PTE */ 251 if (is_gpt_valid(dev_desc, GPT_PRIMARY_PARTITION_TABLE_LBA, 252 gpt_head, &gpt_pte) != 1) { 253 printf("%s: *** ERROR: Invalid GPT ***\n", __func__); 254 if (is_gpt_valid(dev_desc, (dev_desc->lba - 1), 255 gpt_head, &gpt_pte) != 1) { 256 printf("%s: *** ERROR: Invalid Backup GPT ***\n", 257 __func__); 258 return -1; 259 } else { 260 printf("%s: *** Using Backup GPT ***\n", 261 __func__); 262 } 263 } 264 265 if (part > le32_to_cpu(gpt_head->num_partition_entries) || 266 !is_pte_valid(&gpt_pte[part - 1])) { 267 debug("%s: *** ERROR: Invalid partition number %d ***\n", 268 __func__, part); 269 free(gpt_pte); 270 return -1; 271 } 272 273 /* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */ 274 info->start = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].starting_lba); 275 /* The ending LBA is inclusive, to calculate size, add 1 to it */ 276 info->size = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1 277 - info->start; 278 info->blksz = dev_desc->blksz; 279 280 sprintf((char *)info->name, "%s", 281 print_efiname(&gpt_pte[part - 1])); 282 strcpy((char *)info->type, "U-Boot"); 283 info->bootable = is_bootable(&gpt_pte[part - 1]); 284 #if CONFIG_IS_ENABLED(PARTITION_UUIDS) 285 uuid_bin_to_str(gpt_pte[part - 1].unique_partition_guid.b, info->uuid, 286 UUID_STR_FORMAT_GUID); 287 #endif 288 #ifdef CONFIG_PARTITION_TYPE_GUID 289 uuid_bin_to_str(gpt_pte[part - 1].partition_type_guid.b, 290 info->type_guid, UUID_STR_FORMAT_GUID); 291 #endif 292 293 debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__, 294 info->start, info->size, info->name); 295 296 /* Remember to free pte */ 297 free(gpt_pte); 298 return 0; 299 } 300 301 static int part_test_efi(struct blk_desc *dev_desc) 302 { 303 ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz); 304 305 /* Read legacy MBR from block 0 and validate it */ 306 if ((blk_dread(dev_desc, 0, 1, (ulong *)legacymbr) != 1) 307 || (is_pmbr_valid(legacymbr) != 1)) { 308 return -1; 309 } 310 return 0; 311 } 312 313 /** 314 * set_protective_mbr(): Set the EFI protective MBR 315 * @param dev_desc - block device descriptor 316 * 317 * @return - zero on success, otherwise error 318 */ 319 static int set_protective_mbr(struct blk_desc *dev_desc) 320 { 321 /* Setup the Protective MBR */ 322 ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, p_mbr, 1); 323 memset(p_mbr, 0, sizeof(*p_mbr)); 324 325 if (p_mbr == NULL) { 326 printf("%s: calloc failed!\n", __func__); 327 return -1; 328 } 329 330 /* Read MBR to backup boot code if it exists */ 331 if (blk_dread(dev_desc, 0, 1, p_mbr) != 1) { 332 error("** Can't read from device %d **\n", dev_desc->devnum); 333 return -1; 334 } 335 336 /* Append signature */ 337 p_mbr->signature = MSDOS_MBR_SIGNATURE; 338 p_mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT; 339 p_mbr->partition_record[0].start_sect = 1; 340 p_mbr->partition_record[0].nr_sects = (u32) dev_desc->lba - 1; 341 342 /* Write MBR sector to the MMC device */ 343 if (blk_dwrite(dev_desc, 0, 1, p_mbr) != 1) { 344 printf("** Can't write to device %d **\n", 345 dev_desc->devnum); 346 return -1; 347 } 348 349 return 0; 350 } 351 352 int write_gpt_table(struct blk_desc *dev_desc, 353 gpt_header *gpt_h, gpt_entry *gpt_e) 354 { 355 const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries 356 * sizeof(gpt_entry)), dev_desc); 357 u32 calc_crc32; 358 359 debug("max lba: %x\n", (u32) dev_desc->lba); 360 /* Setup the Protective MBR */ 361 if (set_protective_mbr(dev_desc) < 0) 362 goto err; 363 364 /* Generate CRC for the Primary GPT Header */ 365 calc_crc32 = efi_crc32((const unsigned char *)gpt_e, 366 le32_to_cpu(gpt_h->num_partition_entries) * 367 le32_to_cpu(gpt_h->sizeof_partition_entry)); 368 gpt_h->partition_entry_array_crc32 = cpu_to_le32(calc_crc32); 369 370 calc_crc32 = efi_crc32((const unsigned char *)gpt_h, 371 le32_to_cpu(gpt_h->header_size)); 372 gpt_h->header_crc32 = cpu_to_le32(calc_crc32); 373 374 /* Write the First GPT to the block right after the Legacy MBR */ 375 if (blk_dwrite(dev_desc, 1, 1, gpt_h) != 1) 376 goto err; 377 378 if (blk_dwrite(dev_desc, le64_to_cpu(gpt_h->partition_entry_lba), 379 pte_blk_cnt, gpt_e) != pte_blk_cnt) 380 goto err; 381 382 prepare_backup_gpt_header(gpt_h); 383 384 if (blk_dwrite(dev_desc, (lbaint_t)le64_to_cpu(gpt_h->last_usable_lba) 385 + 1, pte_blk_cnt, gpt_e) != pte_blk_cnt) 386 goto err; 387 388 if (blk_dwrite(dev_desc, (lbaint_t)le64_to_cpu(gpt_h->my_lba), 1, 389 gpt_h) != 1) 390 goto err; 391 392 debug("GPT successfully written to block device!\n"); 393 return 0; 394 395 err: 396 printf("** Can't write to device %d **\n", dev_desc->devnum); 397 return -1; 398 } 399 400 int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, 401 disk_partition_t *partitions, int parts) 402 { 403 lbaint_t offset = (lbaint_t)le64_to_cpu(gpt_h->first_usable_lba); 404 lbaint_t start; 405 lbaint_t last_usable_lba = (lbaint_t) 406 le64_to_cpu(gpt_h->last_usable_lba); 407 int i, k; 408 size_t efiname_len, dosname_len; 409 #if CONFIG_IS_ENABLED(PARTITION_UUIDS) 410 char *str_uuid; 411 unsigned char *bin_uuid; 412 #endif 413 #ifdef CONFIG_PARTITION_TYPE_GUID 414 char *str_type_guid; 415 unsigned char *bin_type_guid; 416 #endif 417 418 for (i = 0; i < parts; i++) { 419 /* partition starting lba */ 420 start = partitions[i].start; 421 if (start && (start < offset)) { 422 printf("Partition overlap\n"); 423 return -1; 424 } 425 if (start) { 426 gpt_e[i].starting_lba = cpu_to_le64(start); 427 offset = start + partitions[i].size; 428 } else { 429 gpt_e[i].starting_lba = cpu_to_le64(offset); 430 offset += partitions[i].size; 431 } 432 if (offset > (last_usable_lba + 1)) { 433 printf("Partitions layout exceds disk size\n"); 434 return -1; 435 } 436 /* partition ending lba */ 437 if ((i == parts - 1) && (partitions[i].size == 0)) 438 /* extend the last partition to maximuim */ 439 gpt_e[i].ending_lba = gpt_h->last_usable_lba; 440 else 441 gpt_e[i].ending_lba = cpu_to_le64(offset - 1); 442 443 #ifdef CONFIG_PARTITION_TYPE_GUID 444 str_type_guid = partitions[i].type_guid; 445 bin_type_guid = gpt_e[i].partition_type_guid.b; 446 if (strlen(str_type_guid)) { 447 if (uuid_str_to_bin(str_type_guid, bin_type_guid, 448 UUID_STR_FORMAT_GUID)) { 449 printf("Partition no. %d: invalid type guid: %s\n", 450 i, str_type_guid); 451 return -1; 452 } 453 } else { 454 /* default partition type GUID */ 455 memcpy(bin_type_guid, 456 &PARTITION_BASIC_DATA_GUID, 16); 457 } 458 #else 459 /* partition type GUID */ 460 memcpy(gpt_e[i].partition_type_guid.b, 461 &PARTITION_BASIC_DATA_GUID, 16); 462 #endif 463 464 #if CONFIG_IS_ENABLED(PARTITION_UUIDS) 465 str_uuid = partitions[i].uuid; 466 bin_uuid = gpt_e[i].unique_partition_guid.b; 467 468 if (uuid_str_to_bin(str_uuid, bin_uuid, UUID_STR_FORMAT_GUID)) { 469 printf("Partition no. %d: invalid guid: %s\n", 470 i, str_uuid); 471 return -1; 472 } 473 #endif 474 475 /* partition attributes */ 476 memset(&gpt_e[i].attributes, 0, 477 sizeof(gpt_entry_attributes)); 478 479 if (partitions[i].bootable) 480 gpt_e[i].attributes.fields.legacy_bios_bootable = 1; 481 482 /* partition name */ 483 efiname_len = sizeof(gpt_e[i].partition_name) 484 / sizeof(efi_char16_t); 485 dosname_len = sizeof(partitions[i].name); 486 487 memset(gpt_e[i].partition_name, 0, 488 sizeof(gpt_e[i].partition_name)); 489 490 for (k = 0; k < min(dosname_len, efiname_len); k++) 491 gpt_e[i].partition_name[k] = 492 (efi_char16_t)(partitions[i].name[k]); 493 494 debug("%s: name: %s offset[%d]: 0x" LBAF 495 " size[%d]: 0x" LBAF "\n", 496 __func__, partitions[i].name, i, 497 offset, i, partitions[i].size); 498 } 499 500 return 0; 501 } 502 503 static uint32_t partition_entries_offset(struct blk_desc *dev_desc) 504 { 505 uint32_t offset_blks = 2; 506 int __maybe_unused config_offset; 507 508 #if defined(CONFIG_EFI_PARTITION_ENTRIES_OFF) 509 /* 510 * Some architectures require their SPL loader at a fixed 511 * address within the first 16KB of the disk. To avoid an 512 * overlap with the partition entries of the EFI partition 513 * table, the first safe offset (in bytes, from the start of 514 * the disk) for the entries can be set in 515 * CONFIG_EFI_PARTITION_ENTRIES_OFF. 516 */ 517 offset_blks = 518 PAD_TO_BLOCKSIZE(CONFIG_EFI_PARTITION_ENTRIES_OFF, dev_desc); 519 #endif 520 521 #if defined(CONFIG_OF_CONTROL) 522 /* 523 * Allow the offset of the first partition entires (in bytes 524 * from the start of the device) to be specified as a property 525 * of the device tree '/config' node. 526 */ 527 config_offset = fdtdec_get_config_int(gd->fdt_blob, 528 "u-boot,efi-partition-entries-offset", 529 -EINVAL); 530 if (config_offset != -EINVAL) 531 offset_blks = PAD_TO_BLOCKSIZE(config_offset, dev_desc); 532 #endif 533 534 debug("efi: partition entries offset (in blocks): %d\n", offset_blks); 535 536 /* 537 * The earliest LBA this can be at is LBA#2 (i.e. right behind 538 * the (protective) MBR and the GPT header. 539 */ 540 if (offset_blks < 2) 541 offset_blks = 2; 542 543 return offset_blks; 544 } 545 546 int gpt_fill_header(struct blk_desc *dev_desc, gpt_header *gpt_h, 547 char *str_guid, int parts_count) 548 { 549 gpt_h->signature = cpu_to_le64(GPT_HEADER_SIGNATURE); 550 gpt_h->revision = cpu_to_le32(GPT_HEADER_REVISION_V1); 551 gpt_h->header_size = cpu_to_le32(sizeof(gpt_header)); 552 gpt_h->my_lba = cpu_to_le64(1); 553 gpt_h->alternate_lba = cpu_to_le64(dev_desc->lba - 1); 554 gpt_h->last_usable_lba = cpu_to_le64(dev_desc->lba - 34); 555 gpt_h->partition_entry_lba = 556 cpu_to_le64(partition_entries_offset(dev_desc)); 557 gpt_h->first_usable_lba = 558 cpu_to_le64(le64_to_cpu(gpt_h->partition_entry_lba) + 32); 559 gpt_h->num_partition_entries = cpu_to_le32(GPT_ENTRY_NUMBERS); 560 gpt_h->sizeof_partition_entry = cpu_to_le32(sizeof(gpt_entry)); 561 gpt_h->header_crc32 = 0; 562 gpt_h->partition_entry_array_crc32 = 0; 563 564 if (uuid_str_to_bin(str_guid, gpt_h->disk_guid.b, UUID_STR_FORMAT_GUID)) 565 return -1; 566 567 return 0; 568 } 569 570 int gpt_restore(struct blk_desc *dev_desc, char *str_disk_guid, 571 disk_partition_t *partitions, int parts_count) 572 { 573 int ret; 574 575 gpt_header *gpt_h = calloc(1, PAD_TO_BLOCKSIZE(sizeof(gpt_header), 576 dev_desc)); 577 gpt_entry *gpt_e; 578 579 if (gpt_h == NULL) { 580 printf("%s: calloc failed!\n", __func__); 581 return -1; 582 } 583 584 gpt_e = calloc(1, PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS 585 * sizeof(gpt_entry), 586 dev_desc)); 587 if (gpt_e == NULL) { 588 printf("%s: calloc failed!\n", __func__); 589 free(gpt_h); 590 return -1; 591 } 592 593 /* Generate Primary GPT header (LBA1) */ 594 ret = gpt_fill_header(dev_desc, gpt_h, str_disk_guid, parts_count); 595 if (ret) 596 goto err; 597 598 /* Generate partition entries */ 599 ret = gpt_fill_pte(gpt_h, gpt_e, partitions, parts_count); 600 if (ret) 601 goto err; 602 603 /* Write GPT partition table */ 604 ret = write_gpt_table(dev_desc, gpt_h, gpt_e); 605 606 err: 607 free(gpt_e); 608 free(gpt_h); 609 return ret; 610 } 611 612 static void gpt_convert_efi_name_to_char(char *s, efi_char16_t *es, int n) 613 { 614 char *ess = (char *)es; 615 int i, j; 616 617 memset(s, '\0', n); 618 619 for (i = 0, j = 0; j < n; i += 2, j++) { 620 s[j] = ess[i]; 621 if (!ess[i]) 622 return; 623 } 624 } 625 626 int gpt_verify_headers(struct blk_desc *dev_desc, gpt_header *gpt_head, 627 gpt_entry **gpt_pte) 628 { 629 /* 630 * This function validates AND 631 * fills in the GPT header and PTE 632 */ 633 if (is_gpt_valid(dev_desc, 634 GPT_PRIMARY_PARTITION_TABLE_LBA, 635 gpt_head, gpt_pte) != 1) { 636 printf("%s: *** ERROR: Invalid GPT ***\n", 637 __func__); 638 return -1; 639 } 640 if (is_gpt_valid(dev_desc, (dev_desc->lba - 1), 641 gpt_head, gpt_pte) != 1) { 642 printf("%s: *** ERROR: Invalid Backup GPT ***\n", 643 __func__); 644 return -1; 645 } 646 647 return 0; 648 } 649 650 int gpt_verify_partitions(struct blk_desc *dev_desc, 651 disk_partition_t *partitions, int parts, 652 gpt_header *gpt_head, gpt_entry **gpt_pte) 653 { 654 char efi_str[PARTNAME_SZ + 1]; 655 u64 gpt_part_size; 656 gpt_entry *gpt_e; 657 int ret, i; 658 659 ret = gpt_verify_headers(dev_desc, gpt_head, gpt_pte); 660 if (ret) 661 return ret; 662 663 gpt_e = *gpt_pte; 664 665 for (i = 0; i < parts; i++) { 666 if (i == gpt_head->num_partition_entries) { 667 error("More partitions than allowed!\n"); 668 return -1; 669 } 670 671 /* Check if GPT and ENV partition names match */ 672 gpt_convert_efi_name_to_char(efi_str, gpt_e[i].partition_name, 673 PARTNAME_SZ + 1); 674 675 debug("%s: part: %2d name - GPT: %16s, ENV: %16s ", 676 __func__, i, efi_str, partitions[i].name); 677 678 if (strncmp(efi_str, (char *)partitions[i].name, 679 sizeof(partitions->name))) { 680 error("Partition name: %s does not match %s!\n", 681 efi_str, (char *)partitions[i].name); 682 return -1; 683 } 684 685 /* Check if GPT and ENV sizes match */ 686 gpt_part_size = le64_to_cpu(gpt_e[i].ending_lba) - 687 le64_to_cpu(gpt_e[i].starting_lba) + 1; 688 debug("size(LBA) - GPT: %8llu, ENV: %8llu ", 689 (unsigned long long)gpt_part_size, 690 (unsigned long long)partitions[i].size); 691 692 if (le64_to_cpu(gpt_part_size) != partitions[i].size) { 693 /* We do not check the extend partition size */ 694 if ((i == parts - 1) && (partitions[i].size == 0)) 695 continue; 696 697 error("Partition %s size: %llu does not match %llu!\n", 698 efi_str, (unsigned long long)gpt_part_size, 699 (unsigned long long)partitions[i].size); 700 return -1; 701 } 702 703 /* 704 * Start address is optional - check only if provided 705 * in '$partition' variable 706 */ 707 if (!partitions[i].start) { 708 debug("\n"); 709 continue; 710 } 711 712 /* Check if GPT and ENV start LBAs match */ 713 debug("start LBA - GPT: %8llu, ENV: %8llu\n", 714 le64_to_cpu(gpt_e[i].starting_lba), 715 (unsigned long long)partitions[i].start); 716 717 if (le64_to_cpu(gpt_e[i].starting_lba) != partitions[i].start) { 718 error("Partition %s start: %llu does not match %llu!\n", 719 efi_str, le64_to_cpu(gpt_e[i].starting_lba), 720 (unsigned long long)partitions[i].start); 721 return -1; 722 } 723 } 724 725 return 0; 726 } 727 728 int is_valid_gpt_buf(struct blk_desc *dev_desc, void *buf) 729 { 730 gpt_header *gpt_h; 731 gpt_entry *gpt_e; 732 733 /* determine start of GPT Header in the buffer */ 734 gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * 735 dev_desc->blksz); 736 if (validate_gpt_header(gpt_h, GPT_PRIMARY_PARTITION_TABLE_LBA, 737 dev_desc->lba)) 738 return -1; 739 740 /* determine start of GPT Entries in the buffer */ 741 gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) * 742 dev_desc->blksz); 743 if (validate_gpt_entries(gpt_h, gpt_e)) 744 return -1; 745 746 return 0; 747 } 748 749 int write_mbr_and_gpt_partitions(struct blk_desc *dev_desc, void *buf) 750 { 751 gpt_header *gpt_h; 752 gpt_entry *gpt_e; 753 int gpt_e_blk_cnt; 754 lbaint_t lba; 755 int cnt; 756 757 if (is_valid_gpt_buf(dev_desc, buf)) 758 return -1; 759 760 /* determine start of GPT Header in the buffer */ 761 gpt_h = buf + (GPT_PRIMARY_PARTITION_TABLE_LBA * 762 dev_desc->blksz); 763 764 /* determine start of GPT Entries in the buffer */ 765 gpt_e = buf + (le64_to_cpu(gpt_h->partition_entry_lba) * 766 dev_desc->blksz); 767 gpt_e_blk_cnt = BLOCK_CNT((le32_to_cpu(gpt_h->num_partition_entries) * 768 le32_to_cpu(gpt_h->sizeof_partition_entry)), 769 dev_desc); 770 771 /* write MBR */ 772 lba = 0; /* MBR is always at 0 */ 773 cnt = 1; /* MBR (1 block) */ 774 if (blk_dwrite(dev_desc, lba, cnt, buf) != cnt) { 775 printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n", 776 __func__, "MBR", cnt, lba); 777 return 1; 778 } 779 780 /* write Primary GPT */ 781 lba = GPT_PRIMARY_PARTITION_TABLE_LBA; 782 cnt = 1; /* GPT Header (1 block) */ 783 if (blk_dwrite(dev_desc, lba, cnt, gpt_h) != cnt) { 784 printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n", 785 __func__, "Primary GPT Header", cnt, lba); 786 return 1; 787 } 788 789 lba = le64_to_cpu(gpt_h->partition_entry_lba); 790 cnt = gpt_e_blk_cnt; 791 if (blk_dwrite(dev_desc, lba, cnt, gpt_e) != cnt) { 792 printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n", 793 __func__, "Primary GPT Entries", cnt, lba); 794 return 1; 795 } 796 797 prepare_backup_gpt_header(gpt_h); 798 799 /* write Backup GPT */ 800 lba = le64_to_cpu(gpt_h->partition_entry_lba); 801 cnt = gpt_e_blk_cnt; 802 if (blk_dwrite(dev_desc, lba, cnt, gpt_e) != cnt) { 803 printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n", 804 __func__, "Backup GPT Entries", cnt, lba); 805 return 1; 806 } 807 808 lba = le64_to_cpu(gpt_h->my_lba); 809 cnt = 1; /* GPT Header (1 block) */ 810 if (blk_dwrite(dev_desc, lba, cnt, gpt_h) != cnt) { 811 printf("%s: failed writing '%s' (%d blks at 0x" LBAF ")\n", 812 __func__, "Backup GPT Header", cnt, lba); 813 return 1; 814 } 815 816 return 0; 817 } 818 #endif 819 820 /* 821 * Private functions 822 */ 823 /* 824 * pmbr_part_valid(): Check for EFI partition signature 825 * 826 * Returns: 1 if EFI GPT partition type is found. 827 */ 828 static int pmbr_part_valid(struct partition *part) 829 { 830 if (part->sys_ind == EFI_PMBR_OSTYPE_EFI_GPT && 831 get_unaligned_le32(&part->start_sect) == 1UL) { 832 return 1; 833 } 834 835 return 0; 836 } 837 838 /* 839 * is_pmbr_valid(): test Protective MBR for validity 840 * 841 * Returns: 1 if PMBR is valid, 0 otherwise. 842 * Validity depends on two things: 843 * 1) MSDOS signature is in the last two bytes of the MBR 844 * 2) One partition of type 0xEE is found, checked by pmbr_part_valid() 845 */ 846 static int is_pmbr_valid(legacy_mbr * mbr) 847 { 848 int i = 0; 849 850 if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE) 851 return 0; 852 853 for (i = 0; i < 4; i++) { 854 if (pmbr_part_valid(&mbr->partition_record[i])) { 855 return 1; 856 } 857 } 858 return 0; 859 } 860 861 /** 862 * is_gpt_valid() - tests one GPT header and PTEs for validity 863 * 864 * lba is the logical block address of the GPT header to test 865 * gpt is a GPT header ptr, filled on return. 866 * ptes is a PTEs ptr, filled on return. 867 * 868 * Description: returns 1 if valid, 0 on error. 869 * If valid, returns pointers to PTEs. 870 */ 871 static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba, 872 gpt_header *pgpt_head, gpt_entry **pgpt_pte) 873 { 874 if (!dev_desc || !pgpt_head) { 875 printf("%s: Invalid Argument(s)\n", __func__); 876 return 0; 877 } 878 879 /* Read GPT Header from device */ 880 if (blk_dread(dev_desc, (lbaint_t)lba, 1, pgpt_head) != 1) { 881 printf("*** ERROR: Can't read GPT header ***\n"); 882 return 0; 883 } 884 885 if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba)) 886 return 0; 887 888 /* Read and allocate Partition Table Entries */ 889 *pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head); 890 if (*pgpt_pte == NULL) { 891 printf("GPT: Failed to allocate memory for PTE\n"); 892 return 0; 893 } 894 895 if (validate_gpt_entries(pgpt_head, *pgpt_pte)) { 896 free(*pgpt_pte); 897 return 0; 898 } 899 900 /* We're done, all's well */ 901 return 1; 902 } 903 904 /** 905 * alloc_read_gpt_entries(): reads partition entries from disk 906 * @dev_desc 907 * @gpt - GPT header 908 * 909 * Description: Returns ptes on success, NULL on error. 910 * Allocates space for PTEs based on information found in @gpt. 911 * Notes: remember to free pte when you're done! 912 */ 913 static gpt_entry *alloc_read_gpt_entries(struct blk_desc *dev_desc, 914 gpt_header *pgpt_head) 915 { 916 size_t count = 0, blk_cnt; 917 lbaint_t blk; 918 gpt_entry *pte = NULL; 919 920 if (!dev_desc || !pgpt_head) { 921 printf("%s: Invalid Argument(s)\n", __func__); 922 return NULL; 923 } 924 925 count = le32_to_cpu(pgpt_head->num_partition_entries) * 926 le32_to_cpu(pgpt_head->sizeof_partition_entry); 927 928 debug("%s: count = %u * %u = %lu\n", __func__, 929 (u32) le32_to_cpu(pgpt_head->num_partition_entries), 930 (u32) le32_to_cpu(pgpt_head->sizeof_partition_entry), 931 (ulong)count); 932 933 /* Allocate memory for PTE, remember to FREE */ 934 if (count != 0) { 935 pte = memalign(ARCH_DMA_MINALIGN, 936 PAD_TO_BLOCKSIZE(count, dev_desc)); 937 } 938 939 if (count == 0 || pte == NULL) { 940 printf("%s: ERROR: Can't allocate %#lX bytes for GPT Entries\n", 941 __func__, (ulong)count); 942 return NULL; 943 } 944 945 /* Read GPT Entries from device */ 946 blk = le64_to_cpu(pgpt_head->partition_entry_lba); 947 blk_cnt = BLOCK_CNT(count, dev_desc); 948 if (blk_dread(dev_desc, blk, (lbaint_t)blk_cnt, pte) != blk_cnt) { 949 printf("*** ERROR: Can't read GPT Entries ***\n"); 950 free(pte); 951 return NULL; 952 } 953 return pte; 954 } 955 956 /** 957 * is_pte_valid(): validates a single Partition Table Entry 958 * @gpt_entry - Pointer to a single Partition Table Entry 959 * 960 * Description: returns 1 if valid, 0 on error. 961 */ 962 static int is_pte_valid(gpt_entry * pte) 963 { 964 efi_guid_t unused_guid; 965 966 if (!pte) { 967 printf("%s: Invalid Argument(s)\n", __func__); 968 return 0; 969 } 970 971 /* Only one validation for now: 972 * The GUID Partition Type != Unused Entry (ALL-ZERO) 973 */ 974 memset(unused_guid.b, 0, sizeof(unused_guid.b)); 975 976 if (memcmp(pte->partition_type_guid.b, unused_guid.b, 977 sizeof(unused_guid.b)) == 0) { 978 979 debug("%s: Found an unused PTE GUID at 0x%08X\n", __func__, 980 (unsigned int)(uintptr_t)pte); 981 982 return 0; 983 } else { 984 return 1; 985 } 986 } 987 988 /* 989 * Add an 'a_' prefix so it comes before 'dos' in the linker list. We need to 990 * check EFI first, since a DOS partition is often used as a 'protective MBR' 991 * with EFI. 992 */ 993 U_BOOT_PART_TYPE(a_efi) = { 994 .name = "EFI", 995 .part_type = PART_TYPE_EFI, 996 .max_entries = GPT_ENTRY_NUMBERS, 997 .get_info = part_get_info_ptr(part_get_info_efi), 998 .print = part_print_ptr(part_print_efi), 999 .test = part_test_efi, 1000 }; 1001 #endif 1002