1 /** @file 2 3 Copyright (c) 2014, ARM Ltd. All rights reserved.<BR> 4 Copyright (c) 2015-2017, Linaro. All rights reserved. 5 6 This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 /* 17 Implementation of the Android Fastboot Platform protocol, to be used by the 18 Fastboot UEFI application, for Hisilicon HiKey platform. 19 */ 20 21 #include <Protocol/AndroidFastbootPlatform.h> 22 #include <Protocol/BlockIo.h> 23 #include <Protocol/DiskIo.h> 24 #include <Protocol/EraseBlock.h> 25 #include <Protocol/SimpleTextOut.h> 26 27 #include <Protocol/DevicePathToText.h> 28 29 #include <Library/BaseLib.h> 30 #include <Library/BaseMemoryLib.h> 31 #include <Library/CacheMaintenanceLib.h> 32 #include <Library/DebugLib.h> 33 #include <Library/DevicePathLib.h> 34 #include <Library/IoLib.h> 35 #include <Library/MemoryAllocationLib.h> 36 #include <Library/UefiBootServicesTableLib.h> 37 #include <Library/UefiRuntimeServicesTableLib.h> 38 #include <Library/UsbSerialNumberLib.h> 39 #include <Library/PrintLib.h> 40 #include <Library/TimerLib.h> 41 42 #define PARTITION_NAME_MAX_LENGTH (72/2) 43 44 #define SERIAL_NUMBER_LBA 20 45 #define RANDOM_MAX 0x7FFFFFFFFFFFFFFF 46 #define RANDOM_MAGIC 0x9A4DBEAF 47 48 #define ADB_REBOOT_ADDRESS 0x32100000 49 #define ADB_REBOOT_BOOTLOADER 0x77665500 50 51 #define UFS_BLOCK_SIZE 4096 52 53 typedef struct _FASTBOOT_PARTITION_LIST { 54 LIST_ENTRY Link; 55 CHAR16 PartitionName[PARTITION_NAME_MAX_LENGTH]; 56 EFI_LBA StartingLBA; 57 EFI_LBA EndingLBA; 58 } FASTBOOT_PARTITION_LIST; 59 60 STATIC LIST_ENTRY mPartitionListHead; 61 STATIC EFI_HANDLE mFlashHandle; 62 STATIC EFI_BLOCK_IO_PROTOCOL *mFlashBlockIo; 63 STATIC EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *mTextOut; 64 65 /* 66 Helper to free the partition list 67 */ 68 STATIC 69 VOID 70 FreePartitionList ( 71 VOID 72 ) 73 { 74 FASTBOOT_PARTITION_LIST *Entry; 75 FASTBOOT_PARTITION_LIST *NextEntry; 76 77 Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&mPartitionListHead); 78 while (!IsNull (&mPartitionListHead, &Entry->Link)) { 79 NextEntry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &Entry->Link); 80 81 RemoveEntryList (&Entry->Link); 82 FreePool (Entry); 83 84 Entry = NextEntry; 85 } 86 } 87 88 /* 89 Read the PartitionName fields from the GPT partition entries, putting them 90 into an allocated array that should later be freed. 91 */ 92 STATIC 93 EFI_STATUS 94 ReadPartitionEntries ( 95 IN EFI_BLOCK_IO_PROTOCOL *BlockIo, 96 OUT EFI_PARTITION_ENTRY **PartitionEntries, 97 OUT UINTN *PartitionNumbers 98 ) 99 { 100 UINT32 MediaId; 101 EFI_PARTITION_TABLE_HEADER *GptHeader; 102 EFI_PARTITION_ENTRY *Entry; 103 EFI_STATUS Status; 104 VOID *Buffer; 105 UINTN PageCount; 106 UINTN BlockSize; 107 UINTN Count, EndLBA; 108 109 if ((PartitionEntries == NULL) || (PartitionNumbers == NULL)) { 110 return EFI_INVALID_PARAMETER; 111 } 112 MediaId = BlockIo->Media->MediaId; 113 BlockSize = BlockIo->Media->BlockSize; 114 115 // 116 // Read size of Partition entry and number of entries from GPT header 117 // 118 119 PageCount = EFI_SIZE_TO_PAGES (6 * BlockSize); 120 Buffer = AllocatePages (PageCount); 121 if (Buffer == NULL) { 122 return EFI_OUT_OF_RESOURCES; 123 } 124 125 Status = BlockIo->ReadBlocks (BlockIo, MediaId, 0, PageCount * EFI_PAGE_SIZE, Buffer); 126 if (EFI_ERROR (Status)) { 127 return Status; 128 } 129 GptHeader = (EFI_PARTITION_TABLE_HEADER *)(Buffer + BlockSize); 130 131 // Check there is a GPT on the media 132 if (GptHeader->Header.Signature != EFI_PTAB_HEADER_ID || 133 GptHeader->MyLBA != 1) { 134 DEBUG ((DEBUG_ERROR, 135 "Fastboot platform: No GPT on flash. " 136 "Fastboot on Versatile Express does not support MBR.\n" 137 )); 138 return EFI_DEVICE_ERROR; 139 } 140 141 Entry = (EFI_PARTITION_ENTRY *)(Buffer + (2 * BlockSize)); 142 EndLBA = GptHeader->FirstUsableLBA - 1; 143 Count = 0; 144 while (1) { 145 if ((Entry->StartingLBA > EndLBA) && (Entry->EndingLBA <= GptHeader->LastUsableLBA)) { 146 Count++; 147 EndLBA = Entry->EndingLBA; 148 Entry++; 149 } else { 150 break; 151 } 152 } 153 if (Count == 0) { 154 return EFI_INVALID_PARAMETER; 155 } 156 if (Count > GptHeader->NumberOfPartitionEntries) { 157 Count = GptHeader->NumberOfPartitionEntries; 158 } 159 160 *PartitionEntries = (EFI_PARTITION_ENTRY *)((UINTN)Buffer + (2 * BlockSize)); 161 *PartitionNumbers = Count; 162 return EFI_SUCCESS; 163 } 164 165 EFI_STATUS 166 LoadPtable ( 167 VOID 168 ) 169 { 170 EFI_STATUS Status; 171 EFI_DEVICE_PATH_PROTOCOL *FlashDevicePath; 172 EFI_DEVICE_PATH_PROTOCOL *FlashDevicePathDup; 173 UINTN PartitionNumbers = 0; 174 UINTN LoopIndex; 175 EFI_PARTITION_ENTRY *PartitionEntries = NULL; 176 FASTBOOT_PARTITION_LIST *Entry; 177 178 InitializeListHead (&mPartitionListHead); 179 180 Status = gBS->LocateProtocol (&gEfiSimpleTextOutProtocolGuid, NULL, (VOID **) &mTextOut); 181 if (EFI_ERROR (Status)) { 182 DEBUG ((DEBUG_ERROR, 183 "Fastboot platform: Couldn't open Text Output Protocol: %r\n", Status 184 )); 185 return Status; 186 } 187 188 // 189 // Get EFI_HANDLES for all the partitions on the block devices pointed to by 190 // PcdFastbootFlashDevicePath, also saving their GPT partition labels. 191 // There's no way to find all of a device's children, so we get every handle 192 // in the system supporting EFI_BLOCK_IO_PROTOCOL and then filter out ones 193 // that don't represent partitions on the flash device. 194 // 195 FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath)); 196 197 // Create another device path pointer because LocateDevicePath will modify it. 198 FlashDevicePathDup = FlashDevicePath; 199 Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePathDup, &mFlashHandle); 200 if (EFI_ERROR (Status)) { 201 DEBUG ((DEBUG_ERROR, "Warning: Couldn't locate Android NVM device (status: %r)\n", Status)); 202 // Failing to locate partitions should not prevent to do other Android FastBoot actions 203 return EFI_SUCCESS; 204 } 205 206 207 Status = gBS->OpenProtocol ( 208 mFlashHandle, 209 &gEfiBlockIoProtocolGuid, 210 (VOID **) &mFlashBlockIo, 211 gImageHandle, 212 NULL, 213 EFI_OPEN_PROTOCOL_GET_PROTOCOL 214 ); 215 if (EFI_ERROR (Status)) { 216 DEBUG ((DEBUG_ERROR, "Fastboot platform: Couldn't open Android NVM device (status: %r)\n", Status)); 217 return EFI_DEVICE_ERROR; 218 } 219 220 // Read the GPT partition entry array into memory so we can get the partition names 221 Status = ReadPartitionEntries (mFlashBlockIo, &PartitionEntries, &PartitionNumbers); 222 if (EFI_ERROR (Status)) { 223 DEBUG ((DEBUG_ERROR, "Warning: Failed to read partitions from Android NVM device (status: %r)\n", Status)); 224 // Failing to locate partitions should not prevent to do other Android FastBoot actions 225 return EFI_SUCCESS; 226 } 227 for (LoopIndex = 0; LoopIndex < PartitionNumbers; LoopIndex++) { 228 // Create entry 229 Entry = AllocatePool (sizeof (FASTBOOT_PARTITION_LIST)); 230 if (Entry == NULL) { 231 Status = EFI_OUT_OF_RESOURCES; 232 FreePartitionList (); 233 goto Exit; 234 } 235 StrnCpy ( 236 Entry->PartitionName, 237 PartitionEntries[LoopIndex].PartitionName, 238 PARTITION_NAME_MAX_LENGTH 239 ); 240 Entry->StartingLBA = PartitionEntries[LoopIndex].StartingLBA; 241 Entry->EndingLBA = PartitionEntries[LoopIndex].EndingLBA; 242 InsertTailList (&mPartitionListHead, &Entry->Link); 243 } 244 Exit: 245 FreePages ( 246 (VOID *)((UINTN)PartitionEntries - (2 * mFlashBlockIo->Media->BlockSize)), 247 EFI_SIZE_TO_PAGES (6 * mFlashBlockIo->Media->BlockSize) 248 ); 249 return Status; 250 } 251 252 /* 253 Initialise: Open the Android NVM device and find the partitions on it. Save them in 254 a list along with the "PartitionName" fields for their GPT entries. 255 We will use these partition names as the key in 256 HiKey960FastbootPlatformFlashPartition. 257 */ 258 EFI_STATUS 259 HiKey960FastbootPlatformInit ( 260 VOID 261 ) 262 { 263 EFI_STATUS Status; 264 265 Status = LoadPtable (); 266 if (EFI_ERROR (Status)) { 267 return Status; 268 } 269 return Status; 270 } 271 272 VOID 273 HiKey960FastbootPlatformUnInit ( 274 VOID 275 ) 276 { 277 FreePartitionList (); 278 } 279 280 EFI_STATUS 281 HiKey960FlashPtable ( 282 IN UINTN Size, 283 IN VOID *Image 284 ) 285 { 286 EFI_STATUS Status; 287 Status = mFlashBlockIo->WriteBlocks ( 288 mFlashBlockIo, 289 mFlashBlockIo->Media->MediaId, 290 0, 291 Size, 292 Image 293 ); 294 if (EFI_ERROR (Status)) { 295 DEBUG ((DEBUG_ERROR, "Failed to write (status:%r)\n", Status)); 296 return Status; 297 } 298 FreePartitionList (); 299 Status = LoadPtable (); 300 return Status; 301 } 302 303 EFI_STATUS 304 HiKey960ErasePtable ( 305 VOID 306 ) 307 { 308 EFI_STATUS Status; 309 #if 0 310 EFI_ERASE_BLOCK_PROTOCOL *EraseBlockProtocol; 311 #endif 312 313 #if 0 314 Status = gBS->OpenProtocol ( 315 mFlashHandle, 316 &gEfiEraseBlockProtocolGuid, 317 (VOID **) &EraseBlockProtocol, 318 gImageHandle, 319 NULL, 320 EFI_OPEN_PROTOCOL_GET_PROTOCOL 321 ); 322 if (EFI_ERROR (Status)) { 323 DEBUG ((DEBUG_ERROR, "Fastboot platform: could not open Erase Block IO: %r\n", Status)); 324 return EFI_DEVICE_ERROR; 325 } 326 Status = EraseBlockProtocol->EraseBlocks ( 327 EraseBlockProtocol, 328 mFlashBlockIo->Media->MediaId, 329 0, 330 NULL, 331 6 * mFlashBlockIo->Media->BlockSize 332 ); 333 #else 334 { 335 VOID *DataPtr; 336 UINTN Lba; 337 338 DataPtr = AllocatePages (1); 339 ZeroMem (DataPtr, EFI_PAGE_SIZE); 340 for (Lba = 0; Lba < 6; Lba++) { 341 Status = mFlashBlockIo->WriteBlocks ( 342 mFlashBlockIo, 343 mFlashBlockIo->Media->MediaId, 344 Lba, 345 EFI_PAGE_SIZE, 346 DataPtr 347 ); 348 if (EFI_ERROR (Status)) { 349 goto Exit; 350 } 351 } 352 Exit: 353 FreePages (DataPtr, 1); 354 } 355 #endif 356 FreePartitionList (); 357 return Status; 358 } 359 360 EFI_STATUS 361 HiKey960FlashXloader ( 362 IN UINTN Size, 363 IN VOID *Image 364 ) 365 { 366 EFI_STATUS Status; 367 EFI_DEVICE_PATH_PROTOCOL *DevicePath; 368 EFI_HANDLE Handle; 369 EFI_BLOCK_IO_PROTOCOL *BlockIo; 370 EFI_DISK_IO_PROTOCOL *DiskIo; 371 372 DevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdXloaderDevicePath)); 373 374 Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePath, &Handle); 375 if (EFI_ERROR (Status)) { 376 DEBUG ((DEBUG_ERROR, "Warning: Couldn't locate xloader device (status: %r)\n", Status)); 377 return Status; 378 } 379 380 Status = gBS->OpenProtocol ( 381 Handle, 382 &gEfiBlockIoProtocolGuid, 383 (VOID **) &BlockIo, 384 gImageHandle, 385 NULL, 386 EFI_OPEN_PROTOCOL_GET_PROTOCOL 387 ); 388 if (EFI_ERROR (Status)) { 389 DEBUG ((DEBUG_ERROR, "Fastboot platform: Couldn't open xloader device (status: %r)\n", Status)); 390 return EFI_DEVICE_ERROR; 391 } 392 Status = gBS->OpenProtocol ( 393 Handle, 394 &gEfiDiskIoProtocolGuid, 395 (VOID **) &DiskIo, 396 gImageHandle, 397 NULL, 398 EFI_OPEN_PROTOCOL_GET_PROTOCOL 399 ); 400 if (EFI_ERROR (Status)) { 401 return Status; 402 } 403 404 Status = DiskIo->WriteDisk ( 405 DiskIo, 406 BlockIo->Media->MediaId, 407 0, 408 Size, 409 Image 410 ); 411 if (EFI_ERROR (Status)) { 412 DEBUG ((DEBUG_ERROR, "Failed to write (status:%r)\n", Status)); 413 return Status; 414 } 415 return Status; 416 } 417 418 EFI_STATUS 419 HiKey960FastbootPlatformFlashPartition ( 420 IN CHAR8 *PartitionName, 421 IN UINTN Size, 422 IN VOID *Image 423 ) 424 { 425 EFI_STATUS Status; 426 UINTN PartitionSize; 427 FASTBOOT_PARTITION_LIST *Entry; 428 CHAR16 PartitionNameUnicode[60]; 429 BOOLEAN PartitionFound; 430 EFI_DISK_IO_PROTOCOL *DiskIo; 431 UINTN BlockSize; 432 433 // Support the pseudo partition name, such as "ptable". 434 if (AsciiStrCmp (PartitionName, "ptable") == 0) { 435 return HiKey960FlashPtable (Size, Image); 436 } else if (AsciiStrCmp (PartitionName, "xloader") == 0) { 437 return HiKey960FlashXloader (Size, Image); 438 } 439 440 AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode); 441 PartitionFound = FALSE; 442 Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead)); 443 while (!IsNull (&mPartitionListHead, &Entry->Link)) { 444 // Search the partition list for the partition named by PartitionName 445 if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) { 446 PartitionFound = TRUE; 447 break; 448 } 449 450 Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link); 451 } 452 if (!PartitionFound) { 453 return EFI_NOT_FOUND; 454 } 455 456 // Check image will fit on device 457 BlockSize = mFlashBlockIo->Media->BlockSize; 458 PartitionSize = (Entry->EndingLBA - Entry->StartingLBA + 1) * BlockSize; 459 if (PartitionSize < Size) { 460 DEBUG ((DEBUG_ERROR, "Partition not big enough.\n")); 461 DEBUG ((DEBUG_ERROR, "Partition Size:\t%ld\nImage Size:\t%ld\n", PartitionSize, Size)); 462 463 return EFI_VOLUME_FULL; 464 } 465 466 Status = gBS->OpenProtocol ( 467 mFlashHandle, 468 &gEfiDiskIoProtocolGuid, 469 (VOID **) &DiskIo, 470 gImageHandle, 471 NULL, 472 EFI_OPEN_PROTOCOL_GET_PROTOCOL 473 ); 474 ASSERT_EFI_ERROR (Status); 475 476 Status = DiskIo->WriteDisk ( 477 DiskIo, 478 mFlashBlockIo->Media->MediaId, 479 Entry->StartingLBA * BlockSize, 480 Size, 481 Image 482 ); 483 if (EFI_ERROR (Status)) { 484 DEBUG ((DEBUG_ERROR, "Failed to write %d bytes into 0x%x, Status:%r\n", Size, Entry->StartingLBA * BlockSize, Status)); 485 return Status; 486 } 487 488 mFlashBlockIo->FlushBlocks(mFlashBlockIo); 489 MicroSecondDelay (50000); 490 491 return Status; 492 } 493 494 EFI_STATUS 495 HiKey960FastbootPlatformErasePartition ( 496 IN CHAR8 *PartitionName 497 ) 498 { 499 EFI_STATUS Status; 500 EFI_ERASE_BLOCK_PROTOCOL *EraseBlockProtocol; 501 UINTN Size; 502 BOOLEAN PartitionFound; 503 CHAR16 PartitionNameUnicode[60]; 504 FASTBOOT_PARTITION_LIST *Entry; 505 506 AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode); 507 508 // Support the pseudo partition name, such as "ptable". 509 if (AsciiStrCmp (PartitionName, "ptable") == 0) { 510 return HiKey960ErasePtable (); 511 } 512 513 PartitionFound = FALSE; 514 Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&mPartitionListHead); 515 while (!IsNull (&mPartitionListHead, &Entry->Link)) { 516 // Search the partition list for the partition named by PartitionName 517 if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) { 518 PartitionFound = TRUE; 519 break; 520 } 521 Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &Entry->Link); 522 } 523 if (!PartitionFound) { 524 return EFI_NOT_FOUND; 525 } 526 527 Status = gBS->OpenProtocol ( 528 mFlashHandle, 529 &gEfiEraseBlockProtocolGuid, 530 (VOID **) &EraseBlockProtocol, 531 gImageHandle, 532 NULL, 533 EFI_OPEN_PROTOCOL_GET_PROTOCOL 534 ); 535 if (EFI_ERROR (Status)) { 536 return Status; 537 } 538 Size = (Entry->EndingLBA - Entry->StartingLBA + 1) * mFlashBlockIo->Media->BlockSize; 539 Status = EraseBlockProtocol->EraseBlocks ( 540 EraseBlockProtocol, 541 mFlashBlockIo->Media->MediaId, 542 Entry->StartingLBA, 543 NULL, 544 Size 545 ); 546 return Status; 547 } 548 549 EFI_STATUS 550 HiKey960FastbootPlatformGetVar ( 551 IN CHAR8 *Name, 552 OUT CHAR8 *Value 553 ) 554 { 555 EFI_STATUS Status = EFI_SUCCESS; 556 UINT64 PartitionSize; 557 FASTBOOT_PARTITION_LIST *Entry; 558 CHAR16 PartitionNameUnicode[60]; 559 BOOLEAN PartitionFound; 560 CHAR16 UnicodeSN[SERIAL_NUMBER_SIZE]; 561 562 if (!AsciiStrCmp (Name, "max-download-size")) { 563 AsciiStrCpy (Value, FixedPcdGetPtr (PcdArmFastbootFlashLimit)); 564 } else if (!AsciiStrCmp (Name, "product")) { 565 AsciiStrCpy (Value, FixedPcdGetPtr (PcdFirmwareVendor)); 566 } else if (!AsciiStrCmp (Name, "serialno")) { 567 Status = LoadSNFromBlock (mFlashHandle, SERIAL_NUMBER_LBA, UnicodeSN); 568 UnicodeStrToAsciiStr (UnicodeSN, Value); 569 } else if ( !AsciiStrnCmp (Name, "partition-size", 14)) { 570 AsciiStrToUnicodeStr ((Name + 15), PartitionNameUnicode); 571 PartitionFound = FALSE; 572 Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead)); 573 while (!IsNull (&mPartitionListHead, &Entry->Link)) { 574 // Search the partition list for the partition named by PartitionName 575 if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) { 576 PartitionFound = TRUE; 577 break; 578 } 579 580 Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link); 581 } 582 if (!PartitionFound) { 583 *Value = '\0'; 584 return EFI_NOT_FOUND; 585 } 586 587 PartitionSize = (Entry->EndingLBA - Entry->StartingLBA + 1) * mFlashBlockIo->Media->BlockSize; 588 DEBUG ((DEBUG_ERROR, "Fastboot platform: check for partition-size:%a 0X%llx\n", Name, PartitionSize )); 589 AsciiSPrint (Value, 12, "0x%llx", PartitionSize); 590 } else if ( !AsciiStrnCmp (Name, "partition-type", 14)) { 591 DEBUG ((DEBUG_ERROR, "Fastboot platform: check for partition-type:%a\n", (Name + 15) )); 592 if ( !AsciiStrnCmp ( (Name + 15) , "system", 6) || !AsciiStrnCmp ( (Name + 15) , "userdata", 8) 593 || !AsciiStrnCmp ( (Name + 15) , "cache", 5)) { 594 AsciiStrCpy (Value, "ext4"); 595 } else { 596 AsciiStrCpy (Value, "raw"); 597 } 598 } else if ( !AsciiStrCmp (Name, "erase-block-size")) { 599 AsciiSPrint (Value, 12, "0x%llx", UFS_BLOCK_SIZE); 600 } else if ( !AsciiStrCmp (Name, "logical-block-size")) { 601 AsciiSPrint (Value, 12, "0x%llx", UFS_BLOCK_SIZE); 602 } else { 603 *Value = '\0'; 604 } 605 return Status; 606 } 607 608 EFI_STATUS 609 HiKey960FastbootPlatformOemCommand ( 610 IN CHAR8 *Command 611 ) 612 { 613 EFI_STATUS Status; 614 CHAR16 UnicodeSN[SERIAL_NUMBER_SIZE]; 615 616 if (AsciiStrCmp (Command, "Demonstrate") == 0) { 617 DEBUG ((DEBUG_ERROR, "ARM OEM Fastboot command 'Demonstrate' received.\n")); 618 return EFI_SUCCESS; 619 } else if (AsciiStrCmp (Command, "serialno") == 0) { 620 Status = GenerateUsbSN (UnicodeSN); 621 if (EFI_ERROR (Status)) { 622 DEBUG ((DEBUG_ERROR, "Failed to generate USB Serial Number.\n")); 623 return Status; 624 } 625 Status = StoreSNToBlock (mFlashHandle, SERIAL_NUMBER_LBA, UnicodeSN); 626 return Status; 627 } else if (AsciiStrCmp (Command, "reboot-bootloader") == 0) { 628 MmioWrite32 (ADB_REBOOT_ADDRESS, ADB_REBOOT_BOOTLOADER); 629 WriteBackInvalidateDataCacheRange ((VOID *)ADB_REBOOT_ADDRESS, 4); 630 return EFI_SUCCESS; 631 } else { 632 DEBUG ((DEBUG_ERROR, 633 "HiKey960: Unrecognised Fastboot OEM command: %a\n", 634 Command 635 )); 636 return EFI_NOT_FOUND; 637 } 638 } 639 640 EFI_STATUS 641 HiKey960FastbootPlatformFlashPartitionEx ( 642 IN CHAR8 *PartitionName, 643 IN UINTN Offset, 644 IN UINTN Size, 645 IN VOID *Image 646 ) 647 { 648 EFI_STATUS Status; 649 UINTN PartitionSize; 650 FASTBOOT_PARTITION_LIST *Entry; 651 CHAR16 PartitionNameUnicode[60]; 652 BOOLEAN PartitionFound; 653 UINTN BlockSize; 654 EFI_DISK_IO_PROTOCOL *DiskIo; 655 656 AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode); 657 PartitionFound = FALSE; 658 Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead)); 659 while (!IsNull (&mPartitionListHead, &Entry->Link)) { 660 // Search the partition list for the partition named by PartitionName 661 if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) { 662 PartitionFound = TRUE; 663 break; 664 } 665 666 Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link); 667 } 668 if (!PartitionFound) { 669 return EFI_NOT_FOUND; 670 } 671 672 // Check image will fit on device 673 PartitionSize = (Entry->EndingLBA - Entry->StartingLBA + 1) * mFlashBlockIo->Media->BlockSize; 674 if (PartitionSize < Size) { 675 DEBUG ((DEBUG_ERROR, "Partition not big enough.\n")); 676 DEBUG ((DEBUG_ERROR, "Partition Size:\t%ld\nImage Size:\t%ld\n", PartitionSize, Size)); 677 678 return EFI_VOLUME_FULL; 679 } 680 681 BlockSize = mFlashBlockIo->Media->BlockSize; 682 683 Status = gBS->OpenProtocol ( 684 mFlashHandle, 685 &gEfiDiskIoProtocolGuid, 686 (VOID **) &DiskIo, 687 gImageHandle, 688 NULL, 689 EFI_OPEN_PROTOCOL_GET_PROTOCOL 690 ); 691 if (EFI_ERROR (Status)) { 692 return Status; 693 } 694 695 Status = DiskIo->WriteDisk ( 696 DiskIo, 697 mFlashBlockIo->Media->MediaId, 698 Entry->StartingLBA * BlockSize + Offset, 699 Size, 700 Image 701 ); 702 if (EFI_ERROR (Status)) { 703 DEBUG ((DEBUG_ERROR, "Failed to write %d bytes into 0x%x, Status:%r\n", Size, Entry->StartingLBA * BlockSize + Offset, Status)); 704 return Status; 705 } 706 return Status; 707 } 708 709 FASTBOOT_PLATFORM_PROTOCOL mPlatformProtocol = { 710 HiKey960FastbootPlatformInit, 711 HiKey960FastbootPlatformUnInit, 712 HiKey960FastbootPlatformFlashPartition, 713 HiKey960FastbootPlatformErasePartition, 714 HiKey960FastbootPlatformGetVar, 715 HiKey960FastbootPlatformOemCommand, 716 HiKey960FastbootPlatformFlashPartitionEx 717 }; 718 719 EFI_STATUS 720 EFIAPI 721 HiKey960FastbootPlatformEntryPoint ( 722 IN EFI_HANDLE ImageHandle, 723 IN EFI_SYSTEM_TABLE *SystemTable 724 ) 725 { 726 return gBS->InstallProtocolInterface ( 727 &ImageHandle, 728 &gAndroidFastbootPlatformProtocolGuid, 729 EFI_NATIVE_INTERFACE, 730 &mPlatformProtocol 731 ); 732 } 733