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