Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to
https://svn.code.sf.net/p/edk2/code/trunk/edk2/, which are for MinnowBoard MAX open source project. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: David Wei <david.wei@intel.com> Reviewed-by: Mike Wu <mike.wu@intel.com> Reviewed-by: Hot Tian <hot.tian@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16599 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
927
Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.c
Normal file
927
Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.c
Normal file
@@ -0,0 +1,927 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
|
||||
the terms and conditions of the BSD License that accompanies this distribution.
|
||||
|
||||
The full text of the license may be found at
|
||||
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#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 004FFFFF 004FF000 TXE Region
|
||||
//00500000 007FFFFF 00300000 BIOS Region
|
||||
//
|
||||
FV_REGION_INFO mRegionInfo[] = {
|
||||
{FixedPcdGet32 (PcdFlashDescriptorBase), FixedPcdGet32 (PcdFlashDescriptorSize), TRUE},
|
||||
{FixedPcdGet32 (PcdTxeRomBase), FixedPcdGet32 (PcdTxeRomSize), TRUE},
|
||||
{FixedPcdGet32 (PcdBiosRomBase), FixedPcdGet32 (PcdBiosRomSize), TRUE}
|
||||
};
|
||||
|
||||
UINTN mRegionInfoCount = sizeof (mRegionInfo) / sizeof (mRegionInfo[0]);
|
||||
|
||||
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;
|
||||
}
|
190
Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.h
Normal file
190
Vlv2TbltDevicePkg/Application/FirmwareUpdate/FirmwareUpdate.h
Normal file
@@ -0,0 +1,190 @@
|
||||
/** @file
|
||||
|
||||
Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||
|
||||
|
||||
This program and the accompanying materials are licensed and made available under
|
||||
|
||||
the terms and conditions of the BSD License that accompanies this distribution.
|
||||
|
||||
The full text of the license may be found at
|
||||
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
|
||||
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _FIRMWARE_UPDATE_H_
|
||||
#define _FIRMWARE_UPDATE_H_
|
||||
|
||||
#include <Uefi.h>
|
||||
|
||||
#include <PiDxe.h>
|
||||
|
||||
#include <Guid/FileInfo.h>
|
||||
|
||||
#include <Protocol/FirmwareVolumeBlock.h>
|
||||
#include <Protocol/LoadedImage.h>
|
||||
#include <Protocol/SimpleFileSystem.h>
|
||||
#include <Protocol/Spi.h>
|
||||
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/CacheMaintenanceLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/FileHandleLib.h>
|
||||
#include <Library/HiiLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/ShellLib.h>
|
||||
#include <Library/UefiApplicationEntryPoint.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/UefiRuntimeServicesTableLib.h>
|
||||
|
||||
//
|
||||
// Function Prototypes.
|
||||
//
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
ReadFileData (
|
||||
IN CHAR16 *FileName,
|
||||
OUT UINT8 **Buffer,
|
||||
OUT UINT32 *BufferSize
|
||||
);
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
InternalEraseBlock (
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress
|
||||
);
|
||||
|
||||
#if 0
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
InternalReadBlock (
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
OUT VOID *ReadBuffer
|
||||
);
|
||||
#endif
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
InternalCompareBlock (
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT8 *Buffer
|
||||
);
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
InternalWriteBlock (
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT8 *Buffer,
|
||||
IN UINT32 BufferSize
|
||||
);
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
PrintHelpInfo (
|
||||
VOID
|
||||
);
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SpiFlashRead (
|
||||
IN UINTN Address,
|
||||
IN OUT UINT32 *NumBytes,
|
||||
OUT UINT8 *Buffer
|
||||
);
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SpiFlashWrite (
|
||||
IN UINTN Address,
|
||||
IN OUT UINT32 *NumBytes,
|
||||
IN UINT8 *Buffer
|
||||
);
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SpiFlashBlockErase (
|
||||
IN UINTN Address,
|
||||
IN UINTN *NumBytes
|
||||
);
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ConvertMac (
|
||||
CHAR16 *Str
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
InitializeFVUPDATE (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
);
|
||||
|
||||
//
|
||||
// Flash specific definitions.
|
||||
// - Should we use a PCD for this information?
|
||||
//
|
||||
#define BLOCK_SIZE SIZE_4KB
|
||||
|
||||
//
|
||||
// Flash region layout and update information.
|
||||
//
|
||||
typedef struct {
|
||||
EFI_PHYSICAL_ADDRESS Base;
|
||||
UINTN Size;
|
||||
BOOLEAN Update;
|
||||
} FV_REGION_INFO;
|
||||
|
||||
//
|
||||
// MAC Address information.
|
||||
//
|
||||
#define MAC_ADD_STR_LEN 12
|
||||
#define MAC_ADD_STR_SIZE (MAC_ADD_STR_LEN + 1)
|
||||
#define MAC_ADD_BYTE_COUNT 6
|
||||
#define MAC_ADD_TMP_STR_LEN 2
|
||||
#define MAC_ADD_TMP_STR_SIZE (MAC_ADD_TMP_STR_LEN + 1)
|
||||
|
||||
//
|
||||
// Command Line Data.
|
||||
//
|
||||
#define INPUT_STRING_LEN 255
|
||||
#define INPUT_STRING_SIZE (INPUT_STRING_LEN + 1)
|
||||
typedef struct {
|
||||
BOOLEAN UpdateFromFile;
|
||||
CHAR16 FileName[INPUT_STRING_SIZE];
|
||||
BOOLEAN UpdateMac;
|
||||
UINT8 MacValue[MAC_ADD_BYTE_COUNT];
|
||||
BOOLEAN FullFlashUpdate;
|
||||
} FV_INPUT_DATA;
|
||||
|
||||
//
|
||||
// Prefix Opcode Index on the host SPI controller.
|
||||
//
|
||||
typedef enum {
|
||||
SPI_WREN, // Prefix Opcode 0: Write Enable.
|
||||
SPI_EWSR, // Prefix Opcode 1: Enable Write Status Register.
|
||||
} PREFIX_OPCODE_INDEX;
|
||||
|
||||
//
|
||||
// Opcode Menu Index on the host SPI controller.
|
||||
//
|
||||
typedef enum {
|
||||
SPI_READ_ID, // Opcode 0: READ ID, Read cycle with address.
|
||||
SPI_READ, // Opcode 1: READ, Read cycle with address.
|
@@ -0,0 +1,90 @@
|
||||
## @file
|
||||
# Implements a Tunnel Mountain specific flash update program. This will allow
|
||||
# users to update all regions of the flash as needed in a given update.
|
||||
#
|
||||
# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
|
||||
# This program and the accompanying materials are licensed and made available under
|
||||
|
||||
# the terms and conditions of the BSD License that accompanies this distribution.
|
||||
|
||||
# The full text of the license may be found at
|
||||
|
||||
# http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
#
|
||||
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
#
|
||||
|
||||
#
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = FirmwareUpdate
|
||||
FILE_GUID = AEFAF26C-FB6D-4fef-AF7A-9D78FF201FCA
|
||||
MODULE_TYPE = UEFI_APPLICATION
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = ShellCEntryLib
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
FirmwareUpdateStrings.uni
|
||||
FirmwareUpdate.c
|
||||
FirmwareUpdate.h
|
||||
|
||||
[Packages]
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
MdePkg/MdePkg.dec
|
||||
IA32FamilyCpuPkg/IA32FamilyCpuPkg.dec
|
||||
Vlv2TbltDevicePkg/PlatformPkg.dec
|
||||
Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
|
||||
ShellPkg/ShellPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
BaseMemoryLib
|
||||
CacheMaintenanceLib
|
||||
DebugLib
|
||||
FileHandleLib
|
||||
#FlashDeviceLib
|
||||
#SpiFlashCommonLib
|
||||
MemoryAllocationLib
|
||||
PcdLib
|
||||
ShellCEntryLib
|
||||
ShellLib
|
||||
UefiApplicationEntryPoint
|
||||
UefiBootServicesTableLib
|
||||
UefiLib
|
||||
UefiRuntimeServicesTableLib
|
||||
|
||||
[Protocols]
|
||||
gEfiLoadedImageProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL ALWAYS_CONSUMED
|
||||
gEfiSpiProtocolGuid
|
||||
|
||||
[Pcd]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize ## CONSUMES
|
||||
|
||||
[FixedPcd]
|
||||
# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
|
||||
# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
|
||||
# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
|
||||
# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
|
||||
# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
|
||||
# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
|
||||
|
||||
gPlatformModuleTokenSpaceGuid.PcdFlashChipBase
|
||||
gPlatformModuleTokenSpaceGuid.PcdFlashChipSize
|
||||
gPlatformModuleTokenSpaceGuid.PcdFlashDescriptorBase
|
Binary file not shown.
Reference in New Issue
Block a user