123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922 |
- /** @file
- Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- **/
- #include "FirmwareUpdate.h"
- EFI_HII_HANDLE HiiHandle;
- //
- // MinnowMax Flash Layout
- //
- //Start (hex) End (hex) Length (hex) Area Name
- //----------- --------- ------------ ---------
- //00000000 007FFFFF 00800000 Flash Image
- //
- //00000000 00000FFF 00001000 Descriptor Region
- //00001000 003FFFFF 003FF000 TXE Region
- //00500000 007FFFFF 00400000 BIOS Region
- //
- FV_REGION_INFO mRegionInfo[] = {
- {FixedPcdGet32 (PcdFlashDescriptorBase), FixedPcdGet32 (PcdFlashDescriptorSize), TRUE},
- {FixedPcdGet32 (PcdTxeRomBase), FixedPcdGet32 (PcdTxeRomSize), TRUE},
- {FixedPcdGet32 (PcdBiosRomBase), FixedPcdGet32 (PcdBiosRomSize), TRUE}
- };
- UINTN mRegionInfoCount = ARRAY_SIZE (mRegionInfo);
- FV_INPUT_DATA mInputData = {0};
- EFI_SPI_PROTOCOL *mSpiProtocol;
- EFI_STATUS
- GetRegionIndex (
- IN EFI_PHYSICAL_ADDRESS Address,
- OUT UINTN *RegionIndex
- )
- {
- UINTN Index;
- for (Index = 0; Index < mRegionInfoCount; Index++) {
- if (Address >= mRegionInfo[Index].Base &&
- Address < (mRegionInfo[Index].Base + mRegionInfo[Index].Size)
- ) {
- break;
- }
- }
- *RegionIndex = Index;
- if (Index >= mRegionInfoCount) {
- return EFI_NOT_FOUND;
- }
- return EFI_SUCCESS;
- }
- BOOLEAN
- UpdateBlock (
- IN EFI_PHYSICAL_ADDRESS Address
- )
- {
- EFI_STATUS Status;
- UINTN Index;
- if (mInputData.FullFlashUpdate) {
- return TRUE;
- }
- Status = GetRegionIndex (Address, &Index);
- if ((!EFI_ERROR(Status)) && mRegionInfo[Index].Update) {
- return TRUE;
- }
- return FALSE;
- }
- EFI_STATUS
- MarkRegionState (
- IN EFI_PHYSICAL_ADDRESS Address,
- IN BOOLEAN Update
- )
- {
- EFI_STATUS Status;
- UINTN Index;
- Status = GetRegionIndex (Address, &Index);
- if (!EFI_ERROR(Status)) {
- mRegionInfo[Index].Update = Update;
- }
- return Status;
- }
- UINTN
- InternalPrintToken (
- IN CONST CHAR16 *Format,
- IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *Console,
- IN VA_LIST Marker
- )
- {
- EFI_STATUS Status;
- UINTN Return;
- CHAR16 *Buffer;
- UINTN BufferSize;
- ASSERT (Format != NULL);
- ASSERT (((UINTN) Format & BIT0) == 0);
- ASSERT (Console != NULL);
- BufferSize = (PcdGet32 (PcdUefiLibMaxPrintBufferSize) + 1) * sizeof (CHAR16);
- Buffer = (CHAR16 *) AllocatePool(BufferSize);
- ASSERT (Buffer != NULL);
- Return = UnicodeVSPrint (Buffer, BufferSize, Format, Marker);
- if (Console != NULL && Return > 0) {
- //
- // To be extra safe make sure Console has been initialized.
- //
- Status = Console->OutputString (Console, Buffer);
- if (EFI_ERROR (Status)) {
- Return = 0;
- }
- }
- FreePool (Buffer);
- return Return;
- }
- UINTN
- EFIAPI
- PrintToken (
- IN UINT16 Token,
- IN EFI_HII_HANDLE Handle,
- ...
- )
- {
- VA_LIST Marker;
- UINTN Return;
- CHAR16 *Format;
- VA_START (Marker, Handle);
- Format = HiiGetString (Handle, Token, NULL);
- ASSERT (Format != NULL);
- Return = InternalPrintToken (Format, gST->ConOut, Marker);
- FreePool (Format);
- VA_END (Marker);
- return Return;
- }
- EFI_STATUS
- ParseCommandLine (
- IN UINTN Argc,
- IN CHAR16 **Argv
- )
- {
- EFI_STATUS Status;
- UINTN Index;
- //
- // Check to make sure that the command line has enough arguments for minimal
- // operation. The minimum is just the file name.
- //
- if (Argc < 2 || Argc > 4) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Loop through command line arguments.
- //
- for (Index = 1; Index < Argc; Index++) {
- //
- // Make sure the string is valid.
- //
- if (StrLen (Argv[Index]) == 0) {;
- PrintToken (STRING_TOKEN (STR_FWUPDATE_ZEROLENGTH_ARG), HiiHandle);
- return EFI_INVALID_PARAMETER;
- }
- //
- // Check to see if this is an option or the file name.
- //
- if ((Argv[Index])[0] == L'-' || (Argv[Index])[0] == L'/') {
- //
- // Parse the arguments.
- //
- if ((StrCmp (Argv[Index], L"-h") == 0) ||
- (StrCmp (Argv[Index], L"--help") == 0) ||
- (StrCmp (Argv[Index], L"/?") == 0) ||
- (StrCmp (Argv[Index], L"/h") == 0)) {
- //
- // Print Help Information.
- //
- return EFI_INVALID_PARAMETER;
- } else if (StrCmp (Argv[Index], L"-m") == 0) {
- //
- // Parse the MAC address here.
- //
- Status = ConvertMac(Argv[Index+1]);
- if (EFI_ERROR(Status)) {
- PrintToken (STRING_TOKEN (STR_FWUPDATE_INVAILD_MAC), HiiHandle);
- return Status;
- }
- //
- // Save the MAC address to mInputData.MacValue.
- //
- mInputData.UpdateMac= TRUE;
- Index++;
- } else {
- //
- // Invalid option was provided.
- //
- return EFI_INVALID_PARAMETER;
- }
- }
- if ((Index == Argc - 1) && (StrCmp (Argv[Index - 1], L"-m") != 0)) {
- //
- // The only parameter that is not an option is the firmware image. Check
- // to make sure that the file exists.
- //
- Status = ShellIsFile (Argv[Index]);
- if (EFI_ERROR (Status)) {
- PrintToken (STRING_TOKEN (STR_FWUPDATE_FILE_NOT_FOUND_ERROR), HiiHandle, Argv[Index]);
- return EFI_INVALID_PARAMETER;
- }
- if (StrLen (Argv[Index]) > INPUT_STRING_LEN) {
- PrintToken (STRING_TOKEN (STR_FWUPDATE_PATH_ERROR), HiiHandle, Argv[Index]);
- return EFI_INVALID_PARAMETER;
- }
- StrCpy (mInputData.FileName, Argv[Index]);
- mInputData.UpdateFromFile = TRUE;
- }
- }
- return EFI_SUCCESS;
- }
- INTN
- EFIAPI
- ShellAppMain (
- IN UINTN Argc,
- IN CHAR16 **Argv
- )
- {
- EFI_STATUS Status;
- UINTN Index;
- UINT32 FileSize;
- UINT32 BufferSize;
- UINT8 *FileBuffer;
- UINT8 *Buffer;
- EFI_PHYSICAL_ADDRESS Address;
- UINTN CountOfBlocks;
- EFI_TPL OldTpl;
- BOOLEAN ResetRequired;
- BOOLEAN FlashError;
- Index = 0;
- FileSize = 0;
- BufferSize = 0;
- FileBuffer = NULL;
- Buffer = NULL;
- Address = 0;
- CountOfBlocks = 0;
- ResetRequired = FALSE;
- FlashError = FALSE;
- Status = EFI_SUCCESS;
- mInputData.FullFlashUpdate = TRUE;
- //
- // Publish our HII data.
- //
- HiiHandle = HiiAddPackages (
- &gEfiCallerIdGuid,
- NULL,
- FirmwareUpdateStrings,
- NULL
- );
- if (HiiHandle == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
- //
- // Locate the SPI protocol.
- //
- Status = gBS->LocateProtocol (
- &gEfiSpiProtocolGuid,
- NULL,
- (VOID **)&mSpiProtocol
- );
- if (EFI_ERROR (Status)) {
- PrintToken (STRING_TOKEN (STR_SPI_NOT_FOUND), HiiHandle);
- return EFI_DEVICE_ERROR;
- }
- //
- // Parse the command line.
- //
- Status = ParseCommandLine (Argc, Argv);
- if (EFI_ERROR (Status)) {
- PrintHelpInfo ();
- Status = EFI_SUCCESS;
- goto Done;
- }
- //
- // Display sign-on information.
- //
- PrintToken (STRING_TOKEN (STR_FWUPDATE_FIRMWARE_VOL_UPDATE), HiiHandle);
- PrintToken (STRING_TOKEN (STR_FWUPDATE_VERSION), HiiHandle);
- PrintToken (STRING_TOKEN (STR_FWUPDATE_COPYRIGHT), HiiHandle);
- //
- // Test to see if the firmware needs to be updated.
- //
- if (mInputData.UpdateFromFile) {
- //
- // Get the file to use in the update.
- //
- PrintToken (STRING_TOKEN (STR_FWUPDATE_READ_FILE), HiiHandle, mInputData.FileName);
- Status = ReadFileData (mInputData.FileName, &FileBuffer, &FileSize);
- if (EFI_ERROR (Status)) {
- PrintToken (STRING_TOKEN (STR_FWUPDATE_READ_FILE_ERROR), HiiHandle, mInputData.FileName);
- goto Done;
- }
- //
- // Check that the file and flash sizes match.
- //
- if (FileSize != PcdGet32 (PcdFlashChipSize)) {
- PrintToken (STRING_TOKEN (STR_FWUPDATE_SIZE), HiiHandle);
- Status = EFI_UNSUPPORTED;
- goto Done;
- }
- //
- // Display flash update information.
- //
- PrintToken (STRING_TOKEN (STR_FWUPDATE_UPDATING_FIRMWARE), HiiHandle);
- //
- // Update it.
- //
- Buffer = FileBuffer;
- BufferSize = FileSize;
- Address = PcdGet32 (PcdFlashChipBase);
- CountOfBlocks = (UINTN) (BufferSize / BLOCK_SIZE);
- //
- // Raise TPL to TPL_NOTIFY to block any event handler,
- // while still allowing RaiseTPL(TPL_NOTIFY) within
- // output driver during Print().
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- for (Index = 0; Index < CountOfBlocks; Index++) {
- //
- // Handle block based on address and contents.
- //
- if (!UpdateBlock (Address)) {
- DEBUG((EFI_D_INFO, "Skipping block at 0x%lx\n", Address));
- } else if (!EFI_ERROR (InternalCompareBlock (Address, Buffer))) {
- DEBUG((EFI_D_INFO, "Skipping block at 0x%lx (already programmed)\n", Address));
- } else {
- //
- // Display a dot for each block being updated.
- //
- Print (L".");
- //
- // Flag that the flash image will be changed and the system must be rebooted
- // to use the change.
- //
- ResetRequired = TRUE;
- //
- // Make updating process uninterruptable,
- // so that the flash memory area is not accessed by other entities
- // which may interfere with the updating process.
- //
- Status = InternalEraseBlock (Address);
- ASSERT_EFI_ERROR(Status);
- if (EFI_ERROR (Status)) {
- gBS->RestoreTPL (OldTpl);
- FlashError = TRUE;
- goto Done;
- }
- Status = InternalWriteBlock (
- Address,
- Buffer,
- (BufferSize > BLOCK_SIZE ? BLOCK_SIZE : BufferSize)
- );
- if (EFI_ERROR (Status)) {
- gBS->RestoreTPL (OldTpl);
- FlashError = TRUE;
- goto Done;
- }
- }
- //
- // Move to next block to update.
- //
- Address += BLOCK_SIZE;
- Buffer += BLOCK_SIZE;
- if (BufferSize > BLOCK_SIZE) {
- BufferSize -= BLOCK_SIZE;
- } else {
- BufferSize = 0;
- }
- }
- gBS->RestoreTPL (OldTpl);
- //
- // Print result of update.
- //
- if (!FlashError) {
- if (ResetRequired) {
- Print (L"\n");
- PrintToken (STRING_TOKEN (STR_FWUPDATE_UPDATE_SUCCESS), HiiHandle);
- } else {
- PrintToken (STRING_TOKEN (STR_FWUPDATE_NO_RESET), HiiHandle);
- }
- } else {
- goto Done;
- }
- }
- //
- // All flash updates are done so see if the system needs to be reset.
- //
- if (ResetRequired && !FlashError) {
- //
- // Update successful.
- //
- for (Index = 5; Index > 0; Index--) {
- PrintToken (STRING_TOKEN (STR_FWUPDATE_SHUTDOWN), HiiHandle, Index);
- gBS->Stall (1000000);
- }
- gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
- PrintToken (STRING_TOKEN (STR_FWUPDATE_MANUAL_RESET), HiiHandle);
- CpuDeadLoop ();
- }
- Done:
- //
- // Print flash update failure message if error detected.
- //
- if (FlashError) {
- PrintToken (STRING_TOKEN (STR_FWUPDATE_UPDATE_FAILED), HiiHandle, Index);
- }
- //
- // Do cleanup.
- //
- if (HiiHandle != NULL) {
- HiiRemovePackages (HiiHandle);
- }
- if (FileBuffer) {
- gBS->FreePool (FileBuffer);
- }
- return Status;
- }
- STATIC
- EFI_STATUS
- InternalEraseBlock (
- IN EFI_PHYSICAL_ADDRESS BaseAddress
- )
- /*++
- Routine Description:
- Erase the whole block.
- Arguments:
- BaseAddress - Base address of the block to be erased.
- Returns:
- EFI_SUCCESS - The command completed successfully.
- Other - Device error or wirte-locked, operation failed.
- --*/
- {
- EFI_STATUS Status;
- UINTN NumBytes;
- NumBytes = BLOCK_SIZE;
- Status = SpiFlashBlockErase ((UINTN) BaseAddress, &NumBytes);
- return Status;
- }
- #if 0
- STATIC
- EFI_STATUS
- InternalReadBlock (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- OUT VOID *ReadBuffer
- )
- {
- EFI_STATUS Status;
- UINT32 BlockSize;
- BlockSize = BLOCK_SIZE;
- Status = SpiFlashRead ((UINTN) BaseAddress, &BlockSize, ReadBuffer);
- return Status;
- }
- #endif
- STATIC
- EFI_STATUS
- InternalCompareBlock (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT8 *Buffer
- )
- {
- EFI_STATUS Status;
- VOID *CompareBuffer;
- UINT32 NumBytes;
- INTN CompareResult;
- NumBytes = BLOCK_SIZE;
- CompareBuffer = AllocatePool (NumBytes);
- if (CompareBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
- Status = SpiFlashRead ((UINTN) BaseAddress, &NumBytes, CompareBuffer);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
- CompareResult = CompareMem (CompareBuffer, Buffer, BLOCK_SIZE);
- if (CompareResult != 0) {
- Status = EFI_VOLUME_CORRUPTED;
- }
- Done:
- if (CompareBuffer != NULL) {
- FreePool (CompareBuffer);
- }
- return Status;
- }
- STATIC
- EFI_STATUS
- InternalWriteBlock (
- IN EFI_PHYSICAL_ADDRESS BaseAddress,
- IN UINT8 *Buffer,
- IN UINT32 BufferSize
- )
- /*++
- Routine Description:
- Write a block of data.
- Arguments:
- BaseAddress - Base address of the block.
- Buffer - Data buffer.
- BufferSize - Size of the buffer.
- Returns:
- EFI_SUCCESS - The command completed successfully.
- EFI_INVALID_PARAMETER - Invalid parameter, can not proceed.
- Other - Device error or wirte-locked, operation failed.
- --*/
- {
- EFI_STATUS Status;
- Status = SpiFlashWrite ((UINTN) BaseAddress, &BufferSize, Buffer);
- ASSERT_EFI_ERROR(Status);
- if (EFI_ERROR (Status)) {
- DEBUG((EFI_D_ERROR, "\nFlash write error."));
- return Status;
- }
- WriteBackInvalidateDataCacheRange ((VOID *) (UINTN) BaseAddress, BLOCK_SIZE);
- Status = InternalCompareBlock (BaseAddress, Buffer);
- if (EFI_ERROR (Status)) {
- DEBUG((EFI_D_ERROR, "\nError when writing to BaseAddress %lx with different at offset %x.", BaseAddress, Status));
- } else {
- DEBUG((EFI_D_INFO, "\nVerified data written to Block at %lx is correct.", BaseAddress));
- }
- return Status;
- }
- STATIC
- EFI_STATUS
- ReadFileData (
- IN CHAR16 *FileName,
- OUT UINT8 **Buffer,
- OUT UINT32 *BufferSize
- )
- {
- EFI_STATUS Status;
- SHELL_FILE_HANDLE FileHandle;
- UINT64 Size;
- VOID *NewBuffer;
- UINTN ReadSize;
- FileHandle = NULL;
- NewBuffer = NULL;
- Size = 0;
- Status = ShellOpenFileByName (FileName, &FileHandle, EFI_FILE_MODE_READ, 0);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
- Status = FileHandleIsDirectory (FileHandle);
- if (!EFI_ERROR (Status)) {
- Status = EFI_NOT_FOUND;
- goto Done;
- }
- Status = FileHandleGetSize (FileHandle, &Size);
- if (EFI_ERROR (Status)) {
- goto Done;
- }
- NewBuffer = AllocatePool ((UINTN) Size);
- ReadSize = (UINTN) Size;
- Status = FileHandleRead (FileHandle, &ReadSize, NewBuffer);
- if (EFI_ERROR (Status)) {
- goto Done;
- } else if (ReadSize != (UINTN) Size) {
- Status = EFI_INVALID_PARAMETER;
- goto Done;
- }
- Done:
- if (FileHandle != NULL) {
- ShellCloseFile (&FileHandle);
- }
- if (EFI_ERROR (Status)) {
- if (NewBuffer != NULL) {
- FreePool (NewBuffer);
- }
- } else {
- *Buffer = NewBuffer;
- *BufferSize = (UINT32) Size;
- }
- return Status;
- }
- STATIC
- VOID
- PrintHelpInfo (
- VOID
- )
- /*++
- Routine Description:
- Print out help information.
- Arguments:
- None.
- Returns:
- None.
- --*/
- {
- PrintToken (STRING_TOKEN (STR_FWUPDATE_FIRMWARE_VOL_UPDATE), HiiHandle);
- PrintToken (STRING_TOKEN (STR_FWUPDATE_VERSION), HiiHandle);
- PrintToken (STRING_TOKEN (STR_FWUPDATE_COPYRIGHT), HiiHandle);
- Print (L"\n");
- PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE), HiiHandle);
- PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_1), HiiHandle);
- PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_2), HiiHandle);
- PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_3), HiiHandle);
- PrintToken (STRING_TOKEN (STR_FWUPDATE_USAGE_4), HiiHandle);
- Print (L"\n");
- }
- /**
- Read NumBytes bytes of data from the address specified by
- PAddress into Buffer.
- @param[in] Address The starting physical address of the read.
- @param[in,out] NumBytes On input, the number of bytes to read. On output, the number
- of bytes actually read.
- @param[out] Buffer The destination data buffer for the read.
- @retval EFI_SUCCESS Opertion is successful.
- @retval EFI_DEVICE_ERROR If there is any device errors.
- **/
- EFI_STATUS
- EFIAPI
- SpiFlashRead (
- IN UINTN Address,
- IN OUT UINT32 *NumBytes,
- OUT UINT8 *Buffer
- )
- {
- EFI_STATUS Status = EFI_SUCCESS;
- UINTN Offset = 0;
- ASSERT ((NumBytes != NULL) && (Buffer != NULL));
- Offset = Address - (UINTN)PcdGet32 (PcdFlashChipBase);
- Status = mSpiProtocol->Execute (
- mSpiProtocol,
- 1, //SPI_READ,
- 0, //SPI_WREN,
- TRUE,
- TRUE,
- FALSE,
- Offset,
- BLOCK_SIZE,
- Buffer,
- EnumSpiRegionAll
- );
- return Status;
- }
- /**
- Write NumBytes bytes of data from Buffer to the address specified by
- PAddresss.
- @param[in] Address The starting physical address of the write.
- @param[in,out] NumBytes On input, the number of bytes to write. On output,
- the actual number of bytes written.
- @param[in] Buffer The source data buffer for the write.
- @retval EFI_SUCCESS Opertion is successful.
- @retval EFI_DEVICE_ERROR If there is any device errors.
- **/
- EFI_STATUS
- EFIAPI
- SpiFlashWrite (
- IN UINTN Address,
- IN OUT UINT32 *NumBytes,
- IN UINT8 *Buffer
- )
- {
- EFI_STATUS Status;
- UINTN Offset;
- UINT32 Length;
- UINT32 RemainingBytes;
- ASSERT ((NumBytes != NULL) && (Buffer != NULL));
- ASSERT (Address >= (UINTN)PcdGet32 (PcdFlashChipBase));
- Offset = Address - (UINTN)PcdGet32 (PcdFlashChipBase);
- ASSERT ((*NumBytes + Offset) <= (UINTN)PcdGet32 (PcdFlashChipSize));
- Status = EFI_SUCCESS;
- RemainingBytes = *NumBytes;
- while (RemainingBytes > 0) {
- if (RemainingBytes > SIZE_4KB) {
- Length = SIZE_4KB;
- } else {
- Length = RemainingBytes;
- }
- Status = mSpiProtocol->Execute (
- mSpiProtocol,
- SPI_PROG,
- SPI_WREN,
- TRUE,
- TRUE,
- TRUE,
- (UINT32) Offset,
- Length,
- Buffer,
- EnumSpiRegionAll
- );
- if (EFI_ERROR (Status)) {
- break;
- }
- RemainingBytes -= Length;
- Offset += Length;
- Buffer += Length;
- }
- //
- // Actual number of bytes written.
- //
- *NumBytes -= RemainingBytes;
- return Status;
- }
- /**
- Erase the block starting at Address.
- @param[in] Address The starting physical address of the block to be erased.
- This library assume that caller garantee that the PAddress
- is at the starting address of this block.
- @param[in] NumBytes On input, the number of bytes of the logical block to be erased.
- On output, the actual number of bytes erased.
- @retval EFI_SUCCESS. Opertion is successful.
- @retval EFI_DEVICE_ERROR If there is any device errors.
- **/
- EFI_STATUS
- EFIAPI
- SpiFlashBlockErase (
- IN UINTN Address,
- IN UINTN *NumBytes
- )
- {
- EFI_STATUS Status;
- UINTN Offset;
- UINTN RemainingBytes;
- ASSERT (NumBytes != NULL);
- ASSERT (Address >= (UINTN)PcdGet32 (PcdFlashChipBase));
- Offset = Address - (UINTN)PcdGet32 (PcdFlashChipBase);
- ASSERT ((*NumBytes % SIZE_4KB) == 0);
- ASSERT ((*NumBytes + Offset) <= (UINTN)PcdGet32 (PcdFlashChipSize));
- Status = EFI_SUCCESS;
- RemainingBytes = *NumBytes;
- while (RemainingBytes > 0) {
- Status = mSpiProtocol->Execute (
- mSpiProtocol,
- SPI_SERASE,
- SPI_WREN,
- FALSE,
- TRUE,
- FALSE,
- (UINT32) Offset,
- 0,
- NULL,
- EnumSpiRegionAll
- );
- if (EFI_ERROR (Status)) {
- break;
- }
- RemainingBytes -= SIZE_4KB;
- Offset += SIZE_4KB;
- }
- //
- // Actual number of bytes erased.
- //
- *NumBytes -= RemainingBytes;
- return Status;
- }
- EFI_STATUS
- EFIAPI
- ConvertMac (
- CHAR16 *Str
- )
- {
- UINTN Index;
- UINT8 Temp[MAC_ADD_STR_LEN];
- if (Str == NULL)
- return EFI_INVALID_PARAMETER;
- if (StrLen(Str) != MAC_ADD_STR_LEN)
- return EFI_INVALID_PARAMETER;
- for (Index = 0; Index < MAC_ADD_STR_LEN; Index++) {
- if (Str[Index] >= 0x30 && Str[Index] <= 0x39) {
- Temp[Index] = (UINT8)Str[Index] - 0x30;
- } else if (Str[Index] >= 0x41 && Str[Index] <= 0x46) {
- Temp[Index] = (UINT8)Str[Index] - 0x37;
- } else if (Str[Index] >= 0x61 && Str[Index] <= 0x66) {
- Temp[Index] = (UINT8)Str[Index] - 0x57;
- } else {
- return EFI_INVALID_PARAMETER;
- }
- }
- for (Index = 0; Index < MAC_ADD_BYTE_COUNT; Index++) {
- mInputData.MacValue[Index] = (Temp[2 * Index] << 4) + Temp[2 * Index + 1];
- }
- return EFI_SUCCESS;
- }
|