From baa0b78e96b18ca463ca660eeefc9806fed8a164 Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Wed, 3 Aug 2016 10:19:29 +0800 Subject: BraswellPlatformPkg: Move Override to Common/Override Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang Reviewed-by: David Wei --- .../Library/GenericBdsLib/BdsBoot.c | 4497 ++++++++++++++++++++ .../Library/GenericBdsLib/BdsConnect.c | 435 ++ .../Library/GenericBdsLib/BdsConsole.c | 1301 ++++++ .../Library/GenericBdsLib/BdsMisc.c | 1589 +++++++ .../Library/GenericBdsLib/DevicePath.c | 33 + .../Library/GenericBdsLib/GenericBdsLib.inf | 144 + .../Library/GenericBdsLib/GenericBdsStrings.uni | 36 + .../Library/GenericBdsLib/InternalBdsLib.h | 194 + .../Library/GenericBdsLib/Performance.c | 358 ++ .../Library/GenericBdsLib/String.c | 32 + .../Library/GenericBdsLib/String.h | 48 + .../FspPlatformSecLibSample.c | 149 + .../Ia32/AsmSaveSecContext.S | 37 + .../Ia32/AsmSaveSecContext.asm | 44 + .../SecPeiFspPlatformSecLibSample/Ia32/Fsp.h | 49 + .../Ia32/PeiCoreEntry.S | 124 + .../Ia32/PeiCoreEntry.asm | 134 + .../SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S | 322 ++ .../Ia32/SecEntry.asm | 340 ++ .../SecPeiFspPlatformSecLibSample/Ia32/Stack.S | 74 + .../SecPeiFspPlatformSecLibSample/Ia32/Stack.asm | 80 + .../SecPeiFspPlatformSecLibSample/PlatformInit.c | 45 + .../SecPeiFspPlatformSecLibSample/SaveSecContext.c | 114 + .../SecGetPerformance.c | 89 + .../SecPeiFspPlatformSecLibSample.inf | 94 + .../SecPlatformInformation.c | 83 + .../SecPeiFspPlatformSecLibSample/SecRamInitData.c | 23 + .../SecTempRamSupport.c | 154 + .../BaseSerialPortLib16550.c | 1094 +++++ .../BaseSerialPortLib16550.inf | 48 + .../Library/GenericBdsLib/BdsBoot.c | 4497 -------------------- .../Library/GenericBdsLib/BdsConnect.c | 435 -- .../Library/GenericBdsLib/BdsConsole.c | 1301 ------ .../Library/GenericBdsLib/BdsMisc.c | 1589 ------- .../Library/GenericBdsLib/DevicePath.c | 33 - .../Library/GenericBdsLib/GenericBdsLib.inf | 144 - .../Library/GenericBdsLib/GenericBdsStrings.uni | 36 - .../Library/GenericBdsLib/InternalBdsLib.h | 194 - .../Library/GenericBdsLib/Performance.c | 358 -- .../Library/GenericBdsLib/String.c | 32 - .../Library/GenericBdsLib/String.h | 48 - .../FspPlatformSecLibSample.c | 149 - .../Ia32/AsmSaveSecContext.S | 37 - .../Ia32/AsmSaveSecContext.asm | 44 - .../SecPeiFspPlatformSecLibSample/Ia32/Fsp.h | 49 - .../Ia32/PeiCoreEntry.S | 124 - .../Ia32/PeiCoreEntry.asm | 134 - .../SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S | 322 -- .../Ia32/SecEntry.asm | 340 -- .../SecPeiFspPlatformSecLibSample/Ia32/Stack.S | 74 - .../SecPeiFspPlatformSecLibSample/Ia32/Stack.asm | 80 - .../SecPeiFspPlatformSecLibSample/PlatformInit.c | 45 - .../SecPeiFspPlatformSecLibSample/SaveSecContext.c | 114 - .../SecGetPerformance.c | 89 - .../SecPeiFspPlatformSecLibSample.inf | 94 - .../SecPlatformInformation.c | 83 - .../SecPeiFspPlatformSecLibSample/SecRamInitData.c | 23 - .../SecTempRamSupport.c | 154 - .../BaseSerialPortLib16550.c | 1094 ----- .../BaseSerialPortLib16550.inf | 48 - 60 files changed, 11764 insertions(+), 11764 deletions(-) create mode 100644 BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c create mode 100644 BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConnect.c create mode 100644 BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c create mode 100644 BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c create mode 100644 BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c create mode 100644 BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf create mode 100644 BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsStrings.uni create mode 100644 BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h create mode 100644 BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c create mode 100644 BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.c create mode 100644 BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.h create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c create mode 100644 BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c create mode 100644 BraswellPlatformPkg/Common/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c create mode 100644 BraswellPlatformPkg/Common/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf delete mode 100644 BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c delete mode 100644 BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConnect.c delete mode 100644 BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c delete mode 100644 BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c delete mode 100644 BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c delete mode 100644 BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf delete mode 100644 BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsStrings.uni delete mode 100644 BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h delete mode 100644 BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c delete mode 100644 BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.c delete mode 100644 BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.h delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c delete mode 100644 BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c delete mode 100644 BraswellPlatformPkg/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c delete mode 100644 BraswellPlatformPkg/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf diff --git a/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c new file mode 100644 index 0000000000..8edd9718d3 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c @@ -0,0 +1,4497 @@ +/** @file + BDS Lib functions which relate with create or process the boot option. + +Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which 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 "InternalBdsLib.h" +#include "String.h" + +BOOLEAN mEnumBootDevice = FALSE; +EFI_HII_HANDLE gBdsLibStringPackHandle = NULL; + +/** + The constructor function register UNI strings into imageHandle. + + It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor successfully added string package. + @retval Other value The constructor can't add string package. + +**/ +EFI_STATUS +EFIAPI +GenericBdsLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + + gBdsLibStringPackHandle = HiiAddPackages ( + &gBdsLibStringPackageGuid, + ImageHandle, + GenericBdsLibStrings, + NULL + ); + + ASSERT (gBdsLibStringPackHandle != NULL); + + return EFI_SUCCESS; +} + +/** + Deletete the Boot Option from EFI Variable. The Boot Order Arrray + is also updated. + + @param OptionNumber The number of Boot option want to be deleted. + @param BootOrder The Boot Order array. + @param BootOrderSize The size of the Boot Order Array. + + @retval EFI_SUCCESS The Boot Option Variable was found and removed + @retval EFI_UNSUPPORTED The Boot Option Variable store was inaccessible + @retval EFI_NOT_FOUND The Boot Option Variable was not found +**/ +EFI_STATUS +EFIAPI +BdsDeleteBootOption ( + IN UINTN OptionNumber, + IN OUT UINT16 *BootOrder, + IN OUT UINTN *BootOrderSize + ) +{ + CHAR16 BootOption[9]; + UINTN Index; + EFI_STATUS Status; + + UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber); + Status = gRT->SetVariable ( + BootOption, + &gEfiGlobalVariableGuid, + 0, + 0, + NULL + ); + // + // Deleting variable with existing variable implementation shouldn't fail. + // + ASSERT_EFI_ERROR (Status); + + // + // adjust boot order array + // + for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) { + if (BootOrder[Index] == OptionNumber) { + CopyMem (&BootOrder[Index], &BootOrder[Index+1], *BootOrderSize - (Index+1) * sizeof (UINT16)); + *BootOrderSize -= sizeof (UINT16); + break; + } + } + + return Status; +} +/** + + Translate the first n characters of an Ascii string to + Unicode characters. The count n is indicated by parameter + Size. If Size is greater than the length of string, then + the entire string is translated. + + + @param AStr Pointer to input Ascii string. + @param Size The number of characters to translate. + @param UStr Pointer to output Unicode string buffer. + +**/ +VOID +AsciiToUnicodeSize ( + IN UINT8 *AStr, + IN UINTN Size, + OUT UINT16 *UStr + ) +{ + UINTN Idx; + + Idx = 0; + while (AStr[Idx] != 0) { + UStr[Idx] = (CHAR16) AStr[Idx]; + if (Idx == Size) { + break; + } + + Idx++; + } + UStr[Idx] = 0; +} + +/** + Build Legacy Device Name String according. + + @param CurBBSEntry BBS Table. + @param Index Index. + @param BufSize The buffer size. + @param BootString The output string. + +**/ +VOID +BdsBuildLegacyDevNameString ( + IN BBS_TABLE *CurBBSEntry, + IN UINTN Index, + IN UINTN BufSize, + OUT CHAR16 *BootString + ) +{ + CHAR16 *Fmt; + CHAR16 *Type; + UINT8 *StringDesc; + CHAR16 Temp[80]; + + switch (Index) { + // + // Primary Master + // + case 1: + Fmt = L"Primary Master %s"; + break; + + // + // Primary Slave + // + case 2: + Fmt = L"Primary Slave %s"; + break; + + // + // Secondary Master + // + case 3: + Fmt = L"Secondary Master %s"; + break; + + // + // Secondary Slave + // + case 4: + Fmt = L"Secondary Slave %s"; + break; + + default: + Fmt = L"%s"; + break; + } + + switch (CurBBSEntry->DeviceType) { + case BBS_FLOPPY: + Type = L"Floppy"; + break; + + case BBS_HARDDISK: + Type = L"Harddisk"; + break; + + case BBS_CDROM: + Type = L"CDROM"; + break; + + case BBS_PCMCIA: + Type = L"PCMCIAe"; + break; + + case BBS_USB: + Type = L"USB"; + break; + + case BBS_EMBED_NETWORK: + Type = L"Network"; + break; + + case BBS_BEV_DEVICE: + Type = L"BEVe"; + break; + + case BBS_UNKNOWN: + default: + Type = L"Unknown"; + break; + } + // + // If current BBS entry has its description then use it. + // + StringDesc = (UINT8 *) (UINTN) ((CurBBSEntry->DescStringSegment << 4) + CurBBSEntry->DescStringOffset); + if (NULL != StringDesc) { + // + // Only get fisrt 32 characters, this is suggested by BBS spec + // + AsciiToUnicodeSize (StringDesc, 32, Temp); + Fmt = L"%s"; + Type = Temp; + } + + // + // BbsTable 16 entries are for onboard IDE. + // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11 + // + if (Index >= 5 && Index <= 16 && (CurBBSEntry->DeviceType == BBS_HARDDISK || CurBBSEntry->DeviceType == BBS_CDROM)) { + Fmt = L"%s %d"; + UnicodeSPrint (BootString, BufSize, Fmt, Type, Index - 5); + } else { + UnicodeSPrint (BootString, BufSize, Fmt, Type); + } +} + +/** + + Create a legacy boot option for the specified entry of + BBS table, save it as variable, and append it to the boot + order list. + + + @param CurrentBbsEntry Pointer to current BBS table. + @param CurrentBbsDevPath Pointer to the Device Path Protocol instance of BBS + @param Index Index of the specified entry in BBS table. + @param BootOrderList On input, the original boot order list. + On output, the new boot order list attached with the + created node. + @param BootOrderListSize On input, the original size of boot order list. + On output, the size of new boot order list. + + @retval EFI_SUCCESS Boot Option successfully created. + @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory. + @retval Other Error occurs while setting variable. + +**/ +EFI_STATUS +BdsCreateLegacyBootOption ( + IN BBS_TABLE *CurrentBbsEntry, + IN EFI_DEVICE_PATH_PROTOCOL *CurrentBbsDevPath, + IN UINTN Index, + IN OUT UINT16 **BootOrderList, + IN OUT UINTN *BootOrderListSize + ) +{ + EFI_STATUS Status; + UINT16 CurrentBootOptionNo; + UINT16 BootString[10]; + CHAR16 BootDesc[100]; + CHAR8 HelpString[100]; + UINT16 *NewBootOrderList; + UINTN BufferSize; + UINTN StringLen; + VOID *Buffer; + UINT8 *Ptr; + UINT16 CurrentBbsDevPathSize; + UINTN BootOrderIndex; + UINTN BootOrderLastIndex; + UINTN ArrayIndex; + BOOLEAN IndexNotFound; + BBS_BBS_DEVICE_PATH *NewBbsDevPathNode; + + if ((*BootOrderList) == NULL) { + CurrentBootOptionNo = 0; + } else { + for (ArrayIndex = 0; ArrayIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); ArrayIndex++) { + IndexNotFound = TRUE; + for (BootOrderIndex = 0; BootOrderIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); BootOrderIndex++) { + if ((*BootOrderList)[BootOrderIndex] == ArrayIndex) { + IndexNotFound = FALSE; + break; + } + } + + if (!IndexNotFound) { + continue; + } else { + break; + } + } + + CurrentBootOptionNo = (UINT16) ArrayIndex; + } + + UnicodeSPrint ( + BootString, + sizeof (BootString), + L"Boot%04x", + CurrentBootOptionNo + ); + + BdsBuildLegacyDevNameString (CurrentBbsEntry, Index, sizeof (BootDesc), BootDesc); + + // + // Create new BBS device path node with description string + // + UnicodeStrToAsciiStr (BootDesc, HelpString); + + StringLen = AsciiStrLen (HelpString); + NewBbsDevPathNode = AllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH) + StringLen); + if (NewBbsDevPathNode == NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyMem (NewBbsDevPathNode, CurrentBbsDevPath, sizeof (BBS_BBS_DEVICE_PATH)); + CopyMem (NewBbsDevPathNode->String, HelpString, StringLen + 1); + SetDevicePathNodeLength (&(NewBbsDevPathNode->Header), sizeof (BBS_BBS_DEVICE_PATH) + StringLen); + + // + // Create entire new CurrentBbsDevPath with end node + // + CurrentBbsDevPath = AppendDevicePathNode ( + NULL, + (EFI_DEVICE_PATH_PROTOCOL *) NewBbsDevPathNode + ); + if (CurrentBbsDevPath == NULL) { + FreePool (NewBbsDevPathNode); + return EFI_OUT_OF_RESOURCES; + } + + CurrentBbsDevPathSize = (UINT16) (GetDevicePathSize (CurrentBbsDevPath)); + + BufferSize = sizeof (UINT32) + + sizeof (UINT16) + + StrSize (BootDesc) + + CurrentBbsDevPathSize + + sizeof (BBS_TABLE) + + sizeof (UINT16); + + Buffer = AllocateZeroPool (BufferSize); + if (Buffer == NULL) { + FreePool (NewBbsDevPathNode); + FreePool (CurrentBbsDevPath); + return EFI_OUT_OF_RESOURCES; + } + + Ptr = (UINT8 *) Buffer; + + *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE; + Ptr += sizeof (UINT32); + + *((UINT16 *) Ptr) = CurrentBbsDevPathSize; + Ptr += sizeof (UINT16); + + CopyMem ( + Ptr, + BootDesc, + StrSize (BootDesc) + ); + Ptr += StrSize (BootDesc); + + CopyMem ( + Ptr, + CurrentBbsDevPath, + CurrentBbsDevPathSize + ); + Ptr += CurrentBbsDevPathSize; + + CopyMem ( + Ptr, + CurrentBbsEntry, + sizeof (BBS_TABLE) + ); + + Ptr += sizeof (BBS_TABLE); + *((UINT16 *) Ptr) = (UINT16) Index; + + Status = gRT->SetVariable ( + BootString, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + BufferSize, + Buffer + ); + + FreePool (Buffer); + + Buffer = NULL; + + NewBootOrderList = AllocateZeroPool (*BootOrderListSize + sizeof (UINT16)); + if (NULL == NewBootOrderList) { + FreePool (NewBbsDevPathNode); + FreePool (CurrentBbsDevPath); + return EFI_OUT_OF_RESOURCES; + } + + if (*BootOrderList != NULL) { + CopyMem (NewBootOrderList, *BootOrderList, *BootOrderListSize); + FreePool (*BootOrderList); + } + + BootOrderLastIndex = (UINTN) (*BootOrderListSize / sizeof (UINT16)); + NewBootOrderList[BootOrderLastIndex] = CurrentBootOptionNo; + *BootOrderListSize += sizeof (UINT16); + *BootOrderList = NewBootOrderList; + + FreePool (NewBbsDevPathNode); + FreePool (CurrentBbsDevPath); + return Status; +} + +/** + Check if the boot option is a legacy one. + + @param BootOptionVar The boot option data payload. + @param BbsEntry The BBS Table. + @param BbsIndex The table index. + + @retval TRUE It is a legacy boot option. + @retval FALSE It is not a legacy boot option. + +**/ +BOOLEAN +BdsIsLegacyBootOption ( + IN UINT8 *BootOptionVar, + OUT BBS_TABLE **BbsEntry, + OUT UINT16 *BbsIndex + ) +{ + UINT8 *Ptr; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + BOOLEAN Ret; + UINT16 DevPathLen; + + Ptr = BootOptionVar; + Ptr += sizeof (UINT32); + DevPathLen = *(UINT16 *) Ptr; + Ptr += sizeof (UINT16); + Ptr += StrSize ((UINT16 *) Ptr); + DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr; + if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) { + Ptr += DevPathLen; + *BbsEntry = (BBS_TABLE *) Ptr; + Ptr += sizeof (BBS_TABLE); + *BbsIndex = *(UINT16 *) Ptr; + Ret = TRUE; + } else { + *BbsEntry = NULL; + Ret = FALSE; + } + + return Ret; +} + +/** + Delete all the invalid legacy boot options. + + @retval EFI_SUCCESS All invalide legacy boot options are deleted. + @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory. + @retval EFI_NOT_FOUND Fail to retrive variable of boot order. +**/ +EFI_STATUS +EFIAPI +BdsDeleteAllInvalidLegacyBootOptions ( + VOID + ) +{ + UINT16 *BootOrder; + UINT8 *BootOptionVar; + UINTN BootOrderSize; + UINTN BootOptionSize; + EFI_STATUS Status; + UINT16 HddCount; + UINT16 BbsCount; + HDD_INFO *LocalHddInfo; + BBS_TABLE *LocalBbsTable; + BBS_TABLE *BbsEntry; + UINT16 BbsIndex; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + UINTN Index; + UINT16 BootOption[10]; + UINT16 BootDesc[100]; + BOOLEAN DescStringMatch; + + Status = EFI_SUCCESS; + BootOrder = NULL; + BootOrderSize = 0; + HddCount = 0; + BbsCount = 0; + LocalHddInfo = NULL; + LocalBbsTable = NULL; + BbsEntry = NULL; + + Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); + if (EFI_ERROR (Status)) { + return Status; + } + + BootOrder = BdsLibGetVariableAndSize ( + L"BootOrder", + &gEfiGlobalVariableGuid, + &BootOrderSize + ); + if (BootOrder == NULL) { + return EFI_NOT_FOUND; + } + + LegacyBios->GetBbsInfo ( + LegacyBios, + &HddCount, + &LocalHddInfo, + &BbsCount, + &LocalBbsTable + ); + + Index = 0; + while (Index < BootOrderSize / sizeof (UINT16)) { + UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]); + BootOptionVar = BdsLibGetVariableAndSize ( + BootOption, + &gEfiGlobalVariableGuid, + &BootOptionSize + ); + if (NULL == BootOptionVar) { + BootOptionSize = 0; + Status = gRT->GetVariable ( + BootOption, + &gEfiGlobalVariableGuid, + NULL, + &BootOptionSize, + BootOptionVar + ); + if (Status == EFI_NOT_FOUND) { + // + // Update BootOrder + // + BdsDeleteBootOption ( + BootOrder[Index], + BootOrder, + &BootOrderSize + ); + continue; + } else { + FreePool (BootOrder); + return EFI_OUT_OF_RESOURCES; + } + } + + // + // Skip Non-Legacy boot option + // + if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, &BbsIndex)) { + if (BootOptionVar!= NULL) { + FreePool (BootOptionVar); + } + Index++; + continue; + } + + if (BbsIndex < BbsCount) { + // + // Check if BBS Description String is changed + // + DescStringMatch = FALSE; + BdsBuildLegacyDevNameString ( + &LocalBbsTable[BbsIndex], + BbsIndex, + sizeof (BootDesc), + BootDesc + ); + + if (StrCmp (BootDesc, (UINT16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) == 0) { + DescStringMatch = TRUE; + } + + if (!((LocalBbsTable[BbsIndex].BootPriority == BBS_IGNORE_ENTRY) || + (LocalBbsTable[BbsIndex].BootPriority == BBS_DO_NOT_BOOT_FROM)) && + (LocalBbsTable[BbsIndex].DeviceType == BbsEntry->DeviceType) && + DescStringMatch) { + Index++; + continue; + } + } + + if (BootOptionVar != NULL) { + FreePool (BootOptionVar); + } + // + // should delete + // + BdsDeleteBootOption ( + BootOrder[Index], + BootOrder, + &BootOrderSize + ); + } + + // + // Adjust the number of boot options. + // + Status = gRT->SetVariable ( + L"BootOrder", + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + BootOrderSize, + BootOrder + ); + // + // Shrinking variable with existing variable implementation shouldn't fail. + // + ASSERT_EFI_ERROR (Status); + FreePool (BootOrder); + + return Status; +} + +/** + Find all legacy boot option by device type. + + @param BootOrder The boot order array. + @param BootOptionNum The number of boot option. + @param DevType Device type. + @param DevName Device name. + @param Attribute The boot option attribute. + @param BbsIndex The BBS table index. + @param OptionNumber The boot option index. + + @retval TRUE The Legacy boot option is found. + @retval FALSE The legacy boot option is not found. + +**/ +BOOLEAN +BdsFindLegacyBootOptionByDevTypeAndName ( + IN UINT16 *BootOrder, + IN UINTN BootOptionNum, + IN UINT16 DevType, + IN CHAR16 *DevName, + OUT UINT32 *Attribute, + OUT UINT16 *BbsIndex, + OUT UINT16 *OptionNumber + ) +{ + UINTN Index; + CHAR16 BootOption[9]; + UINTN BootOptionSize; + UINT8 *BootOptionVar; + BBS_TABLE *BbsEntry; + BOOLEAN Found; + + BbsEntry = NULL; + Found = FALSE; + + if (NULL == BootOrder) { + return Found; + } + + // + // Loop all boot option from variable + // + for (Index = 0; Index < BootOptionNum; Index++) { + UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", (UINTN) BootOrder[Index]); + BootOptionVar = BdsLibGetVariableAndSize ( + BootOption, + &gEfiGlobalVariableGuid, + &BootOptionSize + ); + if (NULL == BootOptionVar) { + continue; + } + + // + // Skip Non-legacy boot option + // + if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, BbsIndex)) { + FreePool (BootOptionVar); + continue; + } + + if ( + (BbsEntry->DeviceType != DevType) || + (StrCmp (DevName, (CHAR16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) != 0) + ) { + FreePool (BootOptionVar); + continue; + } + + *Attribute = *(UINT32 *) BootOptionVar; + *OptionNumber = BootOrder[Index]; + Found = TRUE; + FreePool (BootOptionVar); + break; + } + + return Found; +} + +/** + Create a legacy boot option. + + @param BbsItem The BBS Table entry. + @param Index Index of the specified entry in BBS table. + @param BootOrderList The boot order list. + @param BootOrderListSize The size of boot order list. + + @retval EFI_OUT_OF_RESOURCE No enough memory. + @retval EFI_SUCCESS The function complete successfully. + @return Other value if the legacy boot option is not created. + +**/ +EFI_STATUS +BdsCreateOneLegacyBootOption ( + IN BBS_TABLE *BbsItem, + IN UINTN Index, + IN OUT UINT16 **BootOrderList, + IN OUT UINTN *BootOrderListSize + ) +{ + BBS_BBS_DEVICE_PATH BbsDevPathNode; + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevPath; + + DevPath = NULL; + + // + // Create device path node. + // + BbsDevPathNode.Header.Type = BBS_DEVICE_PATH; + BbsDevPathNode.Header.SubType = BBS_BBS_DP; + SetDevicePathNodeLength (&BbsDevPathNode.Header, sizeof (BBS_BBS_DEVICE_PATH)); + BbsDevPathNode.DeviceType = BbsItem->DeviceType; + CopyMem (&BbsDevPathNode.StatusFlag, &BbsItem->StatusFlags, sizeof (UINT16)); + + DevPath = AppendDevicePathNode ( + NULL, + (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevPathNode + ); + if (NULL == DevPath) { + return EFI_OUT_OF_RESOURCES; + } + + Status = BdsCreateLegacyBootOption ( + BbsItem, + DevPath, + Index, + BootOrderList, + BootOrderListSize + ); + BbsItem->BootPriority = 0x00; + + FreePool (DevPath); + + return Status; +} + +/** + Add the legacy boot options from BBS table if they do not exist. + + @retval EFI_SUCCESS The boot options are added successfully + or they are already in boot options. + @retval EFI_NOT_FOUND No legacy boot options is found. + @retval EFI_OUT_OF_RESOURCE No enough memory. + @return Other value LegacyBoot options are not added. +**/ +EFI_STATUS +EFIAPI +BdsAddNonExistingLegacyBootOptions ( + VOID + ) +{ + UINT16 *BootOrder; + UINTN BootOrderSize; + EFI_STATUS Status; + CHAR16 Desc[100]; + UINT16 HddCount; + UINT16 BbsCount; + HDD_INFO *LocalHddInfo; + BBS_TABLE *LocalBbsTable; + UINT16 BbsIndex; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + UINT16 Index; + UINT32 Attribute; + UINT16 OptionNumber; + BOOLEAN Exist; + + HddCount = 0; + BbsCount = 0; + LocalHddInfo = NULL; + LocalBbsTable = NULL; + + Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); + if (EFI_ERROR (Status)) { + return Status; + } + + LegacyBios->GetBbsInfo ( + LegacyBios, + &HddCount, + &LocalHddInfo, + &BbsCount, + &LocalBbsTable + ); + + BootOrder = BdsLibGetVariableAndSize ( + L"BootOrder", + &gEfiGlobalVariableGuid, + &BootOrderSize + ); + if (BootOrder == NULL) { + BootOrderSize = 0; + } + + for (Index = 0; Index < BbsCount; Index++) { + if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) || + (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) + ) { + continue; + } + + BdsBuildLegacyDevNameString (&LocalBbsTable[Index], Index, sizeof (Desc), Desc); + + Exist = BdsFindLegacyBootOptionByDevTypeAndName ( + BootOrder, + BootOrderSize / sizeof (UINT16), + LocalBbsTable[Index].DeviceType, + Desc, + &Attribute, + &BbsIndex, + &OptionNumber + ); + if (!Exist) { + // + // Not found such type of legacy device in boot options or we found but it's disabled + // so we have to create one and put it to the tail of boot order list + // + Status = BdsCreateOneLegacyBootOption ( + &LocalBbsTable[Index], + Index, + &BootOrder, + &BootOrderSize + ); + if (!EFI_ERROR (Status)) { + ASSERT (BootOrder != NULL); + BbsIndex = Index; + OptionNumber = BootOrder[BootOrderSize / sizeof (UINT16) - 1]; + } + } + + ASSERT (BbsIndex == Index); + } + + Status = gRT->SetVariable ( + L"BootOrder", + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + BootOrderSize, + BootOrder + ); + if (BootOrder != NULL) { + FreePool (BootOrder); + } + + return Status; +} + +/** + Fill the device order buffer. + + @param BbsTable The BBS table. + @param BbsType The BBS Type. + @param BbsCount The BBS Count. + @param Buf device order buffer. + + @return The device order buffer. + +**/ +UINT16 * +BdsFillDevOrderBuf ( + IN BBS_TABLE *BbsTable, + IN BBS_TYPE BbsType, + IN UINTN BbsCount, + OUT UINT16 *Buf + ) +{ + UINTN Index; + + for (Index = 0; Index < BbsCount; Index++) { + if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) { + continue; + } + + if (BbsTable[Index].DeviceType != BbsType) { + continue; + } + + *Buf = (UINT16) (Index & 0xFF); + Buf++; + } + + return Buf; +} + +/** + Create the device order buffer. + + @param BbsTable The BBS table. + @param BbsCount The BBS Count. + + @retval EFI_SUCCES The buffer is created and the EFI variable named + VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid is + set correctly. + @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough. + @retval EFI_DEVICE_ERROR Fail to add the device order into EFI variable fail + because of hardware error. +**/ +EFI_STATUS +BdsCreateDevOrder ( + IN BBS_TABLE *BbsTable, + IN UINT16 BbsCount + ) +{ + UINTN Index; + UINTN FDCount; + UINTN HDCount; + UINTN CDCount; + UINTN NETCount; + UINTN BEVCount; + UINTN TotalSize; + UINTN HeaderSize; + LEGACY_DEV_ORDER_ENTRY *DevOrder; + LEGACY_DEV_ORDER_ENTRY *DevOrderPtr; + EFI_STATUS Status; + + FDCount = 0; + HDCount = 0; + CDCount = 0; + NETCount = 0; + BEVCount = 0; + TotalSize = 0; + HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16); + DevOrder = NULL; + Status = EFI_SUCCESS; + + // + // Count all boot devices + // + for (Index = 0; Index < BbsCount; Index++) { + if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) { + continue; + } + + switch (BbsTable[Index].DeviceType) { + case BBS_FLOPPY: + FDCount++; + break; + + case BBS_HARDDISK: + HDCount++; + break; + + case BBS_CDROM: + CDCount++; + break; + + case BBS_EMBED_NETWORK: + NETCount++; + break; + + case BBS_BEV_DEVICE: + BEVCount++; + break; + + default: + break; + } + } + + TotalSize += (HeaderSize + sizeof (UINT16) * FDCount); + TotalSize += (HeaderSize + sizeof (UINT16) * HDCount); + TotalSize += (HeaderSize + sizeof (UINT16) * CDCount); + TotalSize += (HeaderSize + sizeof (UINT16) * NETCount); + TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount); + + // + // Create buffer to hold all boot device order + // + DevOrder = AllocateZeroPool (TotalSize); + if (NULL == DevOrder) { + return EFI_OUT_OF_RESOURCES; + } + DevOrderPtr = DevOrder; + + DevOrderPtr->BbsType = BBS_FLOPPY; + DevOrderPtr->Length = (UINT16) (sizeof (DevOrderPtr->Length) + FDCount * sizeof (UINT16)); + DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, DevOrderPtr->Data); + + DevOrderPtr->BbsType = BBS_HARDDISK; + DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16)); + DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, DevOrderPtr->Data); + + DevOrderPtr->BbsType = BBS_CDROM; + DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16)); + DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, DevOrderPtr->Data); + + DevOrderPtr->BbsType = BBS_EMBED_NETWORK; + DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16)); + DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, DevOrderPtr->Data); + + DevOrderPtr->BbsType = BBS_BEV_DEVICE; + DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16)); + DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, DevOrderPtr->Data); + + ASSERT (TotalSize == (UINTN) ((UINT8 *) DevOrderPtr - (UINT8 *) DevOrder)); + + // + // Save device order for legacy boot device to variable. + // + Status = gRT->SetVariable ( + VAR_LEGACY_DEV_ORDER, + &gEfiLegacyDevOrderVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, + TotalSize, + DevOrder + ); + FreePool (DevOrder); + + return Status; +} + +/** + Add the legacy boot devices from BBS table into + the legacy device boot order. + + @retval EFI_SUCCESS The boot devices are added successfully. + @retval EFI_NOT_FOUND The legacy boot devices are not found. + @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough. + @retval EFI_DEVICE_ERROR Fail to add the legacy device boot order into EFI variable + because of hardware error. +**/ +EFI_STATUS +EFIAPI +BdsUpdateLegacyDevOrder ( + VOID + ) +{ + LEGACY_DEV_ORDER_ENTRY *DevOrder; + LEGACY_DEV_ORDER_ENTRY *NewDevOrder; + LEGACY_DEV_ORDER_ENTRY *Ptr; + LEGACY_DEV_ORDER_ENTRY *NewPtr; + UINTN DevOrderSize; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + EFI_STATUS Status; + UINT16 HddCount; + UINT16 BbsCount; + HDD_INFO *LocalHddInfo; + BBS_TABLE *LocalBbsTable; + UINTN Index; + UINTN Index2; + UINTN *Idx; + UINTN FDCount; + UINTN HDCount; + UINTN CDCount; + UINTN NETCount; + UINTN BEVCount; + UINTN TotalSize; + UINTN HeaderSize; + UINT16 *NewFDPtr; + UINT16 *NewHDPtr; + UINT16 *NewCDPtr; + UINT16 *NewNETPtr; + UINT16 *NewBEVPtr; + UINT16 *NewDevPtr; + UINTN FDIndex; + UINTN HDIndex; + UINTN CDIndex; + UINTN NETIndex; + UINTN BEVIndex; + + Idx = NULL; + FDCount = 0; + HDCount = 0; + CDCount = 0; + NETCount = 0; + BEVCount = 0; + TotalSize = 0; + HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16); + FDIndex = 0; + HDIndex = 0; + CDIndex = 0; + NETIndex = 0; + BEVIndex = 0; + NewDevPtr = NULL; + + Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = LegacyBios->GetBbsInfo ( + LegacyBios, + &HddCount, + &LocalHddInfo, + &BbsCount, + &LocalBbsTable + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DevOrder = BdsLibGetVariableAndSize ( + VAR_LEGACY_DEV_ORDER, + &gEfiLegacyDevOrderVariableGuid, + &DevOrderSize + ); + if (NULL == DevOrder) { + return BdsCreateDevOrder (LocalBbsTable, BbsCount); + } + // + // First we figure out how many boot devices with same device type respectively + // + for (Index = 0; Index < BbsCount; Index++) { + if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) || + (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) + ) { + continue; + } + + switch (LocalBbsTable[Index].DeviceType) { + case BBS_FLOPPY: + FDCount++; + break; + + case BBS_HARDDISK: + HDCount++; + break; + + case BBS_CDROM: + CDCount++; + break; + + case BBS_EMBED_NETWORK: + NETCount++; + break; + + case BBS_BEV_DEVICE: + BEVCount++; + break; + + default: + break; + } + } + + TotalSize += (HeaderSize + FDCount * sizeof (UINT16)); + TotalSize += (HeaderSize + HDCount * sizeof (UINT16)); + TotalSize += (HeaderSize + CDCount * sizeof (UINT16)); + TotalSize += (HeaderSize + NETCount * sizeof (UINT16)); + TotalSize += (HeaderSize + BEVCount * sizeof (UINT16)); + + NewDevOrder = AllocateZeroPool (TotalSize); + if (NULL == NewDevOrder) { + return EFI_OUT_OF_RESOURCES; + } + + + + // + // copy FD + // + Ptr = DevOrder; + NewPtr = NewDevOrder; + NewPtr->BbsType = Ptr->BbsType; + NewPtr->Length = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16)); + for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { + if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || + LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_FLOPPY + ) { + continue; + } + + NewPtr->Data[FDIndex] = Ptr->Data[Index]; + FDIndex++; + } + NewFDPtr = NewPtr->Data; + + // + // copy HD + // + Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); + NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); + NewPtr->BbsType = Ptr->BbsType; + NewPtr->Length = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16)); + for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { + if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_HARDDISK + ) { + continue; + } + + NewPtr->Data[HDIndex] = Ptr->Data[Index]; + HDIndex++; + } + NewHDPtr = NewPtr->Data; + + // + // copy CD + // + Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); + NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); + NewPtr->BbsType = Ptr->BbsType; + NewPtr->Length = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16)); + for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { + if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_CDROM + ) { + continue; + } + + NewPtr->Data[CDIndex] = Ptr->Data[Index]; + CDIndex++; + } + NewCDPtr = NewPtr->Data; + + // + // copy NET + // + Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); + NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); + NewPtr->BbsType = Ptr->BbsType; + NewPtr->Length = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16)); + for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { + if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_EMBED_NETWORK + ) { + continue; + } + + NewPtr->Data[NETIndex] = Ptr->Data[Index]; + NETIndex++; + } + NewNETPtr = NewPtr->Data; + + // + // copy BEV + // + Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); + NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); + NewPtr->BbsType = Ptr->BbsType; + NewPtr->Length = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16)); + for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { + if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || + LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || + LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_BEV_DEVICE + ) { + continue; + } + + NewPtr->Data[BEVIndex] = Ptr->Data[Index]; + BEVIndex++; + } + NewBEVPtr = NewPtr->Data; + + for (Index = 0; Index < BbsCount; Index++) { + if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) || + (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) + ) { + continue; + } + + switch (LocalBbsTable[Index].DeviceType) { + case BBS_FLOPPY: + Idx = &FDIndex; + NewDevPtr = NewFDPtr; + break; + + case BBS_HARDDISK: + Idx = &HDIndex; + NewDevPtr = NewHDPtr; + break; + + case BBS_CDROM: + Idx = &CDIndex; + NewDevPtr = NewCDPtr; + break; + + case BBS_EMBED_NETWORK: + Idx = &NETIndex; + NewDevPtr = NewNETPtr; + break; + + case BBS_BEV_DEVICE: + Idx = &BEVIndex; + NewDevPtr = NewBEVPtr; + break; + + default: + Idx = NULL; + break; + } + // + // at this point we have copied those valid indexes to new buffer + // and we should check if there is any new appeared boot device + // + if (Idx != NULL) { + for (Index2 = 0; Index2 < *Idx; Index2++) { + if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) { + break; + } + } + + if (Index2 == *Idx) { + // + // Index2 == *Idx means we didn't find Index + // so Index is a new appeared device's index in BBS table + // insert it before disabled indexes. + // + for (Index2 = 0; Index2 < *Idx; Index2++) { + if ((NewDevPtr[Index2] & 0xFF00) == 0xFF00) { + break; + } + } + CopyMem (&NewDevPtr[Index2 + 1], &NewDevPtr[Index2], (*Idx - Index2) * sizeof (UINT16)); + NewDevPtr[Index2] = (UINT16) (Index & 0xFF); + (*Idx)++; + } + } + } + + FreePool (DevOrder); + + Status = gRT->SetVariable ( + VAR_LEGACY_DEV_ORDER, + &gEfiLegacyDevOrderVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, + TotalSize, + NewDevOrder + ); + FreePool (NewDevOrder); + + return Status; +} + +/** + Set Boot Priority for specified device type. + + @param DeviceType The device type. + @param BbsIndex The BBS index to set the highest priority. Ignore when -1. + @param LocalBbsTable The BBS table. + @param Priority The prority table. + + @retval EFI_SUCCESS The function completes successfully. + @retval EFI_NOT_FOUND Failed to find device. + @retval EFI_OUT_OF_RESOURCES Failed to get the efi variable of device order. + +**/ +EFI_STATUS +BdsSetBootPriority4SameTypeDev ( + IN UINT16 DeviceType, + IN UINTN BbsIndex, + IN OUT BBS_TABLE *LocalBbsTable, + IN OUT UINT16 *Priority + ) +{ + LEGACY_DEV_ORDER_ENTRY *DevOrder; + LEGACY_DEV_ORDER_ENTRY *DevOrderPtr; + UINTN DevOrderSize; + UINTN Index; + + DevOrder = BdsLibGetVariableAndSize ( + VAR_LEGACY_DEV_ORDER, + &gEfiLegacyDevOrderVariableGuid, + &DevOrderSize + ); + if (NULL == DevOrder) { + return EFI_OUT_OF_RESOURCES; + } + + DevOrderPtr = DevOrder; + while ((UINT8 *) DevOrderPtr < (UINT8 *) DevOrder + DevOrderSize) { + if (DevOrderPtr->BbsType == DeviceType) { + break; + } + + DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) ((UINTN) DevOrderPtr + sizeof (BBS_TYPE) + DevOrderPtr->Length); + } + + if ((UINT8 *) DevOrderPtr >= (UINT8 *) DevOrder + DevOrderSize) { + FreePool (DevOrder); + return EFI_NOT_FOUND; + } + + if (BbsIndex != (UINTN) -1) { + LocalBbsTable[BbsIndex].BootPriority = *Priority; + (*Priority)++; + } + // + // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled. + // + for (Index = 0; Index < DevOrderPtr->Length / sizeof (UINT16) - 1; Index++) { + if ((DevOrderPtr->Data[Index] & 0xFF00) == 0xFF00) { + // + // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY; + // + } else if (DevOrderPtr->Data[Index] != BbsIndex) { + LocalBbsTable[DevOrderPtr->Data[Index]].BootPriority = *Priority; + (*Priority)++; + } + } + + FreePool (DevOrder); + return EFI_SUCCESS; +} + +/** + Print the BBS Table. + + @param LocalBbsTable The BBS table. + @param BbsCount The count of entry in BBS table. +**/ +VOID +PrintBbsTable ( + IN BBS_TABLE *LocalBbsTable, + IN UINT16 BbsCount + ) +{ + UINT16 Idx; + + DEBUG ((DEBUG_ERROR, "\n")); + DEBUG ((DEBUG_ERROR, " NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n")); + DEBUG ((DEBUG_ERROR, "=============================================\n")); + for (Idx = 0; Idx < BbsCount; Idx++) { + if ((LocalBbsTable[Idx].BootPriority == BBS_IGNORE_ENTRY) || + (LocalBbsTable[Idx].BootPriority == BBS_DO_NOT_BOOT_FROM) || + (LocalBbsTable[Idx].BootPriority == BBS_LOWEST_PRIORITY) + ) { + continue; + } + + DEBUG ( + (DEBUG_ERROR, + " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n", + (UINTN) Idx, + (UINTN) LocalBbsTable[Idx].BootPriority, + (UINTN) LocalBbsTable[Idx].Bus, + (UINTN) LocalBbsTable[Idx].Device, + (UINTN) LocalBbsTable[Idx].Function, + (UINTN) LocalBbsTable[Idx].Class, + (UINTN) LocalBbsTable[Idx].SubClass, + (UINTN) LocalBbsTable[Idx].DeviceType, + (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags, + (UINTN) LocalBbsTable[Idx].BootHandlerSegment, + (UINTN) LocalBbsTable[Idx].BootHandlerOffset, + (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset), + (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset)) + ); + } + + DEBUG ((DEBUG_ERROR, "\n")); +} + +/** + Set the boot priority for BBS entries based on boot option entry and boot order. + + @param Entry The boot option is to be checked for refresh BBS table. + + @retval EFI_SUCCESS The boot priority for BBS entries is refreshed successfully. + @retval EFI_NOT_FOUND BBS entries can't be found. + @retval EFI_OUT_OF_RESOURCES Failed to get the legacy device boot order. +**/ +EFI_STATUS +EFIAPI +BdsRefreshBbsTableForBoot ( + IN BDS_COMMON_OPTION *Entry + ) +{ + EFI_STATUS Status; + UINT16 BbsIndex; + UINT16 HddCount; + UINT16 BbsCount; + HDD_INFO *LocalHddInfo; + BBS_TABLE *LocalBbsTable; + UINT16 DevType; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + UINTN Index; + UINT16 Priority; + UINT16 *BootOrder; + UINTN BootOrderSize; + UINT8 *BootOptionVar; + UINTN BootOptionSize; + CHAR16 BootOption[9]; + UINT8 *Ptr; + UINT16 DevPathLen; + EFI_DEVICE_PATH_PROTOCOL *DevPath; + UINT16 *DeviceType; + UINTN DeviceTypeCount; + UINTN DeviceTypeIndex; + + HddCount = 0; + BbsCount = 0; + LocalHddInfo = NULL; + LocalBbsTable = NULL; + DevType = BBS_UNKNOWN; + + Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); + if (EFI_ERROR (Status)) { + return Status; + } + + LegacyBios->GetBbsInfo ( + LegacyBios, + &HddCount, + &LocalHddInfo, + &BbsCount, + &LocalBbsTable + ); + // + // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY + // We will set them according to the settings setup by user + // + for (Index = 0; Index < BbsCount; Index++) { + if (!((BBS_IGNORE_ENTRY == LocalBbsTable[Index].BootPriority) || + (BBS_DO_NOT_BOOT_FROM == LocalBbsTable[Index].BootPriority) || + (BBS_LOWEST_PRIORITY == LocalBbsTable[Index].BootPriority))) { + LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY; + } + } + // + // boot priority always starts at 0 + // + Priority = 0; + if (Entry->LoadOptionsSize == sizeof (BBS_TABLE) + sizeof (UINT16)) { + // + // If Entry stands for a legacy boot option, we prioritize the devices with the same type first. + // + DevType = ((BBS_TABLE *) Entry->LoadOptions)->DeviceType; + BbsIndex = *(UINT16 *) ((BBS_TABLE *) Entry->LoadOptions + 1); + Status = BdsSetBootPriority4SameTypeDev ( + DevType, + BbsIndex, + LocalBbsTable, + &Priority + ); + if (EFI_ERROR (Status)) { + return Status; + } + } + // + // we have to set the boot priority for other BBS entries with different device types + // + BootOrder = BdsLibGetVariableAndSize ( + L"BootOrder", + &gEfiGlobalVariableGuid, + &BootOrderSize + ); + DeviceType = AllocatePool (BootOrderSize + sizeof (UINT16)); + ASSERT (DeviceType != NULL); + + DeviceType[0] = DevType; + DeviceTypeCount = 1; + for (Index = 0; ((BootOrder != NULL) && (Index < BootOrderSize / sizeof (UINT16))); Index++) { + UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]); + BootOptionVar = BdsLibGetVariableAndSize ( + BootOption, + &gEfiGlobalVariableGuid, + &BootOptionSize + ); + if (NULL == BootOptionVar) { + continue; + } + + Ptr = BootOptionVar; + + Ptr += sizeof (UINT32); + DevPathLen = *(UINT16 *) Ptr; + Ptr += sizeof (UINT16); + Ptr += StrSize ((UINT16 *) Ptr); + DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr; + if (BBS_DEVICE_PATH != DevPath->Type || BBS_BBS_DP != DevPath->SubType) { + FreePool (BootOptionVar); + continue; + } + + Ptr += DevPathLen; + DevType = ((BBS_TABLE *) Ptr)->DeviceType; + for (DeviceTypeIndex = 0; DeviceTypeIndex < DeviceTypeCount; DeviceTypeIndex++) { + if (DeviceType[DeviceTypeIndex] == DevType) { + break; + } + } + if (DeviceTypeIndex < DeviceTypeCount) { + // + // We don't want to process twice for a device type + // + FreePool (BootOptionVar); + continue; + } + + DeviceType[DeviceTypeCount] = DevType; + DeviceTypeCount++; + + Status = BdsSetBootPriority4SameTypeDev ( + DevType, + (UINTN) -1, + LocalBbsTable, + &Priority + ); + FreePool (BootOptionVar); + if (EFI_ERROR (Status)) { + break; + } + } + + FreePool (DeviceType); + + if (BootOrder != NULL) { + FreePool (BootOrder); + } + + DEBUG_CODE_BEGIN(); + PrintBbsTable (LocalBbsTable, BbsCount); + DEBUG_CODE_END(); + + return Status; +} + +/** + Connect SATA Device and SDCard Device. + + @param None + + @retval EFI_SUCCESS Connect SATA Device and SDCard Device successfully. + @retval EFI_UNSUPPORTED + +**/ +EFI_STATUS +EFIAPI +PlatformBdsConnectStorageDevice ( + VOID + ) +{ + EFI_STATUS Status; + UINTN Index; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 PciData; + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiPciIoProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index = 0; Index < HandleCount; Index++) { + + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo + ); + + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint8, + 0, + sizeof (PciData), + &PciData + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + if ((PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE && PciData.Hdr.ClassCode[1] == PCI_CLASS_MASS_STORAGE_IDE) + || (PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE && PciData.Hdr.ClassCode[1] == PCI_CLASS_MASS_STORAGE_SATADPA) + || ((PciData.Hdr.ClassCode[2] == 0x08 && PciData.Hdr.ClassCode[1] == 0x05 && PciData.Hdr.ClassCode[0] == 0x01) && (PciData.Hdr.DeviceId == 0x2296))) { + // + //IDE Controller or AHCI Controller or SDCard Controller + // + gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); + } + } + + for (Index = 0; Index < HandleCount; Index++) { + + Status = gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo + ); + + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint8, + 0, + sizeof (PciData), + &PciData + ); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + if ((PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE && PciData.Hdr.ClassCode[1] == PCI_CLASS_MASS_STORAGE_IDE) + || (PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE && PciData.Hdr.ClassCode[1] == PCI_CLASS_MASS_STORAGE_SATADPA) + || ((PciData.Hdr.ClassCode[2] == 0x08 && PciData.Hdr.ClassCode[1] == 0x05 && PciData.Hdr.ClassCode[0] == 0x01) && (PciData.Hdr.DeviceId == 0x2296))) { + // + //IDE Controller or AHCI Controller or SDCard Controller + // + gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); + } + } + + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + } + + return EFI_SUCCESS; +} + +/** + Connect SATA Device and SDCard Device according to Device Path. + + @param[in] DevicePath + +**/ +VOID +PlatformBdsConnectStorageDeviceFromDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + + TempDevicePath = DevicePath; + + while (!IsDevicePathEnd (TempDevicePath)) { + if ((((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH)) && ((DevicePathSubType (TempDevicePath) == MSG_SATA_DP))) + || (((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH)) && ((DevicePathSubType (TempDevicePath) == 0x11)))) { + PlatformBdsConnectStorageDevice(); + break; + } + TempDevicePath = NextDevicePathNode (TempDevicePath); + } +} + +/** + Boot the legacy system with the boot option + + @param Option The legacy boot option which have BBS device path + + @retval EFI_UNSUPPORTED There is no legacybios protocol, do not support + legacy boot. + @retval EFI_STATUS Return the status of LegacyBios->LegacyBoot (). + +**/ +EFI_STATUS +BdsLibDoLegacyBoot ( + IN BDS_COMMON_OPTION *Option + ) +{ + EFI_STATUS Status; + EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; + EFI_EVENT LegacyBootEvent; + + Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); + if (EFI_ERROR (Status)) { + // + // If no LegacyBios protocol we do not support legacy boot + // + return EFI_UNSUPPORTED; + } + // + // Notes: if we separate the int 19, then we don't need to refresh BBS + // + BdsRefreshBbsTableForBoot (Option); + + // + // Write boot to OS performance data for legacy boot. + // + PERF_CODE ( + // + // Create an event to be signalled when Legacy Boot occurs to write performance data. + // + Status = EfiCreateEventLegacyBootEx( + TPL_NOTIFY, + WriteBootToOsPerformanceData, + NULL, + &LegacyBootEvent + ); + ASSERT_EFI_ERROR (Status); + ); + + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Legacy Boot: %S\n", Option->Description)); + return LegacyBios->LegacyBoot ( + LegacyBios, + (BBS_BBS_DEVICE_PATH *) Option->DevicePath, + Option->LoadOptionsSize, + Option->LoadOptions + ); +} + +/** + Internal function to check if the input boot option is a valid EFI NV Boot####. + + @param OptionToCheck Boot option to be checked. + + @retval TRUE This boot option matches a valid EFI NV Boot####. + @retval FALSE If not. + +**/ +BOOLEAN +IsBootOptionValidNVVarialbe ( + IN BDS_COMMON_OPTION *OptionToCheck + ) +{ + LIST_ENTRY TempList; + BDS_COMMON_OPTION *BootOption; + BOOLEAN Valid; + CHAR16 OptionName[20]; + + Valid = FALSE; + + InitializeListHead (&TempList); + UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionToCheck->BootCurrent); + + BootOption = BdsLibVariableToOption (&TempList, OptionName); + if (BootOption == NULL) { + return FALSE; + } + + // + // If the Boot Option Number and Device Path matches, OptionToCheck matches a + // valid EFI NV Boot####. + // + if ((OptionToCheck->BootCurrent == BootOption->BootCurrent) && + (CompareMem (OptionToCheck->DevicePath, BootOption->DevicePath, GetDevicePathSize (OptionToCheck->DevicePath)) == 0)) + { + Valid = TRUE; + } + + FreePool (BootOption); + + return Valid; +} + +/** + Check whether a USB device match the specified USB Class device path. This + function follows "Load Option Processing" behavior in UEFI specification. + + @param UsbIo USB I/O protocol associated with the USB device. + @param UsbClass The USB Class device path to match. + + @retval TRUE The USB device match the USB Class device path. + @retval FALSE The USB device does not match the USB Class device path. + +**/ +BOOLEAN +BdsMatchUsbClass ( + IN EFI_USB_IO_PROTOCOL *UsbIo, + IN USB_CLASS_DEVICE_PATH *UsbClass + ) +{ + EFI_STATUS Status; + EFI_USB_DEVICE_DESCRIPTOR DevDesc; + EFI_USB_INTERFACE_DESCRIPTOR IfDesc; + UINT8 DeviceClass; + UINT8 DeviceSubClass; + UINT8 DeviceProtocol; + + if ((DevicePathType (UsbClass) != MESSAGING_DEVICE_PATH) || + (DevicePathSubType (UsbClass) != MSG_USB_CLASS_DP)){ + return FALSE; + } + + // + // Check Vendor Id and Product Id. + // + Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc); + if (EFI_ERROR (Status)) { + return FALSE; + } + + if ((UsbClass->VendorId != 0xffff) && + (UsbClass->VendorId != DevDesc.IdVendor)) { + return FALSE; + } + + if ((UsbClass->ProductId != 0xffff) && + (UsbClass->ProductId != DevDesc.IdProduct)) { + return FALSE; + } + + DeviceClass = DevDesc.DeviceClass; + DeviceSubClass = DevDesc.DeviceSubClass; + DeviceProtocol = DevDesc.DeviceProtocol; + if (DeviceClass == 0) { + // + // If Class in Device Descriptor is set to 0, use the Class, SubClass and + // Protocol in Interface Descriptor instead. + // + Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc); + if (EFI_ERROR (Status)) { + return FALSE; + } + + DeviceClass = IfDesc.InterfaceClass; + DeviceSubClass = IfDesc.InterfaceSubClass; + DeviceProtocol = IfDesc.InterfaceProtocol; + } + + // + // Check Class, SubClass and Protocol. + // + if ((UsbClass->DeviceClass != 0xff) && + (UsbClass->DeviceClass != DeviceClass)) { + return FALSE; + } + + if ((UsbClass->DeviceSubClass != 0xff) && + (UsbClass->DeviceSubClass != DeviceSubClass)) { + return FALSE; + } + + if ((UsbClass->DeviceProtocol != 0xff) && + (UsbClass->DeviceProtocol != DeviceProtocol)) { + return FALSE; + } + + return TRUE; +} + +/** + Check whether a USB device match the specified USB WWID device path. This + function follows "Load Option Processing" behavior in UEFI specification. + + @param UsbIo USB I/O protocol associated with the USB device. + @param UsbWwid The USB WWID device path to match. + + @retval TRUE The USB device match the USB WWID device path. + @retval FALSE The USB device does not match the USB WWID device path. + +**/ +BOOLEAN +BdsMatchUsbWwid ( + IN EFI_USB_IO_PROTOCOL *UsbIo, + IN USB_WWID_DEVICE_PATH *UsbWwid + ) +{ + EFI_STATUS Status; + EFI_USB_DEVICE_DESCRIPTOR DevDesc; + EFI_USB_INTERFACE_DESCRIPTOR IfDesc; + UINT16 *LangIdTable; + UINT16 TableSize; + UINT16 Index; + CHAR16 *CompareStr; + UINTN CompareLen; + CHAR16 *SerialNumberStr; + UINTN Length; + + if ((DevicePathType (UsbWwid) != MESSAGING_DEVICE_PATH) || + (DevicePathSubType (UsbWwid) != MSG_USB_WWID_DP )){ + return FALSE; + } + + // + // Check Vendor Id and Product Id. + // + Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc); + if (EFI_ERROR (Status)) { + return FALSE; + } + if ((DevDesc.IdVendor != UsbWwid->VendorId) || + (DevDesc.IdProduct != UsbWwid->ProductId)) { + return FALSE; + } + + // + // Check Interface Number. + // + Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc); + if (EFI_ERROR (Status)) { + return FALSE; + } + if (IfDesc.InterfaceNumber != UsbWwid->InterfaceNumber) { + return FALSE; + } + + // + // Check Serial Number. + // + if (DevDesc.StrSerialNumber == 0) { + return FALSE; + } + + // + // Get all supported languages. + // + TableSize = 0; + LangIdTable = NULL; + Status = UsbIo->UsbGetSupportedLanguages (UsbIo, &LangIdTable, &TableSize); + if (EFI_ERROR (Status) || (TableSize == 0) || (LangIdTable == NULL)) { + return FALSE; + } + + // + // Serial number in USB WWID device path is the last 64-or-less UTF-16 characters. + // + CompareStr = (CHAR16 *) (UINTN) (UsbWwid + 1); + CompareLen = (DevicePathNodeLength (UsbWwid) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16); + if (CompareStr[CompareLen - 1] == L'\0') { + CompareLen--; + } + + // + // Compare serial number in each supported language. + // + for (Index = 0; Index < TableSize / sizeof (UINT16); Index++) { + SerialNumberStr = NULL; + Status = UsbIo->UsbGetStringDescriptor ( + UsbIo, + LangIdTable[Index], + DevDesc.StrSerialNumber, + &SerialNumberStr + ); + if (EFI_ERROR (Status) || (SerialNumberStr == NULL)) { + continue; + } + + Length = StrLen (SerialNumberStr); + if ((Length >= CompareLen) && + (CompareMem (SerialNumberStr + Length - CompareLen, CompareStr, CompareLen * sizeof (CHAR16)) == 0)) { + FreePool (SerialNumberStr); + return TRUE; + } + + FreePool (SerialNumberStr); + } + + return FALSE; +} + +/** + Find a USB device path which match the specified short-form device path start + with USB Class or USB WWID device path and load the boot file then return the + image handle. If ParentDevicePath is NULL, this function will search in all USB + devices of the platform. If ParentDevicePath is not NULL,this function will only + search in its child devices. + + @param ParentDevicePath The device path of the parent. + @param ShortFormDevicePath The USB Class or USB WWID device path to match. + + @return The image Handle if find load file from specified short-form device path + or NULL if not found. + +**/ +EFI_HANDLE * +BdsFindUsbDevice ( + IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *ShortFormDevicePath + ) +{ + EFI_STATUS Status; + UINTN UsbIoHandleCount; + EFI_HANDLE *UsbIoHandleBuffer; + EFI_DEVICE_PATH_PROTOCOL *UsbIoDevicePath; + EFI_USB_IO_PROTOCOL *UsbIo; + UINTN Index; + UINTN ParentSize; + UINTN Size; + EFI_HANDLE ImageHandle; + EFI_HANDLE Handle; + EFI_DEVICE_PATH_PROTOCOL *FullDevicePath; + EFI_DEVICE_PATH_PROTOCOL *NextDevicePath; + + FullDevicePath = NULL; + ImageHandle = NULL; + + // + // Get all UsbIo Handles. + // + UsbIoHandleCount = 0; + UsbIoHandleBuffer = NULL; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiUsbIoProtocolGuid, + NULL, + &UsbIoHandleCount, + &UsbIoHandleBuffer + ); + if (EFI_ERROR (Status) || (UsbIoHandleCount == 0) || (UsbIoHandleBuffer == NULL)) { + return NULL; + } + + ParentSize = (ParentDevicePath == NULL) ? 0 : GetDevicePathSize (ParentDevicePath); + for (Index = 0; Index < UsbIoHandleCount; Index++) { + // + // Get the Usb IO interface. + // + Status = gBS->HandleProtocol( + UsbIoHandleBuffer[Index], + &gEfiUsbIoProtocolGuid, + (VOID **) &UsbIo + ); + if (EFI_ERROR (Status)) { + continue; + } + + UsbIoDevicePath = DevicePathFromHandle (UsbIoHandleBuffer[Index]); + if (UsbIoDevicePath == NULL) { + continue; + } + + if (ParentDevicePath != NULL) { + // + // Compare starting part of UsbIoHandle's device path with ParentDevicePath. + // + Size = GetDevicePathSize (UsbIoDevicePath); + if ((Size < ParentSize) || + (CompareMem (UsbIoDevicePath, ParentDevicePath, ParentSize - END_DEVICE_PATH_LENGTH) != 0)) { + continue; + } + } + + if (BdsMatchUsbClass (UsbIo, (USB_CLASS_DEVICE_PATH *) ShortFormDevicePath) || + BdsMatchUsbWwid (UsbIo, (USB_WWID_DEVICE_PATH *) ShortFormDevicePath)) { + // + // Try to find if there is the boot file in this DevicePath + // + NextDevicePath = NextDevicePathNode (ShortFormDevicePath); + if (!IsDevicePathEnd (NextDevicePath)) { + FullDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePath); + // + // Connect the full device path, so that Simple File System protocol + // could be installed for this USB device. + // + BdsLibConnectDevicePath (FullDevicePath); + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad)); + Status = gBS->LoadImage ( + TRUE, + gImageHandle, + FullDevicePath, + NULL, + 0, + &ImageHandle + ); + FreePool (FullDevicePath); + } else { + FullDevicePath = UsbIoDevicePath; + Status = EFI_NOT_FOUND; + } + + // + // If we didn't find an image directly, we need to try as if it is a removable device boot option + // and load the image according to the default boot behavior for removable device. + // + if (EFI_ERROR (Status)) { + // + // check if there is a bootable removable media could be found in this device path , + // and get the bootable media handle + // + Handle = BdsLibGetBootableHandle(UsbIoDevicePath); + if (Handle == NULL) { + continue; + } + // + // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media + // machinename is ia32, ia64, x64, ... + // + FullDevicePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME); + if (FullDevicePath != NULL) { + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad)); + Status = gBS->LoadImage ( + TRUE, + gImageHandle, + FullDevicePath, + NULL, + 0, + &ImageHandle + ); + if (EFI_ERROR (Status)) { + // + // The DevicePath failed, and it's not a valid + // removable media device. + // + continue; + } + } else { + continue; + } + } + break; + } + } + + FreePool (UsbIoHandleBuffer); + return ImageHandle; +} + +/** + Expand USB Class or USB WWID device path node to be full device path of a USB + device in platform then load the boot file on this full device path and return the + image handle. + + This function support following 4 cases: + 1) Boot Option device path starts with a USB Class or USB WWID device path, + and there is no Media FilePath device path in the end. + In this case, it will follow Removable Media Boot Behavior. + 2) Boot Option device path starts with a USB Class or USB WWID device path, + and ended with Media FilePath device path. + 3) Boot Option device path starts with a full device path to a USB Host Controller, + contains a USB Class or USB WWID device path node, while not ended with Media + FilePath device path. In this case, it will follow Removable Media Boot Behavior. + 4) Boot Option device path starts with a full device path to a USB Host Controller, + contains a USB Class or USB WWID device path node, and ended with Media + FilePath device path. + + @param DevicePath The Boot Option device path. + + @return The image handle of boot file, or NULL if there is no boot file found in + the specified USB Class or USB WWID device path. + +**/ +EFI_HANDLE * +BdsExpandUsbShortFormDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + EFI_HANDLE *ImageHandle; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + EFI_DEVICE_PATH_PROTOCOL *ShortFormDevicePath; + + // + // Search for USB Class or USB WWID device path node. + // + ShortFormDevicePath = NULL; + ImageHandle = NULL; + TempDevicePath = DevicePath; + while (!IsDevicePathEnd (TempDevicePath)) { + if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) && + ((DevicePathSubType (TempDevicePath) == MSG_USB_CLASS_DP) || + (DevicePathSubType (TempDevicePath) == MSG_USB_WWID_DP))) { + ShortFormDevicePath = TempDevicePath; + break; + } + TempDevicePath = NextDevicePathNode (TempDevicePath); + } + + if (ShortFormDevicePath == NULL) { + // + // No USB Class or USB WWID device path node found, do nothing. + // + return NULL; + } + + if (ShortFormDevicePath == DevicePath) { + // + // Boot Option device path starts with USB Class or USB WWID device path. + // + ImageHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath); + if (ImageHandle == NULL) { + // + // Failed to find a match in existing devices, connect the short form USB + // device path and try again. + // + BdsLibConnectUsbDevByShortFormDP (0xff, ShortFormDevicePath); + ImageHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath); + } + } else { + // + // Boot Option device path contains USB Class or USB WWID device path node. + // + + // + // Prepare the parent device path for search. + // + TempDevicePath = DuplicateDevicePath (DevicePath); + ASSERT (TempDevicePath != NULL); + SetDevicePathEndNode (((UINT8 *) TempDevicePath) + ((UINTN) ShortFormDevicePath - (UINTN) DevicePath)); + + // + // The USB Host Controller device path is already in Boot Option device path + // and USB Bus driver already support RemainingDevicePath starts with USB + // Class or USB WWID device path, so just search in existing USB devices and + // doesn't perform ConnectController here. + // + ImageHandle = BdsFindUsbDevice (TempDevicePath, ShortFormDevicePath); + FreePool (TempDevicePath); + } + + return ImageHandle; +} + +/** + Process the boot option follow the UEFI specification and + special treat the legacy boot option with BBS_DEVICE_PATH. + + @param Option The boot option need to be processed + @param DevicePath The device path which describe where to load the + boot image or the legacy BBS device path to boot + the legacy OS + @param ExitDataSize The size of exit data. + @param ExitData Data returned when Boot image failed. + + @retval EFI_SUCCESS Boot from the input boot option successfully. + @retval EFI_NOT_FOUND If the Device Path is not found in the system + +**/ +EFI_STATUS +EFIAPI +BdsLibBootViaBootOption ( + IN BDS_COMMON_OPTION *Option, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_STATUS StatusLogo; + EFI_HANDLE Handle; + EFI_HANDLE ImageHandle; + EFI_DEVICE_PATH_PROTOCOL *FilePath; + EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; + EFI_DEVICE_PATH_PROTOCOL *WorkingDevicePath; + LIST_ENTRY TempBootLists; + EFI_BOOT_LOGO_PROTOCOL *BootLogo; + EFI_BOOT_MODE BootMode; + + Status = EFI_SUCCESS; + *ExitDataSize = 0; + *ExitData = NULL; + + // + // If it's Device Path that starts with a hard drive path, append it with the front part to compose a + // full device path + // + WorkingDevicePath = NULL; + if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) && + (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)) { + WorkingDevicePath = BdsExpandPartitionPartialDevicePathToFull ( + (HARDDRIVE_DEVICE_PATH *)DevicePath + ); + if (WorkingDevicePath != NULL) { + DevicePath = WorkingDevicePath; + } + } + + // + // Set Boot Current + // + if (IsBootOptionValidNVVarialbe (Option)) { + // + // For a temporary boot (i.e. a boot by selected a EFI Shell using "Boot From File"), Boot Current is actually not valid. + // In this case, "BootCurrent" is not created. + // Only create the BootCurrent variable when it points to a valid Boot#### variable. + // + SetVariableAndReportStatusCodeOnError ( + L"BootCurrent", + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof (UINT16), + &Option->BootCurrent + ); + } + + // + // Signal the EVT_SIGNAL_READY_TO_BOOT event + // + EfiSignalEventReadyToBoot(); + + // + // Get current Boot Mode + // + BootMode = GetBootModeHob(); + + if ((BootMode != BOOT_WITH_MINIMAL_CONFIGURATION) && (BootMode != BOOT_ASSUMING_NO_CONFIGURATION_CHANGES)) { + // + // Connect Storage Device.(eg:SATA Device and SDCard Device) + // + PlatformBdsConnectStorageDevice(); + } else { + // + // If it is Fast Boot, we only connect SATA Devices or SD Card Devices. Otherwise, we do nothing. + // + PlatformBdsConnectStorageDeviceFromDevicePath (DevicePath); + } + + // + // Report Status Code to indicate ReadyToBoot event was signalled + // + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT)); + + // + // Expand USB Class or USB WWID device path node to be full device path of a USB + // device in platform then load the boot file on this full device path and get the + // image handle. + // + ImageHandle = BdsExpandUsbShortFormDevicePath (DevicePath); + + // + // Adjust the different type memory page number just before booting + // and save the updated info into the variable for next boot to use + // + BdsSetMemoryTypeInformationVariable (); + + // + // By expanding the USB Class or WWID device path, the ImageHandle has returnned. + // Here get the ImageHandle for the non USB class or WWID device path. + // + if (ImageHandle == NULL) { + ASSERT (Option->DevicePath != NULL); + if ((DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) && + (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP) + ) { + // + // Check to see if we should legacy BOOT. If yes then do the legacy boot + // + return BdsLibDoLegacyBoot (Option); + } + + // + // If the boot option point to Internal FV shell, make sure it is valid + // + Status = BdsLibUpdateFvFileDevicePath (&DevicePath, PcdGetPtr(PcdShellFile)); + if (!EFI_ERROR(Status)) { + if (Option->DevicePath != NULL) { + FreePool(Option->DevicePath); + } + Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath)); + ASSERT(Option->DevicePath != NULL); + CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath)); + // + // Update the shell boot option + // + InitializeListHead (&TempBootLists); + BdsLibRegisterNewOption (&TempBootLists, DevicePath, L"EFI Internal Shell", L"BootOrder"); + + // + // free the temporary device path created by BdsLibUpdateFvFileDevicePath() + // + FreePool (DevicePath); + DevicePath = Option->DevicePath; + } + + DEBUG_CODE_BEGIN(); + + if (Option->Description == NULL) { + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting from unknown device path\n")); + } else { + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting %S\n", Option->Description)); + } + + DEBUG_CODE_END(); + + // + // Report status code for OS Loader LoadImage. + // + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad)); + Status = gBS->LoadImage ( + TRUE, + gImageHandle, + DevicePath, + NULL, + 0, + &ImageHandle + ); + + // + // If we didn't find an image directly, we need to try as if it is a removable device boot option + // and load the image according to the default boot behavior for removable device. + // + if (EFI_ERROR (Status)) { + // + // check if there is a bootable removable media could be found in this device path , + // and get the bootable media handle + // + Handle = BdsLibGetBootableHandle(DevicePath); + if (Handle != NULL) { + // + // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media + // machinename is ia32, ia64, x64, ... + // + FilePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME); + if (FilePath != NULL) { + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad)); + Status = gBS->LoadImage ( + TRUE, + gImageHandle, + FilePath, + NULL, + 0, + &ImageHandle + ); + } + } + } + } + // + // Provide the image with it's load options + // + if ((ImageHandle == NULL) || (EFI_ERROR(Status))) { + // + // Report Status Code to indicate that the failure to load boot option + // + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR) + ); + goto Done; + } + + Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo); + ASSERT_EFI_ERROR (Status); + + if (Option->LoadOptionsSize != 0) { + ImageInfo->LoadOptionsSize = Option->LoadOptionsSize; + ImageInfo->LoadOptions = Option->LoadOptions; + } + + // + // Clean to NULL because the image is loaded directly from the firmwares boot manager. + // + ImageInfo->ParentHandle = NULL; + + // + // Before calling the image, enable the Watchdog Timer for + // the 5 Minute period + // + gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL); + + // + // Write boot to OS performance data for UEFI boot + // + PERF_CODE ( + WriteBootToOsPerformanceData (NULL, NULL); + ); + + // + // Report status code for OS Loader StartImage. + // + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderStart)); + + Status = gBS->StartImage (ImageHandle, ExitDataSize, ExitData); + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Image Return Status = %r\n", Status)); + if (EFI_ERROR (Status)) { + // + // Report Status Code to indicate that boot failure + // + REPORT_STATUS_CODE ( + EFI_ERROR_CODE | EFI_ERROR_MINOR, + (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED) + ); + } + + // + // Clear the Watchdog Timer after the image returns + // + gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL); + +Done: + // + // Set Logo status invalid after trying one boot option + // + BootLogo = NULL; + StatusLogo = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo); + if (!EFI_ERROR (StatusLogo) && (BootLogo != NULL)) { + BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0); + } + + // + // Clear Boot Current + // Deleting variable with current implementation shouldn't fail. + // + gRT->SetVariable ( + L"BootCurrent", + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + 0, + NULL + ); + + return Status; +} + + +/** + Expand a device path that starts with a hard drive media device path node to be a + full device path that includes the full hardware path to the device. We need + to do this so it can be booted. As an optimization the front match (the part point + to the partition node. E.g. ACPI() /PCI()/ATA()/Partition() ) is saved in a variable + so a connect all is not required on every boot. All successful history device path + which point to partition node (the front part) will be saved. + + @param HardDriveDevicePath EFI Device Path to boot, if it starts with a hard + drive media device path. + @return A Pointer to the full device path or NULL if a valid Hard Drive devic path + cannot be found. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +EFIAPI +BdsExpandPartitionPartialDevicePathToFull ( + IN HARDDRIVE_DEVICE_PATH *HardDriveDevicePath + ) +{ + EFI_STATUS Status; + UINTN BlockIoHandleCount; + EFI_HANDLE *BlockIoBuffer; + EFI_DEVICE_PATH_PROTOCOL *FullDevicePath; + EFI_DEVICE_PATH_PROTOCOL *BlockIoDevicePath; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN Index; + UINTN InstanceNum; + EFI_DEVICE_PATH_PROTOCOL *CachedDevicePath; + EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath; + UINTN CachedDevicePathSize; + BOOLEAN DeviceExist; + BOOLEAN NeedAdjust; + EFI_DEVICE_PATH_PROTOCOL *Instance; + UINTN Size; + + FullDevicePath = NULL; + // + // Check if there is prestore HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable. + // If exist, search the front path which point to partition node in the variable instants. + // If fail to find or HD_BOOT_DEVICE_PATH_VARIABLE_NAME not exist, reconnect all and search in all system + // + GetVariable2 ( + HD_BOOT_DEVICE_PATH_VARIABLE_NAME, + &gHdBootDevicePathVariablGuid, + (VOID **) &CachedDevicePath, + &CachedDevicePathSize + ); + + // + // Delete the invalid HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable. + // + if ((CachedDevicePath != NULL) && !IsDevicePathValid (CachedDevicePath, CachedDevicePathSize)) { + FreePool (CachedDevicePath); + CachedDevicePath = NULL; + Status = gRT->SetVariable ( + HD_BOOT_DEVICE_PATH_VARIABLE_NAME, + &gHdBootDevicePathVariablGuid, + 0, + 0, + NULL + ); + ASSERT_EFI_ERROR (Status); + } + + if (CachedDevicePath != NULL) { + TempNewDevicePath = CachedDevicePath; + DeviceExist = FALSE; + NeedAdjust = FALSE; + do { + // + // Check every instance of the variable + // First, check whether the instance contain the partition node, which is needed for distinguishing multi + // partial partition boot option. Second, check whether the instance could be connected. + // + Instance = GetNextDevicePathInstance (&TempNewDevicePath, &Size); + if (MatchPartitionDevicePathNode (Instance, HardDriveDevicePath)) { + // + // Connect the device path instance, the device path point to hard drive media device path node + // e.g. ACPI() /PCI()/ATA()/Partition() + // + Status = BdsLibConnectDevicePath (Instance); + if (!EFI_ERROR (Status)) { + DeviceExist = TRUE; + break; + } + } + // + // Come here means the first instance is not matched + // + NeedAdjust = TRUE; + FreePool(Instance); + } while (TempNewDevicePath != NULL); + + if (DeviceExist) { + // + // Find the matched device path. + // Append the file path information from the boot option and return the fully expanded device path. + // + DevicePath = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath); + FullDevicePath = AppendDevicePath (Instance, DevicePath); + + // + // Adjust the HD_BOOT_DEVICE_PATH_VARIABLE_NAME instances sequence if the matched one is not first one. + // + if (NeedAdjust) { + // + // First delete the matched instance. + // + TempNewDevicePath = CachedDevicePath; + CachedDevicePath = BdsLibDelPartMatchInstance (CachedDevicePath, Instance ); + FreePool (TempNewDevicePath); + + // + // Second, append the remaining path after the matched instance + // + TempNewDevicePath = CachedDevicePath; + CachedDevicePath = AppendDevicePathInstance (Instance, CachedDevicePath ); + FreePool (TempNewDevicePath); + // + // Save the matching Device Path so we don't need to do a connect all next time + // Failure to set the variable only impacts the performance when next time expanding the short-form device path. + // + Status = gRT->SetVariable ( + HD_BOOT_DEVICE_PATH_VARIABLE_NAME, + &gHdBootDevicePathVariablGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, + GetDevicePathSize (CachedDevicePath), + CachedDevicePath + ); + } + + FreePool (Instance); + FreePool (CachedDevicePath); + return FullDevicePath; + } + } + + // + // If we get here we fail to find or HD_BOOT_DEVICE_PATH_VARIABLE_NAME not exist, and now we need + // to search all devices in the system for a matched partition + // + BdsLibConnectAllDriversToAllControllers (); + Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &BlockIoHandleCount, &BlockIoBuffer); + if (EFI_ERROR (Status) || BlockIoHandleCount == 0 || BlockIoBuffer == NULL) { + // + // If there was an error or there are no device handles that support + // the BLOCK_IO Protocol, then return. + // + return NULL; + } + // + // Loop through all the device handles that support the BLOCK_IO Protocol + // + for (Index = 0; Index < BlockIoHandleCount; Index++) { + + Status = gBS->HandleProtocol (BlockIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *) &BlockIoDevicePath); + if (EFI_ERROR (Status) || BlockIoDevicePath == NULL) { + continue; + } + + if (MatchPartitionDevicePathNode (BlockIoDevicePath, HardDriveDevicePath)) { + // + // Find the matched partition device path + // + DevicePath = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath); + FullDevicePath = AppendDevicePath (BlockIoDevicePath, DevicePath); + + // + // Save the matched partition device path in HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable + // + if (CachedDevicePath != NULL) { + // + // Save the matched partition device path as first instance of HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable + // + if (BdsLibMatchDevicePaths (CachedDevicePath, BlockIoDevicePath)) { + TempNewDevicePath = CachedDevicePath; + CachedDevicePath = BdsLibDelPartMatchInstance (CachedDevicePath, BlockIoDevicePath); + FreePool(TempNewDevicePath); + } + + if (CachedDevicePath != NULL) { + TempNewDevicePath = CachedDevicePath; + CachedDevicePath = AppendDevicePathInstance (BlockIoDevicePath, CachedDevicePath); + FreePool(TempNewDevicePath); + } else { + CachedDevicePath = DuplicateDevicePath (BlockIoDevicePath); + } + + // + // Here limit the device path instance number to 12, which is max number for a system support 3 IDE controller + // If the user try to boot many OS in different HDs or partitions, in theory, + // the HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable maybe become larger and larger. + // + InstanceNum = 0; + ASSERT (CachedDevicePath != NULL); + TempNewDevicePath = CachedDevicePath; + while (!IsDevicePathEnd (TempNewDevicePath)) { + TempNewDevicePath = NextDevicePathNode (TempNewDevicePath); + // + // Parse one instance + // + while (!IsDevicePathEndType (TempNewDevicePath)) { + TempNewDevicePath = NextDevicePathNode (TempNewDevicePath); + } + InstanceNum++; + // + // If the CachedDevicePath variable contain too much instance, only remain 12 instances. + // + if (InstanceNum >= 12) { + SetDevicePathEndNode (TempNewDevicePath); + break; + } + } + } else { + CachedDevicePath = DuplicateDevicePath (BlockIoDevicePath); + } + + // + // Save the matching Device Path so we don't need to do a connect all next time + // Failure to set the variable only impacts the performance when next time expanding the short-form device path. + // + Status = gRT->SetVariable ( + HD_BOOT_DEVICE_PATH_VARIABLE_NAME, + &gHdBootDevicePathVariablGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, + GetDevicePathSize (CachedDevicePath), + CachedDevicePath + ); + + break; + } + } + + if (CachedDevicePath != NULL) { + FreePool (CachedDevicePath); + } + if (BlockIoBuffer != NULL) { + FreePool (BlockIoBuffer); + } + return FullDevicePath; +} + +/** + Check whether there is a instance in BlockIoDevicePath, which contain multi device path + instances, has the same partition node with HardDriveDevicePath device path + + @param BlockIoDevicePath Multi device path instances which need to check + @param HardDriveDevicePath A device path which starts with a hard drive media + device path. + + @retval TRUE There is a matched device path instance. + @retval FALSE There is no matched device path instance. + +**/ +BOOLEAN +EFIAPI +MatchPartitionDevicePathNode ( + IN EFI_DEVICE_PATH_PROTOCOL *BlockIoDevicePath, + IN HARDDRIVE_DEVICE_PATH *HardDriveDevicePath + ) +{ + HARDDRIVE_DEVICE_PATH *TmpHdPath; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + BOOLEAN Match; + EFI_DEVICE_PATH_PROTOCOL *BlockIoHdDevicePathNode; + + if ((BlockIoDevicePath == NULL) || (HardDriveDevicePath == NULL)) { + return FALSE; + } + + // + // Make PreviousDevicePath == the device path node before the end node + // + DevicePath = BlockIoDevicePath; + BlockIoHdDevicePathNode = NULL; + + // + // find the partition device path node + // + while (!IsDevicePathEnd (DevicePath)) { + if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) && + (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP) + ) { + BlockIoHdDevicePathNode = DevicePath; + break; + } + + DevicePath = NextDevicePathNode (DevicePath); + } + + if (BlockIoHdDevicePathNode == NULL) { + return FALSE; + } + // + // See if the harddrive device path in blockio matches the orig Hard Drive Node + // + TmpHdPath = (HARDDRIVE_DEVICE_PATH *) BlockIoHdDevicePathNode; + Match = FALSE; + + // + // Check for the match + // + if ((TmpHdPath->MBRType == HardDriveDevicePath->MBRType) && + (TmpHdPath->SignatureType == HardDriveDevicePath->SignatureType)) { + switch (TmpHdPath->SignatureType) { + case SIGNATURE_TYPE_GUID: + Match = CompareGuid ((EFI_GUID *)TmpHdPath->Signature, (EFI_GUID *)HardDriveDevicePath->Signature); + break; + case SIGNATURE_TYPE_MBR: + Match = (BOOLEAN)(*((UINT32 *)(&(TmpHdPath->Signature[0]))) == ReadUnaligned32((UINT32 *)(&(HardDriveDevicePath->Signature[0])))); + break; + default: + Match = FALSE; + break; + } + } + + return Match; +} + +/** + Delete the boot option associated with the handle passed in. + + @param Handle The handle which present the device path to create + boot option + + @retval EFI_SUCCESS Delete the boot option success + @retval EFI_NOT_FOUND If the Device Path is not found in the system + @retval EFI_OUT_OF_RESOURCES Lack of memory resource + @retval Other Error return value from SetVariable() + +**/ +EFI_STATUS +BdsLibDeleteOptionFromHandle ( + IN EFI_HANDLE Handle + ) +{ + UINT16 *BootOrder; + UINT8 *BootOptionVar; + UINTN BootOrderSize; + UINTN BootOptionSize; + EFI_STATUS Status; + UINTN Index; + UINT16 BootOption[BOOT_OPTION_MAX_CHAR]; + UINTN DevicePathSize; + UINTN OptionDevicePathSize; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath; + UINT8 *TempPtr; + + Status = EFI_SUCCESS; + BootOrder = NULL; + BootOrderSize = 0; + + // + // Check "BootOrder" variable, if no, means there is no any boot order. + // + BootOrder = BdsLibGetVariableAndSize ( + L"BootOrder", + &gEfiGlobalVariableGuid, + &BootOrderSize + ); + if (BootOrder == NULL) { + return EFI_NOT_FOUND; + } + + // + // Convert device handle to device path protocol instance + // + DevicePath = DevicePathFromHandle (Handle); + if (DevicePath == NULL) { + return EFI_NOT_FOUND; + } + DevicePathSize = GetDevicePathSize (DevicePath); + + // + // Loop all boot order variable and find the matching device path + // + Index = 0; + while (Index < BootOrderSize / sizeof (UINT16)) { + UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]); + BootOptionVar = BdsLibGetVariableAndSize ( + BootOption, + &gEfiGlobalVariableGuid, + &BootOptionSize + ); + + if (BootOptionVar == NULL) { + FreePool (BootOrder); + return EFI_OUT_OF_RESOURCES; + } + + if (!ValidateOption(BootOptionVar, BootOptionSize)) { + BdsDeleteBootOption (BootOrder[Index], BootOrder, &BootOrderSize); + FreePool (BootOptionVar); + Index++; + continue; + } + + TempPtr = BootOptionVar; + TempPtr += sizeof (UINT32) + sizeof (UINT16); + TempPtr += StrSize ((CHAR16 *) TempPtr); + OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr; + OptionDevicePathSize = GetDevicePathSize (OptionDevicePath); + + // + // Check whether the device path match + // + if ((OptionDevicePathSize == DevicePathSize) && + (CompareMem (DevicePath, OptionDevicePath, DevicePathSize) == 0)) { + BdsDeleteBootOption (BootOrder[Index], BootOrder, &BootOrderSize); + FreePool (BootOptionVar); + break; + } + + FreePool (BootOptionVar); + Index++; + } + + // + // Adjust number of boot option for "BootOrder" variable. + // + Status = gRT->SetVariable ( + L"BootOrder", + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + BootOrderSize, + BootOrder + ); + // + // Shrinking variable with existing variable implementation shouldn't fail. + // + ASSERT_EFI_ERROR (Status); + + FreePool (BootOrder); + + return Status; +} + + +/** + Delete all invalid EFI boot options. + + @retval EFI_SUCCESS Delete all invalid boot option success + @retval EFI_NOT_FOUND Variable "BootOrder" is not found + @retval EFI_OUT_OF_RESOURCES Lack of memory resource + @retval Other Error return value from SetVariable() + +**/ +EFI_STATUS +BdsDeleteAllInvalidEfiBootOption ( + VOID + ) +{ + UINT16 *BootOrder; + UINT8 *BootOptionVar; + UINTN BootOrderSize; + UINTN BootOptionSize; + EFI_STATUS Status; + UINTN Index; + UINTN Index2; + UINT16 BootOption[BOOT_OPTION_MAX_CHAR]; + EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath; + UINT8 *TempPtr; + CHAR16 *Description; + BOOLEAN Corrupted; + + Status = EFI_SUCCESS; + BootOrder = NULL; + Description = NULL; + OptionDevicePath = NULL; + BootOrderSize = 0; + Corrupted = FALSE; + + // + // Check "BootOrder" variable firstly, this variable hold the number of boot options + // + BootOrder = BdsLibGetVariableAndSize ( + L"BootOrder", + &gEfiGlobalVariableGuid, + &BootOrderSize + ); + if (NULL == BootOrder) { + return EFI_NOT_FOUND; + } + + Index = 0; + while (Index < BootOrderSize / sizeof (UINT16)) { + UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]); + BootOptionVar = BdsLibGetVariableAndSize ( + BootOption, + &gEfiGlobalVariableGuid, + &BootOptionSize + ); + if (NULL == BootOptionVar) { + FreePool (BootOrder); + return EFI_OUT_OF_RESOURCES; + } + + if (!ValidateOption(BootOptionVar, BootOptionSize)) { + Corrupted = TRUE; + } else { + TempPtr = BootOptionVar; + TempPtr += sizeof (UINT32) + sizeof (UINT16); + Description = (CHAR16 *) TempPtr; + TempPtr += StrSize ((CHAR16 *) TempPtr); + OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr; + + // + // Skip legacy boot option (BBS boot device) + // + if ((DevicePathType (OptionDevicePath) == BBS_DEVICE_PATH) && + (DevicePathSubType (OptionDevicePath) == BBS_BBS_DP)) { + FreePool (BootOptionVar); + Index++; + continue; + } + } + + if (Corrupted || !BdsLibIsValidEFIBootOptDevicePathExt (OptionDevicePath, FALSE, Description)) { + // + // Delete this invalid boot option "Boot####" + // + Status = gRT->SetVariable ( + BootOption, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + 0, + NULL + ); + // + // Deleting variable with current variable implementation shouldn't fail. + // + ASSERT_EFI_ERROR (Status); + // + // Mark this boot option in boot order as deleted + // + BootOrder[Index] = 0xffff; + Corrupted = FALSE; + } + + FreePool (BootOptionVar); + Index++; + } + + // + // Adjust boot order array + // + Index2 = 0; + for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) { + if (BootOrder[Index] != 0xffff) { + BootOrder[Index2] = BootOrder[Index]; + Index2 ++; + } + } + Status = gRT->SetVariable ( + L"BootOrder", + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + Index2 * sizeof (UINT16), + BootOrder + ); + // + // Shrinking variable with current variable implementation shouldn't fail. + // + ASSERT_EFI_ERROR (Status); + + FreePool (BootOrder); + + return Status; +} + + +/** + For EFI boot option, BDS separate them as six types: + 1. Network - The boot option points to the SimpleNetworkProtocol device. + Bds will try to automatically create this type boot option when enumerate. + 2. Shell - The boot option points to internal flash shell. + Bds will try to automatically create this type boot option when enumerate. + 3. Removable BlockIo - The boot option only points to the removable media + device, like USB flash disk, DVD, Floppy etc. + These device should contain a *removable* blockIo + protocol in their device handle. + Bds will try to automatically create this type boot option + when enumerate. + 4. Fixed BlockIo - The boot option only points to a Fixed blockIo device, + like HardDisk. + These device should contain a *fixed* blockIo + protocol in their device handle. + BDS will skip fixed blockIo devices, and NOT + automatically create boot option for them. But BDS + will help to delete those fixed blockIo boot option, + whose description rule conflict with other auto-created + boot options. + 5. Non-BlockIo Simplefile - The boot option points to a device whose handle + has SimpleFileSystem Protocol, but has no blockio + protocol. These devices do not offer blockIo + protocol, but BDS still can get the + \EFI\BOOT\boot{machinename}.EFI by SimpleFileSystem + Protocol. + 6. File - The boot option points to a file. These boot options are usually + created by user manually or OS loader. BDS will not delete or modify + these boot options. + + This function will enumerate all possible boot device in the system, and + automatically create boot options for Network, Shell, Removable BlockIo, + and Non-BlockIo Simplefile devices. + It will only execute once of every boot. + + @param BdsBootOptionList The header of the link list which indexed all + current boot options + + @retval EFI_SUCCESS Finished all the boot device enumerate and create + the boot option base on that boot device + + @retval EFI_OUT_OF_RESOURCES Failed to enumerate the boot device and create the boot option list +**/ +EFI_STATUS +EFIAPI +BdsLibEnumerateAllBootOption ( + IN OUT LIST_ENTRY *BdsBootOptionList + ) +{ + EFI_STATUS Status; + UINT16 FloppyNumber; + UINT16 HarddriveNumber; + UINT16 CdromNumber; + UINT16 UsbNumber; + UINT16 MiscNumber; + UINT16 ScsiNumber; + UINT16 NonBlockNumber; + UINTN NumberBlockIoHandles; + EFI_HANDLE *BlockIoHandles; + EFI_BLOCK_IO_PROTOCOL *BlkIo; + BOOLEAN Removable[2]; + UINTN RemovableIndex; + UINTN Index; + UINTN NumOfLoadFileHandles; + EFI_HANDLE *LoadFileHandles; + UINTN FvHandleCount; + EFI_HANDLE *FvHandleBuffer; + EFI_FV_FILETYPE Type; + UINTN Size; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINT32 AuthenticationStatus; + EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN DevicePathType; + CHAR16 Buffer[40]; + EFI_HANDLE *FileSystemHandles; + UINTN NumberFileSystemHandles; + BOOLEAN NeedDelete; + EFI_IMAGE_DOS_HEADER DosHeader; + CHAR8 *PlatLang; + CHAR8 *LastLang; + EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + + FloppyNumber = 0; + HarddriveNumber = 0; + CdromNumber = 0; + UsbNumber = 0; + MiscNumber = 0; + ScsiNumber = 0; + PlatLang = NULL; + LastLang = NULL; + ZeroMem (Buffer, sizeof (Buffer)); + + // + // If the boot device enumerate happened, just get the boot + // device from the boot order variable + // + if (mEnumBootDevice) { + GetVariable2 (LAST_ENUM_LANGUAGE_VARIABLE_NAME, &gLastEnumLangGuid, (VOID**)&LastLang, NULL); + GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatLang, NULL); + ASSERT (PlatLang != NULL); + if ((LastLang != NULL) && (AsciiStrCmp (LastLang, PlatLang) == 0)) { + Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder"); + FreePool (LastLang); + FreePool (PlatLang); + return Status; + } else { + Status = gRT->SetVariable ( + LAST_ENUM_LANGUAGE_VARIABLE_NAME, + &gLastEnumLangGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, + AsciiStrSize (PlatLang), + PlatLang + ); + // + // Failure to set the variable only impacts the performance next time enumerating the boot options. + // + + if (LastLang != NULL) { + FreePool (LastLang); + } + FreePool (PlatLang); + } + } + + // + // Notes: this dirty code is to get the legacy boot option from the + // BBS table and create to variable as the EFI boot option, it should + // be removed after the CSM can provide legacy boot option directly + // + REFRESH_LEGACY_BOOT_OPTIONS; + + // + // Delete invalid boot option + // + BdsDeleteAllInvalidEfiBootOption (); + + // + // Parse removable media followed by fixed media. + // The Removable[] array is used by the for-loop below to create removable media boot options + // at first, and then to create fixed media boot options. + // + Removable[0] = FALSE; + Removable[1] = TRUE; + + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiBlockIoProtocolGuid, + NULL, + &NumberBlockIoHandles, + &BlockIoHandles + ); + + for (RemovableIndex = 0; RemovableIndex < 2; RemovableIndex++) { + for (Index = 0; Index < NumberBlockIoHandles; Index++) { + Status = gBS->HandleProtocol ( + BlockIoHandles[Index], + &gEfiBlockIoProtocolGuid, + (VOID **) &BlkIo + ); + // + // skip the logical partition + // + if (EFI_ERROR (Status) || BlkIo->Media->LogicalPartition) { + continue; + } + + // + // firstly fixed block io then the removable block io + // + if (BlkIo->Media->RemovableMedia == Removable[RemovableIndex]) { + continue; + } + DevicePath = DevicePathFromHandle (BlockIoHandles[Index]); + DevicePathType = BdsGetBootTypeFromDevicePath (DevicePath); + + switch (DevicePathType) { + case BDS_EFI_ACPI_FLOPPY_BOOT: + if (FloppyNumber != 0) { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)), FloppyNumber); + } else { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY))); + } + BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); + FloppyNumber++; + break; + + // + // Assume a removable SATA device should be the DVD/CD device, a fixed SATA device should be the Hard Drive device. + // + case BDS_EFI_MESSAGE_ATAPI_BOOT: + case BDS_EFI_MESSAGE_SATA_BOOT: + if (BlkIo->Media->RemovableMedia) { + if (CdromNumber != 0) { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)), CdromNumber); + } else { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD))); + } + CdromNumber++; + } else { + if (HarddriveNumber != 0) { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)), HarddriveNumber); + } else { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE))); + } + HarddriveNumber++; + } + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Buffer: %S\n", Buffer)); + BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); + break; + + case BDS_EFI_MESSAGE_USB_DEVICE_BOOT: + if (UsbNumber != 0) { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)), UsbNumber); + } else { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB))); + } + BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); + UsbNumber++; + break; + + case BDS_EFI_MESSAGE_SCSI_BOOT: + if (ScsiNumber != 0) { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)), ScsiNumber); + } else { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI))); + } + BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); + ScsiNumber++; + break; + + case BDS_EFI_MESSAGE_MISC_BOOT: + default: + if (MiscNumber != 0) { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)), MiscNumber); + } else { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC))); + } + BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); + MiscNumber++; + break; + } + } + } + + if (NumberBlockIoHandles != 0) { + FreePool (BlockIoHandles); + } + + // + // If there is simple file protocol which does not consume block Io protocol, create a boot option for it here. + // + NonBlockNumber = 0; + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimpleFileSystemProtocolGuid, + NULL, + &NumberFileSystemHandles, + &FileSystemHandles + ); + for (Index = 0; Index < NumberFileSystemHandles; Index++) { + Status = gBS->HandleProtocol ( + FileSystemHandles[Index], + &gEfiBlockIoProtocolGuid, + (VOID **) &BlkIo + ); + if (!EFI_ERROR (Status)) { + // + // Skip if the file system handle supports a BlkIo protocol, + // + continue; + } + + // + // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI + // machinename is ia32, ia64, x64, ... + // + Hdr.Union = &HdrData; + NeedDelete = TRUE; + Status = BdsLibGetImageHeader ( + FileSystemHandles[Index], + EFI_REMOVABLE_MEDIA_FILE_NAME, + &DosHeader, + Hdr + ); + if (!EFI_ERROR (Status) && + EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) && + Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) { + NeedDelete = FALSE; + } + + if (NeedDelete) { + // + // No such file or the file is not a EFI application, delete this boot option + // + BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]); + } else { + if (NonBlockNumber != 0) { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)), NonBlockNumber); + } else { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK))); + } + BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList, Buffer); + NonBlockNumber++; + } + } + + if (NumberFileSystemHandles != 0) { + FreePool (FileSystemHandles); + } + + // + // Parse Network Boot Device + // + NumOfLoadFileHandles = 0; + // + // Search Load File protocol for PXE boot option. + // + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiLoadFileProtocolGuid, + NULL, + &NumOfLoadFileHandles, + &LoadFileHandles + ); + + for (Index = 0; Index < NumOfLoadFileHandles; Index++) { + if (Index != 0) { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)), Index); + } else { + UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK))); + } + BdsLibBuildOptionFromHandle (LoadFileHandles[Index], BdsBootOptionList, Buffer); + } + + if (NumOfLoadFileHandles != 0) { + FreePool (LoadFileHandles); + } + + // + // Check if we have on flash shell + // + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolume2ProtocolGuid, + NULL, + &FvHandleCount, + &FvHandleBuffer + ); + for (Index = 0; Index < FvHandleCount; Index++) { + gBS->HandleProtocol ( + FvHandleBuffer[Index], + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **) &Fv + ); + + Status = Fv->ReadFile ( + Fv, + PcdGetPtr(PcdShellFile), + NULL, + &Size, + &Type, + &Attributes, + &AuthenticationStatus + ); + if (EFI_ERROR (Status)) { + // + // Skip if no shell file in the FV + // + continue; + } + // + // Build the shell boot option + // + BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList); + } + + if (FvHandleCount != 0) { + FreePool (FvHandleBuffer); + } + // + // Make sure every boot only have one time + // boot device enumerate + // + Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder"); + mEnumBootDevice = TRUE; + + return Status; +} + +/** + Build the boot option with the handle parsed in + + @param Handle The handle which present the device path to create + boot option + @param BdsBootOptionList The header of the link list which indexed all + current boot options + @param String The description of the boot option. + +**/ +VOID +EFIAPI +BdsLibBuildOptionFromHandle ( + IN EFI_HANDLE Handle, + IN LIST_ENTRY *BdsBootOptionList, + IN CHAR16 *String + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + DevicePath = DevicePathFromHandle (Handle); + + // + // Create and register new boot option + // + BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, String, L"BootOrder"); +} + + +/** + Build the on flash shell boot option with the handle parsed in. + + @param Handle The handle which present the device path to create + on flash shell boot option + @param BdsBootOptionList The header of the link list which indexed all + current boot options + +**/ +VOID +EFIAPI +BdsLibBuildOptionFromShell ( + IN EFI_HANDLE Handle, + IN OUT LIST_ENTRY *BdsBootOptionList + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode; + + DevicePath = DevicePathFromHandle (Handle); + + // + // Build the shell device path + // + EfiInitializeFwVolDevicepathNode (&ShellNode, PcdGetPtr(PcdShellFile)); + + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &ShellNode); + + // + // Create and register the shell boot option + // + BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, L"EFI Internal Shell", L"BootOrder"); + +} + +/** + Boot from the UEFI spec defined "BootNext" variable. + +**/ +VOID +EFIAPI +BdsLibBootNext ( + VOID + ) +{ + EFI_STATUS Status; + UINT16 *BootNext; + UINTN BootNextSize; + CHAR16 Buffer[20]; + BDS_COMMON_OPTION *BootOption; + LIST_ENTRY TempList; + UINTN ExitDataSize; + CHAR16 *ExitData; + + // + // Init the boot option name buffer and temp link list + // + InitializeListHead (&TempList); + ZeroMem (Buffer, sizeof (Buffer)); + + BootNext = BdsLibGetVariableAndSize ( + L"BootNext", + &gEfiGlobalVariableGuid, + &BootNextSize + ); + + // + // Clear the boot next variable first + // + if (BootNext != NULL) { + Status = gRT->SetVariable ( + L"BootNext", + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + 0, + NULL + ); + // + // Deleting variable with current variable implementation shouldn't fail. + // + ASSERT_EFI_ERROR (Status); + + // + // Start to build the boot option and try to boot + // + UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *BootNext); + BootOption = BdsLibVariableToOption (&TempList, Buffer); + ASSERT (BootOption != NULL); + BdsLibConnectDevicePath (BootOption->DevicePath); + BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData); + FreePool(BootOption); + FreePool(BootNext); + } + +} + +/** + Return the bootable media handle. + First, check the device is connected + Second, check whether the device path point to a device which support SimpleFileSystemProtocol, + Third, detect the the default boot file in the Media, and return the removable Media handle. + + @param DevicePath Device Path to a bootable device + + @return The bootable media handle. If the media on the DevicePath is not bootable, NULL will return. + +**/ +EFI_HANDLE +EFIAPI +BdsLibGetBootableHandle ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + EFI_STATUS Status; + EFI_TPL OldTpl; + EFI_DEVICE_PATH_PROTOCOL *UpdatedDevicePath; + EFI_DEVICE_PATH_PROTOCOL *DupDevicePath; + EFI_HANDLE Handle; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + VOID *Buffer; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + UINTN Size; + UINTN TempSize; + EFI_HANDLE ReturnHandle; + EFI_HANDLE *SimpleFileSystemHandles; + + UINTN NumberSimpleFileSystemHandles; + UINTN Index; + EFI_IMAGE_DOS_HEADER DosHeader; + EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData; + EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; + + UpdatedDevicePath = DevicePath; + + // + // Enter to critical section to protect the acquired BlockIo instance + // from getting released due to the USB mass storage hotplug event + // + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + // + // Check whether the device is connected + // + Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &UpdatedDevicePath, &Handle); + if (EFI_ERROR (Status)) { + // + // Skip the case that the boot option point to a simple file protocol which does not consume block Io protocol, + // + Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &UpdatedDevicePath, &Handle); + if (EFI_ERROR (Status)) { + // + // Fail to find the proper BlockIo and simple file protocol, maybe because device not present, we need to connect it firstly + // + UpdatedDevicePath = DevicePath; + Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &UpdatedDevicePath, &Handle); + gBS->ConnectController (Handle, NULL, NULL, TRUE); + } + } else { + // + // For removable device boot option, its contained device path only point to the removable device handle, + // should make sure all its children handles (its child partion or media handles) are created and connected. + // + gBS->ConnectController (Handle, NULL, NULL, TRUE); + // + // Get BlockIo protocol and check removable attribute + // + Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo); + ASSERT_EFI_ERROR (Status); + + // + // Issue a dummy read to the device to check for media change. + // When the removable media is changed, any Block IO read/write will + // cause the BlockIo protocol be reinstalled and EFI_MEDIA_CHANGED is + // returned. After the Block IO protocol is reinstalled, subsequent + // Block IO read/write will success. + // + Buffer = AllocatePool (BlockIo->Media->BlockSize); + if (Buffer != NULL) { + BlockIo->ReadBlocks ( + BlockIo, + BlockIo->Media->MediaId, + 0, + BlockIo->Media->BlockSize, + Buffer + ); + FreePool(Buffer); + } + } + + // + // Detect the the default boot file from removable Media + // + + // + // If fail to get bootable handle specified by a USB boot option, the BDS should try to find other bootable device in the same USB bus + // Try to locate the USB node device path first, if fail then use its previous PCI node to search + // + DupDevicePath = DuplicateDevicePath (DevicePath); + ASSERT (DupDevicePath != NULL); + + UpdatedDevicePath = DupDevicePath; + Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &UpdatedDevicePath, &Handle); + // + // if the resulting device path point to a usb node, and the usb node is a dummy node, should only let device path only point to the previous Pci node + // Acpi()/Pci()/Usb() --> Acpi()/Pci() + // + if ((DevicePathType (UpdatedDevicePath) == MESSAGING_DEVICE_PATH) && + (DevicePathSubType (UpdatedDevicePath) == MSG_USB_DP)) { + // + // Remove the usb node, let the device path only point to PCI node + // + SetDevicePathEndNode (UpdatedDevicePath); + UpdatedDevicePath = DupDevicePath; + } else { + UpdatedDevicePath = DevicePath; + } + + // + // Get the device path size of boot option + // + Size = GetDevicePathSize(UpdatedDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL); // minus the end node + ReturnHandle = NULL; + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimpleFileSystemProtocolGuid, + NULL, + &NumberSimpleFileSystemHandles, + &SimpleFileSystemHandles + ); + for (Index = 0; Index < NumberSimpleFileSystemHandles; Index++) { + // + // Get the device path size of SimpleFileSystem handle + // + TempDevicePath = DevicePathFromHandle (SimpleFileSystemHandles[Index]); + TempSize = GetDevicePathSize (TempDevicePath)- sizeof (EFI_DEVICE_PATH_PROTOCOL); // minus the end node + // + // Check whether the device path of boot option is part of the SimpleFileSystem handle's device path + // + if (Size <= TempSize && CompareMem (TempDevicePath, UpdatedDevicePath, Size)==0) { + // + // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media + // machinename is ia32, ia64, x64, ... + // + Hdr.Union = &HdrData; + Status = BdsLibGetImageHeader ( + SimpleFileSystemHandles[Index], + EFI_REMOVABLE_MEDIA_FILE_NAME, + &DosHeader, + Hdr + ); + if (!EFI_ERROR (Status) && + EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) && + Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) { + ReturnHandle = SimpleFileSystemHandles[Index]; + break; + } + } + } + + FreePool(DupDevicePath); + + if (SimpleFileSystemHandles != NULL) { + FreePool(SimpleFileSystemHandles); + } + + gBS->RestoreTPL (OldTpl); + + return ReturnHandle; +} + +/** + Check to see if the network cable is plugged in. If the DevicePath is not + connected it will be connected. + + @param DevicePath Device Path to check + + @retval TRUE DevicePath points to an Network that is connected + @retval FALSE DevicePath does not point to a bootable network + +**/ +BOOLEAN +BdsLibNetworkBootWithMediaPresent ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *UpdatedDevicePath; + EFI_HANDLE Handle; + EFI_SIMPLE_NETWORK_PROTOCOL *Snp; + BOOLEAN MediaPresent; + UINT32 InterruptStatus; + + MediaPresent = FALSE; + + UpdatedDevicePath = DevicePath; + // + // Locate Load File Protocol for PXE boot option first + // + Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &UpdatedDevicePath, &Handle); + if (EFI_ERROR (Status)) { + // + // Device not present so see if we need to connect it + // + Status = BdsLibConnectDevicePath (DevicePath); + if (!EFI_ERROR (Status)) { + // + // This one should work after we did the connect + // + Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &UpdatedDevicePath, &Handle); + } + } + + if (!EFI_ERROR (Status)) { + Status = gBS->HandleProtocol (Handle, &gEfiSimpleNetworkProtocolGuid, (VOID **)&Snp); + if (EFI_ERROR (Status)) { + // + // Failed to open SNP from this handle, try to get SNP from parent handle + // + UpdatedDevicePath = DevicePathFromHandle (Handle); + if (UpdatedDevicePath != NULL) { + Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid, &UpdatedDevicePath, &Handle); + if (!EFI_ERROR (Status)) { + // + // SNP handle found, get SNP from it + // + Status = gBS->HandleProtocol (Handle, &gEfiSimpleNetworkProtocolGuid, (VOID **) &Snp); + } + } + } + + if (!EFI_ERROR (Status)) { + if (Snp->Mode->MediaPresentSupported) { + if (Snp->Mode->State == EfiSimpleNetworkInitialized) { + // + // Invoke Snp->GetStatus() to refresh the media status + // + Snp->GetStatus (Snp, &InterruptStatus, NULL); + + // + // In case some one else is using the SNP check to see if it's connected + // + MediaPresent = Snp->Mode->MediaPresent; + } else { + // + // No one is using SNP so we need to Start and Initialize so + // MediaPresent will be valid. + // + Status = Snp->Start (Snp); + if (!EFI_ERROR (Status)) { + Status = Snp->Initialize (Snp, 0, 0); + if (!EFI_ERROR (Status)) { + MediaPresent = Snp->Mode->MediaPresent; + Snp->Shutdown (Snp); + } + Snp->Stop (Snp); + } + } + } else { + MediaPresent = TRUE; + } + } + } + + return MediaPresent; +} + +/** + For a bootable Device path, return its boot type. + + @param DevicePath The bootable device Path to check + + @retval BDS_EFI_MEDIA_HD_BOOT If given device path contains MEDIA_DEVICE_PATH type device path node + which subtype is MEDIA_HARDDRIVE_DP + @retval BDS_EFI_MEDIA_CDROM_BOOT If given device path contains MEDIA_DEVICE_PATH type device path node + which subtype is MEDIA_CDROM_DP + @retval BDS_EFI_ACPI_FLOPPY_BOOT If given device path contains ACPI_DEVICE_PATH type device path node + which HID is floppy device. + @retval BDS_EFI_MESSAGE_ATAPI_BOOT If given device path contains MESSAGING_DEVICE_PATH type device path node + and its last device path node's subtype is MSG_ATAPI_DP. + @retval BDS_EFI_MESSAGE_SCSI_BOOT If given device path contains MESSAGING_DEVICE_PATH type device path node + and its last device path node's subtype is MSG_SCSI_DP. + @retval BDS_EFI_MESSAGE_USB_DEVICE_BOOT If given device path contains MESSAGING_DEVICE_PATH type device path node + and its last device path node's subtype is MSG_USB_DP. + @retval BDS_EFI_MESSAGE_MISC_BOOT If the device path not contains any media device path node, and + its last device path node point to a message device path node. + @retval BDS_LEGACY_BBS_BOOT If given device path contains BBS_DEVICE_PATH type device path node. + @retval BDS_EFI_UNSUPPORT An EFI Removable BlockIO device path not point to a media and message device, + +**/ +UINT32 +EFIAPI +BdsGetBootTypeFromDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + ACPI_HID_DEVICE_PATH *Acpi; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode; + UINT32 BootType; + + if (NULL == DevicePath) { + return BDS_EFI_UNSUPPORT; + } + + TempDevicePath = DevicePath; + + while (!IsDevicePathEndType (TempDevicePath)) { + switch (DevicePathType (TempDevicePath)) { + case BBS_DEVICE_PATH: + return BDS_LEGACY_BBS_BOOT; + case MEDIA_DEVICE_PATH: + if (DevicePathSubType (TempDevicePath) == MEDIA_HARDDRIVE_DP) { + return BDS_EFI_MEDIA_HD_BOOT; + } else if (DevicePathSubType (TempDevicePath) == MEDIA_CDROM_DP) { + return BDS_EFI_MEDIA_CDROM_BOOT; + } + break; + case ACPI_DEVICE_PATH: + Acpi = (ACPI_HID_DEVICE_PATH *) TempDevicePath; + if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) { + return BDS_EFI_ACPI_FLOPPY_BOOT; + } + break; + case MESSAGING_DEVICE_PATH: + // + // Get the last device path node + // + LastDeviceNode = NextDevicePathNode (TempDevicePath); + if (DevicePathSubType(LastDeviceNode) == MSG_DEVICE_LOGICAL_UNIT_DP) { + // + // if the next node type is Device Logical Unit, which specify the Logical Unit Number (LUN), + // skip it + // + LastDeviceNode = NextDevicePathNode (LastDeviceNode); + } + // + // if the device path not only point to driver device, it is not a messaging device path, + // + if (!IsDevicePathEndType (LastDeviceNode)) { + break; + } + + switch (DevicePathSubType (TempDevicePath)) { + case MSG_ATAPI_DP: + BootType = BDS_EFI_MESSAGE_ATAPI_BOOT; + break; + + case MSG_USB_DP: + BootType = BDS_EFI_MESSAGE_USB_DEVICE_BOOT; + break; + + case MSG_SCSI_DP: + BootType = BDS_EFI_MESSAGE_SCSI_BOOT; + break; + + case MSG_SATA_DP: + BootType = BDS_EFI_MESSAGE_SATA_BOOT; + break; + + case MSG_MAC_ADDR_DP: + case MSG_VLAN_DP: + case MSG_IPv4_DP: + case MSG_IPv6_DP: + BootType = BDS_EFI_MESSAGE_MAC_BOOT; + break; + + default: + BootType = BDS_EFI_MESSAGE_MISC_BOOT; + break; + } + return BootType; + + default: + break; + } + TempDevicePath = NextDevicePathNode (TempDevicePath); + } + + return BDS_EFI_UNSUPPORT; +} + +/** + Check whether the Device path in a boot option point to a valid bootable device, + And if CheckMedia is true, check the device is ready to boot now. + + @param DevPath the Device path in a boot option + @param CheckMedia if true, check the device is ready to boot now. + + @retval TRUE the Device path is valid + @retval FALSE the Device path is invalid . + +**/ +BOOLEAN +EFIAPI +BdsLibIsValidEFIBootOptDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevPath, + IN BOOLEAN CheckMedia + ) +{ + return BdsLibIsValidEFIBootOptDevicePathExt (DevPath, CheckMedia, NULL); +} + +/** + Check whether the Device path in a boot option point to a valid bootable device, + And if CheckMedia is true, check the device is ready to boot now. + If Description is not NULL and the device path point to a fixed BlockIo + device, check the description whether conflict with other auto-created + boot options. + + @param DevPath the Device path in a boot option + @param CheckMedia if true, check the device is ready to boot now. + @param Description the description in a boot option + + @retval TRUE the Device path is valid + @retval FALSE the Device path is invalid . + +**/ +BOOLEAN +EFIAPI +BdsLibIsValidEFIBootOptDevicePathExt ( + IN EFI_DEVICE_PATH_PROTOCOL *DevPath, + IN BOOLEAN CheckMedia, + IN CHAR16 *Description + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode; + EFI_BLOCK_IO_PROTOCOL *BlockIo; + + TempDevicePath = DevPath; + LastDeviceNode = DevPath; + + // + // Check if it's a valid boot option for network boot device. + // Check if there is EfiLoadFileProtocol installed. + // If yes, that means there is a boot option for network. + // + Status = gBS->LocateDevicePath ( + &gEfiLoadFileProtocolGuid, + &TempDevicePath, + &Handle + ); + if (EFI_ERROR (Status)) { + // + // Device not present so see if we need to connect it + // + TempDevicePath = DevPath; + BdsLibConnectDevicePath (TempDevicePath); + Status = gBS->LocateDevicePath ( + &gEfiLoadFileProtocolGuid, + &TempDevicePath, + &Handle + ); + } + + if (!EFI_ERROR (Status)) { + if (!IsDevicePathEnd (TempDevicePath)) { + // + // LoadFile protocol is not installed on handle with exactly the same DevPath + // + return FALSE; + } + + if (CheckMedia) { + // + // Test if it is ready to boot now + // + if (BdsLibNetworkBootWithMediaPresent(DevPath)) { + return TRUE; + } + } else { + return TRUE; + } + } + + // + // If the boot option point to a file, it is a valid EFI boot option, + // and assume it is ready to boot now + // + while (!IsDevicePathEnd (TempDevicePath)) { + // + // If there is USB Class or USB WWID device path node, treat it as valid EFI + // Boot Option. BdsExpandUsbShortFormDevicePath () will be used to expand it + // to full device path. + // + if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) && + ((DevicePathSubType (TempDevicePath) == MSG_USB_CLASS_DP) || + (DevicePathSubType (TempDevicePath) == MSG_USB_WWID_DP))) { + return TRUE; + } + + LastDeviceNode = TempDevicePath; + TempDevicePath = NextDevicePathNode (TempDevicePath); + } + if ((DevicePathType (LastDeviceNode) == MEDIA_DEVICE_PATH) && + (DevicePathSubType (LastDeviceNode) == MEDIA_FILEPATH_DP)) { + return TRUE; + } + + // + // Check if it's a valid boot option for internal FV application + // + if (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode) != NULL) { + // + // If the boot option point to internal FV application, make sure it is valid + // + TempDevicePath = DevPath; + Status = BdsLibUpdateFvFileDevicePath ( + &TempDevicePath, + EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode) + ); + if (Status == EFI_ALREADY_STARTED) { + return TRUE; + } else { + if (Status == EFI_SUCCESS) { + FreePool (TempDevicePath); + } + return FALSE; + } + } + + // + // If the boot option point to a blockIO device: + // if it is a removable blockIo device, it is valid. + // if it is a fixed blockIo device, check its description confliction. + // + TempDevicePath = DevPath; + Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle); + if (EFI_ERROR (Status)) { + // + // Device not present so see if we need to connect it + // + Status = BdsLibConnectDevicePath (DevPath); + if (!EFI_ERROR (Status)) { + // + // Try again to get the Block Io protocol after we did the connect + // + TempDevicePath = DevPath; + Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle); + } + } + + if (!EFI_ERROR (Status)) { + Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo); + if (!EFI_ERROR (Status)) { + if (CheckMedia) { + // + // Test if it is ready to boot now + // + if (BdsLibGetBootableHandle (DevPath) != NULL) { + return TRUE; + } + } else { + return TRUE; + } + } + } else { + // + // if the boot option point to a simple file protocol which does not consume block Io protocol, it is also a valid EFI boot option, + // + Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &TempDevicePath, &Handle); + if (!EFI_ERROR (Status)) { + if (CheckMedia) { + // + // Test if it is ready to boot now + // + if (BdsLibGetBootableHandle (DevPath) != NULL) { + return TRUE; + } + } else { + return TRUE; + } + } + } + + return FALSE; +} + + +/** + According to a file guild, check a Fv file device path is valid. If it is invalid, + try to return the valid device path. + FV address maybe changes for memory layout adjust from time to time, use this function + could promise the Fv file device path is right. + + @param DevicePath on input, the Fv file device path need to check on + output, the updated valid Fv file device path + @param FileGuid the Fv file guild + + @retval EFI_INVALID_PARAMETER the input DevicePath or FileGuid is invalid + parameter + @retval EFI_UNSUPPORTED the input DevicePath does not contain Fv file + guild at all + @retval EFI_ALREADY_STARTED the input DevicePath has pointed to Fv file, it is + valid + @retval EFI_SUCCESS has successfully updated the invalid DevicePath, + and return the updated device path in DevicePath + +**/ +EFI_STATUS +EFIAPI +BdsLibUpdateFvFileDevicePath ( + IN OUT EFI_DEVICE_PATH_PROTOCOL ** DevicePath, + IN EFI_GUID *FileGuid + ) +{ + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode; + EFI_STATUS Status; + EFI_GUID *GuidPoint; + UINTN Index; + UINTN FvHandleCount; + EFI_HANDLE *FvHandleBuffer; + EFI_FV_FILETYPE Type; + UINTN Size; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINT32 AuthenticationStatus; + BOOLEAN FindFvFile; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileNode; + EFI_HANDLE FoundFvHandle; + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + + if ((DevicePath == NULL) || (*DevicePath == NULL)) { + return EFI_INVALID_PARAMETER; + } + if (FileGuid == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Check whether the device path point to the default the input Fv file + // + TempDevicePath = *DevicePath; + LastDeviceNode = TempDevicePath; + while (!IsDevicePathEnd (TempDevicePath)) { + LastDeviceNode = TempDevicePath; + TempDevicePath = NextDevicePathNode (TempDevicePath); + } + GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode ( + (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode + ); + if (GuidPoint == NULL) { + // + // if this option does not points to a Fv file, just return EFI_UNSUPPORTED + // + return EFI_UNSUPPORTED; + } + if (!CompareGuid (GuidPoint, FileGuid)) { + // + // If the Fv file is not the input file guid, just return EFI_UNSUPPORTED + // + return EFI_UNSUPPORTED; + } + + // + // Check whether the input Fv file device path is valid + // + TempDevicePath = *DevicePath; + FoundFvHandle = NULL; + Status = gBS->LocateDevicePath ( + &gEfiFirmwareVolume2ProtocolGuid, + &TempDevicePath, + &FoundFvHandle + ); + if (!EFI_ERROR (Status)) { + Status = gBS->HandleProtocol ( + FoundFvHandle, + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **) &Fv + ); + if (!EFI_ERROR (Status)) { + // + // Set FV ReadFile Buffer as NULL, only need to check whether input Fv file exist there + // + Status = Fv->ReadFile ( + Fv, + FileGuid, + NULL, + &Size, + &Type, + &Attributes, + &AuthenticationStatus + ); + if (!EFI_ERROR (Status)) { + return EFI_ALREADY_STARTED; + } + } + } + + // + // Look for the input wanted FV file in current FV + // First, try to look for in Bds own FV. Bds and input wanted FV file usually are in the same FV + // + FindFvFile = FALSE; + FoundFvHandle = NULL; + Status = gBS->HandleProtocol ( + gImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &LoadedImage + ); + if (!EFI_ERROR (Status)) { + Status = gBS->HandleProtocol ( + LoadedImage->DeviceHandle, + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **) &Fv + ); + if (!EFI_ERROR (Status)) { + Status = Fv->ReadFile ( + Fv, + FileGuid, + NULL, + &Size, + &Type, + &Attributes, + &AuthenticationStatus + ); + if (!EFI_ERROR (Status)) { + FindFvFile = TRUE; + FoundFvHandle = LoadedImage->DeviceHandle; + } + } + } + // + // Second, if fail to find, try to enumerate all FV + // + if (!FindFvFile) { + FvHandleBuffer = NULL; + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolume2ProtocolGuid, + NULL, + &FvHandleCount, + &FvHandleBuffer + ); + for (Index = 0; Index < FvHandleCount; Index++) { + gBS->HandleProtocol ( + FvHandleBuffer[Index], + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **) &Fv + ); + + Status = Fv->ReadFile ( + Fv, + FileGuid, + NULL, + &Size, + &Type, + &Attributes, + &AuthenticationStatus + ); + if (EFI_ERROR (Status)) { + // + // Skip if input Fv file not in the FV + // + continue; + } + FindFvFile = TRUE; + FoundFvHandle = FvHandleBuffer[Index]; + break; + } + + if (FvHandleBuffer != NULL) { + FreePool (FvHandleBuffer); + } + } + + if (FindFvFile) { + // + // Build the shell device path + // + NewDevicePath = DevicePathFromHandle (FoundFvHandle); + EfiInitializeFwVolDevicepathNode (&FvFileNode, FileGuid); + NewDevicePath = AppendDevicePathNode (NewDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &FvFileNode); + ASSERT (NewDevicePath != NULL); + *DevicePath = NewDevicePath; + return EFI_SUCCESS; + } + return EFI_NOT_FOUND; +} diff --git a/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConnect.c b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConnect.c new file mode 100644 index 0000000000..1970c84aee --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConnect.c @@ -0,0 +1,435 @@ +/** @file + BDS Lib functions which relate with connect the device + +Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which 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 "InternalBdsLib.h" + + +/** + This function will connect all the system driver to controller + first, and then special connect the default console, this make + sure all the system controller available and the platform default + console connected. + +**/ +VOID +EFIAPI +BdsLibConnectAll ( + VOID + ) +{ + // + // Connect the platform console first + // + BdsLibConnectAllDefaultConsoles (); + + // + // Generic way to connect all the drivers + // + BdsLibConnectAllDriversToAllControllers (); + + // + // Here we have the assumption that we have already had + // platform default console + // + BdsLibConnectAllDefaultConsoles (); +} + + +/** + This function will connect all the system drivers to all controllers + first, and then connect all the console devices the system current + have. After this we should get all the device work and console available + if the system have console device. + +**/ +VOID +BdsLibGenericConnectAll ( + VOID + ) +{ + // + // Most generic way to connect all the drivers + // + BdsLibConnectAllDriversToAllControllers (); + BdsLibConnectAllConsoles (); +} + +/** + This function will create all handles associate with every device + path node. If the handle associate with one device path node can not + be created successfully, then still give chance to do the dispatch, + which load the missing drivers if possible. + + @param DevicePathToConnect The device path which will be connected, it can be + a multi-instance device path + + @retval EFI_SUCCESS All handles associate with every device path node + have been created + @retval EFI_OUT_OF_RESOURCES There is no resource to create new handles + @retval EFI_NOT_FOUND Create the handle associate with one device path + node failed + +**/ +EFI_STATUS +EFIAPI +BdsLibConnectDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath; + EFI_DEVICE_PATH_PROTOCOL *Instance; + EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; + EFI_DEVICE_PATH_PROTOCOL *Next; + EFI_HANDLE Handle; + EFI_HANDLE PreviousHandle; + UINTN Size; + EFI_TPL CurrentTpl; + + if (DevicePathToConnect == NULL) { + return EFI_SUCCESS; + } + + CurrentTpl = EfiGetCurrentTpl (); + + DevicePath = DuplicateDevicePath (DevicePathToConnect); + if (DevicePath == NULL) { + return EFI_OUT_OF_RESOURCES; + } + CopyOfDevicePath = DevicePath; + + do { + // + // The outer loop handles multi instance device paths. + // Only console variables contain multiple instance device paths. + // + // After this call DevicePath points to the next Instance + // + Instance = GetNextDevicePathInstance (&DevicePath, &Size); + if (Instance == NULL) { + FreePool (CopyOfDevicePath); + return EFI_OUT_OF_RESOURCES; + } + + Next = Instance; + while (!IsDevicePathEndType (Next)) { + Next = NextDevicePathNode (Next); + } + + SetDevicePathEndNode (Next); + + // + // Start the real work of connect with RemainingDevicePath + // + PreviousHandle = NULL; + do { + // + // Find the handle that best matches the Device Path. If it is only a + // partial match the remaining part of the device path is returned in + // RemainingDevicePath. + // + RemainingDevicePath = Instance; + Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle); + + if (!EFI_ERROR (Status)) { + if (Handle == PreviousHandle) { + // + // If no forward progress is made try invoking the Dispatcher. + // A new FV may have been added to the system an new drivers + // may now be found. + // Status == EFI_SUCCESS means a driver was dispatched + // Status == EFI_NOT_FOUND means no new drivers were dispatched + // + if (CurrentTpl == TPL_APPLICATION) { + // + // Dispatch calls LoadImage/StartImage which cannot run at TPL > TPL_APPLICATION + // + Status = gDS->Dispatch (); + } else { + // + // Always return EFI_NOT_FOUND here + // to prevent dead loop when control handle is found but connection failded case + // + Status = EFI_NOT_FOUND; + } + } + + if (!EFI_ERROR (Status)) { + PreviousHandle = Handle; + // + // Connect all drivers that apply to Handle and RemainingDevicePath, + // the Recursive flag is FALSE so only one level will be expanded. + // + // Do not check the connect status here, if the connect controller fail, + // then still give the chance to do dispatch, because partial + // RemainingDevicepath may be in the new FV + // + // 1. If the connect fail, RemainingDevicepath and handle will not + // change, so next time will do the dispatch, then dispatch's status + // will take effect + // 2. If the connect success, the RemainingDevicepath and handle will + // change, then avoid the dispatch, we have chance to continue the + // next connection + // + gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE); + } + } + // + // Loop until RemainingDevicePath is an empty device path + // + } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath)); + + } while (DevicePath != NULL); + + if (CopyOfDevicePath != NULL) { + FreePool (CopyOfDevicePath); + } + // + // All handle with DevicePath exists in the handle database + // + return Status; +} + +/** + This function will connect all current system handles recursively. + + gBS->ConnectController() service is invoked for each handle exist in system handler buffer. + If the handle is bus type handler, all childrens also will be connected recursively + by gBS->ConnectController(). + + @retval EFI_SUCCESS All handles and it's child handle have been connected + @retval EFI_STATUS Error status returned by of gBS->LocateHandleBuffer(). + +**/ +EFI_STATUS +EFIAPI +BdsLibConnectAllEfi ( + VOID + ) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + + Status = gBS->LocateHandleBuffer ( + AllHandles, + NULL, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); + } + + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + } + + return EFI_SUCCESS; +} + +/** + This function will disconnect all current system handles. + + gBS->DisconnectController() is invoked for each handle exists in system handle buffer. + If handle is a bus type handle, all childrens also are disconnected recursively by + gBS->DisconnectController(). + + @retval EFI_SUCCESS All handles have been disconnected + @retval EFI_STATUS Error status returned by of gBS->LocateHandleBuffer(). + +**/ +EFI_STATUS +EFIAPI +BdsLibDisconnectAllEfi ( + VOID + ) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + + // + // Disconnect all + // + Status = gBS->LocateHandleBuffer ( + AllHandles, + NULL, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); + } + + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + } + + return EFI_SUCCESS; +} + + +/** + Connects all drivers to all controllers. + This function make sure all the current system driver will manage + the correspoinding controllers if have. And at the same time, make + sure all the system controllers have driver to manage it if have. + +**/ +VOID +EFIAPI +BdsLibConnectAllDriversToAllControllers ( + VOID + ) +{ + EFI_STATUS Status; + + do { + // + // Connect All EFI 1.10 drivers following EFI 1.10 algorithm + // + BdsLibConnectAllEfi (); + + // + // Check to see if it's possible to dispatch an more DXE drivers. + // The BdsLibConnectAllEfi () may have made new DXE drivers show up. + // If anything is Dispatched Status == EFI_SUCCESS and we will try + // the connect again. + // + Status = gDS->Dispatch (); + + } while (!EFI_ERROR (Status)); + +} + + +/** + Connect the specific Usb device which match the short form device path, + and whose bus is determined by Host Controller (Uhci or Ehci). + + @param HostControllerPI Uhci (0x00) or Ehci (0x20) or Both uhci and ehci + (0xFF) + @param RemainingDevicePath a short-form device path that starts with the first + element being a USB WWID or a USB Class device + path + + @return EFI_INVALID_PARAMETER RemainingDevicePath is NULL pointer. + RemainingDevicePath is not a USB device path. + Invalid HostControllerPI type. + @return EFI_SUCCESS Success to connect USB device + @return EFI_NOT_FOUND Fail to find handle for USB controller to connect. + +**/ +EFI_STATUS +EFIAPI +BdsLibConnectUsbDevByShortFormDP( + IN UINT8 HostControllerPI, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleArray; + UINTN HandleArrayCount; + UINTN Index; + EFI_PCI_IO_PROTOCOL *PciIo; + UINT8 Class[3]; + BOOLEAN AtLeastOneConnected; + + // + // Check the passed in parameters + // + if (RemainingDevicePath == NULL) { + return EFI_INVALID_PARAMETER; + } + + if ((DevicePathType (RemainingDevicePath) != MESSAGING_DEVICE_PATH) || + ((DevicePathSubType (RemainingDevicePath) != MSG_USB_CLASS_DP) + && (DevicePathSubType (RemainingDevicePath) != MSG_USB_WWID_DP) + )) { + return EFI_INVALID_PARAMETER; + } + + if (HostControllerPI != 0xFF && + HostControllerPI != 0x00 && + HostControllerPI != 0x20) { + return EFI_INVALID_PARAMETER; + } + + // + // Find the usb host controller firstly, then connect with the remaining device path + // + AtLeastOneConnected = FALSE; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiPciIoProtocolGuid, + NULL, + &HandleArrayCount, + &HandleArray + ); + if (!EFI_ERROR (Status)) { + for (Index = 0; Index < HandleArrayCount; Index++) { + Status = gBS->HandleProtocol ( + HandleArray[Index], + &gEfiPciIoProtocolGuid, + (VOID **)&PciIo + ); + if (!EFI_ERROR (Status)) { + // + // Check whether the Pci device is the wanted usb host controller + // + Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class); + if (!EFI_ERROR (Status)) { + if ((PCI_CLASS_SERIAL == Class[2]) && + (PCI_CLASS_SERIAL_USB == Class[1])) { + if (HostControllerPI == Class[0] || HostControllerPI == 0xFF) { + Status = gBS->ConnectController ( + HandleArray[Index], + NULL, + RemainingDevicePath, + FALSE + ); + if (!EFI_ERROR(Status)) { + AtLeastOneConnected = TRUE; + } + } + } + } + } + } + + if (HandleArray != NULL) { + FreePool (HandleArray); + } + + if (AtLeastOneConnected) { + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} diff --git a/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c new file mode 100644 index 0000000000..7832fc49c7 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c @@ -0,0 +1,1301 @@ +/** @file + BDS Lib functions which contain all the code to connect console device + +Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which 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 "InternalBdsLib.h" +#include + + +/** + Check if we need to save the EFI variable with "ConVarName" as name + as NV type + If ConVarName is NULL, then ASSERT(). + + @param ConVarName The name of the EFI variable. + + @retval TRUE Set the EFI variable as NV type. + @retval FALSE EFI variable as NV type can be set NonNV. +**/ +BOOLEAN +IsNvNeed ( + IN CHAR16 *ConVarName + ) +{ + CHAR16 *Ptr; + + ASSERT (ConVarName != NULL); + + Ptr = ConVarName; + + // + // If the variable includes "Dev" at last, we consider + // it does not support NV attribute. + // + while (*Ptr != L'\0') { + Ptr++; + } + + if (((INTN)((UINTN)Ptr - (UINTN)ConVarName) / sizeof (CHAR16)) <= 3) { + return TRUE; + } + + if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) { + return FALSE; + } else { + return TRUE; + } +} + +/** + Fill console handle in System Table if there are no valid console handle in. + + Firstly, check the validation of console handle in System Table. If it is invalid, + update it by the first console device handle from EFI console variable. + + @param VarName The name of the EFI console variable. + @param ConsoleGuid Specified Console protocol GUID. + @param ConsoleHandle On IN, console handle in System Table to be checked. + On OUT, new console handle in system table. + @param ProtocolInterface On IN, console protocol on console handle in System Table to be checked. + On OUT, new console protocol on new console handle in system table. + + @retval TRUE System Table has been updated. + @retval FALSE System Table hasn't been updated. + +**/ +BOOLEAN +UpdateSystemTableConsole ( + IN CHAR16 *VarName, + IN EFI_GUID *ConsoleGuid, + IN OUT EFI_HANDLE *ConsoleHandle, + IN OUT VOID **ProtocolInterface + ) +{ + EFI_STATUS Status; + UINTN DevicePathSize; + EFI_DEVICE_PATH_PROTOCOL *FullDevicePath; + EFI_DEVICE_PATH_PROTOCOL *VarConsole; + EFI_DEVICE_PATH_PROTOCOL *Instance; + VOID *Interface; + EFI_HANDLE NewHandle; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut; + + ASSERT (VarName != NULL); + ASSERT (ConsoleHandle != NULL); + ASSERT (ConsoleGuid != NULL); + ASSERT (ProtocolInterface != NULL); + + if (*ConsoleHandle != NULL) { + Status = gBS->HandleProtocol ( + *ConsoleHandle, + ConsoleGuid, + &Interface + ); + if (Status == EFI_SUCCESS && Interface == *ProtocolInterface) { + // + // If ConsoleHandle is valid and console protocol on this handle also + // also matched, just return. + // + return FALSE; + } + } + + // + // Get all possible consoles device path from EFI variable + // + VarConsole = BdsLibGetVariableAndSize ( + VarName, + &gEfiGlobalVariableGuid, + &DevicePathSize + ); + if (VarConsole == NULL) { + // + // If there is no any console device, just return. + // + return FALSE; + } + + FullDevicePath = VarConsole; + + do { + // + // Check every instance of the console variable + // + Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize); + if (Instance == NULL) { + FreePool (FullDevicePath); + ASSERT (FALSE); + } + + // + // Find console device handle by device path instance + // + Status = gBS->LocateDevicePath ( + ConsoleGuid, + &Instance, + &NewHandle + ); + if (!EFI_ERROR (Status)) { + // + // Get the console protocol on this console device handle + // + Status = gBS->HandleProtocol ( + NewHandle, + ConsoleGuid, + &Interface + ); + if (!EFI_ERROR (Status)) { + // + // Update new console handle in System Table. + // + *ConsoleHandle = NewHandle; + *ProtocolInterface = Interface; + if (CompareGuid (ConsoleGuid, &gEfiSimpleTextOutProtocolGuid)) { + // + // If it is console out device, set console mode 80x25 if current mode is invalid. + // + TextOut = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *) Interface; + if (TextOut->Mode->Mode == -1) { + TextOut->SetMode (TextOut, 0); + } + } + return TRUE; + } + } + + } while (Instance != NULL); + + // + // No any available console devcie found. + // + return FALSE; +} + +/** + This function update console variable based on ConVarName, it can + add or remove one specific console device path from the variable + + @param ConVarName Console related variable name, ConIn, ConOut, + ErrOut. + @param CustomizedConDevicePath The console device path which will be added to + the console variable ConVarName, this parameter + can not be multi-instance. + @param ExclusiveDevicePath The console device path which will be removed + from the console variable ConVarName, this + parameter can not be multi-instance. + + @retval EFI_UNSUPPORTED The added device path is same to the removed one. + @retval EFI_SUCCESS Success add or remove the device path from the + console variable. + +**/ +EFI_STATUS +EFIAPI +BdsLibUpdateConsoleVariable ( + IN CHAR16 *ConVarName, + IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath, + IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *VarConsole; + UINTN DevicePathSize; + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath; + UINT32 Attributes; + + VarConsole = NULL; + DevicePathSize = 0; + + // + // Notes: check the device path point, here should check + // with compare memory + // + if (CustomizedConDevicePath == ExclusiveDevicePath) { + return EFI_UNSUPPORTED; + } + // + // Delete the ExclusiveDevicePath from current default console + // + VarConsole = BdsLibGetVariableAndSize ( + ConVarName, + &gEfiGlobalVariableGuid, + &DevicePathSize + ); + + // + // Initialize NewDevicePath + // + NewDevicePath = VarConsole; + + // + // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it. + // In the end, NewDevicePath is the final device path. + // + if (ExclusiveDevicePath != NULL && VarConsole != NULL) { + NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath); + } + // + // Try to append customized device path to NewDevicePath. + // + if (CustomizedConDevicePath != NULL) { + if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) { + // + // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it. + // + NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath); + // + // In the first check, the default console variable will be _ModuleEntryPoint, + // just append current customized device path + // + TempNewDevicePath = NewDevicePath; + NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath); + if (TempNewDevicePath != NULL) { + FreePool(TempNewDevicePath); + } + } + } + + // + // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV. + // + if (IsNvNeed(ConVarName)) { + // + // ConVarName has NV attribute. + // + Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE; + } else { + // + // ConVarName does not have NV attribute. + // + Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; + } + + // + // Finally, Update the variable of the default console by NewDevicePath + // + DevicePathSize = GetDevicePathSize (NewDevicePath); + Status = SetVariableAndReportStatusCodeOnError ( + ConVarName, + &gEfiGlobalVariableGuid, + Attributes, + DevicePathSize, + NewDevicePath + ); + if ((DevicePathSize == 0) && (Status == EFI_NOT_FOUND)) { + Status = EFI_SUCCESS; + } + + if (VarConsole == NewDevicePath) { + if (VarConsole != NULL) { + FreePool(VarConsole); + } + } else { + if (VarConsole != NULL) { + FreePool(VarConsole); + } + if (NewDevicePath != NULL) { + FreePool(NewDevicePath); + } + } + + return Status; + +} + + +/** + Connect the console device base on the variable ConVarName, if + device path of the ConVarName is multi-instance device path and + anyone of the instances is connected success, then this function + will return success. + If the handle associate with one device path node can not + be created successfully, then still give chance to do the dispatch, + which load the missing drivers if possible.. + + @param ConVarName Console related variable name, ConIn, ConOut, + ErrOut. + + @retval EFI_NOT_FOUND There is not any console devices connected + success + @retval EFI_SUCCESS Success connect any one instance of the console + device path base on the variable ConVarName. + +**/ +EFI_STATUS +EFIAPI +BdsLibConnectConsoleVariable ( + IN CHAR16 *ConVarName + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *StartDevicePath; + UINTN VariableSize; + EFI_DEVICE_PATH_PROTOCOL *Instance; + EFI_DEVICE_PATH_PROTOCOL *Next; + EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath; + UINTN Size; + BOOLEAN DeviceExist; + + Status = EFI_SUCCESS; + DeviceExist = FALSE; + + // + // Check if the console variable exist + // + StartDevicePath = BdsLibGetVariableAndSize ( + ConVarName, + &gEfiGlobalVariableGuid, + &VariableSize + ); + if (StartDevicePath == NULL) { + return EFI_UNSUPPORTED; + } + + CopyOfDevicePath = StartDevicePath; + do { + // + // Check every instance of the console variable + // + Instance = GetNextDevicePathInstance (&CopyOfDevicePath, &Size); + if (Instance == NULL) { + FreePool (StartDevicePath); + return EFI_UNSUPPORTED; + } + + Next = Instance; + while (!IsDevicePathEndType (Next)) { + Next = NextDevicePathNode (Next); + } + + SetDevicePathEndNode (Next); + // + // Connect the USB console + // USB console device path is a short-form device path that + // starts with the first element being a USB WWID + // or a USB Class device path + // + if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) && + ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP) + || (DevicePathSubType (Instance) == MSG_USB_WWID_DP) + )) { + Status = BdsLibConnectUsbDevByShortFormDP (0xFF, Instance); + if (!EFI_ERROR (Status)) { + DeviceExist = TRUE; + } + } else { + // + // Connect the instance device path + // + Status = BdsLibConnectDevicePath (Instance); + + if (EFI_ERROR (Status)) { + // + // Delete the instance from the console varialbe + // + BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance); + } else { + DeviceExist = TRUE; + } + } + FreePool(Instance); + } while (CopyOfDevicePath != NULL); + + FreePool (StartDevicePath); + + if (!DeviceExist) { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +/** + This function will search every simpletext device in current system, + and make every simpletext device as pertantial console device. + +**/ +VOID +EFIAPI +BdsLibConnectAllConsoles ( + VOID + ) +{ + UINTN Index; + EFI_DEVICE_PATH_PROTOCOL *ConDevicePath; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + + Index = 0; + HandleCount = 0; + HandleBuffer = NULL; + ConDevicePath = NULL; + + // + // Update all the console variables + // + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimpleTextInProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + + for (Index = 0; Index < HandleCount; Index++) { + gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiDevicePathProtocolGuid, + (VOID **) &ConDevicePath + ); + BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL); + } + + if (HandleBuffer != NULL) { + FreePool(HandleBuffer); + HandleBuffer = NULL; + } + + gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiSimpleTextOutProtocolGuid, + NULL, + &HandleCount, + &HandleBuffer + ); + for (Index = 0; Index < HandleCount; Index++) { + gBS->HandleProtocol ( + HandleBuffer[Index], + &gEfiDevicePathProtocolGuid, + (VOID **) &ConDevicePath + ); + BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL); + BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL); + } + + if (HandleBuffer != NULL) { + FreePool(HandleBuffer); + } + + // + // Connect all console variables + // + BdsLibConnectAllDefaultConsoles (); + +} + +/** + This function will connect console device base on the console + device variable ConIn, ConOut and ErrOut. + + @retval EFI_SUCCESS At least one of the ConIn and ConOut device have + been connected success. + @retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable (). + +**/ +EFI_STATUS +EFIAPI +BdsLibConnectAllDefaultConsoles ( + VOID + ) +{ + EFI_STATUS Status; + BOOLEAN SystemTableUpdated; + + // + // Connect all default console variables + // + + // + // It seems impossible not to have any ConOut device on platform, + // so we check the status here. + // + Status = BdsLibConnectConsoleVariable (L"ConOut"); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Insert the performance probe for Console Out + // + PERF_START (NULL, "ConOut", "BDS", 1); + PERF_END (NULL, "ConOut", "BDS", 0); + + // + // Because possibly the platform is legacy free, in such case, + // ConIn devices (Serial Port and PS2 Keyboard ) does not exist, + // so we need not check the status. + // + BdsLibConnectConsoleVariable (L"ConIn"); + + // + // The _ModuleEntryPoint err out var is legal. + // + BdsLibConnectConsoleVariable (L"ErrOut"); + + SystemTableUpdated = FALSE; + // + // Fill console handles in System Table if no console device assignd. + // + if (UpdateSystemTableConsole (L"ConIn", &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **) &gST->ConIn)) { + SystemTableUpdated = TRUE; + } + if (UpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **) &gST->ConOut)) { + SystemTableUpdated = TRUE; + } + if (UpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **) &gST->StdErr)) { + SystemTableUpdated = TRUE; + } + + if (SystemTableUpdated) { + // + // Update the CRC32 in the EFI System Table header + // + gST->Hdr.CRC32 = 0; + gBS->CalculateCrc32 ( + (UINT8 *) &gST->Hdr, + gST->Hdr.HeaderSize, + &gST->Hdr.CRC32 + ); + } + + return EFI_SUCCESS; + +} + +/** + This function will connect console device except ConIn base on the console + device variable ConOut and ErrOut. + + @retval EFI_SUCCESS At least one of the ConOut device have + been connected success. + @retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable (). + +**/ +EFI_STATUS +EFIAPI +BdsLibConnectAllDefaultConsolesWithOutConIn ( + VOID + ) +{ + EFI_STATUS Status; + BOOLEAN SystemTableUpdated; + + // + // Connect all default console variables except ConIn + // + + // + // It seems impossible not to have any ConOut device on platform, + // so we check the status here. + // + Status = BdsLibConnectConsoleVariable (L"ConOut"); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Insert the performance probe for Console Out + // + PERF_START (NULL, "ConOut", "BDS", 1); + PERF_END (NULL, "ConOut", "BDS", 0); + + // + // The _ModuleEntryPoint err out var is legal. + // + BdsLibConnectConsoleVariable (L"ErrOut"); + + SystemTableUpdated = FALSE; + // + // Fill console handles in System Table if no console device assignd. + // + if (UpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **) &gST->ConOut)) { + SystemTableUpdated = TRUE; + } + if (UpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **) &gST->StdErr)) { + SystemTableUpdated = TRUE; + } + + if (SystemTableUpdated) { + // + // Update the CRC32 in the EFI System Table header + // + gST->Hdr.CRC32 = 0; + gBS->CalculateCrc32 ( + (UINT8 *) &gST->Hdr, + gST->Hdr.HeaderSize, + &gST->Hdr.CRC32 + ); + } + + return EFI_SUCCESS; + +} + +/** + Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer + is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt + buffer is passed in it will be used if it is big enough. + + @param BmpImage Pointer to BMP file + @param BmpImageSize Number of bytes in BmpImage + @param GopBlt Buffer containing GOP version of BmpImage. + @param GopBltSize Size of GopBlt in bytes. + @param PixelHeight Height of GopBlt/BmpImage in pixels + @param PixelWidth Width of GopBlt/BmpImage in pixels + + @retval EFI_SUCCESS GopBlt and GopBltSize are returned. + @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image + @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough. + GopBltSize will contain the required size. + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate. + +**/ +EFI_STATUS +ConvertBmpToGopBlt ( + IN VOID *BmpImage, + IN UINTN BmpImageSize, + IN OUT VOID **GopBlt, + IN OUT UINTN *GopBltSize, + OUT UINTN *PixelHeight, + OUT UINTN *PixelWidth + ) +{ + UINT8 *Image; + UINT8 *ImageHeader; + BMP_IMAGE_HEADER *BmpHeader; + BMP_COLOR_MAP *BmpColorMap; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; + UINT64 BltBufferSize; + UINTN Index; + UINTN Height; + UINTN Width; + UINTN ImageIndex; + UINT32 DataSizePerLine; + BOOLEAN IsAllocated; + UINT32 ColorMapNum; + + if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) { + return EFI_INVALID_PARAMETER; + } + + BmpHeader = (BMP_IMAGE_HEADER *) BmpImage; + + if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') { + return EFI_UNSUPPORTED; + } + + // + // Doesn't support compress. + // + if (BmpHeader->CompressionType != 0) { + return EFI_UNSUPPORTED; + } + + // + // Only support BITMAPINFOHEADER format. + // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER + // + if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) { + return EFI_UNSUPPORTED; + } + + // + // The data size in each line must be 4 byte alignment. + // + DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3); + BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight); + if (BltBufferSize > (UINT32) ~0) { + return EFI_INVALID_PARAMETER; + } + + if ((BmpHeader->Size != BmpImageSize) || + (BmpHeader->Size < BmpHeader->ImageOffset) || + (BmpHeader->Size - BmpHeader->ImageOffset != BmpHeader->PixelHeight * DataSizePerLine)) { + return EFI_INVALID_PARAMETER; + } + + // + // Calculate Color Map offset in the image. + // + Image = BmpImage; + BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER)); + if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) { + return EFI_INVALID_PARAMETER; + } + + if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) { + switch (BmpHeader->BitPerPixel) { + case 1: + ColorMapNum = 2; + break; + case 4: + ColorMapNum = 16; + break; + case 8: + ColorMapNum = 256; + break; + default: + ColorMapNum = 0; + break; + } + // + // BMP file may has padding data between the bmp header section and the bmp data section. + // + if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum) { + return EFI_INVALID_PARAMETER; + } + } + + // + // Calculate graphics image data address in the image + // + Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset; + ImageHeader = Image; + + // + // Calculate the BltBuffer needed size. + // + BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight); + // + // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow + // + if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) { + return EFI_UNSUPPORTED; + } + BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + + IsAllocated = FALSE; + if (*GopBlt == NULL) { + // + // GopBlt is not allocated by caller. + // + *GopBltSize = (UINTN) BltBufferSize; + *GopBlt = AllocatePool (*GopBltSize); + IsAllocated = TRUE; + if (*GopBlt == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } else { + // + // GopBlt has been allocated by caller. + // + if (*GopBltSize < (UINTN) BltBufferSize) { + *GopBltSize = (UINTN) BltBufferSize; + return EFI_BUFFER_TOO_SMALL; + } + } + + *PixelWidth = BmpHeader->PixelWidth; + *PixelHeight = BmpHeader->PixelHeight; + + // + // Convert image from BMP to Blt buffer format + // + BltBuffer = *GopBlt; + for (Height = 0; Height < BmpHeader->PixelHeight; Height++) { + Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth]; + for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) { + switch (BmpHeader->BitPerPixel) { + case 1: + // + // Convert 1-bit (2 colors) BMP to 24-bit color + // + for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) { + Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red; + Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green; + Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue; + Blt++; + Width++; + } + + Blt--; + Width--; + break; + + case 4: + // + // Convert 4-bit (16 colors) BMP Palette to 24-bit color + // + Index = (*Image) >> 4; + Blt->Red = BmpColorMap[Index].Red; + Blt->Green = BmpColorMap[Index].Green; + Blt->Blue = BmpColorMap[Index].Blue; + if (Width < (BmpHeader->PixelWidth - 1)) { + Blt++; + Width++; + Index = (*Image) & 0x0f; + Blt->Red = BmpColorMap[Index].Red; + Blt->Green = BmpColorMap[Index].Green; + Blt->Blue = BmpColorMap[Index].Blue; + } + break; + + case 8: + // + // Convert 8-bit (256 colors) BMP Palette to 24-bit color + // + Blt->Red = BmpColorMap[*Image].Red; + Blt->Green = BmpColorMap[*Image].Green; + Blt->Blue = BmpColorMap[*Image].Blue; + break; + + case 24: + // + // It is 24-bit BMP. + // + Blt->Blue = *Image++; + Blt->Green = *Image++; + Blt->Red = *Image; + break; + + default: + // + // Other bit format BMP is not supported. + // + if (IsAllocated) { + FreePool (*GopBlt); + *GopBlt = NULL; + } + return EFI_UNSUPPORTED; + break; + }; + + } + + ImageIndex = (UINTN) (Image - ImageHeader); + if ((ImageIndex % 4) != 0) { + // + // Bmp Image starts each row on a 32-bit boundary! + // + Image = Image + (4 - (ImageIndex % 4)); + } + } + + return EFI_SUCCESS; +} + +/** + Use SystemTable Conout to stop video based Simple Text Out consoles from going + to the video device. Put up LogoFile on every video device that is a console. + + @param[in] LogoFile File name of logo to display on the center of the screen. + + @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed. + @retval EFI_UNSUPPORTED Logo not found + +**/ +EFI_STATUS +EFIAPI +EnableQuietBoot ( + IN EFI_GUID *LogoFile + ) +{ + EFI_STATUS Status; + EFI_OEM_BADGING_PROTOCOL *Badging; + UINT32 SizeOfX; + UINT32 SizeOfY; + INTN DestX; + INTN DestY; + UINT8 *ImageData; + UINTN ImageSize; + UINTN BltSize; + UINT32 Instance; + EFI_BADGING_FORMAT Format; + EFI_BADGING_DISPLAY_ATTRIBUTE Attribute; + UINTN CoordinateX; + UINTN CoordinateY; + UINTN Height; + UINTN Width; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; + EFI_UGA_DRAW_PROTOCOL *UgaDraw; + UINT32 ColorDepth; + UINT32 RefreshRate; + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; + EFI_BOOT_LOGO_PROTOCOL *BootLogo; + UINTN NumberOfLogos; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt; + UINTN LogoDestX; + UINTN LogoDestY; + UINTN LogoHeight; + UINTN LogoWidth; + UINTN NewDestX; + UINTN NewDestY; + UINTN NewHeight; + UINTN NewWidth; + UINT64 BufferSize; + + UgaDraw = NULL; + // + // Try to open GOP first + // + Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput); + if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) { + GraphicsOutput = NULL; + // + // Open GOP failed, try to open UGA + // + Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw); + } + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + // + // Try to open Boot Logo Protocol. + // + BootLogo = NULL; + gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo); + + // + // Erase Cursor from screen + // + gST->ConOut->EnableCursor (gST->ConOut, FALSE); + + Badging = NULL; + Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging); + + if (GraphicsOutput != NULL) { + SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution; + SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution; + + } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { + Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + } else { + return EFI_UNSUPPORTED; + } + + Blt = NULL; + NumberOfLogos = 0; + LogoDestX = 0; + LogoDestY = 0; + LogoHeight = 0; + LogoWidth = 0; + NewDestX = 0; + NewDestY = 0; + NewHeight = 0; + NewWidth = 0; + Instance = 0; + while (1) { + ImageData = NULL; + ImageSize = 0; + + if (Badging != NULL) { + // + // Get image from OEMBadging protocol. + // + Status = Badging->GetImage ( + Badging, + &Instance, + &Format, + &ImageData, + &ImageSize, + &Attribute, + &CoordinateX, + &CoordinateY + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + // + // Currently only support BMP format. + // + if (Format != EfiBadgingFormatBMP) { + if (ImageData != NULL) { + FreePool (ImageData); + } + continue; + } + } else { + // + // Get the specified image from FV. + // + Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + + CoordinateX = 0; + CoordinateY = 0; + if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { + Attribute = EfiBadgingDisplayAttributeCenter; + } else { + Attribute = EfiBadgingDisplayAttributeCustomized; + } + } + + if (Blt != NULL) { + FreePool (Blt); + } + Blt = NULL; + Status = ConvertBmpToGopBlt ( + ImageData, + ImageSize, + (VOID **) &Blt, + &BltSize, + &Height, + &Width + ); + if (EFI_ERROR (Status)) { + FreePool (ImageData); + + if (Badging == NULL) { + return Status; + } else { + continue; + } + } + + // + // Calculate the display position according to Attribute. + // + switch (Attribute) { + case EfiBadgingDisplayAttributeLeftTop: + DestX = CoordinateX; + DestY = CoordinateY; + break; + + case EfiBadgingDisplayAttributeCenterTop: + DestX = (SizeOfX - Width) / 2; + DestY = CoordinateY; + break; + + case EfiBadgingDisplayAttributeRightTop: + DestX = (SizeOfX - Width - CoordinateX); + DestY = CoordinateY;; + break; + + case EfiBadgingDisplayAttributeCenterRight: + DestX = (SizeOfX - Width - CoordinateX); + DestY = (SizeOfY - Height) / 2; + break; + + case EfiBadgingDisplayAttributeRightBottom: + DestX = (SizeOfX - Width - CoordinateX); + DestY = (SizeOfY - Height - CoordinateY); + break; + + case EfiBadgingDisplayAttributeCenterBottom: + DestX = (SizeOfX - Width) / 2; + DestY = (SizeOfY - Height - CoordinateY); + break; + + case EfiBadgingDisplayAttributeLeftBottom: + DestX = CoordinateX; + DestY = (SizeOfY - Height - CoordinateY); + break; + + case EfiBadgingDisplayAttributeCenterLeft: + DestX = CoordinateX; + DestY = (SizeOfY - Height) / 2; + break; + + case EfiBadgingDisplayAttributeCenter: + DestX = (SizeOfX - Width) / 2; + DestY = (SizeOfY - Height) / 2; + break; + + case EfiBadgingDisplayAttributeCustomized: + DestX = (SizeOfX - Width) / 2; + DestY = ((SizeOfY * 382) / 1000) - Height / 2; + break; + + default: + DestX = CoordinateX; + DestY = CoordinateY; + break; + } + + if ((DestX >= 0) && (DestY >= 0)) { + if (GraphicsOutput != NULL) { + Status = GraphicsOutput->Blt ( + GraphicsOutput, + Blt, + EfiBltBufferToVideo, + 0, + 0, + (UINTN) DestX, + (UINTN) DestY, + Width, + Height, + Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { + Status = UgaDraw->Blt ( + UgaDraw, + (EFI_UGA_PIXEL *) Blt, + EfiUgaBltBufferToVideo, + 0, + 0, + (UINTN) DestX, + (UINTN) DestY, + Width, + Height, + Width * sizeof (EFI_UGA_PIXEL) + ); + } else { + Status = EFI_UNSUPPORTED; + } + + // + // Report displayed Logo information. + // + if (!EFI_ERROR (Status)) { + NumberOfLogos++; + + if (LogoWidth == 0) { + // + // The first Logo. + // + LogoDestX = (UINTN) DestX; + LogoDestY = (UINTN) DestY; + LogoWidth = Width; + LogoHeight = Height; + } else { + // + // Merge new logo with old one. + // + NewDestX = MIN ((UINTN) DestX, LogoDestX); + NewDestY = MIN ((UINTN) DestY, LogoDestY); + NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX; + NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY; + + LogoDestX = NewDestX; + LogoDestY = NewDestY; + LogoWidth = NewWidth; + LogoHeight = NewHeight; + } + } + } + + FreePool (ImageData); + + if (Badging == NULL) { + break; + } + } + +Done: + if (BootLogo == NULL || NumberOfLogos == 0) { + // + // No logo displayed. + // + if (Blt != NULL) { + FreePool (Blt); + } + + return Status; + } + + // + // Advertise displayed Logo information. + // + if (NumberOfLogos == 1) { + // + // Only one logo displayed, use its Blt buffer directly for BootLogo protocol. + // + LogoBlt = Blt; + Status = EFI_SUCCESS; + } else { + // + // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation. + // + if (Blt != NULL) { + FreePool (Blt); + } + + // + // Ensure the LogoHeight * LogoWidth doesn't overflow + // + if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) { + return EFI_UNSUPPORTED; + } + BufferSize = MultU64x64 (LogoWidth, LogoHeight); + + // + // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow + // + if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) { + return EFI_UNSUPPORTED; + } + + LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + if (LogoBlt == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (GraphicsOutput != NULL) { + Status = GraphicsOutput->Blt ( + GraphicsOutput, + LogoBlt, + EfiBltVideoToBltBuffer, + LogoDestX, + LogoDestY, + 0, + 0, + LogoWidth, + LogoHeight, + LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + ); + } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { + Status = UgaDraw->Blt ( + UgaDraw, + (EFI_UGA_PIXEL *) LogoBlt, + EfiUgaVideoToBltBuffer, + LogoDestX, + LogoDestY, + 0, + 0, + LogoWidth, + LogoHeight, + LogoWidth * sizeof (EFI_UGA_PIXEL) + ); + } else { + Status = EFI_UNSUPPORTED; + } + } + + if (!EFI_ERROR (Status)) { + BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight); + } + FreePool (LogoBlt); + + return Status; +} + +/** + Use SystemTable Conout to turn on video based Simple Text Out consoles. The + Simple Text Out screens will now be synced up with all non video output devices + + @retval EFI_SUCCESS UGA devices are back in text mode and synced up. + +**/ +EFI_STATUS +EFIAPI +DisableQuietBoot ( + VOID + ) +{ + + // + // Enable Cursor on Screen + // + gST->ConOut->EnableCursor (gST->ConOut, TRUE); + return EFI_SUCCESS; +} + diff --git a/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c new file mode 100644 index 0000000000..29854563f5 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c @@ -0,0 +1,1589 @@ +/** @file + Misc BDS library function + +Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which 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 "InternalBdsLib.h" + + +#define MAX_STRING_LEN 200 + +BOOLEAN mFeaturerSwitch = TRUE; +BOOLEAN mResetRequired = FALSE; + +extern UINT16 gPlatformBootTimeOutDefault; + +/** + The function will go through the driver option link list, load and start + every driver the driver option device path point to. + + @param BdsDriverLists The header of the current driver option link list + +**/ +VOID +EFIAPI +BdsLibLoadDrivers ( + IN LIST_ENTRY *BdsDriverLists + ) +{ + EFI_STATUS Status; + LIST_ENTRY *Link; + BDS_COMMON_OPTION *Option; + EFI_HANDLE ImageHandle; + EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; + UINTN ExitDataSize; + CHAR16 *ExitData; + BOOLEAN ReconnectAll; + + ReconnectAll = FALSE; + + // + // Process the driver option + // + for (Link = BdsDriverLists->ForwardLink; Link != BdsDriverLists; Link = Link->ForwardLink) { + Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE); + + // + // If a load option is not marked as LOAD_OPTION_ACTIVE, + // the boot manager will not automatically load the option. + // + if (!IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_ACTIVE)) { + continue; + } + + // + // If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT, + // then all of the EFI drivers in the system will be disconnected and + // reconnected after the last driver load option is processed. + // + if (IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_FORCE_RECONNECT)) { + ReconnectAll = TRUE; + } + + // + // Make sure the driver path is connected. + // + BdsLibConnectDevicePath (Option->DevicePath); + + // + // Load and start the image that Driver#### describes + // + Status = gBS->LoadImage ( + FALSE, + gImageHandle, + Option->DevicePath, + NULL, + 0, + &ImageHandle + ); + + if (!EFI_ERROR (Status)) { + gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo); + + // + // Verify whether this image is a driver, if not, + // exit it and continue to parse next load option + // + if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) { + gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL); + continue; + } + + if (Option->LoadOptionsSize != 0) { + ImageInfo->LoadOptionsSize = Option->LoadOptionsSize; + ImageInfo->LoadOptions = Option->LoadOptions; + } + // + // Before calling the image, enable the Watchdog Timer for + // the 5 Minute period + // + gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL); + + Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData); + DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Driver Return Status = %r\n", Status)); + + // + // Clear the Watchdog Timer after the image returns + // + gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL); + } + } + + // + // Process the LOAD_OPTION_FORCE_RECONNECT driver option + // + if (ReconnectAll) { + BdsLibDisconnectAllEfi (); + BdsLibConnectAll (); + } + +} + +/** + Get the Option Number that does not used. + Try to locate the specific option variable one by one utile find a free number. + + @param VariableName Indicate if the boot#### or driver#### option + + @return The Minimal Free Option Number + +**/ +UINT16 +BdsLibGetFreeOptionNumber ( + IN CHAR16 *VariableName + ) +{ + UINTN Index; + CHAR16 StrTemp[10]; + UINT16 *OptionBuffer; + UINTN OptionSize; + + // + // Try to find the minimum free number from 0, 1, 2, 3.... + // + Index = 0; + do { + if (*VariableName == 'B') { + UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Boot%04x", Index); + } else { + UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Driver%04x", Index); + } + // + // try if the option number is used + // + OptionBuffer = BdsLibGetVariableAndSize ( + StrTemp, + &gEfiGlobalVariableGuid, + &OptionSize + ); + if (OptionBuffer == NULL) { + break; + } + FreePool(OptionBuffer); + Index++; + } while (TRUE); + + return ((UINT16) Index); +} + + +/** + This function will register the new boot#### or driver#### option base on + the VariableName. The new registered boot#### or driver#### will be linked + to BdsOptionList and also update to the VariableName. After the boot#### or + driver#### updated, the BootOrder or DriverOrder will also be updated. + + @param BdsOptionList The header of the boot#### or driver#### link list + @param DevicePath The device path which the boot#### or driver#### + option present + @param String The description of the boot#### or driver#### + @param VariableName Indicate if the boot#### or driver#### option + + @retval EFI_SUCCESS The boot#### or driver#### have been success + registered + @retval EFI_STATUS Return the status of gRT->SetVariable (). + +**/ +EFI_STATUS +EFIAPI +BdsLibRegisterNewOption ( + IN LIST_ENTRY *BdsOptionList, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *String, + IN CHAR16 *VariableName + ) +{ + EFI_STATUS Status; + UINTN Index; + UINT16 RegisterOptionNumber; + UINT16 *TempOptionPtr; + UINTN TempOptionSize; + UINT16 *OptionOrderPtr; + VOID *OptionPtr; + UINTN OptionSize; + UINT8 *TempPtr; + EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath; + CHAR16 *Description; + CHAR16 OptionName[10]; + BOOLEAN UpdateDescription; + UINT16 BootOrderEntry; + UINTN OrderItemNum; + + if (DevicePath == NULL) { + return EFI_INVALID_PARAMETER; + } + + OptionPtr = NULL; + OptionSize = 0; + TempPtr = NULL; + OptionDevicePath = NULL; + Description = NULL; + OptionOrderPtr = NULL; + UpdateDescription = FALSE; + Status = EFI_SUCCESS; + ZeroMem (OptionName, sizeof (OptionName)); + + TempOptionSize = 0; + TempOptionPtr = BdsLibGetVariableAndSize ( + VariableName, + &gEfiGlobalVariableGuid, + &TempOptionSize + ); + // + // Compare with current option variable if the previous option is set in global variable. + // + for (Index = 0; Index < TempOptionSize / sizeof (UINT16); Index++) { + // + // TempOptionPtr must not be NULL if we have non-zero TempOptionSize. + // + ASSERT (TempOptionPtr != NULL); + + if (*VariableName == 'B') { + UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", TempOptionPtr[Index]); + } else { + UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", TempOptionPtr[Index]); + } + + OptionPtr = BdsLibGetVariableAndSize ( + OptionName, + &gEfiGlobalVariableGuid, + &OptionSize + ); + if (OptionPtr == NULL) { + continue; + } + + // + // Validate the variable. + // + if (!ValidateOption(OptionPtr, OptionSize)) { + FreePool(OptionPtr); + continue; + } + + TempPtr = OptionPtr; + TempPtr += sizeof (UINT32) + sizeof (UINT16); + Description = (CHAR16 *) TempPtr; + TempPtr += StrSize ((CHAR16 *) TempPtr); + OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr; + + // + // Notes: the description may will change base on the GetStringToken + // + if (CompareMem (OptionDevicePath, DevicePath, GetDevicePathSize (OptionDevicePath)) == 0) { + if (CompareMem (Description, String, StrSize (Description)) == 0) { + // + // Got the option, so just return + // + FreePool (OptionPtr); + FreePool (TempOptionPtr); + return EFI_SUCCESS; + } else { + // + // Option description changed, need update. + // + UpdateDescription = TRUE; + FreePool (OptionPtr); + break; + } + } + + FreePool (OptionPtr); + } + + OptionSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (String); + OptionSize += GetDevicePathSize (DevicePath); + OptionPtr = AllocateZeroPool (OptionSize); + ASSERT (OptionPtr != NULL); + + TempPtr = OptionPtr; + *(UINT32 *) TempPtr = LOAD_OPTION_ACTIVE; + TempPtr += sizeof (UINT32); + *(UINT16 *) TempPtr = (UINT16) GetDevicePathSize (DevicePath); + TempPtr += sizeof (UINT16); + CopyMem (TempPtr, String, StrSize (String)); + TempPtr += StrSize (String); + CopyMem (TempPtr, DevicePath, GetDevicePathSize (DevicePath)); + + if (UpdateDescription) { + // + // The number in option#### to be updated. + // In this case, we must have non-NULL TempOptionPtr. + // + ASSERT (TempOptionPtr != NULL); + RegisterOptionNumber = TempOptionPtr[Index]; + } else { + // + // The new option#### number + // + RegisterOptionNumber = BdsLibGetFreeOptionNumber(VariableName); + } + + if (*VariableName == 'B') { + UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", RegisterOptionNumber); + } else { + UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", RegisterOptionNumber); + } + + Status = gRT->SetVariable ( + OptionName, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + OptionSize, + OptionPtr + ); + // + // Return if only need to update a changed description or fail to set option. + // + if (EFI_ERROR (Status) || UpdateDescription) { + FreePool (OptionPtr); + if (TempOptionPtr != NULL) { + FreePool (TempOptionPtr); + } + return Status; + } + + FreePool (OptionPtr); + + // + // Update the option order variable + // + + // + // If no option order + // + if (TempOptionSize == 0) { + BootOrderEntry = 0; + Status = gRT->SetVariable ( + VariableName, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + sizeof (UINT16), + &BootOrderEntry + ); + if (TempOptionPtr != NULL) { + FreePool (TempOptionPtr); + } + return Status; + } + + // + // TempOptionPtr must not be NULL if TempOptionSize is not zero. + // + ASSERT (TempOptionPtr != NULL); + // + // Append the new option number to the original option order + // + OrderItemNum = (TempOptionSize / sizeof (UINT16)) + 1 ; + OptionOrderPtr = AllocateZeroPool ( OrderItemNum * sizeof (UINT16)); + ASSERT (OptionOrderPtr!= NULL); + CopyMem (OptionOrderPtr, TempOptionPtr, (OrderItemNum - 1) * sizeof (UINT16)); + + OptionOrderPtr[Index] = RegisterOptionNumber; + + Status = gRT->SetVariable ( + VariableName, + &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, + OrderItemNum * sizeof (UINT16), + OptionOrderPtr + ); + FreePool (TempOptionPtr); + FreePool (OptionOrderPtr); + + return Status; +} + +/** + Returns the size of a device path in bytes. + + This function returns the size, in bytes, of the device path data structure + specified by DevicePath including the end of device path node. If DevicePath + is NULL, then 0 is returned. If the length of the device path is bigger than + MaxSize, also return 0 to indicate this is an invalidate device path. + + @param DevicePath A pointer to a device path data structure. + @param MaxSize Max valid device path size. If big than this size, + return error. + + @retval 0 An invalid device path. + @retval Others The size of a device path in bytes. + +**/ +UINTN +GetDevicePathSizeEx ( + IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN UINTN MaxSize + ) +{ + UINTN Size; + UINTN NodeSize; + + if (DevicePath == NULL) { + return 0; + } + + // + // Search for the end of the device path structure + // + Size = 0; + while (!IsDevicePathEnd (DevicePath)) { + NodeSize = DevicePathNodeLength (DevicePath); + if (NodeSize < END_DEVICE_PATH_LENGTH) { + return 0; + } + Size += NodeSize; + if (Size > MaxSize) { + return 0; + } + DevicePath = NextDevicePathNode (DevicePath); + } + Size += DevicePathNodeLength (DevicePath); + if (Size > MaxSize) { + return 0; + } + + return Size; +} + +/** + Returns the length of a Null-terminated Unicode string. If the length is + bigger than MaxStringLen, return length 0 to indicate that this is an + invalidate string. + + This function returns the byte length of Unicode characters in the Null-terminated + Unicode string specified by String. + + If String is NULL, then ASSERT(). + If String is not aligned on a 16-bit boundary, then ASSERT(). + + @param String A pointer to a Null-terminated Unicode string. + @param MaxStringLen Max string len in this string. + + @retval 0 An invalid string. + @retval Others The length of String. + +**/ +UINTN +StrSizeEx ( + IN CONST CHAR16 *String, + IN UINTN MaxStringLen + ) +{ + UINTN Length; + + ASSERT (String != NULL && MaxStringLen != 0); + ASSERT (((UINTN) String & BIT0) == 0); + + for (Length = 0; *String != L'\0' && MaxStringLen != Length; String++, Length+=2); + + if (*String != L'\0' && MaxStringLen == Length) { + return 0; + } + + return Length + 2; +} + +/** + Validate the EFI Boot#### variable (VendorGuid/Name) + + @param Variable Boot#### variable data. + @param VariableSize Returns the size of the EFI variable that was read + + @retval TRUE The variable data is correct. + @retval FALSE The variable data is corrupted. + +**/ +BOOLEAN +ValidateOption ( + UINT8 *Variable, + UINTN VariableSize + ) +{ + UINT16 FilePathSize; + UINT8 *TempPtr; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN TempSize; + + if (VariableSize <= sizeof (UINT16) + sizeof (UINT32)) { + return FALSE; + } + + // + // Skip the option attribute + // + TempPtr = Variable; + TempPtr += sizeof (UINT32); + + // + // Get the option's device path size + // + FilePathSize = *(UINT16 *) TempPtr; + TempPtr += sizeof (UINT16); + + // + // Get the option's description string size + // + TempSize = StrSizeEx ((CHAR16 *) TempPtr, VariableSize - sizeof (UINT16) - sizeof (UINT32)); + TempPtr += TempSize; + + // + // Get the option's device path + // + DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr; + TempPtr += FilePathSize; + + // + // Validation boot option variable. + // + if ((FilePathSize == 0) || (TempSize == 0)) { + return FALSE; + } + + if (TempSize + FilePathSize + sizeof (UINT16) + sizeof (UINT32) > VariableSize) { + return FALSE; + } + + return (BOOLEAN) (GetDevicePathSizeEx (DevicePath, FilePathSize) != 0); +} + +/** + Convert a single character to number. + It assumes the input Char is in the scope of L'0' ~ L'9' and L'A' ~ L'F' + + @param Char The input char which need to change to a hex number. + +**/ +UINTN +CharToUint ( + IN CHAR16 Char + ) +{ + if ((Char >= L'0') && (Char <= L'9')) { + return (UINTN) (Char - L'0'); + } + + if ((Char >= L'A') && (Char <= L'F')) { + return (UINTN) (Char - L'A' + 0xA); + } + + ASSERT (FALSE); + return 0; +} + +/** + Build the boot#### or driver#### option from the VariableName, the + build boot#### or driver#### will also be linked to BdsCommonOptionList. + + @param BdsCommonOptionList The header of the boot#### or driver#### option + link list + @param VariableName EFI Variable name indicate if it is boot#### or + driver#### + + @retval BDS_COMMON_OPTION Get the option just been created + @retval NULL Failed to get the new option + +**/ +BDS_COMMON_OPTION * +EFIAPI +BdsLibVariableToOption ( + IN OUT LIST_ENTRY *BdsCommonOptionList, + IN CHAR16 *VariableName + ) +{ + UINT32 Attribute; + UINT16 FilePathSize; + UINT8 *Variable; + UINT8 *TempPtr; + UINTN VariableSize; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + BDS_COMMON_OPTION *Option; + VOID *LoadOptions; + UINT32 LoadOptionsSize; + CHAR16 *Description; + UINT8 NumOff; + + // + // Read the variable. We will never free this data. + // + Variable = BdsLibGetVariableAndSize ( + VariableName, + &gEfiGlobalVariableGuid, + &VariableSize + ); + if (Variable == NULL) { + return NULL; + } + + // + // Validate Boot#### variable data. + // + if (!ValidateOption(Variable, VariableSize)) { + FreePool (Variable); + return NULL; + } + + // + // Notes: careful defined the variable of Boot#### or + // Driver####, consider use some macro to abstract the code + // + // + // Get the option attribute + // + TempPtr = Variable; + Attribute = *(UINT32 *) Variable; + TempPtr += sizeof (UINT32); + + // + // Get the option's device path size + // + FilePathSize = *(UINT16 *) TempPtr; + TempPtr += sizeof (UINT16); + + // + // Get the option's description string + // + Description = (CHAR16 *) TempPtr; + + // + // Get the option's description string size + // + TempPtr += StrSize((CHAR16 *) TempPtr); + + // + // Get the option's device path + // + DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr; + TempPtr += FilePathSize; + + // + // Get load opion data. + // + LoadOptions = TempPtr; + LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable)); + + // + // The Console variables may have multiple device paths, so make + // an Entry for each one. + // + Option = AllocateZeroPool (sizeof (BDS_COMMON_OPTION)); + if (Option == NULL) { + FreePool (Variable); + return NULL; + } + + Option->Signature = BDS_LOAD_OPTION_SIGNATURE; + Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath)); + ASSERT(Option->DevicePath != NULL); + CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath)); + + Option->Attribute = Attribute; + Option->Description = AllocateZeroPool (StrSize (Description)); + ASSERT(Option->Description != NULL); + CopyMem (Option->Description, Description, StrSize (Description)); + + Option->LoadOptions = AllocateZeroPool (LoadOptionsSize); + ASSERT(Option->LoadOptions != NULL); + CopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize); + Option->LoadOptionsSize = LoadOptionsSize; + + // + // Get the value from VariableName Unicode string + // since the ISO standard assumes ASCII equivalent abbreviations, we can be safe in converting this + // Unicode stream to ASCII without any loss in meaning. + // + if (*VariableName == 'B') { + NumOff = (UINT8) (sizeof (L"Boot") / sizeof (CHAR16) - 1); + Option->BootCurrent = (UINT16) (CharToUint (VariableName[NumOff+0]) * 0x1000) + + (UINT16) (CharToUint (VariableName[NumOff+1]) * 0x100) + + (UINT16) (CharToUint (VariableName[NumOff+2]) * 0x10) + + (UINT16) (CharToUint (VariableName[NumOff+3]) * 0x1); + } + InsertTailList (BdsCommonOptionList, &Option->Link); + FreePool (Variable); + return Option; +} + +/** + Process BootOrder, or DriverOrder variables, by calling + BdsLibVariableToOption () for each UINT16 in the variables. + + @param BdsCommonOptionList The header of the option list base on variable + VariableName + @param VariableName EFI Variable name indicate the BootOrder or + DriverOrder + + @retval EFI_SUCCESS Success create the boot option or driver option + list + @retval EFI_OUT_OF_RESOURCES Failed to get the boot option or driver option list + +**/ +EFI_STATUS +EFIAPI +BdsLibBuildOptionFromVar ( + IN LIST_ENTRY *BdsCommonOptionList, + IN CHAR16 *VariableName + ) +{ + UINT16 *OptionOrder; + UINTN OptionOrderSize; + UINTN Index; + BDS_COMMON_OPTION *Option; + CHAR16 OptionName[20]; + + // + // Zero Buffer in order to get all BOOT#### variables + // + ZeroMem (OptionName, sizeof (OptionName)); + + // + // Read the BootOrder, or DriverOrder variable. + // + OptionOrder = BdsLibGetVariableAndSize ( + VariableName, + &gEfiGlobalVariableGuid, + &OptionOrderSize + ); + if (OptionOrder == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) { + if (*VariableName == 'B') { + UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionOrder[Index]); + } else { + UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", OptionOrder[Index]); + } + + Option = BdsLibVariableToOption (BdsCommonOptionList, OptionName); + if (Option != NULL) { + Option->BootCurrent = OptionOrder[Index]; + } + } + + FreePool (OptionOrder); + + return EFI_SUCCESS; +} + +/** + Get boot mode by looking up configuration table and parsing HOB list + + @param BootMode Boot mode from PEI handoff HOB. + + @retval EFI_SUCCESS Successfully get boot mode + +**/ +EFI_STATUS +EFIAPI +BdsLibGetBootMode ( + OUT EFI_BOOT_MODE *BootMode + ) +{ + *BootMode = GetBootModeHob (); + + return EFI_SUCCESS; +} + +/** + Read the EFI variable (VendorGuid/Name) and return a dynamically allocated + buffer, and the size of the buffer. If failure return NULL. + + @param Name String part of EFI variable name + @param VendorGuid GUID part of EFI variable name + @param VariableSize Returns the size of the EFI variable that was read + + @return Dynamically allocated memory that contains a copy of the EFI variable + Caller is responsible freeing the buffer. + @retval NULL Variable was not read + +**/ +VOID * +EFIAPI +BdsLibGetVariableAndSize ( + IN CHAR16 *Name, + IN EFI_GUID *VendorGuid, + OUT UINTN *VariableSize + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + VOID *Buffer; + + Buffer = NULL; + + // + // Pass in a zero size buffer to find the required buffer size. + // + BufferSize = 0; + Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer); + if (Status == EFI_BUFFER_TOO_SMALL) { + // + // Allocate the buffer to return + // + Buffer = AllocateZeroPool (BufferSize); + if (Buffer == NULL) { + *VariableSize = 0; + return NULL; + } + // + // Read variable into the allocated buffer. + // + Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer); + if (EFI_ERROR (Status)) { + FreePool (Buffer); + BufferSize = 0; + Buffer = NULL; + } + } + + ASSERT (((Buffer == NULL) && (BufferSize == 0)) || + ((Buffer != NULL) && (BufferSize != 0)) + ); + *VariableSize = BufferSize; + return Buffer; +} + +/** + Delete the instance in Multi which matches partly with Single instance + + @param Multi A pointer to a multi-instance device path data + structure. + @param Single A pointer to a single-instance device path data + structure. + + @return This function will remove the device path instances in Multi which partly + match with the Single, and return the result device path. If there is no + remaining device path as a result, this function will return NULL. + +**/ +EFI_DEVICE_PATH_PROTOCOL * +EFIAPI +BdsLibDelPartMatchInstance ( + IN EFI_DEVICE_PATH_PROTOCOL *Multi, + IN EFI_DEVICE_PATH_PROTOCOL *Single + ) +{ + EFI_DEVICE_PATH_PROTOCOL *Instance; + EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; + EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath; + UINTN InstanceSize; + UINTN SingleDpSize; + UINTN Size; + + NewDevicePath = NULL; + TempNewDevicePath = NULL; + + if (Multi == NULL || Single == NULL) { + return Multi; + } + + Instance = GetNextDevicePathInstance (&Multi, &InstanceSize); + SingleDpSize = GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH; + InstanceSize -= END_DEVICE_PATH_LENGTH; + + while (Instance != NULL) { + + Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize; + + if ((CompareMem (Instance, Single, Size) != 0)) { + // + // Append the device path instance which does not match with Single + // + TempNewDevicePath = NewDevicePath; + NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance); + if (TempNewDevicePath != NULL) { + FreePool(TempNewDevicePath); + } + } + FreePool(Instance); + Instance = GetNextDevicePathInstance (&Multi, &InstanceSize); + InstanceSize -= END_DEVICE_PATH_LENGTH; + } + + return NewDevicePath; +} + +/** + Function compares a device path data structure to that of all the nodes of a + second device path instance. + + @param Multi A pointer to a multi-instance device path data + structure. + @param Single A pointer to a single-instance device path data + structure. + + @retval TRUE If the Single device path is contained within Multi device path. + @retval FALSE The Single device path is not match within Multi device path. + +**/ +BOOLEAN +EFIAPI +BdsLibMatchDevicePaths ( + IN EFI_DEVICE_PATH_PROTOCOL *Multi, + IN EFI_DEVICE_PATH_PROTOCOL *Single + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *DevicePathInst; + UINTN Size; + + if (Multi == NULL || Single == NULL) { + return FALSE; + } + + DevicePath = Multi; + DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size); + + // + // Search for the match of 'Single' in 'Multi' + // + while (DevicePathInst != NULL) { + // + // If the single device path is found in multiple device paths, + // return success + // + if (CompareMem (Single, DevicePathInst, Size) == 0) { + FreePool (DevicePathInst); + return TRUE; + } + + FreePool (DevicePathInst); + DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size); + } + + return FALSE; +} + +/** + This function prints a series of strings. + + @param ConOut Pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL + @param ... A variable argument list containing series of + strings, the last string must be NULL. + + @retval EFI_SUCCESS Success print out the string using ConOut. + @retval EFI_STATUS Return the status of the ConOut->OutputString (). + +**/ +EFI_STATUS +EFIAPI +BdsLibOutputStrings ( + IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut, + ... + ) +{ + VA_LIST Args; + EFI_STATUS Status; + CHAR16 *String; + + Status = EFI_SUCCESS; + VA_START (Args, ConOut); + + while (!EFI_ERROR (Status)) { + // + // If String is NULL, then it's the end of the list + // + String = VA_ARG (Args, CHAR16 *); + if (String == NULL) { + break; + } + + Status = ConOut->OutputString (ConOut, String); + + if (EFI_ERROR (Status)) { + break; + } + } + + VA_END(Args); + return Status; +} + +// +// Following are BDS Lib functions which contain all the code about setup browser reset reminder feature. +// Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if +// user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection. +// + + +/** + Enable the setup browser reset reminder feature. + This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it. + +**/ +VOID +EFIAPI +EnableResetReminderFeature ( + VOID + ) +{ + mFeaturerSwitch = TRUE; +} + + +/** + Disable the setup browser reset reminder feature. + This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it. + +**/ +VOID +EFIAPI +DisableResetReminderFeature ( + VOID + ) +{ + mFeaturerSwitch = FALSE; +} + + +/** + Record the info that a reset is required. + A module boolean variable is used to record whether a reset is required. + +**/ +VOID +EFIAPI +EnableResetRequired ( + VOID + ) +{ + mResetRequired = TRUE; +} + + +/** + Record the info that no reset is required. + A module boolean variable is used to record whether a reset is required. + +**/ +VOID +EFIAPI +DisableResetRequired ( + VOID + ) +{ + mResetRequired = FALSE; +} + + +/** + Check whether platform policy enable the reset reminder feature. The default is enabled. + +**/ +BOOLEAN +EFIAPI +IsResetReminderFeatureEnable ( + VOID + ) +{ + return mFeaturerSwitch; +} + + +/** + Check if user changed any option setting which needs a system reset to be effective. + +**/ +BOOLEAN +EFIAPI +IsResetRequired ( + VOID + ) +{ + return mResetRequired; +} + + +/** + Check whether a reset is needed, and finish the reset reminder feature. + If a reset is needed, Popup a menu to notice user, and finish the feature + according to the user selection. + +**/ +VOID +EFIAPI +SetupResetReminder ( + VOID + ) +{ + EFI_INPUT_KEY Key; + CHAR16 *StringBuffer1; + CHAR16 *StringBuffer2; + + + // + //check any reset required change is applied? if yes, reset system + // + if (IsResetReminderFeatureEnable ()) { + if (IsResetRequired ()) { + + StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); + ASSERT (StringBuffer1 != NULL); + StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); + ASSERT (StringBuffer2 != NULL); + StrCpyS ( + StringBuffer1, + MAX_STRING_LEN, + L"Configuration changed. Reset to apply it Now." + ); + StrCpyS ( + StringBuffer2, + MAX_STRING_LEN, + L"Press ENTER to reset" + ); + // + // Popup a menu to notice user + // + do { + CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL); + } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); + + FreePool (StringBuffer1); + FreePool (StringBuffer2); + + gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); + } + } +} + +/** + Get the headers (dos, image, optional header) from an image + + @param Device SimpleFileSystem device handle + @param FileName File name for the image + @param DosHeader Pointer to dos header + @param Hdr The buffer in which to return the PE32, PE32+, or TE header. + + @retval EFI_SUCCESS Successfully get the machine type. + @retval EFI_NOT_FOUND The file is not found. + @retval EFI_LOAD_ERROR File is not a valid image file. + +**/ +EFI_STATUS +EFIAPI +BdsLibGetImageHeader ( + IN EFI_HANDLE Device, + IN CHAR16 *FileName, + OUT EFI_IMAGE_DOS_HEADER *DosHeader, + OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr + ) +{ + EFI_STATUS Status; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; + EFI_FILE_HANDLE Root; + EFI_FILE_HANDLE ThisFile; + UINTN BufferSize; + UINT64 FileSize; + EFI_FILE_INFO *Info; + + Root = NULL; + ThisFile = NULL; + // + // Handle the file system interface to the device + // + Status = gBS->HandleProtocol ( + Device, + &gEfiSimpleFileSystemProtocolGuid, + (VOID *) &Volume + ); + if (EFI_ERROR (Status)) { + goto Done; + } + + Status = Volume->OpenVolume ( + Volume, + &Root + ); + if (EFI_ERROR (Status)) { + Root = NULL; + goto Done; + } + ASSERT (Root != NULL); + Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0); + if (EFI_ERROR (Status)) { + goto Done; + } + ASSERT (ThisFile != NULL); + + // + // Get file size + // + BufferSize = SIZE_OF_EFI_FILE_INFO + 200; + do { + Info = NULL; + Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info); + if (EFI_ERROR (Status)) { + goto Done; + } + Status = ThisFile->GetInfo ( + ThisFile, + &gEfiFileInfoGuid, + &BufferSize, + Info + ); + if (!EFI_ERROR (Status)) { + break; + } + if (Status != EFI_BUFFER_TOO_SMALL) { + FreePool (Info); + goto Done; + } + FreePool (Info); + } while (TRUE); + + FileSize = Info->FileSize; + FreePool (Info); + + // + // Read dos header + // + BufferSize = sizeof (EFI_IMAGE_DOS_HEADER); + Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader); + if (EFI_ERROR (Status) || + BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) || + FileSize <= DosHeader->e_lfanew || + DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { + Status = EFI_LOAD_ERROR; + goto Done; + } + + // + // Move to PE signature + // + Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew); + if (EFI_ERROR (Status)) { + Status = EFI_LOAD_ERROR; + goto Done; + } + + // + // Read and check PE signature + // + BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION); + Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32); + if (EFI_ERROR (Status) || + BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) || + Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { + Status = EFI_LOAD_ERROR; + goto Done; + } + + // + // Check PE32 or PE32+ magic + // + if (Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC && + Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + Status = EFI_LOAD_ERROR; + goto Done; + } + + Done: + if (ThisFile != NULL) { + ThisFile->Close (ThisFile); + } + if (Root != NULL) { + Root->Close (Root); + } + return Status; +} + +/** + This routine adjust the memory information for different memory type and + save them into the variables for next boot. +**/ +VOID +BdsSetMemoryTypeInformationVariable ( + VOID + ) +{ + EFI_STATUS Status; + EFI_MEMORY_TYPE_INFORMATION *PreviousMemoryTypeInformation; + EFI_MEMORY_TYPE_INFORMATION *CurrentMemoryTypeInformation; + UINTN VariableSize; + UINTN Index; + UINTN Index1; + UINT32 Previous; + UINT32 Current; + UINT32 Next; + EFI_HOB_GUID_TYPE *GuidHob; + BOOLEAN MemoryTypeInformationModified; + BOOLEAN MemoryTypeInformationVariableExists; + EFI_BOOT_MODE BootMode; + + MemoryTypeInformationModified = FALSE; + MemoryTypeInformationVariableExists = FALSE; + + + BootMode = GetBootModeHob (); + // + // In BOOT_IN_RECOVERY_MODE, Variable region is not reliable. + // + if (BootMode == BOOT_IN_RECOVERY_MODE) { + return; + } + + // + // Only check the the Memory Type Information variable in the boot mode + // other than BOOT_WITH_DEFAULT_SETTINGS because the Memory Type + // Information is not valid in this boot mode. + // + if (BootMode != BOOT_WITH_DEFAULT_SETTINGS) { + VariableSize = 0; + Status = gRT->GetVariable ( + EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, + &gEfiMemoryTypeInformationGuid, + NULL, + &VariableSize, + NULL + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + MemoryTypeInformationVariableExists = TRUE; + } + } + + // + // Retrieve the current memory usage statistics. If they are not found, then + // no adjustments can be made to the Memory Type Information variable. + // + Status = EfiGetSystemConfigurationTable ( + &gEfiMemoryTypeInformationGuid, + (VOID **) &CurrentMemoryTypeInformation + ); + if (EFI_ERROR (Status) || CurrentMemoryTypeInformation == NULL) { + return; + } + + // + // Get the Memory Type Information settings from Hob if they exist, + // PEI is responsible for getting them from variable and build a Hob to save them. + // If the previous Memory Type Information is not available, then set defaults + // + GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid); + if (GuidHob == NULL) { + // + // If Platform has not built Memory Type Info into the Hob, just return. + // + return; + } + PreviousMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob); + VariableSize = GET_GUID_HOB_DATA_SIZE (GuidHob); + + // + // Use a heuristic to adjust the Memory Type Information for the next boot + // + DEBUG ((EFI_D_INFO, "Memory Previous Current Next \n")); + DEBUG ((EFI_D_INFO, " Type Pages Pages Pages \n")); + DEBUG ((EFI_D_INFO, "====== ======== ======== ========\n")); + + for (Index = 0; PreviousMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) { + + for (Index1 = 0; CurrentMemoryTypeInformation[Index1].Type != EfiMaxMemoryType; Index1++) { + if (PreviousMemoryTypeInformation[Index].Type == CurrentMemoryTypeInformation[Index1].Type) { + break; + } + } + if (CurrentMemoryTypeInformation[Index1].Type == EfiMaxMemoryType) { + continue; + } + + // + // Previous is the number of pages pre-allocated + // Current is the number of pages actually needed + // + Previous = PreviousMemoryTypeInformation[Index].NumberOfPages; + Current = CurrentMemoryTypeInformation[Index1].NumberOfPages; + Next = Previous; + + // + // Inconsistent Memory Reserved across bootings may lead to S4 fail + // Write next varible to 125% * current when the pre-allocated memory is: + // 1. More than 150% of needed memory and boot mode is BOOT_WITH_DEFAULT_SETTING + // 2. Less than the needed memory + // + if ((Current + (Current >> 1)) < Previous) { + if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { + Next = Current + (Current >> 2); + } + } else if (Current > Previous) { + Next = Current + (Current >> 2); + } + if (Next > 0 && Next < 4) { + Next = 4; + } + + if (Next != Previous) { + PreviousMemoryTypeInformation[Index].NumberOfPages = Next; + MemoryTypeInformationModified = TRUE; + } + + DEBUG ((EFI_D_INFO, " %02x %08x %08x %08x\n", PreviousMemoryTypeInformation[Index].Type, Previous, Current, Next)); + } + + // + // If any changes were made to the Memory Type Information settings, then set the new variable value; + // Or create the variable in first boot. + // + if (MemoryTypeInformationModified || !MemoryTypeInformationVariableExists) { + Status = SetVariableAndReportStatusCodeOnError ( + EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, + &gEfiMemoryTypeInformationGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + VariableSize, + PreviousMemoryTypeInformation + ); + + if (!EFI_ERROR (Status)) { + // + // If the Memory Type Information settings have been modified, then reset the platform + // so the new Memory Type Information setting will be used to guarantee that an S4 + // entry/resume cycle will not fail. + // + if (MemoryTypeInformationModified && PcdGetBool (PcdResetOnMemoryTypeInformationChange)) { + DEBUG ((EFI_D_INFO, "Memory Type Information settings change. Warm Reset!!!\n")); + gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); + } + } else { + DEBUG ((EFI_D_ERROR, "Memory Type Information settings cannot be saved. OS S4 may fail!\n")); + } + } +} + +/** + This routine is kept for backward compatibility. +**/ +VOID +EFIAPI +BdsLibSaveMemoryTypeInformation ( + VOID + ) +{ +} + + +/** + Identify a user and, if authenticated, returns the current user profile handle. + + @param[out] User Point to user profile handle. + + @retval EFI_SUCCESS User is successfully identified, or user identification + is not supported. + @retval EFI_ACCESS_DENIED User is not successfully identified + +**/ +EFI_STATUS +EFIAPI +BdsLibUserIdentify ( + OUT EFI_USER_PROFILE_HANDLE *User + ) +{ + EFI_STATUS Status; + EFI_USER_MANAGER_PROTOCOL *Manager; + + Status = gBS->LocateProtocol ( + &gEfiUserManagerProtocolGuid, + NULL, + (VOID **) &Manager + ); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + return Manager->Identify (Manager, User); +} + +/** + Set the variable and report the error through status code upon failure. + + @param VariableName A Null-terminated string that is the name of the vendor's variable. + Each VariableName is unique for each VendorGuid. VariableName must + contain 1 or more characters. If VariableName is an empty string, + then EFI_INVALID_PARAMETER is returned. + @param VendorGuid A unique identifier for the vendor. + @param Attributes Attributes bitmask to set for the variable. + @param DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE, + EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero + causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is + set, then a SetVariable() call with a DataSize of zero will not cause any change to + the variable value (the timestamp associated with the variable may be updated however + even if no new data value is provided,see the description of the + EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not + be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated). + @param Data The contents for the variable. + + @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as + defined by the Attributes. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the + DataSize exceeds the maximum allowed. + @retval EFI_INVALID_PARAMETER VariableName is an empty string. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. + @retval EFI_WRITE_PROTECTED The variable in question is read-only. + @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. + @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS + or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo + does NOT pass the validation check carried out by the firmware. + + @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. +**/ +EFI_STATUS +SetVariableAndReportStatusCodeOnError ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ) +{ + EFI_STATUS Status; + EDKII_SET_VARIABLE_STATUS *SetVariableStatus; + UINTN NameSize; + + Status = gRT->SetVariable ( + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); + if (EFI_ERROR (Status)) { + NameSize = StrSize (VariableName); + SetVariableStatus = AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize); + if (SetVariableStatus != NULL) { + CopyGuid (&SetVariableStatus->Guid, VendorGuid); + SetVariableStatus->NameSize = NameSize; + SetVariableStatus->DataSize = DataSize; + SetVariableStatus->SetStatus = Status; + SetVariableStatus->Attributes = Attributes; + CopyMem (SetVariableStatus + 1, VariableName, NameSize); + if ((Data != NULL) && (DataSize != 0)) { + CopyMem (((UINT8 *) (SetVariableStatus + 1)) + NameSize, Data, DataSize); + } + + REPORT_STATUS_CODE_EX ( + EFI_ERROR_CODE, + PcdGet32 (PcdErrorCodeSetVariable), + 0, + NULL, + &gEdkiiStatusCodeDataTypeVariableGuid, + SetVariableStatus, + sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize + ); + + FreePool (SetVariableStatus); + } + } + + return Status; +} + diff --git a/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c new file mode 100644 index 0000000000..2f22e7df7f --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c @@ -0,0 +1,33 @@ +/** @file + BDS internal function define the default device path string, it can be + replaced by platform device path. + +Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which 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 "InternalBdsLib.h" + +/** + This function converts an input device structure to a Unicode string. + + @param DevPath A pointer to the device path structure. + + @return A new allocated Unicode string that represents the device path. + +**/ +CHAR16 * +EFIAPI +DevicePathToStr ( + IN EFI_DEVICE_PATH_PROTOCOL *DevPath + ) +{ + return ConvertDevicePathToText (DevPath, TRUE, TRUE); +} diff --git a/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf new file mode 100644 index 0000000000..a4c1165e30 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf @@ -0,0 +1,144 @@ +## @file +# General BDS library. +# +# General BDS defines and produce general interfaces for platform BDS driver including: +# 1) BDS boot policy interface; +# 2) BDS boot device connect interface; +# 3) BDS Misc interfaces for mainting boot variable, ouput string, etc. +# +# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which 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 = 0x00010018 + BASE_NAME = GenericBdsLib + FILE_GUID = e405ec31-ccaa-4dd4-83e8-0aec01703f7e + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = GenericBdsLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION + CONSTRUCTOR = GenericBdsLibConstructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + DevicePath.c + Performance.c + BdsConnect.c + BdsMisc.c + BdsConsole.c + BdsBoot.c + InternalBdsLib.h + String.h + String.c + GenericBdsStrings.uni + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + +[LibraryClasses] + DevicePathLib + PeCoffGetEntryPointLib + BaseLib + HobLib + UefiRuntimeServicesTableLib + DxeServicesTableLib + MemoryAllocationLib + UefiLib + UefiBootServicesTableLib + BaseMemoryLib + DebugLib + PrintLib + PcdLib + PerformanceLib + TimerLib + DxeServicesLib + HiiLib + ReportStatusCodeLib + +[Guids] + ## SOMETIMES_CONSUMES ## HOB # The hob holding memory type information + ## SOMETIMES_CONSUMES ## SystemTable # The identifier of memory type information type in system table + ## SOMETIMES_CONSUMES ## Variable:L"MemoryTypeInformation" + ## SOMETIMES_PRODUCES ## Variable:L"MemoryTypeInformation" + gEfiMemoryTypeInformationGuid + ## SOMETIMES_CONSUMES ## Variable:L"BootXXXX" # Boot option variable + ## SOMETIMES_PRODUCES ## Variable:L"BootXXXX" # Boot option variable + ## SOMETIMES_CONSUMES ## Variable:L"DriverXXXX" # Driver load option. + ## SOMETIMES_PRODUCES ## Variable:L"DriverXXXX" # Driver load option. + ## SOMETIMES_CONSUMES ## Variable:L"BootNext" # Next Boot Option + ## SOMETIMES_PRODUCES ## Variable:L"BootNext" # Next Boot Option + ## SOMETIMES_CONSUMES ## Variable:L"BootOrder" # The boot option array + ## SOMETIMES_PRODUCES ## Variable:L"BootOrder" # The boot option array + ## SOMETIMES_CONSUMES ## Variable:L"DriverOrder" # The driver order list + ## SOMETIMES_CONSUMES ## Variable:L"ConIn" # The device path of console in device + ## SOMETIMES_PRODUCES ## Variable:L"ConIn" # The device path of console in device + ## SOMETIMES_CONSUMES ## Variable:L"ConOut" # The device path of console out device + ## SOMETIMES_PRODUCES ## Variable:L"ConOut" # The device path of console out device + ## SOMETIMES_CONSUMES ## Variable:L"ErrOut" # The device path of error out device + ## SOMETIMES_PRODUCES ## Variable:L"ErrOut" # The device path of error out device + ## SOMETIMES_PRODUCES ## Variable:L"BootCurrent" # The boot option of current boot + ## SOMETIMES_PRODUCES ## Variable:L"BootNext" # The number of next boot option + gEfiGlobalVariableGuid + gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## GUID + gPerformanceProtocolGuid ## SOMETIMES_PRODUCES ## Variable:L"PerfDataMemAddr" # The ACPI address of performance data + gLastEnumLangGuid ## SOMETIMES_PRODUCES ## Variable:L"LastEnumLang" # Platform language at last time enumeration. + gHdBootDevicePathVariablGuid ## SOMETIMES_PRODUCES ## Variable:L"HDDP" # The device path of Boot file on Hard device. + gBdsLibStringPackageGuid ## CONSUMES ## HII # HII String PackageList Guid + ## SOMETIMES_PRODUCES ## Variable:L"LegacyDevOrder" + ## SOMETIMES_CONSUMES ## Variable:L"LegacyDevOrder" + gEfiLegacyDevOrderVariableGuid + gEdkiiStatusCodeDataTypeVariableGuid ## SOMETIMES_CONSUMES ## GUID + +[Protocols] + gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES + gEfiLoadFileProtocolGuid ## SOMETIMES_CONSUMES + gEfiSimpleTextOutProtocolGuid ## CONSUMES + gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES + gEfiSimpleNetworkProtocolGuid ## SOMETIMES_CONSUMES + gEfiDebugPortProtocolGuid ## SOMETIMES_CONSUMES + gEfiSimpleTextInProtocolGuid ## CONSUMES + gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiFirmwareVolume2ProtocolGuid ## SOMETIMES_CONSUMES + gEfiLegacyBiosProtocolGuid ## SOMETIMES_CONSUMES + gEfiCpuArchProtocolGuid ## CONSUMES + gEfiDevicePathProtocolGuid ## CONSUMES + gEfiGraphicsOutputProtocolGuid ## SOMETIMES_CONSUMES + gEfiUgaDrawProtocolGuid |gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport ## SOMETIMES_CONSUMES + gEfiOEMBadgingProtocolGuid ## SOMETIMES_CONSUMES + gEfiHiiFontProtocolGuid ## CONSUMES + gEfiUserManagerProtocolGuid ## SOMETIMES_CONSUMES + gEfiUsbIoProtocolGuid ## SOMETIMES_CONSUMES + gEfiBootLogoProtocolGuid ## SOMETIMES_CONSUMES + +[FeaturePcd] + gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport ## CONSUMES + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootlogoOnlyEnable ## CONSUMES + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderLoad ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderStart ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable ## CONSUMES + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile ## CONSUMES + +# +# [BootMode] +# RECOVERY_FULL ## SOMETIMES_CONSUMES # Memory Type Information variable +# + diff --git a/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsStrings.uni b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsStrings.uni new file mode 100644 index 0000000000..568774b59a --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsStrings.uni @@ -0,0 +1,36 @@ +///** @file +// +// String definitions for Boot Option description. +// +// Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
+// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which 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. +// +//**/ + +/=# + +#langdef en-US "English" +#langdef fr "Français" + +#string STR_DESCRIPTION_FLOPPY #language en-US "EFI Floppy" + #language fr "fr: EFI Floppy" +#string STR_DESCRIPTION_CD_DVD #language en-US "EFI DVD/CDROM" + #language fr "fr: EFI DVD/CDROM" +#string STR_DESCRIPTION_HARDDRIVE #language en-US "EFI Hard Drive" + #language fr "fr: EFI Hard Drive" +#string STR_DESCRIPTION_USB #language en-US "EFI USB Device" + #language fr "fr: EFI USB Device" +#string STR_DESCRIPTION_SCSI #language en-US "EFI SCSI Device" + #language fr "fr: EFI SCSI Device" +#string STR_DESCRIPTION_MISC #language en-US "EFI Misc Device" + #language fr "fr: EFI Misc Device" +#string STR_DESCRIPTION_NETWORK #language en-US "EFI Network" + #language fr "fr: EFI Network" +#string STR_DESCRIPTION_NON_BLOCK #language en-US "EFI Non-Block Boot Device" + #language fr "fr: EFI Non-Block Boot Device" diff --git a/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h new file mode 100644 index 0000000000..4f2817a284 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h @@ -0,0 +1,194 @@ +/** @file + BDS library definition, include the file and data structure + +Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which 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 _INTERNAL_BDS_LIB_H_ +#define _INTERNAL_BDS_LIB_H_ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined (EFI_REMOVABLE_MEDIA_FILE_NAME) + #if defined (MDE_CPU_EBC) + // + // Uefi specification only defines the default boot file name for IA32, X64 + // and IPF processor, so need define boot file name for EBC architecture here. + // + #define EFI_REMOVABLE_MEDIA_FILE_NAME L"\\EFI\\BOOT\\BOOTEBC.EFI" + #else + #error "Can not determine the default boot file name for unknown processor type!" + #endif +#endif + +/** + + Writes performance data of booting into the allocated memory. + OS can process these records. + + @param Event The triggered event. + @param Context Context for this event. + +**/ +VOID +EFIAPI +WriteBootToOsPerformanceData ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Get the headers (dos, image, optional header) from an image + + @param Device SimpleFileSystem device handle + @param FileName File name for the image + @param DosHeader Pointer to dos header + @param Hdr The buffer in which to return the PE32, PE32+, or TE header. + + @retval EFI_SUCCESS Successfully get the machine type. + @retval EFI_NOT_FOUND The file is not found. + @retval EFI_LOAD_ERROR File is not a valid image file. + +**/ +EFI_STATUS +EFIAPI +BdsLibGetImageHeader ( + IN EFI_HANDLE Device, + IN CHAR16 *FileName, + OUT EFI_IMAGE_DOS_HEADER *DosHeader, + OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr + ); + +/** + This routine adjust the memory information for different memory type and + save them into the variables for next boot. +**/ +VOID +BdsSetMemoryTypeInformationVariable ( + VOID + ); + +/** + Validate the EFI Boot#### or Driver#### variable (VendorGuid/Name) + + @param Variable Boot#### variable data. + @param VariableSize Returns the size of the EFI variable that was read + + @retval TRUE The variable data is correct. + @retval FALSE The variable data is corrupted. + +**/ +BOOLEAN +ValidateOption ( + UINT8 *Variable, + UINTN VariableSize + ); + +/** + Set the variable and report the error through status code upon failure. + + @param VariableName A Null-terminated string that is the name of the vendor's variable. + Each VariableName is unique for each VendorGuid. VariableName must + contain 1 or more characters. If VariableName is an empty string, + then EFI_INVALID_PARAMETER is returned. + @param VendorGuid A unique identifier for the vendor. + @param Attributes Attributes bitmask to set for the variable. + @param DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE, + EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or + EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero + causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is + set, then a SetVariable() call with a DataSize of zero will not cause any change to + the variable value (the timestamp associated with the variable may be updated however + even if no new data value is provided,see the description of the + EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not + be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated). + @param Data The contents for the variable. + + @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as + defined by the Attributes. + @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the + DataSize exceeds the maximum allowed. + @retval EFI_INVALID_PARAMETER VariableName is an empty string. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. + @retval EFI_WRITE_PROTECTED The variable in question is read-only. + @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. + @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS + or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo + does NOT pass the validation check carried out by the firmware. + + @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. +**/ +EFI_STATUS +SetVariableAndReportStatusCodeOnError ( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data + ); + +#endif // _BDS_LIB_H_ diff --git a/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c new file mode 100644 index 0000000000..9786fc7e24 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c @@ -0,0 +1,358 @@ +/** @file + This file include the file which can help to get the system + performance, all the function will only include if the performance + switch is set. + +Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which 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 "InternalBdsLib.h" + +PERF_HEADER mPerfHeader; +PERF_DATA mPerfData; +EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase = 0x0FFFFFFFFULL; + +/** + Get the short verion of PDB file name to be + used in performance data logging. + + @param PdbFileName The long PDB file name. + @param GaugeString The output string to be logged by performance logger. + +**/ +VOID +GetShortPdbFileName ( + IN CONST CHAR8 *PdbFileName, + OUT CHAR8 *GaugeString + ) +{ + UINTN Index; + UINTN Index1; + UINTN StartIndex; + UINTN EndIndex; + + if (PdbFileName == NULL) { + AsciiStrCpyS (GaugeString, PERF_TOKEN_SIZE, " "); + } else { + StartIndex = 0; + for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++) + ; + + for (Index = 0; PdbFileName[Index] != 0; Index++) { + if (PdbFileName[Index] == '\\') { + StartIndex = Index + 1; + } + + if (PdbFileName[Index] == '.') { + EndIndex = Index; + } + } + + Index1 = 0; + for (Index = StartIndex; Index < EndIndex; Index++) { + GaugeString[Index1] = PdbFileName[Index]; + Index1++; + if (Index1 == PERF_TOKEN_LENGTH) { + break; + } + } + + GaugeString[Index1] = 0; + } + + return ; +} + +/** + Get the name from the Driver handle, which can be a handle with + EFI_LOADED_IMAGE_PROTOCOL or EFI_DRIVER_BINDING_PROTOCOL installed. + This name can be used in performance data logging. + + @param Handle Driver handle. + @param GaugeString The output string to be logged by performance logger. + +**/ +VOID +GetNameFromHandle ( + IN EFI_HANDLE Handle, + OUT CHAR8 *GaugeString + ) +{ + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *Image; + CHAR8 *PdbFileName; + EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; + + AsciiStrCpyS (GaugeString, PERF_TOKEN_SIZE, " "); + + // + // Get handle name from image protocol + // + Status = gBS->HandleProtocol ( + Handle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &Image + ); + + if (EFI_ERROR (Status)) { + Status = gBS->OpenProtocol ( + Handle, + &gEfiDriverBindingProtocolGuid, + (VOID **) &DriverBinding, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return ; + } + // + // Get handle name from image protocol + // + Status = gBS->HandleProtocol ( + DriverBinding->ImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &Image + ); + } + + PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase); + + if (PdbFileName != NULL) { + GetShortPdbFileName (PdbFileName, GaugeString); + } + + return ; +} + +/** + + Writes performance data of booting into the allocated memory. + OS can process these records. + + @param Event The triggered event. + @param Context Context for this event. + +**/ +VOID +EFIAPI +WriteBootToOsPerformanceData ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + UINT32 LimitCount; + EFI_HANDLE *Handles; + UINTN NoHandles; + CHAR8 GaugeString[PERF_TOKEN_SIZE]; + UINT8 *Ptr; + UINT32 Index; + UINT64 Ticker; + UINT64 Freq; + UINT32 Duration; + UINTN LogEntryKey; + CONST VOID *Handle; + CONST CHAR8 *Token; + CONST CHAR8 *Module; + UINT64 StartTicker; + UINT64 EndTicker; + UINT64 StartValue; + UINT64 EndValue; + BOOLEAN CountUp; + UINTN EntryIndex; + UINTN NumPerfEntries; + // + // List of flags indicating PerfEntry contains DXE handle + // + BOOLEAN *PerfEntriesAsDxeHandle; + UINTN VarSize; + + // + // Record the performance data for End of BDS + // + PERF_END(NULL, "BDS", NULL, 0); + + // + // Retrieve time stamp count as early as possible + // + Ticker = GetPerformanceCounter (); + + Freq = GetPerformanceCounterProperties (&StartValue, &EndValue); + + Freq = DivU64x32 (Freq, 1000); + + mPerfHeader.CpuFreq = Freq; + + // + // Record BDS raw performance data + // + if (EndValue >= StartValue) { + mPerfHeader.BDSRaw = Ticker - StartValue; + CountUp = TRUE; + } else { + mPerfHeader.BDSRaw = StartValue - Ticker; + CountUp = FALSE; + } + + if (mAcpiLowMemoryBase == 0x0FFFFFFFF) { + VarSize = sizeof (EFI_PHYSICAL_ADDRESS); + Status = gRT->GetVariable ( + L"PerfDataMemAddr", + &gPerformanceProtocolGuid, + NULL, + &VarSize, + &mAcpiLowMemoryBase + ); + if (EFI_ERROR (Status)) { + // + // Fail to get the variable, return. + // + return; + } + } + + // + // Put Detailed performance data into memory + // + Handles = NULL; + Status = gBS->LocateHandleBuffer ( + AllHandles, + NULL, + NULL, + &NoHandles, + &Handles + ); + if (EFI_ERROR (Status)) { + return ; + } + + Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER)); + LimitCount = (UINT32) (PERF_DATA_MAX_LENGTH - sizeof (PERF_HEADER)) / sizeof (PERF_DATA); + + NumPerfEntries = 0; + LogEntryKey = 0; + while ((LogEntryKey = GetPerformanceMeasurement ( + LogEntryKey, + &Handle, + &Token, + &Module, + &StartTicker, + &EndTicker)) != 0) { + NumPerfEntries++; + } + PerfEntriesAsDxeHandle = AllocateZeroPool (NumPerfEntries * sizeof (BOOLEAN)); + ASSERT (PerfEntriesAsDxeHandle != NULL); + + // + // Get DXE drivers performance + // + for (Index = 0; Index < NoHandles; Index++) { + Ticker = 0; + LogEntryKey = 0; + EntryIndex = 0; + while ((LogEntryKey = GetPerformanceMeasurement ( + LogEntryKey, + &Handle, + &Token, + &Module, + &StartTicker, + &EndTicker)) != 0) { + if (Handle == Handles[Index] && !PerfEntriesAsDxeHandle[EntryIndex]) { + PerfEntriesAsDxeHandle[EntryIndex] = TRUE; + } + EntryIndex++; + if ((Handle == Handles[Index]) && (EndTicker != 0)) { + if (StartTicker == 1) { + StartTicker = StartValue; + } + if (EndTicker == 1) { + EndTicker = StartValue; + } + Ticker += CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker); + } + } + + Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq); + + if (Duration > 0) { + + GetNameFromHandle (Handles[Index], GaugeString); + + AsciiStrCpyS (mPerfData.Token, PERF_TOKEN_SIZE, GaugeString); + mPerfData.Duration = Duration; + + CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA)); + Ptr += sizeof (PERF_DATA); + + mPerfHeader.Count++; + if (mPerfHeader.Count == LimitCount) { + goto Done; + } + } + } + + // + // Get inserted performance data + // + LogEntryKey = 0; + EntryIndex = 0; + while ((LogEntryKey = GetPerformanceMeasurement ( + LogEntryKey, + &Handle, + &Token, + &Module, + &StartTicker, + &EndTicker)) != 0) { + if (!PerfEntriesAsDxeHandle[EntryIndex] && EndTicker != 0) { + + ZeroMem (&mPerfData, sizeof (PERF_DATA)); + + AsciiStrnCpyS (mPerfData.Token, PERF_TOKEN_SIZE, Token, PERF_TOKEN_LENGTH); + if (StartTicker == 1) { + StartTicker = StartValue; + } + if (EndTicker == 1) { + EndTicker = StartValue; + } + Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker); + + mPerfData.Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq); + + CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA)); + Ptr += sizeof (PERF_DATA); + + mPerfHeader.Count++; + if (mPerfHeader.Count == LimitCount) { + goto Done; + } + } + EntryIndex++; + } + +Done: + + FreePool (Handles); + FreePool (PerfEntriesAsDxeHandle); + + mPerfHeader.Signiture = PERFORMANCE_SIGNATURE; + + // + // Put performance data to Reserved memory + // + CopyMem ( + (UINTN *) (UINTN) mAcpiLowMemoryBase, + &mPerfHeader, + sizeof (PERF_HEADER) + ); + + return ; +} diff --git a/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.c b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.c new file mode 100644 index 0000000000..762871605d --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.c @@ -0,0 +1,32 @@ +/** @file + String support + +Copyright (c) 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which 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 "String.h" + +/** + Get string by string id from HII Interface + + + @param Id String ID. + + @retval CHAR16 * String from ID. + @retval NULL If error occurs. + +**/ +CHAR16 * +BdsLibGetStringById ( + IN EFI_STRING_ID Id + ) +{ + return HiiGetString (gBdsLibStringPackHandle, Id, NULL); +} diff --git a/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.h b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.h new file mode 100644 index 0000000000..13b745de87 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.h @@ -0,0 +1,48 @@ +/** @file + String support + +Copyright (c) 2010, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which 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 _STRING_H_ +#define _STRING_H_ + +#include +#include +#include +#include +#include + +extern EFI_HII_HANDLE gBdsLibStringPackHandle; + +// +// This is the VFR compiler generated header file which defines the +// string identifiers. +// + +extern UINT8 GenericBdsLibStrings[]; + +/** + Get string by string id from HII Interface + + + @param Id String ID. + + @retval CHAR16 * String from ID. + @retval NULL If error occurs. + +**/ +CHAR16 * +BdsLibGetStringById ( + IN EFI_STRING_ID Id + ); + +#endif // _STRING_H_ diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c new file mode 100644 index 0000000000..373cea2a23 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c @@ -0,0 +1,149 @@ +/** @file + Sample to provide FSP wrapper platform sec related function. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which 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 +#include +#include +#include +#include + +/** + This interface conveys state information out of the Security (SEC) phase into PEI. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in,out] StructureSize Pointer to the variable describing size of the input buffer. + @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ); + +/** + This interface conveys performance information out of the Security (SEC) phase into PEI. + + This service is published by the SEC phase. The SEC phase handoff has an optional + EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the + PEI Foundation. As such, if the platform supports collecting performance data in SEC, + this information is encapsulated into the data structure abstracted by this service. + This information is collected for the boot-strap processor (BSP) on IA-32. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI. + @param[out] Performance The pointer to performance data collected in SEC phase. + + @retval EFI_SUCCESS The data was successfully returned. + +**/ +EFI_STATUS +EFIAPI +SecGetPerformance ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN PEI_SEC_PERFORMANCE_PPI *This, + OUT FIRMWARE_SEC_PERFORMANCE *Performance + ); + +/** + This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into + permanent memory. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] CopySize Amount of memory to migrate from temporary to permanent memory. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when + TemporaryMemoryBase > PermanentMemoryBase. + +**/ +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + +EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformationPpi = { + SecPlatformInformation +}; + +PEI_SEC_PERFORMANCE_PPI mSecPerformancePpi = { + SecGetPerformance +}; + +EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = { + SecTemporaryRamSupport +}; + +EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformPpi[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiSecPlatformInformationPpiGuid, + &mSecPlatformInformationPpi + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gPeiSecPerformancePpiGuid, + &mSecPerformancePpi + }, + { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &gEfiTemporaryRamSupportPpiGuid, + &gSecTemporaryRamSupportPpi + }, +}; + +/** + A developer supplied function to perform platform specific operations. + + It's a developer supplied function to perform any operations appropriate to a + given platform. It's invoked just before passing control to PEI core by SEC + core. Platform developer may modify the SecCoreData passed to PEI Core. + It returns a platform specific PPI list that platform wishes to pass to PEI core. + The Generic SEC core module will merge this list to join the final list passed to + PEI core. + + @param[in,out] SecCoreData The same parameter as passing to PEI core. It + could be overridden by this function. + + @return The platform specific PPI list to be passed to PEI core or + NULL if there is no need of such platform specific PPI list. + +**/ +EFI_PEI_PPI_DESCRIPTOR * +EFIAPI +SecPlatformMain ( + IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData + ) +{ + EFI_PEI_PPI_DESCRIPTOR *PpiList; + + InitializeApicTimer (0, (UINT32) -1, TRUE, 5); + PpiList = &mPeiSecPlatformPpi[0]; + + return PpiList; +} diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S new file mode 100644 index 0000000000..2f1cf6b5d0 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S @@ -0,0 +1,37 @@ +## @file +# Save Sec Conext before call FspInit API +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which 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 +# +## + +#---------------------------------------------------------------------------- +# MMX Usage: +# MM0 = BIST State +# MM5 = Save time-stamp counter value high32bit +# MM6 = Save time-stamp counter value low32bit. +# +# It should be same as SecEntry.asm and PeiCoreEntry.asm. +#---------------------------------------------------------------------------- + +ASM_GLOBAL ASM_PFX(AsmSaveBistValue) +ASM_PFX(AsmSaveBistValue): + movl 4(%esp), %eax + movd %eax, %mm0 + ret + +ASM_GLOBAL ASM_PFX(AsmSaveTickerValue) +ASM_PFX(AsmSaveTickerValue): + movl 4(%esp), %eax + movd %eax, %mm6 + movl 8(%esp), %eax + movd %eax, %mm5 + ret diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm new file mode 100644 index 0000000000..2f767a8264 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm @@ -0,0 +1,44 @@ +;; @file +; Save Sec Conext before call FspInit API +; +; Copyright (c) 2015, Intel Corporation. All rights reserved.
+; +; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which 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. +; +;; + +.686p +.xmm +.model flat,c +.code + +;---------------------------------------------------------------------------- +; MMX Usage: +; MM0 = BIST State +; MM5 = Save time-stamp counter value high32bit +; MM6 = Save time-stamp counter value low32bit. +; +; It should be same as SecEntry.asm and PeiCoreEntry.asm. +;---------------------------------------------------------------------------- + +AsmSaveBistValue PROC PUBLIC + mov eax, [esp+4] + movd mm0, eax + ret +AsmSaveBistValue ENDP + +AsmSaveTickerValue PROC PUBLIC + mov eax, [esp+4] + movd mm6, eax + mov eax, [esp+8] + movd mm5, eax + ret +AsmSaveTickerValue ENDP + +END diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h new file mode 100644 index 0000000000..606c14548f --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h @@ -0,0 +1,49 @@ +/** @file + Fsp related definitions + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which 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 __FSP_H__ +#define __FSP_H__ + +// +// Fv Header +// +#define FVH_SIGINATURE_OFFSET 0x28 +#define FVH_SIGINATURE_VALID_VALUE 0x4856465F // valid signature:_FVH +#define FVH_HEADER_LENGTH_OFFSET 0x30 +#define FVH_EXTHEADER_OFFSET_OFFSET 0x34 +#define FVH_EXTHEADER_SIZE_OFFSET 0x10 + +// +// Ffs Header +// +#define FSP_HEADER_GUID_DWORD1 0x912740BE +#define FSP_HEADER_GUID_DWORD2 0x47342284 +#define FSP_HEADER_GUID_DWORD3 0xB08471B9 +#define FSP_HEADER_GUID_DWORD4 0x0C3F3527 +#define FFS_HEADER_SIZE_VALUE 0x18 + +// +// Section Header +// +#define SECTION_HEADER_TYPE_OFFSET 0x03 +#define RAW_SECTION_HEADER_SIZE_VALUE 0x04 + +// +// Fsp Header +// +#define FSP_HEADER_IMAGEBASE_OFFSET 0x1C +#define FSP_HEADER_TEMPRAMINIT_OFFSET 0x30 + +#endif diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S new file mode 100644 index 0000000000..da851d18f0 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S @@ -0,0 +1,124 @@ +## @file +# Find and call SecStartup +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which 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 +# +## + +ASM_GLOBAL ASM_PFX(CallPeiCoreEntryPoint) +ASM_PFX(CallPeiCoreEntryPoint): + # + # Obtain the hob list pointer + # + movl 0x4(%esp), %eax + # + # Obtain the stack information + # ECX: start of range + # EDX: end of range + # + movl 0x8(%esp), %ecx + movl 0xC(%esp), %edx + + # + # Platform init + # + pushal + pushl %edx + pushl %ecx + pushl %eax + call ASM_PFX(PlatformInit) + popl %eax + popl %eax + popl %eax + popal + + # + # Set stack top pointer + # + movl %edx, %esp + + # + # Push the hob list pointer + # + pushl %eax + + # + # Save the value + # ECX: start of range + # EDX: end of range + # + movl %esp, %ebp + pushl %ecx + pushl %edx + + # + # Push processor count to stack first, then BIST status (AP then BSP) + # + movl $1, %eax + cpuid + shr $16, %ebx + andl $0x000000FF, %ebx + cmp $1, %bl + jae PushProcessorCount + + # + # Some processors report 0 logical processors. Effectively 0 = 1. + # So we fix up the processor count + # + inc %ebx + +PushProcessorCount: + pushl %ebx + + # + # We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST + # for all processor threads + # + xorl %ecx, %ecx + movb %bl, %cl +PushBist: + movd %mm0, %eax + pushl %eax + loop PushBist + + # Save Time-Stamp Counter + movd %mm5, %eax + pushl %eax + + movd %mm6, %eax + pushl %eax + + # + # Pass entry point of the PEI core + # + movl $0xFFFFFFE0, %edi + pushl %ds:(%edi) + + # + # Pass BFV into the PEI Core + # + movl $0xFFFFFFFC, %edi + pushl %ds:(%edi) + + # + # Pass stack size into the PEI Core + # + movl -4(%ebp), %ecx + movl -8(%ebp), %edx + pushl %ecx # RamBase + + subl %ecx, %edx + pushl %edx # RamSize + + # + # Pass Control into the PEI Core + # + call ASM_PFX(SecStartup) diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm new file mode 100644 index 0000000000..808a21b2fc --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm @@ -0,0 +1,134 @@ +;; @file +; Find and call SecStartup +; +; Copyright (c) 2015, Intel Corporation. All rights reserved.
+; +; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which 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. +; +;; + +.686p +.xmm +.model flat, c +.code + +EXTRN SecStartup:NEAR +EXTRN PlatformInit:NEAR + +CallPeiCoreEntryPoint PROC PUBLIC + ; + ; Obtain the hob list pointer + ; + mov eax, [esp+4] + ; + ; Obtain the stack information + ; ECX: start of range + ; EDX: end of range + ; + mov ecx, [esp+8] + mov edx, [esp+0Ch] + + ; + ; Platform init + ; + pushad + push edx + push ecx + push eax + call PlatformInit + pop eax + pop eax + pop eax + popad + + ; + ; Set stack top pointer + ; + mov esp, edx + + ; + ; Push the hob list pointer + ; + push eax + + ; + ; Save the value + ; ECX: start of range + ; EDX: end of range + ; + mov ebp, esp + push ecx + push edx + + ; + ; Push processor count to stack first, then BIST status (AP then BSP) + ; + mov eax, 1 + cpuid + shr ebx, 16 + and ebx, 0000000FFh + cmp bl, 1 + jae PushProcessorCount + + ; + ; Some processors report 0 logical processors. Effectively 0 = 1. + ; So we fix up the processor count + ; + inc ebx + +PushProcessorCount: + push ebx + + ; + ; We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST + ; for all processor threads + ; + xor ecx, ecx + mov cl, bl +PushBist: + movd eax, mm0 + push eax + loop PushBist + + ; Save Time-Stamp Counter + movd eax, mm5 + push eax + + movd eax, mm6 + push eax + + ; + ; Pass entry point of the PEI core + ; + mov edi, 0FFFFFFE0h + push DWORD PTR ds:[edi] + + ; + ; Pass BFV into the PEI Core + ; + mov edi, 0FFFFFFFCh + push DWORD PTR ds:[edi] + + ; + ; Pass stack size into the PEI Core + ; + mov ecx, [ebp - 4] + mov edx, [ebp - 8] + push ecx ; RamBase + + sub edx, ecx + push edx ; RamSize + + ; + ; Pass Control into the PEI Core + ; + call SecStartup +CallPeiCoreEntryPoint ENDP + +END diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S new file mode 100644 index 0000000000..52d897b1d3 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S @@ -0,0 +1,322 @@ +## @file +# This is the code that goes from real-mode to protected mode. +# It consumes the reset vector, calls TempRamInit API from FSP binary. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which 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 "Fsp.h" + +ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase) +ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize) + +ASM_GLOBAL ASM_PFX(_TEXT_REALMODE) +ASM_PFX(_TEXT_REALMODE): +#---------------------------------------------------------------------------- +# +# Procedure: _ModuleEntryPoint +# +# Input: None +# +# Output: None +# +# Destroys: Assume all registers +# +# Description: +# +# Transition to non-paged flat-model protected mode from a +# hard-coded GDT that provides exactly two descriptors. +# This is a bare bones transition to protected mode only +# used for a while in PEI and possibly DXE. +# +# After enabling protected mode, a far jump is executed to +# transfer to PEI using the newly loaded GDT. +# +# Return: None +# +# MMX Usage: +# MM0 = BIST State +# MM5 = Save time-stamp counter value high32bit +# MM6 = Save time-stamp counter value low32bit. +# +#---------------------------------------------------------------------------- + +.align 4 +ASM_GLOBAL ASM_PFX(_ModuleEntryPoint) +ASM_PFX(_ModuleEntryPoint): + fninit # clear any pending Floating point exceptions + # + # Store the BIST value in mm0 + # + movd %eax, %mm0 + + # + # Save time-stamp counter value + # rdtsc load 64bit time-stamp counter to EDX:EAX + # + rdtsc + movd %edx, %mm5 + movd %ecx, %mm6 + + # + # Load the GDT table in GdtDesc + # + movl $GdtDesc, %esi + .byte 0x66 + lgdt %cs:(%si) + + # + # Transition to 16 bit protected mode + # + movl %cr0, %eax # Get control register 0 + orl $0x00000003, %eax # Set PE bit (bit #0) & MP bit (bit #1) + movl %eax, %cr0 # Activate protected mode + + movl %cr4, %eax # Get control register 4 + orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) + movl %eax, %cr4 + + # + # Now we're in 16 bit protected mode + # Set up the selectors for 32 bit protected mode entry + # + movw SYS_DATA_SEL, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + + # + # Transition to Flat 32 bit protected mode + # The jump to a far pointer causes the transition to 32 bit mode + # + movl ASM_PFX(ProtectedModeEntryLinearAddress), %esi + jmp *%cs:(%si) + +ASM_GLOBAL ASM_PFX(_TEXT_PROTECTED_MODE) +ASM_PFX(_TEXT_PROTECTED_MODE): + +#---------------------------------------------------------------------------- +# +# Procedure: ProtectedModeEntryPoint +# +# Input: None +# +# Output: None +# +# Destroys: Assume all registers +# +# Description: +# +# This function handles: +# Call two basic APIs from FSP binary +# Initializes stack with some early data (BIST, PEI entry, etc) +# +# Return: None +# +#---------------------------------------------------------------------------- + +.align 4 +ASM_GLOBAL ASM_PFX(ProtectedModeEntryPoint) +ASM_PFX(ProtectedModeEntryPoint): + + # Find the fsp info header + movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase), %edi + movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize), %ecx + + movl FVH_SIGINATURE_OFFSET(%edi), %eax + cmp $FVH_SIGINATURE_VALID_VALUE, %eax + jnz FspHeaderNotFound + + xorl %eax, %eax + movw FVH_EXTHEADER_OFFSET_OFFSET(%edi), %ax + cmp %ax, 0 + jnz FspFvExtHeaderExist + + xorl %eax, %eax + movw FVH_HEADER_LENGTH_OFFSET(%edi), %ax # Bypass Fv Header + addl %eax, %edi + jmp FspCheckFfsHeader + +FspFvExtHeaderExist: + addl %eax, %edi + movl FVH_EXTHEADER_SIZE_OFFSET(%edi), %eax # Bypass Ext Fv Header + addl %eax, %edi + + # Round up to 8 byte alignment + movl %edi, %eax + andb $0x07, %al + jz FspCheckFfsHeader + + and $0xFFFFFFF8, %edi + add $0x08, %edi + +FspCheckFfsHeader: + # Check the ffs guid + movl (%edi), %eax + cmp $FSP_HEADER_GUID_DWORD1, %eax + jnz FspHeaderNotFound + + movl 0x4(%edi), %eax + cmp $FSP_HEADER_GUID_DWORD2, %eax + jnz FspHeaderNotFound + + movl 0x08(%edi), %eax + cmp $FSP_HEADER_GUID_DWORD3, %eax + jnz FspHeaderNotFound + + movl 0x0c(%edi), %eax + cmp $FSP_HEADER_GUID_DWORD4, %eax + jnz FspHeaderNotFound + + add $FFS_HEADER_SIZE_VALUE, %edi # Bypass the ffs header + + # Check the section type as raw section + movb SECTION_HEADER_TYPE_OFFSET(%edi), %al + cmp $0x19, %al + jnz FspHeaderNotFound + + addl $RAW_SECTION_HEADER_SIZE_VALUE, %edi # Bypass the section header + jmp FspHeaderFound + +FspHeaderNotFound: + jmp . + +FspHeaderFound: + # Get the fsp TempRamInit Api address + movl FSP_HEADER_IMAGEBASE_OFFSET(%edi), %eax + addl FSP_HEADER_TEMPRAMINIT_OFFSET(%edi), %eax + + # Setup the hardcode stack + movl $TempRamInitStack, %esp + + # Call the fsp TempRamInit Api + jmp *%eax + +TempRamInitDone: + cmp $0x0, %eax + jnz FspApiFailed + + # ECX: start of range + # EDX: end of range + movl %edx, %esp + pushl %edx + pushl %ecx + pushl %eax # zero - no hob list yet + call ASM_PFX(CallPeiCoreEntryPoint) + +FspApiFailed: + jmp . + +.align 0x10 +TempRamInitStack: + .long TempRamInitDone + .long ASM_PFX(TempRamInitParams) + +# +# ROM-based Global-Descriptor Table for the Tiano PEI Phase +# +.align 16 + +# +# GDT[0]: 0x00: Null entry, never used. +# +.equ NULL_SEL, . - GDT_BASE # Selector [0] +GDT_BASE: +BootGdtTable: .long 0 + .long 0 +# +# Linear data segment descriptor +# +.equ LINEAR_SEL, . - GDT_BASE # Selector [0x8] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x92 # present, ring 0, data, expand-up, writable + .byte 0xCF # page-granular, 32-bit + .byte 0 +# +# Linear code segment descriptor +# +.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x9B # present, ring 0, data, expand-up, not-writable + .byte 0xCF # page-granular, 32-bit + .byte 0 +# +# System data segment descriptor +# +.equ SYS_DATA_SEL, . - GDT_BASE # Selector [0x18] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x93 # present, ring 0, data, expand-up, not-writable + .byte 0xCF # page-granular, 32-bit + .byte 0 + +# +# System code segment descriptor +# +.equ SYS_CODE_SEL, . - GDT_BASE # Selector [0x20] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0 + .byte 0x9A # present, ring 0, data, expand-up, writable + .byte 0xCF # page-granular, 32-bit + .byte 0 +# +# Spare segment descriptor +# +.equ SYS16_CODE_SEL, . - GDT_BASE # Selector [0x28] + .word 0xFFFF # limit 0xFFFFF + .word 0 # base 0 + .byte 0x0E # Changed from F000 to E000. + .byte 0x9B # present, ring 0, code, expand-up, writable + .byte 0x00 # byte-granular, 16-bit + .byte 0 +# +# Spare segment descriptor +# +.equ SYS16_DATA_SEL, . - GDT_BASE # Selector [0x30] + .word 0xFFFF # limit 0xFFFF + .word 0 # base 0 + .byte 0 + .byte 0x93 # present, ring 0, data, expand-up, not-writable + .byte 0x00 # byte-granular, 16-bit + .byte 0 + +# +# Spare segment descriptor +# +.equ SPARE5_SEL, . - GDT_BASE # Selector [0x38] + .word 0 # limit 0 + .word 0 # base 0 + .byte 0 + .byte 0 # present, ring 0, data, expand-up, writable + .byte 0 # page-granular, 32-bit + .byte 0 +.equ GDT_SIZE, . - BootGdtTable # Size, in bytes + +# +# GDT Descriptor +# +GdtDesc: # GDT descriptor + .word GDT_SIZE - 1 # GDT limit + .long BootGdtTable # GDT base address + +ASM_PFX(ProtectedModeEntryLinearAddress): +ProtectedModeEntryLinearOffset: + .long ASM_PFX(ProtectedModeEntryPoint) # Offset of our 32 bit code + .word LINEAR_CODE_SEL diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm new file mode 100644 index 0000000000..9b2a526549 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm @@ -0,0 +1,340 @@ +;; @file +; This is the code that goes from real-mode to protected mode. +; It consumes the reset vector, calls TempRamInit API from FSP binary. +; +; Copyright (c) 2015, Intel Corporation. All rights reserved.
+; +; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which 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 "Fsp.h" + +.686p +.xmm +.model small, c + +EXTRN CallPeiCoreEntryPoint:NEAR +EXTRN TempRamInitParams:FAR + +; Pcds +EXTRN PcdGet32 (PcdFlashFvFspBase):DWORD +EXTRN PcdGet32 (PcdFlashFvFspSize):DWORD + +_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE' + ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE + +;---------------------------------------------------------------------------- +; +; Procedure: _ModuleEntryPoint +; +; Input: None +; +; Output: None +; +; Destroys: Assume all registers +; +; Description: +; +; Transition to non-paged flat-model protected mode from a +; hard-coded GDT that provides exactly two descriptors. +; This is a bare bones transition to protected mode only +; used for a while in PEI and possibly DXE. +; +; After enabling protected mode, a far jump is executed to +; transfer to PEI using the newly loaded GDT. +; +; Return: None +; +; MMX Usage: +; MM0 = BIST State +; MM5 = Save time-stamp counter value high32bit +; MM6 = Save time-stamp counter value low32bit. +; +;---------------------------------------------------------------------------- + +align 4 +_ModuleEntryPoint PROC NEAR C PUBLIC + fninit ; clear any pending Floating point exceptions + ; + ; Store the BIST value in mm0 + ; + movd mm0, eax + + ; + ; Save time-stamp counter value + ; rdtsc load 64bit time-stamp counter to EDX:EAX + ; + rdtsc + movd mm5, edx + movd mm6, eax + + ; + ; Load the GDT table in GdtDesc + ; + mov esi, OFFSET GdtDesc + DB 66h + lgdt fword ptr cs:[si] + + ; + ; Transition to 16 bit protected mode + ; + mov eax, cr0 ; Get control register 0 + or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1) + mov cr0, eax ; Activate protected mode + + mov eax, cr4 ; Get control register 4 + or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) + mov cr4, eax + + ; + ; Now we're in 16 bit protected mode + ; Set up the selectors for 32 bit protected mode entry + ; + mov ax, SYS_DATA_SEL + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + + ; + ; Transition to Flat 32 bit protected mode + ; The jump to a far pointer causes the transition to 32 bit mode + ; + mov esi, offset ProtectedModeEntryLinearAddress + jmp fword ptr cs:[si] + +_ModuleEntryPoint ENDP +_TEXT_REALMODE ENDS + +_TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE' + ASSUME CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE + +;---------------------------------------------------------------------------- +; +; Procedure: ProtectedModeEntryPoint +; +; Input: None +; +; Output: None +; +; Destroys: Assume all registers +; +; Description: +; +; This function handles: +; Call two basic APIs from FSP binary +; Initializes stack with some early data (BIST, PEI entry, etc) +; +; Return: None +; +;---------------------------------------------------------------------------- + +align 4 +ProtectedModeEntryPoint PROC NEAR PUBLIC + + ; Find the fsp info header + mov edi, PcdGet32 (PcdFlashFvFspBase) + mov ecx, PcdGet32 (PcdFlashFvFspSize) + + mov eax, dword ptr [edi + FVH_SIGINATURE_OFFSET] + cmp eax, FVH_SIGINATURE_VALID_VALUE + jnz FspHeaderNotFound + + xor eax, eax + mov ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET] + cmp ax, 0 + jnz FspFvExtHeaderExist + + xor eax, eax + mov ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header + add edi, eax + jmp FspCheckFfsHeader + +FspFvExtHeaderExist: + add edi, eax + mov eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header + add edi, eax + + ; Round up to 8 byte alignment + mov eax, edi + and al, 07h + jz FspCheckFfsHeader + + and edi, 0FFFFFFF8h + add edi, 08h + +FspCheckFfsHeader: + ; Check the ffs guid + mov eax, dword ptr [edi] + cmp eax, FSP_HEADER_GUID_DWORD1 + jnz FspHeaderNotFound + + mov eax, dword ptr [edi + 4] + cmp eax, FSP_HEADER_GUID_DWORD2 + jnz FspHeaderNotFound + + mov eax, dword ptr [edi + 8] + cmp eax, FSP_HEADER_GUID_DWORD3 + jnz FspHeaderNotFound + + mov eax, dword ptr [edi + 0Ch] + cmp eax, FSP_HEADER_GUID_DWORD4 + jnz FspHeaderNotFound + + add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header + + ; Check the section type as raw section + mov al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET] + cmp al, 019h + jnz FspHeaderNotFound + + add edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header + jmp FspHeaderFound + +FspHeaderNotFound: + jmp $ + +FspHeaderFound: + ; Get the fsp TempRamInit Api address + mov eax, dword ptr [edi + FSP_HEADER_IMAGEBASE_OFFSET] + add eax, dword ptr [edi + FSP_HEADER_TEMPRAMINIT_OFFSET] + + ; Setup the hardcode stack + mov esp, OFFSET TempRamInitStack + + ; Call the fsp TempRamInit Api + jmp eax + +TempRamInitDone: + cmp eax, 0 + jnz FspApiFailed + + ; ECX: start of range + ; EDX: end of range + mov esp, edx + push edx + push ecx + push eax ; zero - no hob list yet + call CallPeiCoreEntryPoint + +FspApiFailed: + jmp $ + +align 10h +TempRamInitStack: + DD OFFSET TempRamInitDone + DD OFFSET TempRamInitParams + +ProtectedModeEntryPoint ENDP + +; +; ROM-based Global-Descriptor Table for the Tiano PEI Phase +; +align 16 +PUBLIC BootGdtTable + +; +; GDT[0]: 0x00: Null entry, never used. +; +NULL_SEL EQU $ - GDT_BASE ; Selector [0] +GDT_BASE: +BootGdtTable DD 0 + DD 0 +; +; Linear data segment descriptor +; +LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 092h ; present, ring 0, data, expand-up, writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; Linear code segment descriptor +; +LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 09Bh ; present, ring 0, data, expand-up, not-writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; System data segment descriptor +; +SYS_DATA_SEL EQU $ - GDT_BASE ; Selector [0x18] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 093h ; present, ring 0, data, expand-up, not-writable + DB 0CFh ; page-granular, 32-bit + DB 0 + +; +; System code segment descriptor +; +SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0 + DB 09Ah ; present, ring 0, data, expand-up, writable + DB 0CFh ; page-granular, 32-bit + DB 0 +; +; Spare segment descriptor +; +SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28] + DW 0FFFFh ; limit 0xFFFFF + DW 0 ; base 0 + DB 0Eh ; Changed from F000 to E000. + DB 09Bh ; present, ring 0, code, expand-up, writable + DB 00h ; byte-granular, 16-bit + DB 0 +; +; Spare segment descriptor +; +SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30] + DW 0FFFFh ; limit 0xFFFF + DW 0 ; base 0 + DB 0 + DB 093h ; present, ring 0, data, expand-up, not-writable + DB 00h ; byte-granular, 16-bit + DB 0 + +; +; Spare segment descriptor +; +SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38] + DW 0 ; limit 0 + DW 0 ; base 0 + DB 0 + DB 0 ; present, ring 0, data, expand-up, writable + DB 0 ; page-granular, 32-bit + DB 0 +GDT_SIZE EQU $ - BootGdtTable ; Size, in bytes + +; +; GDT Descriptor +; +GdtDesc: ; GDT descriptor + DW GDT_SIZE - 1 ; GDT limit + DD OFFSET BootGdtTable ; GDT base address + + +ProtectedModeEntryLinearAddress LABEL FWORD +ProtectedModeEntryLinearOffset LABEL DWORD + DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code + DW LINEAR_CODE_SEL + +_TEXT_PROTECTED_MODE ENDS +END diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S new file mode 100644 index 0000000000..bbfdc11ebf --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S @@ -0,0 +1,74 @@ +## @file +# Switch the stack from temporary memory to permenent memory. +# +# Copyright (c) 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which 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 +# +## + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# SecSwitchStack ( +# UINT32 TemporaryMemoryBase, +# UINT32 PermenentMemoryBase +# )# +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX (SecSwitchStack) +ASM_PFX(SecSwitchStack): + # + # Save standard registers so they can be used to change stack + # + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + + # + # !!CAUTION!! this function address's is pushed into stack after + # migration of whole temporary memory, so need save it to permenent + # memory at first! + # + movl 20(%esp), %ebx # Save the first parameter + movl 24(%esp), %ecx # Save the second parameter + + # + # Save this function's return address into permenent memory at first. + # Then, Fixup the esp point to permenent memory + # + movl %esp, %eax + subl %ebx, %eax + addl %ecx, %eax + movl 0(%esp), %edx # copy pushed register's value to permenent memory + movl %edx, 0(%eax) + movl 4(%esp), %edx + movl %edx, 4(%eax) + movl 8(%esp), %edx + movl %edx, 8(%eax) + movl 12(%esp), %edx + movl %edx, 12(%eax) + movl 16(%esp), %edx # Update this function's return address into permenent memory + movl %edx, 16(%eax) + movl %eax, %esp # From now, esp is pointed to permenent memory + + # + # Fixup the ebp point to permenent memory + # + movl %ebp, %eax + subl %ebx, %eax + addl %ecx, %eax + movl %eax, %ebp # From now, ebp is pointed to permenent memory + + popl %edx + popl %ecx + popl %ebx + popl %eax + ret + diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm new file mode 100644 index 0000000000..e9618fc34a --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm @@ -0,0 +1,80 @@ +;; @file +; Switch the stack from temporary memory to permenent memory. +; +; Copyright (c) 2015, Intel Corporation. All rights reserved.
+; +; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which 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. +; +;; + + .586p + .model flat,C + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; SecSwitchStack ( +; UINT32 TemporaryMemoryBase, +; UINT32 PermenentMemoryBase +; ); +;------------------------------------------------------------------------------ +SecSwitchStack PROC + ; + ; Save three register: eax, ebx, ecx + ; + push eax + push ebx + push ecx + push edx + + ; + ; !!CAUTION!! this function address's is pushed into stack after + ; migration of whole temporary memory, so need save it to permenent + ; memory at first! + ; + + mov ebx, [esp + 20] ; Save the first parameter + mov ecx, [esp + 24] ; Save the second parameter + + ; + ; Save this function's return address into permenent memory at first. + ; Then, Fixup the esp point to permenent memory + ; + mov eax, esp + sub eax, ebx + add eax, ecx + mov edx, dword ptr [esp] ; copy pushed register's value to permenent memory + mov dword ptr [eax], edx + mov edx, dword ptr [esp + 4] + mov dword ptr [eax + 4], edx + mov edx, dword ptr [esp + 8] + mov dword ptr [eax + 8], edx + mov edx, dword ptr [esp + 12] + mov dword ptr [eax + 12], edx + mov edx, dword ptr [esp + 16] ; Update this function's return address into permenent memory + mov dword ptr [eax + 16], edx + mov esp, eax ; From now, esp is pointed to permenent memory + + ; + ; Fixup the ebp point to permenent memory + ; + mov eax, ebp + sub eax, ebx + add eax, ecx + mov ebp, eax ; From now, ebp is pointed to permenent memory + + pop edx + pop ecx + pop ebx + pop eax + ret +SecSwitchStack ENDP + + END diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c new file mode 100644 index 0000000000..a9703b6d1a --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c @@ -0,0 +1,45 @@ +/** @file + Sample to provide platform init function. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which 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 +#include + +/** + Platform initialization. + + @param[in] FspHobList HobList produced by FSP. + @param[in] StartOfRange Start of temporary RAM. + @param[in] EndOfRange End of temporary RAM. + +**/ +VOID +EFIAPI +PlatformInit ( + IN VOID *FspHobList, + IN VOID *StartOfRange, + IN VOID *EndOfRange + ) +{ + // + // Platform initialization + // Enable Serial port here + // + + DEBUG ((DEBUG_INFO, "PrintPeiCoreEntryPointParam\n")); + DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList)); + DEBUG ((DEBUG_INFO, "StartOfRange - 0x%x\n", StartOfRange)); + DEBUG ((DEBUG_INFO, "EndOfRange - 0x%x\n", EndOfRange)); +} diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c new file mode 100644 index 0000000000..8f875fe6a4 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c @@ -0,0 +1,114 @@ +/** @file + Sample to provide SaveSecContext function. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which 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 +#include +#include +#include + +/** + Save BIST value before call FspInit. + + @param[in] Bist BIST value. + +**/ +VOID +AsmSaveBistValue ( + IN UINT32 Bist + ); + +/** + Save Ticker value before call FspInit. + + @param[in] Ticker Ticker value. + +**/ +VOID +AsmSaveTickerValue ( + IN UINT64 Ticker + ); + +/** + Save SEC context before call FspInit. + + @param[in] PeiServices Pointer to PEI Services Table. + +**/ +VOID +EFIAPI +SaveSecContext ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + UINT32 *Bist; + UINT64 *Ticker; + UINT32 Size; + UINT32 Count; + UINT32 TopOfTemporaryRam; + VOID *TopOfTemporaryRamPpi; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "SaveSecContext - 0x%x\n", PeiServices)); + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gTopOfTemporaryRamPpiGuid, + 0, + NULL, + (VOID **) &TopOfTemporaryRamPpi + ); + if (EFI_ERROR (Status)) { + return ; + } + + DEBUG ((DEBUG_INFO, "TopOfTemporaryRamPpi - 0x%x\n", TopOfTemporaryRamPpi)); + + // + // The entries of BIST information, together with the number of them, + // reside in the bottom of stack, left untouched by normal stack operation. + // This routine copies the BIST information to the buffer pointed by + // PlatformInformationRecord for output. + // + // |--------------| <- TopOfTemporaryRam + // |Number of BSPs| + // |--------------| + // | BIST | + // |--------------| + // | .... | + // |--------------| + // | TSC[63:32] | + // |--------------| + // | TSC[31:00] | + // |--------------| + // + + TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof(UINT32); + TopOfTemporaryRam -= sizeof(UINT32) * 2; + DEBUG ((DEBUG_INFO, "TopOfTemporaryRam - 0x%x\n", TopOfTemporaryRam)); + Count = *(UINT32 *)(UINTN)(TopOfTemporaryRam - sizeof(UINT32)); + DEBUG ((DEBUG_INFO, "Count - 0x%x\n", Count)); + Size = Count * sizeof (IA32_HANDOFF_STATUS); + DEBUG ((DEBUG_INFO, "Size - 0x%x\n", Size)); + + Bist = (UINT32 *)(UINTN)(TopOfTemporaryRam - sizeof(UINT32) - Size); + DEBUG ((DEBUG_INFO, "Bist - 0x%x\n", *Bist)); + Ticker = (UINT64 *)(UINTN)(TopOfTemporaryRam - sizeof(UINT32) - Size - sizeof(UINT64)); + DEBUG ((DEBUG_INFO, "Ticker - 0x%lx\n", *Ticker)); + + // Just need record BSP + AsmSaveBistValue (*Bist); + AsmSaveTickerValue (*Ticker); +} diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c new file mode 100644 index 0000000000..d6085b73c7 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c @@ -0,0 +1,89 @@ +/** @file + Sample to provide SecGetPerformance function. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which 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 +#include +#include +#include +#include +#include + +/** + This interface conveys performance information out of the Security (SEC) phase into PEI. + + This service is published by the SEC phase. The SEC phase handoff has an optional + EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the + PEI Foundation. As such, if the platform supports collecting performance data in SEC, + this information is encapsulated into the data structure abstracted by this service. + This information is collected for the boot-strap processor (BSP) on IA-32. + + @param[in] PeiServices The pointer to the PEI Services Table. + @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI. + @param[out] Performance The pointer to performance data collected in SEC phase. + + @retval EFI_SUCCESS The data was successfully returned. + +**/ +EFI_STATUS +EFIAPI +SecGetPerformance ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN PEI_SEC_PERFORMANCE_PPI *This, + OUT FIRMWARE_SEC_PERFORMANCE *Performance + ) +{ + UINT32 Size; + UINT32 Count; + UINT32 TopOfTemporaryRam; + UINT64 Ticker; + VOID *TopOfTemporaryRamPpi; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "SecGetPerformance\n")); + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gTopOfTemporaryRamPpiGuid, + 0, + NULL, + (VOID **) &TopOfTemporaryRamPpi + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + // + // |--------------| <- TopOfTemporaryRam + // |Number of BSPs| + // |--------------| + // | BIST | + // |--------------| + // | .... | + // |--------------| + // | TSC[63:32] | + // |--------------| + // | TSC[31:00] | + // |--------------| + // + TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof(UINT32); + TopOfTemporaryRam -= sizeof(UINT32) * 2; + Count = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32)); + Size = Count * sizeof (UINT64); + + Ticker = *(UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size - sizeof (UINT32) * 2); + Performance->ResetEnd = GetTimeInNanoSecond (Ticker); + + return EFI_SUCCESS; +} diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf new file mode 100644 index 0000000000..8d019d827d --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf @@ -0,0 +1,94 @@ +## @file +# Sample to provide FSP wrapper platform sec related function. +# +# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which 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 Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SecPeiFspPlatformSecLibSample + FILE_GUID = 5B2B6493-BEBB-4d44-8278-35F40F5289BC + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspPlatformSecLib + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources] + FspPlatformSecLibSample.c + SecRamInitData.c + SaveSecContext.c + SecPlatformInformation.c + SecGetPerformance.c + SecTempRamSupport.c + PlatformInit.c + +[Sources.IA32] + Ia32/SecEntry.asm + Ia32/PeiCoreEntry.asm + Ia32/AsmSaveSecContext.asm + Ia32/Stack.asm + Ia32/Fsp.h + Ia32/SecEntry.S + Ia32/PeiCoreEntry.S + Ia32/AsmSaveSecContext.S + Ia32/Stack.S + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + IntelFspPkg/IntelFspPkg.dec + IntelFspWrapperPkg/IntelFspWrapperPkg.dec + +[LibraryClasses] + LocalApicLib + +[Ppis] + gEfiSecPlatformInformationPpiGuid ## CONSUMES + gPeiSecPerformancePpiGuid ## CONSUMES + gEfiTemporaryRamSupportPpiGuid ## CONSUMES + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize ## CONSUMES + +[FixedPcd] + gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize ## CONSUMES diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c new file mode 100644 index 0000000000..ebf3d12ddc --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c @@ -0,0 +1,83 @@ +/** @file + Sample to provide SecPlatformInformation function. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which 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 +#include +#include +#include +#include + +/** + This interface conveys state information out of the Security (SEC) phase into PEI. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in,out] StructureSize Pointer to the variable describing size of the input buffer. + @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_BUFFER_TOO_SMALL The buffer was too small. + +**/ +EFI_STATUS +EFIAPI +SecPlatformInformation ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT UINT64 *StructureSize, + OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord + ) +{ + UINT32 *Bist; + UINT32 Size; + UINT32 Count; + UINT32 TopOfTemporaryRam; + VOID *TopOfTemporaryRamPpi; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "SecPlatformInformation\n")); + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gTopOfTemporaryRamPpiGuid, + 0, + NULL, + (VOID **) &TopOfTemporaryRamPpi + ); + if (EFI_ERROR (Status)) { + return EFI_NOT_FOUND; + } + + // + // The entries of BIST information, together with the number of them, + // reside in the bottom of stack, left untouched by normal stack operation. + // This routine copies the BIST information to the buffer pointed by + // PlatformInformationRecord for output. + // + TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof (UINT32); + TopOfTemporaryRam -= sizeof(UINT32) * 2; + Count = *((UINT32 *)(UINTN) (TopOfTemporaryRam - sizeof (UINT32))); + Size = Count * sizeof (IA32_HANDOFF_STATUS); + + if ((*StructureSize) < (UINT64) Size) { + *StructureSize = Size; + return EFI_BUFFER_TOO_SMALL; + } + + *StructureSize = Size; + Bist = (UINT32 *) (TopOfTemporaryRam - sizeof (UINT32) - Size); + + CopyMem (PlatformInformationRecord, Bist, Size); + + return EFI_SUCCESS; +} diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c new file mode 100644 index 0000000000..26fed03611 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c @@ -0,0 +1,23 @@ +/** @file + Sample to provide TempRamInitParams data. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which 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 + +GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 TempRamInitParams[4] = { + ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchAddress) + FixedPcdGet32 (PcdFlashMicroCodeOffset)), + ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) - FixedPcdGet32 (PcdFlashMicroCodeOffset)), + FixedPcdGet32 (PcdFlashCodeCacheAddress), + FixedPcdGet32 (PcdFlashCodeCacheSize) +}; diff --git a/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c new file mode 100644 index 0000000000..419cf9c8e4 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c @@ -0,0 +1,154 @@ +/** @file + Sample to provide SecTemporaryRamSupport function. + + Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which 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 +#include +#include +#include +#include +#include + +/** + Switch the stack in the temporary memory to the one in the permanent memory. + + This function must be invoked after the memory migration immediately. The relative + position of the stack in the temporary and permanent memory is same. + + @param[in] TemporaryMemoryBase Base address of the temporary memory. + @param[in] PermenentMemoryBase Base address of the permanent memory. + +**/ +VOID +EFIAPI +SecSwitchStack ( + IN UINT32 TemporaryMemoryBase, + IN UINT32 PermenentMemoryBase + ); + +/** + This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into + permanent memory. + + @param[in] PeiServices Pointer to the PEI Services Table. + @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the + Temporary RAM contents. + @param[in] CopySize Amount of memory to migrate from temporary to permanent memory. + + @retval EFI_SUCCESS The data was successfully returned. + @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when + TemporaryMemoryBase > PermanentMemoryBase. + +**/ +EFI_STATUS +EFIAPI +SecTemporaryRamSupport ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ) +{ + IA32_DESCRIPTOR IdtDescriptor; + VOID* OldHeap; + VOID* NewHeap; + VOID* OldStack; + VOID* NewStack; + DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext; + BOOLEAN OldStatus; + UINTN PeiStackSize; + + PeiStackSize = (UINTN)PcdGet32 (PcdPeiTemporaryRamStackSize); + if (PeiStackSize == 0) { + PeiStackSize = (CopySize >> 1); + } + + ASSERT (PeiStackSize < CopySize); + + // + // |-------------------|----> + // | Stack | PeiStackSize + // |-------------------|----> + // | Heap | PeiTemporayRamSize + // |-------------------|----> TempRamBase + // + // |-------------------|----> + // | Heap | PeiTemporayRamSize + // |-------------------|----> + // | Stack | PeiStackSize + // |-------------------|----> PermanentMemoryBase + // + + OldHeap = (VOID*)(UINTN)TemporaryMemoryBase; + NewHeap = (VOID*)((UINTN)PermanentMemoryBase + PeiStackSize); + + OldStack = (VOID*)((UINTN)TemporaryMemoryBase + CopySize - PeiStackSize); + NewStack = (VOID*)(UINTN)PermanentMemoryBase; + + DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap; + DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack; + + OldStatus = SaveAndSetDebugTimerInterrupt (FALSE); + // + // Initialize Debug Agent to support source level debug in PEI phase after memory ready. + // It will build HOB and fix up the pointer in IDT table. + // + InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL); + + // + // Migrate Heap + // + CopyMem (NewHeap, OldHeap, CopySize - PeiStackSize); + + // + // Migrate Stack + // + CopyMem (NewStack, OldStack, PeiStackSize); + + + // + // We need *not* fix the return address because currently, + // The PeiCore is executed in flash. + // + + // + // Rebase IDT table in permanent memory + // + AsmReadIdtr (&IdtDescriptor); + IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack; + + AsmWriteIdtr (&IdtDescriptor); + + + // + // Program MTRR + // + + // + // SecSwitchStack function must be invoked after the memory migration + // immediatly, also we need fixup the stack change caused by new call into + // permenent memory. + // + SecSwitchStack ( + (UINT32) (UINTN) OldStack, + (UINT32) (UINTN) NewStack + ); + + SaveAndSetDebugTimerInterrupt (OldStatus); + + return EFI_SUCCESS; +} + diff --git a/BraswellPlatformPkg/Common/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c b/BraswellPlatformPkg/Common/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c new file mode 100644 index 0000000000..bc7ba44dee --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c @@ -0,0 +1,1094 @@ +/** @file + 16550 UART Serial Port library functions + + (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
+ Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which 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 +#include +#include +#include +#include +#include +#include +#include + +// +// PCI Defintions. +// +#define PCI_BRIDGE_32_BIT_IO_SPACE 0x01 + +// +// 16550 UART register offsets and bitfields +// +#define R_UART_RXBUF 0 +#define R_UART_TXBUF 0 +#define R_UART_BAUD_LOW 0 +#define R_UART_BAUD_HIGH 1 +#define R_UART_FCR 2 +#define B_UART_FCR_FIFOE BIT0 +#define B_UART_FCR_FIFO64 BIT5 +#define R_UART_LCR 3 +#define B_UART_LCR_DLAB BIT7 +#define R_UART_MCR 4 +#define B_UART_MCR_DTRC BIT0 +#define B_UART_MCR_RTS BIT1 +#define R_UART_LSR 5 +#define B_UART_LSR_RXRDY BIT0 +#define B_UART_LSR_TXRDY BIT5 +#define B_UART_LSR_TEMT BIT6 +#define R_UART_MSR 6 +#define B_UART_MSR_CTS BIT4 +#define B_UART_MSR_DSR BIT5 +#define B_UART_MSR_RI BIT6 +#define B_UART_MSR_DCD BIT7 + +// +// 4-byte structure for each PCI node in PcdSerialPciDeviceInfo +// +typedef struct { + UINT8 Device; + UINT8 Function; + UINT16 PowerManagementStatusAndControlRegister; +} PCI_UART_DEVICE_INFO; + +/** + Read an 8-bit 16550 register. If PcdSerialUseMmio is TRUE, then the value is read from + MMIO space. If PcdSerialUseMmio is FALSE, then the value is read from I/O space. The + parameter Offset is added to the base address of the 16550 registers that is specified + by PcdSerialRegisterBase. + + @param Base The base address register of UART device. + @param Offset The offset of the 16550 register to read. + + @return The value read from the 16550 register. + +**/ +UINT8 +SerialPortReadRegister ( + UINTN Base, + UINTN Offset + ) +{ + if (PcdGetBool (PcdSerialUseMmio)) { + return MmioRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride)); + } else { + return IoRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride)); + } +} + +/** + Write an 8-bit 16550 register. If PcdSerialUseMmio is TRUE, then the value is written to + MMIO space. If PcdSerialUseMmio is FALSE, then the value is written to I/O space. The + parameter Offset is added to the base address of the 16550 registers that is specified + by PcdSerialRegisterBase. + + @param Base The base address register of UART device. + @param Offset The offset of the 16550 register to write. + @param Value The value to write to the 16550 register specified by Offset. + + @return The value written to the 16550 register. + +**/ +UINT8 +SerialPortWriteRegister ( + UINTN Base, + UINTN Offset, + UINT8 Value + ) +{ + if (PcdGetBool (PcdSerialUseMmio)) { + return MmioWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), Value); + } else { + return IoWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), Value); + } +} + +/** + Update the value of an 16-bit PCI configuration register in a PCI device. If the + PCI Configuration register specified by PciAddress is already programmed with a + non-zero value, then return the current value. Otherwise update the PCI configuration + register specified by PciAddress with the value specified by Value and return the + value programmed into the PCI configuration register. All values must be masked + using the bitmask specified by Mask. + + @param PciAddress PCI Library address of the PCI Configuration register to update. + @param Value The value to program into the PCI Configuration Register. + @param Mask Bitmask of the bits to check and update in the PCI configuration register. + +**/ +UINT16 +SerialPortLibUpdatePciRegister16 ( + UINTN PciAddress, + UINT16 Value, + UINT16 Mask + ) +{ + UINT16 CurrentValue; + + CurrentValue = PciRead16 (PciAddress) & Mask; + if (CurrentValue != 0) { + return CurrentValue; + } + return PciWrite16 (PciAddress, Value & Mask); +} + +/** + Update the value of an 32-bit PCI configuration register in a PCI device. If the + PCI Configuration register specified by PciAddress is already programmed with a + non-zero value, then return the current value. Otherwise update the PCI configuration + register specified by PciAddress with the value specified by Value and return the + value programmed into the PCI configuration register. All values must be masked + using the bitmask specified by Mask. + + @param PciAddress PCI Library address of the PCI Configuration register to update. + @param Value The value to program into the PCI Configuration Register. + @param Mask Bitmask of the bits to check and update in the PCI configuration register. + + @return The Secondary bus number that is actually programed into the PCI to PCI Bridge device. + +**/ +UINT32 +SerialPortLibUpdatePciRegister32 ( + UINTN PciAddress, + UINT32 Value, + UINT32 Mask + ) +{ + UINT32 CurrentValue; + + CurrentValue = PciRead32 (PciAddress) & Mask; + if (CurrentValue != 0) { + return CurrentValue; + } + return PciWrite32 (PciAddress, Value & Mask); +} + +/** + Retrieve the I/O or MMIO base address register for the PCI UART device. + + This function assumes Root Bus Numer is Zero, and enables I/O and MMIO in PCI UART + Device if they are not already enabled. + + @return The base address register of the UART device. + +**/ +UINTN +GetSerialRegisterBase ( + VOID + ) +{ + UINTN PciLibAddress; + UINTN BusNumber; + UINTN SubordinateBusNumber; + UINT32 ParentIoBase; + UINT32 ParentIoLimit; + UINT16 ParentMemoryBase; + UINT16 ParentMemoryLimit; + UINT32 IoBase; + UINT32 IoLimit; + UINT16 MemoryBase; + UINT16 MemoryLimit; + UINTN SerialRegisterBase; + UINTN BarIndex; + UINT32 RegisterBaseMask; + PCI_UART_DEVICE_INFO *DeviceInfo; + + // + // Get PCI Device Info + // + DeviceInfo = (PCI_UART_DEVICE_INFO *) PcdGetPtr (PcdSerialPciDeviceInfo); + + // + // If PCI Device Info is empty, then assume fixed address UART and return PcdSerialRegisterBase + // + if (DeviceInfo->Device == 0xff) { + return (UINTN)PcdGet64 (PcdSerialRegisterBase); + } + + // + // Assume PCI Bus 0 I/O window is 0-64KB and MMIO windows is 0-4GB + // + ParentMemoryBase = 0 >> 16; + ParentMemoryLimit = 0xfff00000 >> 16; + ParentIoBase = 0 >> 12; + ParentIoLimit = 0xf000 >> 12; + + // + // Enable I/O and MMIO in PCI Bridge + // Assume Root Bus Numer is Zero. + // + for (BusNumber = 0; (DeviceInfo + 1)->Device != 0xff; DeviceInfo++) { + // + // Compute PCI Lib Address to PCI to PCI Bridge + // + PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device, DeviceInfo->Function, 0); + + // + // Retrieve and verify the bus numbers in the PCI to PCI Bridge + // + BusNumber = PciRead8 (PciLibAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET); + SubordinateBusNumber = PciRead8 (PciLibAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET); + if (BusNumber == 0 || BusNumber > SubordinateBusNumber) { + return 0; + } + + // + // Retrieve and verify the I/O or MMIO decode window in the PCI to PCI Bridge + // + if (PcdGetBool (PcdSerialUseMmio)) { + MemoryLimit = PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit)) & 0xfff0; + MemoryBase = PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase)) & 0xfff0; + + // + // If PCI Bridge MMIO window is disabled, then return 0 + // + if (MemoryLimit < MemoryBase) { + return 0; + } + + // + // If PCI Bridge MMIO window is not in the address range decoded by the parent PCI Bridge, then return 0 + // + if (MemoryBase < ParentMemoryBase || MemoryBase > ParentMemoryLimit || MemoryLimit > ParentMemoryLimit) { + return 0; + } + ParentMemoryBase = MemoryBase; + ParentMemoryLimit = MemoryLimit; + } else { + IoLimit = PciRead8 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit)); + if ((IoLimit & PCI_BRIDGE_32_BIT_IO_SPACE ) == 0) { + IoLimit = IoLimit >> 4; + } else { + IoLimit = (PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimitUpper16)) << 4) | (IoLimit >> 4); + } + IoBase = PciRead8 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase)); + if ((IoBase & PCI_BRIDGE_32_BIT_IO_SPACE ) == 0) { + IoBase = IoBase >> 4; + } else { + IoBase = (PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16)) << 4) | (IoBase >> 4); + } + + // + // If PCI Bridge I/O window is disabled, then return 0 + // + if (IoLimit < IoBase) { + return 0; + } + + // + // If PCI Bridge I/O window is not in the address range decoded by the parent PCI Bridge, then return 0 + // + if (IoBase < ParentIoBase || IoBase > ParentIoLimit || IoLimit > ParentIoLimit) { + return 0; + } + ParentIoBase = IoBase; + ParentIoLimit = IoLimit; + } + } + + // + // Compute PCI Lib Address to PCI UART + // + PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device, DeviceInfo->Function, 0); + + // + // Find the first IO or MMIO BAR + // + RegisterBaseMask = 0xFFFFFFF0; + for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex ++) { + SerialRegisterBase = PciRead32 (PciLibAddress + PCI_BASE_ADDRESSREG_OFFSET + BarIndex * 4); + if (PcdGetBool (PcdSerialUseMmio) && ((SerialRegisterBase & BIT0) == 0)) { + // + // MMIO BAR is found + // + RegisterBaseMask = 0xFFFFFFF0; + break; + } + + if ((!PcdGetBool (PcdSerialUseMmio)) && ((SerialRegisterBase & BIT0) != 0)) { + // + // IO BAR is found + // + RegisterBaseMask = 0xFFFFFFF8; + break; + } + } + + // + // MMIO or IO BAR is not found. + // + if (BarIndex == PCI_MAX_BAR) { + return 0; + } + + // + // Program UART BAR + // + SerialRegisterBase = SerialPortLibUpdatePciRegister32 ( + PciLibAddress + PCI_BASE_ADDRESSREG_OFFSET + BarIndex * 4, + (UINT32)PcdGet64 (PcdSerialRegisterBase), + RegisterBaseMask + ); + + // + // Verify that the UART BAR is in the address range decoded by the parent PCI Bridge + // + if (PcdGetBool (PcdSerialUseMmio)) { + if (((SerialRegisterBase >> 16) & 0xfff0) < ParentMemoryBase || ((SerialRegisterBase >> 16) & 0xfff0) > ParentMemoryLimit) { + return 0; + } + } else { + if ((SerialRegisterBase >> 12) < ParentIoBase || (SerialRegisterBase >> 12) > ParentIoLimit) { + return 0; + } + } + + // + // Enable I/O and MMIO in PCI UART Device if they are not already enabled + // + PciOr16 ( + PciLibAddress + PCI_COMMAND_OFFSET, + PcdGetBool (PcdSerialUseMmio) ? EFI_PCI_COMMAND_MEMORY_SPACE : EFI_PCI_COMMAND_IO_SPACE + ); + + // + // Force D0 state if a Power Management and Status Register is specified + // + if (DeviceInfo->PowerManagementStatusAndControlRegister != 0x00) { + if ((PciRead16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister) & (BIT0 | BIT1)) != 0x00) { + PciAnd16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister, (UINT16)~(BIT0 | BIT1)); + // + // If PCI UART was not in D0, then make sure FIFOs are enabled, but do not reset FIFOs + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64))); + } + } + + // + // Get PCI Device Info + // + DeviceInfo = (PCI_UART_DEVICE_INFO *) PcdGetPtr (PcdSerialPciDeviceInfo); + + // + // Enable I/O or MMIO in PCI Bridge + // Assume Root Bus Numer is Zero. + // + for (BusNumber = 0; (DeviceInfo + 1)->Device != 0xff; DeviceInfo++) { + // + // Compute PCI Lib Address to PCI to PCI Bridge + // + PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device, DeviceInfo->Function, 0); + + // + // Enable the I/O or MMIO decode windows in the PCI to PCI Bridge + // + PciOr16 ( + PciLibAddress + PCI_COMMAND_OFFSET, + PcdGetBool (PcdSerialUseMmio) ? EFI_PCI_COMMAND_MEMORY_SPACE : EFI_PCI_COMMAND_IO_SPACE + ); + + // + // Force D0 state if a Power Management and Status Register is specified + // + if (DeviceInfo->PowerManagementStatusAndControlRegister != 0x00) { + if ((PciRead16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister) & (BIT0 | BIT1)) != 0x00) { + PciAnd16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister, (UINT16)~(BIT0 | BIT1)); + } + } + + BusNumber = PciRead8 (PciLibAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET); + } + + return SerialRegisterBase; +} + +/** + Return whether the hardware flow control signal allows writing. + + @param SerialRegisterBase The base address register of UART device. + + @retval TRUE The serial port is writable. + @retval FALSE The serial port is not writable. +**/ +BOOLEAN +SerialPortWritable ( + UINTN SerialRegisterBase + ) +{ + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + if (PcdGetBool (PcdSerialDetectCable)) { + // + // Wait for both DSR and CTS to be set + // DSR is set if a cable is connected. + // CTS is set if it is ok to transmit data + // + // DSR CTS Description Action + // === === ======================================== ======== + // 0 0 No cable connected. Wait + // 0 1 No cable connected. Wait + // 1 0 Cable connected, but not clear to send. Wait + // 1 1 Cable connected, and clear to send. Transmit + // + return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) == (B_UART_MSR_DSR | B_UART_MSR_CTS)); + } else { + // + // Wait for both DSR and CTS to be set OR for DSR to be clear. + // DSR is set if a cable is connected. + // CTS is set if it is ok to transmit data + // + // DSR CTS Description Action + // === === ======================================== ======== + // 0 0 No cable connected. Transmit + // 0 1 No cable connected. Transmit + // 1 0 Cable connected, but not clear to send. Wait + // 1 1 Cable connected, and clar to send. Transmit + // + return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) != (B_UART_MSR_DSR)); + } + } + + return TRUE; +} + +/** + Initialize the serial device hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfully initialized, then return RETURN_SUCCESS. + If the serial device could not be initialized, then return RETURN_DEVICE_ERROR. + + @retval RETURN_SUCCESS The serial device was initialized. + @retval RETURN_DEVICE_ERROR The serial device could not be initialized. + +**/ +RETURN_STATUS +EFIAPI +SerialPortInitialize ( + VOID + ) +{ + RETURN_STATUS Status; + UINTN SerialRegisterBase; + UINT32 Divisor; + UINT32 CurrentDivisor; + BOOLEAN Initialized; + + // + // Perform platform specific initialization required to enable use of the 16550 device + // at the location specified by PcdSerialUseMmio and PcdSerialRegisterBase. + // + Status = PlatformHookSerialPortInitialize (); + if (RETURN_ERROR (Status)) { + return Status; + } + + // + // Calculate divisor for baud generator + // Ref_Clk_Rate / Baud_Rate / 16 + // + Divisor = PcdGet32 (PcdSerialClockRate) / (PcdGet32 (PcdSerialBaudRate) * 16); + if ((PcdGet32 (PcdSerialClockRate) % (PcdGet32 (PcdSerialBaudRate) * 16)) >= PcdGet32 (PcdSerialBaudRate) * 8) { + Divisor++; + } + + // + // Get the base address of the serial port in either I/O or MMIO space + // + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase ==0) { + return RETURN_DEVICE_ERROR; + } + + // + // See if the serial port is already initialized + // + Initialized = TRUE; + if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & 0x3F) != (PcdGet8 (PcdSerialLineControl) & 0x3F)) { + Initialized = FALSE; + } + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) | B_UART_LCR_DLAB)); + CurrentDivisor = SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_HIGH) << 8; + CurrentDivisor |= (UINT32) SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_LOW); + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & ~B_UART_LCR_DLAB)); + if (CurrentDivisor != Divisor) { + Initialized = FALSE; + } + if (Initialized) { + return RETURN_SUCCESS; + } + + // + // Wait for the serial port to be ready. + // Verify that both the transmit FIFO and the shift register are empty. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)); + + // + // Configure baud rate + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8) (Divisor >> 8)); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8) (Divisor & 0xff)); + + // + // Clear DLAB and configure Data Bits, Parity, and Stop Bits. + // Strip reserved bits from PcdSerialLineControl + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3F)); + + // + // Enable and reset FIFOs + // Strip reserved bits from PcdSerialFifoControl + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00); + SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64))); + + // + // Put Modem Control Register(MCR) into its reset state of 0x00. + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, 0x00); + + return RETURN_SUCCESS; +} + +/** + Write data from buffer to serial device. + + Writes NumberOfBytes data bytes from Buffer to the serial device. + The number of bytes actually written to the serial device is returned. + If the return value is less than NumberOfBytes, then the write operation failed. + + If Buffer is NULL, then ASSERT(). + + If NumberOfBytes is zero, then return 0. + + @param Buffer Pointer to the data buffer to be written. + @param NumberOfBytes Number of bytes to written to the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes written to the serial device. + If this value is less than NumberOfBytes, then the read operation failed. + +**/ +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + UINTN SerialRegisterBase; + UINTN Result; + UINTN Index; + UINTN FifoSize; + + if (Buffer == NULL) { + return 0; + } + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase ==0) { + return 0; + } + + if (NumberOfBytes == 0) { + // + // Flush the hardware + // + + // + // Wait for both the transmit FIFO and shift register empty. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)); + + // + // Wait for the hardware flow control signal + // + while (!SerialPortWritable (SerialRegisterBase)); + return 0; + } + + // + // Compute the maximum size of the Tx FIFO + // + FifoSize = 1; + if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFOE) != 0) { + if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFO64) == 0) { + FifoSize = 16; + } else { + FifoSize = PcdGet32 (PcdSerialExtendedTxFifoSize); + } + } + + Result = NumberOfBytes; + while (NumberOfBytes != 0) { + // + // Wait for the serial port to be ready, to make sure both the transmit FIFO + // and shift register empty. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_TEMT) == 0); + + // + // Fill then entire Tx FIFO + // + for (Index = 0; Index < FifoSize && NumberOfBytes != 0; Index++, NumberOfBytes--, Buffer++) { + // + // Wait for the hardware flow control signal + // + while (!SerialPortWritable (SerialRegisterBase)); + + // + // Write byte to the transmit buffer. + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_TXBUF, *Buffer); + } + } + return Result; +} + +/** + Reads data from a serial device into a buffer. + + @param Buffer Pointer to the data buffer to store the data read from the serial device. + @param NumberOfBytes Number of bytes to read from the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes read from the serial device. + If this value is less than NumberOfBytes, then the read operation failed. + +**/ +UINTN +EFIAPI +SerialPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + UINTN SerialRegisterBase; + UINTN Result; + UINT8 Mcr; + + if (NULL == Buffer) { + return 0; + } + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase ==0) { + return 0; + } + + Mcr = (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) & ~B_UART_MCR_RTS); + + for (Result = 0; NumberOfBytes-- != 0; Result++, Buffer++) { + // + // Wait for the serial port to have some data. + // + while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_RXRDY) == 0) { + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Set RTS to let the peer send some data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(Mcr | B_UART_MCR_RTS)); + } + } + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Clear RTS to prevent peer from sending data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr); + } + + // + // Read byte from the receive buffer. + // + *Buffer = SerialPortReadRegister (SerialRegisterBase, R_UART_RXBUF); + } + + return Result; +} + + +/** + Polls a serial device to see if there is any data waiting to be read. + + Polls aserial device to see if there is any data waiting to be read. + If there is data waiting to be read from the serial device, then TRUE is returned. + If there is no data waiting to be read from the serial device, then FALSE is returned. + + @retval TRUE Data is waiting to be read from the serial device. + @retval FALSE There is no data waiting to be read from the serial device. + +**/ +BOOLEAN +EFIAPI +SerialPortPoll ( + VOID + ) +{ + UINTN SerialRegisterBase; + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase ==0) { + return FALSE; + } + + // + // Read the serial port status + // + if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_RXRDY) != 0) { + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Clear RTS to prevent peer from sending data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) & ~B_UART_MCR_RTS)); + } + return TRUE; + } + + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + // + // Set RTS to let the peer send some data + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) | B_UART_MCR_RTS)); + } + + return FALSE; +} + +/** + Sets the control bits on a serial device. + + @param Control Sets the bits of Control that are settable. + + @retval RETURN_SUCCESS The new control bits were set on the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortSetControl ( + IN UINT32 Control + ) +{ + UINTN SerialRegisterBase; + UINT8 Mcr; + + // + // First determine the parameter is invalid. + // + if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY | + EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0) { + return RETURN_UNSUPPORTED; + } + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase ==0) { + return RETURN_UNSUPPORTED; + } + + // + // Read the Modem Control Register. + // + Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR); + Mcr &= (~(B_UART_MCR_DTRC | B_UART_MCR_RTS)); + + if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) == EFI_SERIAL_DATA_TERMINAL_READY) { + Mcr |= B_UART_MCR_DTRC; + } + + if ((Control & EFI_SERIAL_REQUEST_TO_SEND) == EFI_SERIAL_REQUEST_TO_SEND) { + Mcr |= B_UART_MCR_RTS; + } + + // + // Write the Modem Control Register. + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr); + + return RETURN_SUCCESS; +} + +/** + Retrieve the status of the control bits on a serial device. + + @param Control A pointer to return the current control signals from the serial device. + + @retval RETURN_SUCCESS The control bits were read from the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortGetControl ( + OUT UINT32 *Control + ) +{ + UINTN SerialRegisterBase; + UINT8 Msr; + UINT8 Mcr; + UINT8 Lsr; + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase ==0) { + return RETURN_UNSUPPORTED; + } + + *Control = 0; + + // + // Read the Modem Status Register. + // + Msr = SerialPortReadRegister (SerialRegisterBase, R_UART_MSR); + + if ((Msr & B_UART_MSR_CTS) == B_UART_MSR_CTS) { + *Control |= EFI_SERIAL_CLEAR_TO_SEND; + } + + if ((Msr & B_UART_MSR_DSR) == B_UART_MSR_DSR) { + *Control |= EFI_SERIAL_DATA_SET_READY; + } + + if ((Msr & B_UART_MSR_RI) == B_UART_MSR_RI) { + *Control |= EFI_SERIAL_RING_INDICATE; + } + + if ((Msr & B_UART_MSR_DCD) == B_UART_MSR_DCD) { + *Control |= EFI_SERIAL_CARRIER_DETECT; + } + + // + // Read the Modem Control Register. + // + Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR); + + if ((Mcr & B_UART_MCR_DTRC) == B_UART_MCR_DTRC) { + *Control |= EFI_SERIAL_DATA_TERMINAL_READY; + } + + if ((Mcr & B_UART_MCR_RTS) == B_UART_MCR_RTS) { + *Control |= EFI_SERIAL_REQUEST_TO_SEND; + } + + if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { + *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; + } + + // + // Read the Line Status Register. + // + Lsr = SerialPortReadRegister (SerialRegisterBase, R_UART_LSR); + + if ((Lsr & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) == (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) { + *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY; + } + + if ((Lsr & B_UART_LSR_RXRDY) == 0) { + *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY; + } + + return RETURN_SUCCESS; +} + +/** + Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, + data bits, and stop bits on a serial device. + + @param BaudRate The requested baud rate. A BaudRate value of 0 will use the + device's default interface speed. + On output, the value actually set. + @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the + serial interface. A ReceiveFifoDepth value of 0 will use + the device's default FIFO depth. + On output, the value actually set. + @param Timeout The requested time out for a single character in microseconds. + This timeout applies to both the transmit and receive side of the + interface. A Timeout value of 0 will use the device's default time + out value. + On output, the value actually set. + @param Parity The type of parity to use on this serial device. A Parity value of + DefaultParity will use the device's default parity value. + On output, the value actually set. + @param DataBits The number of data bits to use on the serial device. A DataBits + vaule of 0 will use the device's default data bit setting. + On output, the value actually set. + @param StopBits The number of stop bits to use on this serial device. A StopBits + value of DefaultStopBits will use the device's default number of + stop bits. + On output, the value actually set. + + @retval RETURN_SUCCESS The new attributes were set on the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an unsupported value. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortSetAttributes ( + IN OUT UINT64 *BaudRate, + IN OUT UINT32 *ReceiveFifoDepth, + IN OUT UINT32 *Timeout, + IN OUT EFI_PARITY_TYPE *Parity, + IN OUT UINT8 *DataBits, + IN OUT EFI_STOP_BITS_TYPE *StopBits + ) +{ + UINTN SerialRegisterBase; + UINT32 SerialBaudRate; + UINTN Divisor; + UINT8 Lcr; + UINT8 LcrData; + UINT8 LcrParity; + UINT8 LcrStop; + + SerialRegisterBase = GetSerialRegisterBase (); + if (SerialRegisterBase ==0) { + return RETURN_UNSUPPORTED; + } + + // + // Check for default settings and fill in actual values. + // + if (*BaudRate == 0) { + *BaudRate = PcdGet32 (PcdSerialBaudRate); + } + SerialBaudRate = (UINT32) *BaudRate; + + if (*DataBits == 0) { + LcrData = (UINT8) (PcdGet8 (PcdSerialLineControl) & 0x3); + *DataBits = LcrData + 5; + } else { + if ((*DataBits < 5) || (*DataBits > 8)) { + return RETURN_INVALID_PARAMETER; + } + // + // Map 5..8 to 0..3 + // + LcrData = (UINT8) (*DataBits - (UINT8) 5); + } + + if (*Parity == DefaultParity) { + LcrParity = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 3) & 0x7); + switch (LcrParity) { + case 0: + *Parity = NoParity; + break; + + case 3: + *Parity = EvenParity; + break; + + case 1: + *Parity = OddParity; + break; + + case 7: + *Parity = SpaceParity; + break; + + case 5: + *Parity = MarkParity; + break; + + default: + break; + } + } else { + switch (*Parity) { + case NoParity: + LcrParity = 0; + break; + + case EvenParity: + LcrParity = 3; + break; + + case OddParity: + LcrParity = 1; + break; + + case SpaceParity: + LcrParity = 7; + break; + + case MarkParity: + LcrParity = 5; + break; + + default: + return RETURN_INVALID_PARAMETER; + } + } + + if (*StopBits == DefaultStopBits) { + LcrStop = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 2) & 0x1); + switch (LcrStop) { + case 0: + *StopBits = OneStopBit; + break; + + case 1: + if (*DataBits == 5) { + *StopBits = OneFiveStopBits; + } else { + *StopBits = TwoStopBits; + } + break; + + default: + break; + } + } else { + switch (*StopBits) { + case OneStopBit: + LcrStop = 0; + break; + + case OneFiveStopBits: + case TwoStopBits: + LcrStop = 1; + break; + + default: + return RETURN_INVALID_PARAMETER; + } + } + + // + // Calculate divisor for baud generator + // Ref_Clk_Rate / Baud_Rate / 16 + // + Divisor = PcdGet32 (PcdSerialClockRate) / (SerialBaudRate * 16); + if ((PcdGet32 (PcdSerialClockRate) % (SerialBaudRate * 16)) >= SerialBaudRate * 8) { + Divisor++; + } + + // + // Configure baud rate + // + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8) (Divisor >> 8)); + SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8) (Divisor & 0xff)); + + // + // Clear DLAB and configure Data Bits, Parity, and Stop Bits. + // Strip reserved bits from line control value + // + Lcr = (UINT8) ((LcrParity << 3) | (LcrStop << 2) | LcrData); + SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8) (Lcr & 0x3F)); + + return RETURN_SUCCESS; +} + diff --git a/BraswellPlatformPkg/Common/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf b/BraswellPlatformPkg/Common/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf new file mode 100644 index 0000000000..42feb21059 --- /dev/null +++ b/BraswellPlatformPkg/Common/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf @@ -0,0 +1,48 @@ +## @file +# SerialPortLib instance for 16550 UART. +# +# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which 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 = 0x00010018 + BASE_NAME = BaseSerialPortLib16550 + FILE_GUID = 9E7C00CF-355A-4d4e-BF60-0428CFF95540 + MODULE_TYPE = BASE + VERSION_STRING = 1.1 + LIBRARY_CLASS = SerialPortLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + +[LibraryClasses] + PcdLib + IoLib + PlatformHookLib + PciLib + +[Sources] + BaseSerialPortLib16550.c + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## CONSUMES diff --git a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c b/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c deleted file mode 100644 index 8edd9718d3..0000000000 --- a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsBoot.c +++ /dev/null @@ -1,4497 +0,0 @@ -/** @file - BDS Lib functions which relate with create or process the boot option. - -Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which 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 "InternalBdsLib.h" -#include "String.h" - -BOOLEAN mEnumBootDevice = FALSE; -EFI_HII_HANDLE gBdsLibStringPackHandle = NULL; - -/** - The constructor function register UNI strings into imageHandle. - - It will ASSERT() if that operation fails and it will always return EFI_SUCCESS. - - @param ImageHandle The firmware allocated handle for the EFI image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The constructor successfully added string package. - @retval Other value The constructor can't add string package. - -**/ -EFI_STATUS -EFIAPI -GenericBdsLibConstructor ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - - gBdsLibStringPackHandle = HiiAddPackages ( - &gBdsLibStringPackageGuid, - ImageHandle, - GenericBdsLibStrings, - NULL - ); - - ASSERT (gBdsLibStringPackHandle != NULL); - - return EFI_SUCCESS; -} - -/** - Deletete the Boot Option from EFI Variable. The Boot Order Arrray - is also updated. - - @param OptionNumber The number of Boot option want to be deleted. - @param BootOrder The Boot Order array. - @param BootOrderSize The size of the Boot Order Array. - - @retval EFI_SUCCESS The Boot Option Variable was found and removed - @retval EFI_UNSUPPORTED The Boot Option Variable store was inaccessible - @retval EFI_NOT_FOUND The Boot Option Variable was not found -**/ -EFI_STATUS -EFIAPI -BdsDeleteBootOption ( - IN UINTN OptionNumber, - IN OUT UINT16 *BootOrder, - IN OUT UINTN *BootOrderSize - ) -{ - CHAR16 BootOption[9]; - UINTN Index; - EFI_STATUS Status; - - UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", OptionNumber); - Status = gRT->SetVariable ( - BootOption, - &gEfiGlobalVariableGuid, - 0, - 0, - NULL - ); - // - // Deleting variable with existing variable implementation shouldn't fail. - // - ASSERT_EFI_ERROR (Status); - - // - // adjust boot order array - // - for (Index = 0; Index < *BootOrderSize / sizeof (UINT16); Index++) { - if (BootOrder[Index] == OptionNumber) { - CopyMem (&BootOrder[Index], &BootOrder[Index+1], *BootOrderSize - (Index+1) * sizeof (UINT16)); - *BootOrderSize -= sizeof (UINT16); - break; - } - } - - return Status; -} -/** - - Translate the first n characters of an Ascii string to - Unicode characters. The count n is indicated by parameter - Size. If Size is greater than the length of string, then - the entire string is translated. - - - @param AStr Pointer to input Ascii string. - @param Size The number of characters to translate. - @param UStr Pointer to output Unicode string buffer. - -**/ -VOID -AsciiToUnicodeSize ( - IN UINT8 *AStr, - IN UINTN Size, - OUT UINT16 *UStr - ) -{ - UINTN Idx; - - Idx = 0; - while (AStr[Idx] != 0) { - UStr[Idx] = (CHAR16) AStr[Idx]; - if (Idx == Size) { - break; - } - - Idx++; - } - UStr[Idx] = 0; -} - -/** - Build Legacy Device Name String according. - - @param CurBBSEntry BBS Table. - @param Index Index. - @param BufSize The buffer size. - @param BootString The output string. - -**/ -VOID -BdsBuildLegacyDevNameString ( - IN BBS_TABLE *CurBBSEntry, - IN UINTN Index, - IN UINTN BufSize, - OUT CHAR16 *BootString - ) -{ - CHAR16 *Fmt; - CHAR16 *Type; - UINT8 *StringDesc; - CHAR16 Temp[80]; - - switch (Index) { - // - // Primary Master - // - case 1: - Fmt = L"Primary Master %s"; - break; - - // - // Primary Slave - // - case 2: - Fmt = L"Primary Slave %s"; - break; - - // - // Secondary Master - // - case 3: - Fmt = L"Secondary Master %s"; - break; - - // - // Secondary Slave - // - case 4: - Fmt = L"Secondary Slave %s"; - break; - - default: - Fmt = L"%s"; - break; - } - - switch (CurBBSEntry->DeviceType) { - case BBS_FLOPPY: - Type = L"Floppy"; - break; - - case BBS_HARDDISK: - Type = L"Harddisk"; - break; - - case BBS_CDROM: - Type = L"CDROM"; - break; - - case BBS_PCMCIA: - Type = L"PCMCIAe"; - break; - - case BBS_USB: - Type = L"USB"; - break; - - case BBS_EMBED_NETWORK: - Type = L"Network"; - break; - - case BBS_BEV_DEVICE: - Type = L"BEVe"; - break; - - case BBS_UNKNOWN: - default: - Type = L"Unknown"; - break; - } - // - // If current BBS entry has its description then use it. - // - StringDesc = (UINT8 *) (UINTN) ((CurBBSEntry->DescStringSegment << 4) + CurBBSEntry->DescStringOffset); - if (NULL != StringDesc) { - // - // Only get fisrt 32 characters, this is suggested by BBS spec - // - AsciiToUnicodeSize (StringDesc, 32, Temp); - Fmt = L"%s"; - Type = Temp; - } - - // - // BbsTable 16 entries are for onboard IDE. - // Set description string for SATA harddisks, Harddisk 0 ~ Harddisk 11 - // - if (Index >= 5 && Index <= 16 && (CurBBSEntry->DeviceType == BBS_HARDDISK || CurBBSEntry->DeviceType == BBS_CDROM)) { - Fmt = L"%s %d"; - UnicodeSPrint (BootString, BufSize, Fmt, Type, Index - 5); - } else { - UnicodeSPrint (BootString, BufSize, Fmt, Type); - } -} - -/** - - Create a legacy boot option for the specified entry of - BBS table, save it as variable, and append it to the boot - order list. - - - @param CurrentBbsEntry Pointer to current BBS table. - @param CurrentBbsDevPath Pointer to the Device Path Protocol instance of BBS - @param Index Index of the specified entry in BBS table. - @param BootOrderList On input, the original boot order list. - On output, the new boot order list attached with the - created node. - @param BootOrderListSize On input, the original size of boot order list. - On output, the size of new boot order list. - - @retval EFI_SUCCESS Boot Option successfully created. - @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory. - @retval Other Error occurs while setting variable. - -**/ -EFI_STATUS -BdsCreateLegacyBootOption ( - IN BBS_TABLE *CurrentBbsEntry, - IN EFI_DEVICE_PATH_PROTOCOL *CurrentBbsDevPath, - IN UINTN Index, - IN OUT UINT16 **BootOrderList, - IN OUT UINTN *BootOrderListSize - ) -{ - EFI_STATUS Status; - UINT16 CurrentBootOptionNo; - UINT16 BootString[10]; - CHAR16 BootDesc[100]; - CHAR8 HelpString[100]; - UINT16 *NewBootOrderList; - UINTN BufferSize; - UINTN StringLen; - VOID *Buffer; - UINT8 *Ptr; - UINT16 CurrentBbsDevPathSize; - UINTN BootOrderIndex; - UINTN BootOrderLastIndex; - UINTN ArrayIndex; - BOOLEAN IndexNotFound; - BBS_BBS_DEVICE_PATH *NewBbsDevPathNode; - - if ((*BootOrderList) == NULL) { - CurrentBootOptionNo = 0; - } else { - for (ArrayIndex = 0; ArrayIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); ArrayIndex++) { - IndexNotFound = TRUE; - for (BootOrderIndex = 0; BootOrderIndex < (UINTN) (*BootOrderListSize / sizeof (UINT16)); BootOrderIndex++) { - if ((*BootOrderList)[BootOrderIndex] == ArrayIndex) { - IndexNotFound = FALSE; - break; - } - } - - if (!IndexNotFound) { - continue; - } else { - break; - } - } - - CurrentBootOptionNo = (UINT16) ArrayIndex; - } - - UnicodeSPrint ( - BootString, - sizeof (BootString), - L"Boot%04x", - CurrentBootOptionNo - ); - - BdsBuildLegacyDevNameString (CurrentBbsEntry, Index, sizeof (BootDesc), BootDesc); - - // - // Create new BBS device path node with description string - // - UnicodeStrToAsciiStr (BootDesc, HelpString); - - StringLen = AsciiStrLen (HelpString); - NewBbsDevPathNode = AllocateZeroPool (sizeof (BBS_BBS_DEVICE_PATH) + StringLen); - if (NewBbsDevPathNode == NULL) { - return EFI_OUT_OF_RESOURCES; - } - CopyMem (NewBbsDevPathNode, CurrentBbsDevPath, sizeof (BBS_BBS_DEVICE_PATH)); - CopyMem (NewBbsDevPathNode->String, HelpString, StringLen + 1); - SetDevicePathNodeLength (&(NewBbsDevPathNode->Header), sizeof (BBS_BBS_DEVICE_PATH) + StringLen); - - // - // Create entire new CurrentBbsDevPath with end node - // - CurrentBbsDevPath = AppendDevicePathNode ( - NULL, - (EFI_DEVICE_PATH_PROTOCOL *) NewBbsDevPathNode - ); - if (CurrentBbsDevPath == NULL) { - FreePool (NewBbsDevPathNode); - return EFI_OUT_OF_RESOURCES; - } - - CurrentBbsDevPathSize = (UINT16) (GetDevicePathSize (CurrentBbsDevPath)); - - BufferSize = sizeof (UINT32) + - sizeof (UINT16) + - StrSize (BootDesc) + - CurrentBbsDevPathSize + - sizeof (BBS_TABLE) + - sizeof (UINT16); - - Buffer = AllocateZeroPool (BufferSize); - if (Buffer == NULL) { - FreePool (NewBbsDevPathNode); - FreePool (CurrentBbsDevPath); - return EFI_OUT_OF_RESOURCES; - } - - Ptr = (UINT8 *) Buffer; - - *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE; - Ptr += sizeof (UINT32); - - *((UINT16 *) Ptr) = CurrentBbsDevPathSize; - Ptr += sizeof (UINT16); - - CopyMem ( - Ptr, - BootDesc, - StrSize (BootDesc) - ); - Ptr += StrSize (BootDesc); - - CopyMem ( - Ptr, - CurrentBbsDevPath, - CurrentBbsDevPathSize - ); - Ptr += CurrentBbsDevPathSize; - - CopyMem ( - Ptr, - CurrentBbsEntry, - sizeof (BBS_TABLE) - ); - - Ptr += sizeof (BBS_TABLE); - *((UINT16 *) Ptr) = (UINT16) Index; - - Status = gRT->SetVariable ( - BootString, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, - BufferSize, - Buffer - ); - - FreePool (Buffer); - - Buffer = NULL; - - NewBootOrderList = AllocateZeroPool (*BootOrderListSize + sizeof (UINT16)); - if (NULL == NewBootOrderList) { - FreePool (NewBbsDevPathNode); - FreePool (CurrentBbsDevPath); - return EFI_OUT_OF_RESOURCES; - } - - if (*BootOrderList != NULL) { - CopyMem (NewBootOrderList, *BootOrderList, *BootOrderListSize); - FreePool (*BootOrderList); - } - - BootOrderLastIndex = (UINTN) (*BootOrderListSize / sizeof (UINT16)); - NewBootOrderList[BootOrderLastIndex] = CurrentBootOptionNo; - *BootOrderListSize += sizeof (UINT16); - *BootOrderList = NewBootOrderList; - - FreePool (NewBbsDevPathNode); - FreePool (CurrentBbsDevPath); - return Status; -} - -/** - Check if the boot option is a legacy one. - - @param BootOptionVar The boot option data payload. - @param BbsEntry The BBS Table. - @param BbsIndex The table index. - - @retval TRUE It is a legacy boot option. - @retval FALSE It is not a legacy boot option. - -**/ -BOOLEAN -BdsIsLegacyBootOption ( - IN UINT8 *BootOptionVar, - OUT BBS_TABLE **BbsEntry, - OUT UINT16 *BbsIndex - ) -{ - UINT8 *Ptr; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - BOOLEAN Ret; - UINT16 DevPathLen; - - Ptr = BootOptionVar; - Ptr += sizeof (UINT32); - DevPathLen = *(UINT16 *) Ptr; - Ptr += sizeof (UINT16); - Ptr += StrSize ((UINT16 *) Ptr); - DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr; - if ((BBS_DEVICE_PATH == DevicePath->Type) && (BBS_BBS_DP == DevicePath->SubType)) { - Ptr += DevPathLen; - *BbsEntry = (BBS_TABLE *) Ptr; - Ptr += sizeof (BBS_TABLE); - *BbsIndex = *(UINT16 *) Ptr; - Ret = TRUE; - } else { - *BbsEntry = NULL; - Ret = FALSE; - } - - return Ret; -} - -/** - Delete all the invalid legacy boot options. - - @retval EFI_SUCCESS All invalide legacy boot options are deleted. - @retval EFI_OUT_OF_RESOURCES Fail to allocate necessary memory. - @retval EFI_NOT_FOUND Fail to retrive variable of boot order. -**/ -EFI_STATUS -EFIAPI -BdsDeleteAllInvalidLegacyBootOptions ( - VOID - ) -{ - UINT16 *BootOrder; - UINT8 *BootOptionVar; - UINTN BootOrderSize; - UINTN BootOptionSize; - EFI_STATUS Status; - UINT16 HddCount; - UINT16 BbsCount; - HDD_INFO *LocalHddInfo; - BBS_TABLE *LocalBbsTable; - BBS_TABLE *BbsEntry; - UINT16 BbsIndex; - EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; - UINTN Index; - UINT16 BootOption[10]; - UINT16 BootDesc[100]; - BOOLEAN DescStringMatch; - - Status = EFI_SUCCESS; - BootOrder = NULL; - BootOrderSize = 0; - HddCount = 0; - BbsCount = 0; - LocalHddInfo = NULL; - LocalBbsTable = NULL; - BbsEntry = NULL; - - Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); - if (EFI_ERROR (Status)) { - return Status; - } - - BootOrder = BdsLibGetVariableAndSize ( - L"BootOrder", - &gEfiGlobalVariableGuid, - &BootOrderSize - ); - if (BootOrder == NULL) { - return EFI_NOT_FOUND; - } - - LegacyBios->GetBbsInfo ( - LegacyBios, - &HddCount, - &LocalHddInfo, - &BbsCount, - &LocalBbsTable - ); - - Index = 0; - while (Index < BootOrderSize / sizeof (UINT16)) { - UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]); - BootOptionVar = BdsLibGetVariableAndSize ( - BootOption, - &gEfiGlobalVariableGuid, - &BootOptionSize - ); - if (NULL == BootOptionVar) { - BootOptionSize = 0; - Status = gRT->GetVariable ( - BootOption, - &gEfiGlobalVariableGuid, - NULL, - &BootOptionSize, - BootOptionVar - ); - if (Status == EFI_NOT_FOUND) { - // - // Update BootOrder - // - BdsDeleteBootOption ( - BootOrder[Index], - BootOrder, - &BootOrderSize - ); - continue; - } else { - FreePool (BootOrder); - return EFI_OUT_OF_RESOURCES; - } - } - - // - // Skip Non-Legacy boot option - // - if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, &BbsIndex)) { - if (BootOptionVar!= NULL) { - FreePool (BootOptionVar); - } - Index++; - continue; - } - - if (BbsIndex < BbsCount) { - // - // Check if BBS Description String is changed - // - DescStringMatch = FALSE; - BdsBuildLegacyDevNameString ( - &LocalBbsTable[BbsIndex], - BbsIndex, - sizeof (BootDesc), - BootDesc - ); - - if (StrCmp (BootDesc, (UINT16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) == 0) { - DescStringMatch = TRUE; - } - - if (!((LocalBbsTable[BbsIndex].BootPriority == BBS_IGNORE_ENTRY) || - (LocalBbsTable[BbsIndex].BootPriority == BBS_DO_NOT_BOOT_FROM)) && - (LocalBbsTable[BbsIndex].DeviceType == BbsEntry->DeviceType) && - DescStringMatch) { - Index++; - continue; - } - } - - if (BootOptionVar != NULL) { - FreePool (BootOptionVar); - } - // - // should delete - // - BdsDeleteBootOption ( - BootOrder[Index], - BootOrder, - &BootOrderSize - ); - } - - // - // Adjust the number of boot options. - // - Status = gRT->SetVariable ( - L"BootOrder", - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, - BootOrderSize, - BootOrder - ); - // - // Shrinking variable with existing variable implementation shouldn't fail. - // - ASSERT_EFI_ERROR (Status); - FreePool (BootOrder); - - return Status; -} - -/** - Find all legacy boot option by device type. - - @param BootOrder The boot order array. - @param BootOptionNum The number of boot option. - @param DevType Device type. - @param DevName Device name. - @param Attribute The boot option attribute. - @param BbsIndex The BBS table index. - @param OptionNumber The boot option index. - - @retval TRUE The Legacy boot option is found. - @retval FALSE The legacy boot option is not found. - -**/ -BOOLEAN -BdsFindLegacyBootOptionByDevTypeAndName ( - IN UINT16 *BootOrder, - IN UINTN BootOptionNum, - IN UINT16 DevType, - IN CHAR16 *DevName, - OUT UINT32 *Attribute, - OUT UINT16 *BbsIndex, - OUT UINT16 *OptionNumber - ) -{ - UINTN Index; - CHAR16 BootOption[9]; - UINTN BootOptionSize; - UINT8 *BootOptionVar; - BBS_TABLE *BbsEntry; - BOOLEAN Found; - - BbsEntry = NULL; - Found = FALSE; - - if (NULL == BootOrder) { - return Found; - } - - // - // Loop all boot option from variable - // - for (Index = 0; Index < BootOptionNum; Index++) { - UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", (UINTN) BootOrder[Index]); - BootOptionVar = BdsLibGetVariableAndSize ( - BootOption, - &gEfiGlobalVariableGuid, - &BootOptionSize - ); - if (NULL == BootOptionVar) { - continue; - } - - // - // Skip Non-legacy boot option - // - if (!BdsIsLegacyBootOption (BootOptionVar, &BbsEntry, BbsIndex)) { - FreePool (BootOptionVar); - continue; - } - - if ( - (BbsEntry->DeviceType != DevType) || - (StrCmp (DevName, (CHAR16*)(BootOptionVar + sizeof (UINT32) + sizeof (UINT16))) != 0) - ) { - FreePool (BootOptionVar); - continue; - } - - *Attribute = *(UINT32 *) BootOptionVar; - *OptionNumber = BootOrder[Index]; - Found = TRUE; - FreePool (BootOptionVar); - break; - } - - return Found; -} - -/** - Create a legacy boot option. - - @param BbsItem The BBS Table entry. - @param Index Index of the specified entry in BBS table. - @param BootOrderList The boot order list. - @param BootOrderListSize The size of boot order list. - - @retval EFI_OUT_OF_RESOURCE No enough memory. - @retval EFI_SUCCESS The function complete successfully. - @return Other value if the legacy boot option is not created. - -**/ -EFI_STATUS -BdsCreateOneLegacyBootOption ( - IN BBS_TABLE *BbsItem, - IN UINTN Index, - IN OUT UINT16 **BootOrderList, - IN OUT UINTN *BootOrderListSize - ) -{ - BBS_BBS_DEVICE_PATH BbsDevPathNode; - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *DevPath; - - DevPath = NULL; - - // - // Create device path node. - // - BbsDevPathNode.Header.Type = BBS_DEVICE_PATH; - BbsDevPathNode.Header.SubType = BBS_BBS_DP; - SetDevicePathNodeLength (&BbsDevPathNode.Header, sizeof (BBS_BBS_DEVICE_PATH)); - BbsDevPathNode.DeviceType = BbsItem->DeviceType; - CopyMem (&BbsDevPathNode.StatusFlag, &BbsItem->StatusFlags, sizeof (UINT16)); - - DevPath = AppendDevicePathNode ( - NULL, - (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevPathNode - ); - if (NULL == DevPath) { - return EFI_OUT_OF_RESOURCES; - } - - Status = BdsCreateLegacyBootOption ( - BbsItem, - DevPath, - Index, - BootOrderList, - BootOrderListSize - ); - BbsItem->BootPriority = 0x00; - - FreePool (DevPath); - - return Status; -} - -/** - Add the legacy boot options from BBS table if they do not exist. - - @retval EFI_SUCCESS The boot options are added successfully - or they are already in boot options. - @retval EFI_NOT_FOUND No legacy boot options is found. - @retval EFI_OUT_OF_RESOURCE No enough memory. - @return Other value LegacyBoot options are not added. -**/ -EFI_STATUS -EFIAPI -BdsAddNonExistingLegacyBootOptions ( - VOID - ) -{ - UINT16 *BootOrder; - UINTN BootOrderSize; - EFI_STATUS Status; - CHAR16 Desc[100]; - UINT16 HddCount; - UINT16 BbsCount; - HDD_INFO *LocalHddInfo; - BBS_TABLE *LocalBbsTable; - UINT16 BbsIndex; - EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; - UINT16 Index; - UINT32 Attribute; - UINT16 OptionNumber; - BOOLEAN Exist; - - HddCount = 0; - BbsCount = 0; - LocalHddInfo = NULL; - LocalBbsTable = NULL; - - Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); - if (EFI_ERROR (Status)) { - return Status; - } - - LegacyBios->GetBbsInfo ( - LegacyBios, - &HddCount, - &LocalHddInfo, - &BbsCount, - &LocalBbsTable - ); - - BootOrder = BdsLibGetVariableAndSize ( - L"BootOrder", - &gEfiGlobalVariableGuid, - &BootOrderSize - ); - if (BootOrder == NULL) { - BootOrderSize = 0; - } - - for (Index = 0; Index < BbsCount; Index++) { - if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) || - (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) - ) { - continue; - } - - BdsBuildLegacyDevNameString (&LocalBbsTable[Index], Index, sizeof (Desc), Desc); - - Exist = BdsFindLegacyBootOptionByDevTypeAndName ( - BootOrder, - BootOrderSize / sizeof (UINT16), - LocalBbsTable[Index].DeviceType, - Desc, - &Attribute, - &BbsIndex, - &OptionNumber - ); - if (!Exist) { - // - // Not found such type of legacy device in boot options or we found but it's disabled - // so we have to create one and put it to the tail of boot order list - // - Status = BdsCreateOneLegacyBootOption ( - &LocalBbsTable[Index], - Index, - &BootOrder, - &BootOrderSize - ); - if (!EFI_ERROR (Status)) { - ASSERT (BootOrder != NULL); - BbsIndex = Index; - OptionNumber = BootOrder[BootOrderSize / sizeof (UINT16) - 1]; - } - } - - ASSERT (BbsIndex == Index); - } - - Status = gRT->SetVariable ( - L"BootOrder", - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, - BootOrderSize, - BootOrder - ); - if (BootOrder != NULL) { - FreePool (BootOrder); - } - - return Status; -} - -/** - Fill the device order buffer. - - @param BbsTable The BBS table. - @param BbsType The BBS Type. - @param BbsCount The BBS Count. - @param Buf device order buffer. - - @return The device order buffer. - -**/ -UINT16 * -BdsFillDevOrderBuf ( - IN BBS_TABLE *BbsTable, - IN BBS_TYPE BbsType, - IN UINTN BbsCount, - OUT UINT16 *Buf - ) -{ - UINTN Index; - - for (Index = 0; Index < BbsCount; Index++) { - if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) { - continue; - } - - if (BbsTable[Index].DeviceType != BbsType) { - continue; - } - - *Buf = (UINT16) (Index & 0xFF); - Buf++; - } - - return Buf; -} - -/** - Create the device order buffer. - - @param BbsTable The BBS table. - @param BbsCount The BBS Count. - - @retval EFI_SUCCES The buffer is created and the EFI variable named - VAR_LEGACY_DEV_ORDER and gEfiLegacyDevOrderVariableGuid is - set correctly. - @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough. - @retval EFI_DEVICE_ERROR Fail to add the device order into EFI variable fail - because of hardware error. -**/ -EFI_STATUS -BdsCreateDevOrder ( - IN BBS_TABLE *BbsTable, - IN UINT16 BbsCount - ) -{ - UINTN Index; - UINTN FDCount; - UINTN HDCount; - UINTN CDCount; - UINTN NETCount; - UINTN BEVCount; - UINTN TotalSize; - UINTN HeaderSize; - LEGACY_DEV_ORDER_ENTRY *DevOrder; - LEGACY_DEV_ORDER_ENTRY *DevOrderPtr; - EFI_STATUS Status; - - FDCount = 0; - HDCount = 0; - CDCount = 0; - NETCount = 0; - BEVCount = 0; - TotalSize = 0; - HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16); - DevOrder = NULL; - Status = EFI_SUCCESS; - - // - // Count all boot devices - // - for (Index = 0; Index < BbsCount; Index++) { - if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) { - continue; - } - - switch (BbsTable[Index].DeviceType) { - case BBS_FLOPPY: - FDCount++; - break; - - case BBS_HARDDISK: - HDCount++; - break; - - case BBS_CDROM: - CDCount++; - break; - - case BBS_EMBED_NETWORK: - NETCount++; - break; - - case BBS_BEV_DEVICE: - BEVCount++; - break; - - default: - break; - } - } - - TotalSize += (HeaderSize + sizeof (UINT16) * FDCount); - TotalSize += (HeaderSize + sizeof (UINT16) * HDCount); - TotalSize += (HeaderSize + sizeof (UINT16) * CDCount); - TotalSize += (HeaderSize + sizeof (UINT16) * NETCount); - TotalSize += (HeaderSize + sizeof (UINT16) * BEVCount); - - // - // Create buffer to hold all boot device order - // - DevOrder = AllocateZeroPool (TotalSize); - if (NULL == DevOrder) { - return EFI_OUT_OF_RESOURCES; - } - DevOrderPtr = DevOrder; - - DevOrderPtr->BbsType = BBS_FLOPPY; - DevOrderPtr->Length = (UINT16) (sizeof (DevOrderPtr->Length) + FDCount * sizeof (UINT16)); - DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_FLOPPY, BbsCount, DevOrderPtr->Data); - - DevOrderPtr->BbsType = BBS_HARDDISK; - DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16)); - DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_HARDDISK, BbsCount, DevOrderPtr->Data); - - DevOrderPtr->BbsType = BBS_CDROM; - DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16)); - DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_CDROM, BbsCount, DevOrderPtr->Data); - - DevOrderPtr->BbsType = BBS_EMBED_NETWORK; - DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16)); - DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_EMBED_NETWORK, BbsCount, DevOrderPtr->Data); - - DevOrderPtr->BbsType = BBS_BEV_DEVICE; - DevOrderPtr->Length = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16)); - DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) BdsFillDevOrderBuf (BbsTable, BBS_BEV_DEVICE, BbsCount, DevOrderPtr->Data); - - ASSERT (TotalSize == (UINTN) ((UINT8 *) DevOrderPtr - (UINT8 *) DevOrder)); - - // - // Save device order for legacy boot device to variable. - // - Status = gRT->SetVariable ( - VAR_LEGACY_DEV_ORDER, - &gEfiLegacyDevOrderVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, - TotalSize, - DevOrder - ); - FreePool (DevOrder); - - return Status; -} - -/** - Add the legacy boot devices from BBS table into - the legacy device boot order. - - @retval EFI_SUCCESS The boot devices are added successfully. - @retval EFI_NOT_FOUND The legacy boot devices are not found. - @retval EFI_OUT_OF_RESOURCES Memmory or storage is not enough. - @retval EFI_DEVICE_ERROR Fail to add the legacy device boot order into EFI variable - because of hardware error. -**/ -EFI_STATUS -EFIAPI -BdsUpdateLegacyDevOrder ( - VOID - ) -{ - LEGACY_DEV_ORDER_ENTRY *DevOrder; - LEGACY_DEV_ORDER_ENTRY *NewDevOrder; - LEGACY_DEV_ORDER_ENTRY *Ptr; - LEGACY_DEV_ORDER_ENTRY *NewPtr; - UINTN DevOrderSize; - EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; - EFI_STATUS Status; - UINT16 HddCount; - UINT16 BbsCount; - HDD_INFO *LocalHddInfo; - BBS_TABLE *LocalBbsTable; - UINTN Index; - UINTN Index2; - UINTN *Idx; - UINTN FDCount; - UINTN HDCount; - UINTN CDCount; - UINTN NETCount; - UINTN BEVCount; - UINTN TotalSize; - UINTN HeaderSize; - UINT16 *NewFDPtr; - UINT16 *NewHDPtr; - UINT16 *NewCDPtr; - UINT16 *NewNETPtr; - UINT16 *NewBEVPtr; - UINT16 *NewDevPtr; - UINTN FDIndex; - UINTN HDIndex; - UINTN CDIndex; - UINTN NETIndex; - UINTN BEVIndex; - - Idx = NULL; - FDCount = 0; - HDCount = 0; - CDCount = 0; - NETCount = 0; - BEVCount = 0; - TotalSize = 0; - HeaderSize = sizeof (BBS_TYPE) + sizeof (UINT16); - FDIndex = 0; - HDIndex = 0; - CDIndex = 0; - NETIndex = 0; - BEVIndex = 0; - NewDevPtr = NULL; - - Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = LegacyBios->GetBbsInfo ( - LegacyBios, - &HddCount, - &LocalHddInfo, - &BbsCount, - &LocalBbsTable - ); - if (EFI_ERROR (Status)) { - return Status; - } - - DevOrder = BdsLibGetVariableAndSize ( - VAR_LEGACY_DEV_ORDER, - &gEfiLegacyDevOrderVariableGuid, - &DevOrderSize - ); - if (NULL == DevOrder) { - return BdsCreateDevOrder (LocalBbsTable, BbsCount); - } - // - // First we figure out how many boot devices with same device type respectively - // - for (Index = 0; Index < BbsCount; Index++) { - if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) || - (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) - ) { - continue; - } - - switch (LocalBbsTable[Index].DeviceType) { - case BBS_FLOPPY: - FDCount++; - break; - - case BBS_HARDDISK: - HDCount++; - break; - - case BBS_CDROM: - CDCount++; - break; - - case BBS_EMBED_NETWORK: - NETCount++; - break; - - case BBS_BEV_DEVICE: - BEVCount++; - break; - - default: - break; - } - } - - TotalSize += (HeaderSize + FDCount * sizeof (UINT16)); - TotalSize += (HeaderSize + HDCount * sizeof (UINT16)); - TotalSize += (HeaderSize + CDCount * sizeof (UINT16)); - TotalSize += (HeaderSize + NETCount * sizeof (UINT16)); - TotalSize += (HeaderSize + BEVCount * sizeof (UINT16)); - - NewDevOrder = AllocateZeroPool (TotalSize); - if (NULL == NewDevOrder) { - return EFI_OUT_OF_RESOURCES; - } - - - - // - // copy FD - // - Ptr = DevOrder; - NewPtr = NewDevOrder; - NewPtr->BbsType = Ptr->BbsType; - NewPtr->Length = (UINT16) (sizeof (UINT16) + FDCount * sizeof (UINT16)); - for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { - if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || - LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || - LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_FLOPPY - ) { - continue; - } - - NewPtr->Data[FDIndex] = Ptr->Data[Index]; - FDIndex++; - } - NewFDPtr = NewPtr->Data; - - // - // copy HD - // - Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); - NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); - NewPtr->BbsType = Ptr->BbsType; - NewPtr->Length = (UINT16) (sizeof (UINT16) + HDCount * sizeof (UINT16)); - for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { - if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || - LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || - LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || - LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_HARDDISK - ) { - continue; - } - - NewPtr->Data[HDIndex] = Ptr->Data[Index]; - HDIndex++; - } - NewHDPtr = NewPtr->Data; - - // - // copy CD - // - Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); - NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); - NewPtr->BbsType = Ptr->BbsType; - NewPtr->Length = (UINT16) (sizeof (UINT16) + CDCount * sizeof (UINT16)); - for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { - if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || - LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || - LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || - LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_CDROM - ) { - continue; - } - - NewPtr->Data[CDIndex] = Ptr->Data[Index]; - CDIndex++; - } - NewCDPtr = NewPtr->Data; - - // - // copy NET - // - Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); - NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); - NewPtr->BbsType = Ptr->BbsType; - NewPtr->Length = (UINT16) (sizeof (UINT16) + NETCount * sizeof (UINT16)); - for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { - if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || - LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || - LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || - LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_EMBED_NETWORK - ) { - continue; - } - - NewPtr->Data[NETIndex] = Ptr->Data[Index]; - NETIndex++; - } - NewNETPtr = NewPtr->Data; - - // - // copy BEV - // - Ptr = (LEGACY_DEV_ORDER_ENTRY *) (&Ptr->Data[Ptr->Length / sizeof (UINT16) - 1]); - NewPtr = (LEGACY_DEV_ORDER_ENTRY *) (&NewPtr->Data[NewPtr->Length / sizeof (UINT16) -1]); - NewPtr->BbsType = Ptr->BbsType; - NewPtr->Length = (UINT16) (sizeof (UINT16) + BEVCount * sizeof (UINT16)); - for (Index = 0; Index < Ptr->Length / sizeof (UINT16) - 1; Index++) { - if (LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_IGNORE_ENTRY || - LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_DO_NOT_BOOT_FROM || - LocalBbsTable[Ptr->Data[Index] & 0xFF].BootPriority == BBS_LOWEST_PRIORITY || - LocalBbsTable[Ptr->Data[Index] & 0xFF].DeviceType != BBS_BEV_DEVICE - ) { - continue; - } - - NewPtr->Data[BEVIndex] = Ptr->Data[Index]; - BEVIndex++; - } - NewBEVPtr = NewPtr->Data; - - for (Index = 0; Index < BbsCount; Index++) { - if ((LocalBbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) || - (LocalBbsTable[Index].BootPriority == BBS_DO_NOT_BOOT_FROM) - ) { - continue; - } - - switch (LocalBbsTable[Index].DeviceType) { - case BBS_FLOPPY: - Idx = &FDIndex; - NewDevPtr = NewFDPtr; - break; - - case BBS_HARDDISK: - Idx = &HDIndex; - NewDevPtr = NewHDPtr; - break; - - case BBS_CDROM: - Idx = &CDIndex; - NewDevPtr = NewCDPtr; - break; - - case BBS_EMBED_NETWORK: - Idx = &NETIndex; - NewDevPtr = NewNETPtr; - break; - - case BBS_BEV_DEVICE: - Idx = &BEVIndex; - NewDevPtr = NewBEVPtr; - break; - - default: - Idx = NULL; - break; - } - // - // at this point we have copied those valid indexes to new buffer - // and we should check if there is any new appeared boot device - // - if (Idx != NULL) { - for (Index2 = 0; Index2 < *Idx; Index2++) { - if ((NewDevPtr[Index2] & 0xFF) == (UINT16) Index) { - break; - } - } - - if (Index2 == *Idx) { - // - // Index2 == *Idx means we didn't find Index - // so Index is a new appeared device's index in BBS table - // insert it before disabled indexes. - // - for (Index2 = 0; Index2 < *Idx; Index2++) { - if ((NewDevPtr[Index2] & 0xFF00) == 0xFF00) { - break; - } - } - CopyMem (&NewDevPtr[Index2 + 1], &NewDevPtr[Index2], (*Idx - Index2) * sizeof (UINT16)); - NewDevPtr[Index2] = (UINT16) (Index & 0xFF); - (*Idx)++; - } - } - } - - FreePool (DevOrder); - - Status = gRT->SetVariable ( - VAR_LEGACY_DEV_ORDER, - &gEfiLegacyDevOrderVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, - TotalSize, - NewDevOrder - ); - FreePool (NewDevOrder); - - return Status; -} - -/** - Set Boot Priority for specified device type. - - @param DeviceType The device type. - @param BbsIndex The BBS index to set the highest priority. Ignore when -1. - @param LocalBbsTable The BBS table. - @param Priority The prority table. - - @retval EFI_SUCCESS The function completes successfully. - @retval EFI_NOT_FOUND Failed to find device. - @retval EFI_OUT_OF_RESOURCES Failed to get the efi variable of device order. - -**/ -EFI_STATUS -BdsSetBootPriority4SameTypeDev ( - IN UINT16 DeviceType, - IN UINTN BbsIndex, - IN OUT BBS_TABLE *LocalBbsTable, - IN OUT UINT16 *Priority - ) -{ - LEGACY_DEV_ORDER_ENTRY *DevOrder; - LEGACY_DEV_ORDER_ENTRY *DevOrderPtr; - UINTN DevOrderSize; - UINTN Index; - - DevOrder = BdsLibGetVariableAndSize ( - VAR_LEGACY_DEV_ORDER, - &gEfiLegacyDevOrderVariableGuid, - &DevOrderSize - ); - if (NULL == DevOrder) { - return EFI_OUT_OF_RESOURCES; - } - - DevOrderPtr = DevOrder; - while ((UINT8 *) DevOrderPtr < (UINT8 *) DevOrder + DevOrderSize) { - if (DevOrderPtr->BbsType == DeviceType) { - break; - } - - DevOrderPtr = (LEGACY_DEV_ORDER_ENTRY *) ((UINTN) DevOrderPtr + sizeof (BBS_TYPE) + DevOrderPtr->Length); - } - - if ((UINT8 *) DevOrderPtr >= (UINT8 *) DevOrder + DevOrderSize) { - FreePool (DevOrder); - return EFI_NOT_FOUND; - } - - if (BbsIndex != (UINTN) -1) { - LocalBbsTable[BbsIndex].BootPriority = *Priority; - (*Priority)++; - } - // - // If the high byte of the DevIndex is 0xFF, it indicates that this device has been disabled. - // - for (Index = 0; Index < DevOrderPtr->Length / sizeof (UINT16) - 1; Index++) { - if ((DevOrderPtr->Data[Index] & 0xFF00) == 0xFF00) { - // - // LocalBbsTable[DevIndex[Index] & 0xFF].BootPriority = BBS_DISABLED_ENTRY; - // - } else if (DevOrderPtr->Data[Index] != BbsIndex) { - LocalBbsTable[DevOrderPtr->Data[Index]].BootPriority = *Priority; - (*Priority)++; - } - } - - FreePool (DevOrder); - return EFI_SUCCESS; -} - -/** - Print the BBS Table. - - @param LocalBbsTable The BBS table. - @param BbsCount The count of entry in BBS table. -**/ -VOID -PrintBbsTable ( - IN BBS_TABLE *LocalBbsTable, - IN UINT16 BbsCount - ) -{ - UINT16 Idx; - - DEBUG ((DEBUG_ERROR, "\n")); - DEBUG ((DEBUG_ERROR, " NO Prio bb/dd/ff cl/sc Type Stat segm:offs\n")); - DEBUG ((DEBUG_ERROR, "=============================================\n")); - for (Idx = 0; Idx < BbsCount; Idx++) { - if ((LocalBbsTable[Idx].BootPriority == BBS_IGNORE_ENTRY) || - (LocalBbsTable[Idx].BootPriority == BBS_DO_NOT_BOOT_FROM) || - (LocalBbsTable[Idx].BootPriority == BBS_LOWEST_PRIORITY) - ) { - continue; - } - - DEBUG ( - (DEBUG_ERROR, - " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x %04x:%04x\n", - (UINTN) Idx, - (UINTN) LocalBbsTable[Idx].BootPriority, - (UINTN) LocalBbsTable[Idx].Bus, - (UINTN) LocalBbsTable[Idx].Device, - (UINTN) LocalBbsTable[Idx].Function, - (UINTN) LocalBbsTable[Idx].Class, - (UINTN) LocalBbsTable[Idx].SubClass, - (UINTN) LocalBbsTable[Idx].DeviceType, - (UINTN) * (UINT16 *) &LocalBbsTable[Idx].StatusFlags, - (UINTN) LocalBbsTable[Idx].BootHandlerSegment, - (UINTN) LocalBbsTable[Idx].BootHandlerOffset, - (UINTN) ((LocalBbsTable[Idx].MfgStringSegment << 4) + LocalBbsTable[Idx].MfgStringOffset), - (UINTN) ((LocalBbsTable[Idx].DescStringSegment << 4) + LocalBbsTable[Idx].DescStringOffset)) - ); - } - - DEBUG ((DEBUG_ERROR, "\n")); -} - -/** - Set the boot priority for BBS entries based on boot option entry and boot order. - - @param Entry The boot option is to be checked for refresh BBS table. - - @retval EFI_SUCCESS The boot priority for BBS entries is refreshed successfully. - @retval EFI_NOT_FOUND BBS entries can't be found. - @retval EFI_OUT_OF_RESOURCES Failed to get the legacy device boot order. -**/ -EFI_STATUS -EFIAPI -BdsRefreshBbsTableForBoot ( - IN BDS_COMMON_OPTION *Entry - ) -{ - EFI_STATUS Status; - UINT16 BbsIndex; - UINT16 HddCount; - UINT16 BbsCount; - HDD_INFO *LocalHddInfo; - BBS_TABLE *LocalBbsTable; - UINT16 DevType; - EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; - UINTN Index; - UINT16 Priority; - UINT16 *BootOrder; - UINTN BootOrderSize; - UINT8 *BootOptionVar; - UINTN BootOptionSize; - CHAR16 BootOption[9]; - UINT8 *Ptr; - UINT16 DevPathLen; - EFI_DEVICE_PATH_PROTOCOL *DevPath; - UINT16 *DeviceType; - UINTN DeviceTypeCount; - UINTN DeviceTypeIndex; - - HddCount = 0; - BbsCount = 0; - LocalHddInfo = NULL; - LocalBbsTable = NULL; - DevType = BBS_UNKNOWN; - - Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); - if (EFI_ERROR (Status)) { - return Status; - } - - LegacyBios->GetBbsInfo ( - LegacyBios, - &HddCount, - &LocalHddInfo, - &BbsCount, - &LocalBbsTable - ); - // - // First, set all the present devices' boot priority to BBS_UNPRIORITIZED_ENTRY - // We will set them according to the settings setup by user - // - for (Index = 0; Index < BbsCount; Index++) { - if (!((BBS_IGNORE_ENTRY == LocalBbsTable[Index].BootPriority) || - (BBS_DO_NOT_BOOT_FROM == LocalBbsTable[Index].BootPriority) || - (BBS_LOWEST_PRIORITY == LocalBbsTable[Index].BootPriority))) { - LocalBbsTable[Index].BootPriority = BBS_UNPRIORITIZED_ENTRY; - } - } - // - // boot priority always starts at 0 - // - Priority = 0; - if (Entry->LoadOptionsSize == sizeof (BBS_TABLE) + sizeof (UINT16)) { - // - // If Entry stands for a legacy boot option, we prioritize the devices with the same type first. - // - DevType = ((BBS_TABLE *) Entry->LoadOptions)->DeviceType; - BbsIndex = *(UINT16 *) ((BBS_TABLE *) Entry->LoadOptions + 1); - Status = BdsSetBootPriority4SameTypeDev ( - DevType, - BbsIndex, - LocalBbsTable, - &Priority - ); - if (EFI_ERROR (Status)) { - return Status; - } - } - // - // we have to set the boot priority for other BBS entries with different device types - // - BootOrder = BdsLibGetVariableAndSize ( - L"BootOrder", - &gEfiGlobalVariableGuid, - &BootOrderSize - ); - DeviceType = AllocatePool (BootOrderSize + sizeof (UINT16)); - ASSERT (DeviceType != NULL); - - DeviceType[0] = DevType; - DeviceTypeCount = 1; - for (Index = 0; ((BootOrder != NULL) && (Index < BootOrderSize / sizeof (UINT16))); Index++) { - UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]); - BootOptionVar = BdsLibGetVariableAndSize ( - BootOption, - &gEfiGlobalVariableGuid, - &BootOptionSize - ); - if (NULL == BootOptionVar) { - continue; - } - - Ptr = BootOptionVar; - - Ptr += sizeof (UINT32); - DevPathLen = *(UINT16 *) Ptr; - Ptr += sizeof (UINT16); - Ptr += StrSize ((UINT16 *) Ptr); - DevPath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr; - if (BBS_DEVICE_PATH != DevPath->Type || BBS_BBS_DP != DevPath->SubType) { - FreePool (BootOptionVar); - continue; - } - - Ptr += DevPathLen; - DevType = ((BBS_TABLE *) Ptr)->DeviceType; - for (DeviceTypeIndex = 0; DeviceTypeIndex < DeviceTypeCount; DeviceTypeIndex++) { - if (DeviceType[DeviceTypeIndex] == DevType) { - break; - } - } - if (DeviceTypeIndex < DeviceTypeCount) { - // - // We don't want to process twice for a device type - // - FreePool (BootOptionVar); - continue; - } - - DeviceType[DeviceTypeCount] = DevType; - DeviceTypeCount++; - - Status = BdsSetBootPriority4SameTypeDev ( - DevType, - (UINTN) -1, - LocalBbsTable, - &Priority - ); - FreePool (BootOptionVar); - if (EFI_ERROR (Status)) { - break; - } - } - - FreePool (DeviceType); - - if (BootOrder != NULL) { - FreePool (BootOrder); - } - - DEBUG_CODE_BEGIN(); - PrintBbsTable (LocalBbsTable, BbsCount); - DEBUG_CODE_END(); - - return Status; -} - -/** - Connect SATA Device and SDCard Device. - - @param None - - @retval EFI_SUCCESS Connect SATA Device and SDCard Device successfully. - @retval EFI_UNSUPPORTED - -**/ -EFI_STATUS -EFIAPI -PlatformBdsConnectStorageDevice ( - VOID - ) -{ - EFI_STATUS Status; - UINTN Index; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - EFI_PCI_IO_PROTOCOL *PciIo; - PCI_TYPE00 PciData; - - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiPciIoProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return Status; - } - - for (Index = 0; Index < HandleCount; Index++) { - - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo - ); - - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - 0, - sizeof (PciData), - &PciData - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - if ((PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE && PciData.Hdr.ClassCode[1] == PCI_CLASS_MASS_STORAGE_IDE) - || (PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE && PciData.Hdr.ClassCode[1] == PCI_CLASS_MASS_STORAGE_SATADPA) - || ((PciData.Hdr.ClassCode[2] == 0x08 && PciData.Hdr.ClassCode[1] == 0x05 && PciData.Hdr.ClassCode[0] == 0x01) && (PciData.Hdr.DeviceId == 0x2296))) { - // - //IDE Controller or AHCI Controller or SDCard Controller - // - gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); - } - } - - for (Index = 0; Index < HandleCount; Index++) { - - Status = gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiPciIoProtocolGuid, - (VOID **) &PciIo - ); - - Status = PciIo->Pci.Read ( - PciIo, - EfiPciIoWidthUint8, - 0, - sizeof (PciData), - &PciData - ); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - if ((PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE && PciData.Hdr.ClassCode[1] == PCI_CLASS_MASS_STORAGE_IDE) - || (PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE && PciData.Hdr.ClassCode[1] == PCI_CLASS_MASS_STORAGE_SATADPA) - || ((PciData.Hdr.ClassCode[2] == 0x08 && PciData.Hdr.ClassCode[1] == 0x05 && PciData.Hdr.ClassCode[0] == 0x01) && (PciData.Hdr.DeviceId == 0x2296))) { - // - //IDE Controller or AHCI Controller or SDCard Controller - // - gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); - } - } - - if (HandleBuffer != NULL) { - FreePool (HandleBuffer); - } - - return EFI_SUCCESS; -} - -/** - Connect SATA Device and SDCard Device according to Device Path. - - @param[in] DevicePath - -**/ -VOID -PlatformBdsConnectStorageDeviceFromDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - - TempDevicePath = DevicePath; - - while (!IsDevicePathEnd (TempDevicePath)) { - if ((((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH)) && ((DevicePathSubType (TempDevicePath) == MSG_SATA_DP))) - || (((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH)) && ((DevicePathSubType (TempDevicePath) == 0x11)))) { - PlatformBdsConnectStorageDevice(); - break; - } - TempDevicePath = NextDevicePathNode (TempDevicePath); - } -} - -/** - Boot the legacy system with the boot option - - @param Option The legacy boot option which have BBS device path - - @retval EFI_UNSUPPORTED There is no legacybios protocol, do not support - legacy boot. - @retval EFI_STATUS Return the status of LegacyBios->LegacyBoot (). - -**/ -EFI_STATUS -BdsLibDoLegacyBoot ( - IN BDS_COMMON_OPTION *Option - ) -{ - EFI_STATUS Status; - EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; - EFI_EVENT LegacyBootEvent; - - Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios); - if (EFI_ERROR (Status)) { - // - // If no LegacyBios protocol we do not support legacy boot - // - return EFI_UNSUPPORTED; - } - // - // Notes: if we separate the int 19, then we don't need to refresh BBS - // - BdsRefreshBbsTableForBoot (Option); - - // - // Write boot to OS performance data for legacy boot. - // - PERF_CODE ( - // - // Create an event to be signalled when Legacy Boot occurs to write performance data. - // - Status = EfiCreateEventLegacyBootEx( - TPL_NOTIFY, - WriteBootToOsPerformanceData, - NULL, - &LegacyBootEvent - ); - ASSERT_EFI_ERROR (Status); - ); - - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Legacy Boot: %S\n", Option->Description)); - return LegacyBios->LegacyBoot ( - LegacyBios, - (BBS_BBS_DEVICE_PATH *) Option->DevicePath, - Option->LoadOptionsSize, - Option->LoadOptions - ); -} - -/** - Internal function to check if the input boot option is a valid EFI NV Boot####. - - @param OptionToCheck Boot option to be checked. - - @retval TRUE This boot option matches a valid EFI NV Boot####. - @retval FALSE If not. - -**/ -BOOLEAN -IsBootOptionValidNVVarialbe ( - IN BDS_COMMON_OPTION *OptionToCheck - ) -{ - LIST_ENTRY TempList; - BDS_COMMON_OPTION *BootOption; - BOOLEAN Valid; - CHAR16 OptionName[20]; - - Valid = FALSE; - - InitializeListHead (&TempList); - UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionToCheck->BootCurrent); - - BootOption = BdsLibVariableToOption (&TempList, OptionName); - if (BootOption == NULL) { - return FALSE; - } - - // - // If the Boot Option Number and Device Path matches, OptionToCheck matches a - // valid EFI NV Boot####. - // - if ((OptionToCheck->BootCurrent == BootOption->BootCurrent) && - (CompareMem (OptionToCheck->DevicePath, BootOption->DevicePath, GetDevicePathSize (OptionToCheck->DevicePath)) == 0)) - { - Valid = TRUE; - } - - FreePool (BootOption); - - return Valid; -} - -/** - Check whether a USB device match the specified USB Class device path. This - function follows "Load Option Processing" behavior in UEFI specification. - - @param UsbIo USB I/O protocol associated with the USB device. - @param UsbClass The USB Class device path to match. - - @retval TRUE The USB device match the USB Class device path. - @retval FALSE The USB device does not match the USB Class device path. - -**/ -BOOLEAN -BdsMatchUsbClass ( - IN EFI_USB_IO_PROTOCOL *UsbIo, - IN USB_CLASS_DEVICE_PATH *UsbClass - ) -{ - EFI_STATUS Status; - EFI_USB_DEVICE_DESCRIPTOR DevDesc; - EFI_USB_INTERFACE_DESCRIPTOR IfDesc; - UINT8 DeviceClass; - UINT8 DeviceSubClass; - UINT8 DeviceProtocol; - - if ((DevicePathType (UsbClass) != MESSAGING_DEVICE_PATH) || - (DevicePathSubType (UsbClass) != MSG_USB_CLASS_DP)){ - return FALSE; - } - - // - // Check Vendor Id and Product Id. - // - Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc); - if (EFI_ERROR (Status)) { - return FALSE; - } - - if ((UsbClass->VendorId != 0xffff) && - (UsbClass->VendorId != DevDesc.IdVendor)) { - return FALSE; - } - - if ((UsbClass->ProductId != 0xffff) && - (UsbClass->ProductId != DevDesc.IdProduct)) { - return FALSE; - } - - DeviceClass = DevDesc.DeviceClass; - DeviceSubClass = DevDesc.DeviceSubClass; - DeviceProtocol = DevDesc.DeviceProtocol; - if (DeviceClass == 0) { - // - // If Class in Device Descriptor is set to 0, use the Class, SubClass and - // Protocol in Interface Descriptor instead. - // - Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc); - if (EFI_ERROR (Status)) { - return FALSE; - } - - DeviceClass = IfDesc.InterfaceClass; - DeviceSubClass = IfDesc.InterfaceSubClass; - DeviceProtocol = IfDesc.InterfaceProtocol; - } - - // - // Check Class, SubClass and Protocol. - // - if ((UsbClass->DeviceClass != 0xff) && - (UsbClass->DeviceClass != DeviceClass)) { - return FALSE; - } - - if ((UsbClass->DeviceSubClass != 0xff) && - (UsbClass->DeviceSubClass != DeviceSubClass)) { - return FALSE; - } - - if ((UsbClass->DeviceProtocol != 0xff) && - (UsbClass->DeviceProtocol != DeviceProtocol)) { - return FALSE; - } - - return TRUE; -} - -/** - Check whether a USB device match the specified USB WWID device path. This - function follows "Load Option Processing" behavior in UEFI specification. - - @param UsbIo USB I/O protocol associated with the USB device. - @param UsbWwid The USB WWID device path to match. - - @retval TRUE The USB device match the USB WWID device path. - @retval FALSE The USB device does not match the USB WWID device path. - -**/ -BOOLEAN -BdsMatchUsbWwid ( - IN EFI_USB_IO_PROTOCOL *UsbIo, - IN USB_WWID_DEVICE_PATH *UsbWwid - ) -{ - EFI_STATUS Status; - EFI_USB_DEVICE_DESCRIPTOR DevDesc; - EFI_USB_INTERFACE_DESCRIPTOR IfDesc; - UINT16 *LangIdTable; - UINT16 TableSize; - UINT16 Index; - CHAR16 *CompareStr; - UINTN CompareLen; - CHAR16 *SerialNumberStr; - UINTN Length; - - if ((DevicePathType (UsbWwid) != MESSAGING_DEVICE_PATH) || - (DevicePathSubType (UsbWwid) != MSG_USB_WWID_DP )){ - return FALSE; - } - - // - // Check Vendor Id and Product Id. - // - Status = UsbIo->UsbGetDeviceDescriptor (UsbIo, &DevDesc); - if (EFI_ERROR (Status)) { - return FALSE; - } - if ((DevDesc.IdVendor != UsbWwid->VendorId) || - (DevDesc.IdProduct != UsbWwid->ProductId)) { - return FALSE; - } - - // - // Check Interface Number. - // - Status = UsbIo->UsbGetInterfaceDescriptor (UsbIo, &IfDesc); - if (EFI_ERROR (Status)) { - return FALSE; - } - if (IfDesc.InterfaceNumber != UsbWwid->InterfaceNumber) { - return FALSE; - } - - // - // Check Serial Number. - // - if (DevDesc.StrSerialNumber == 0) { - return FALSE; - } - - // - // Get all supported languages. - // - TableSize = 0; - LangIdTable = NULL; - Status = UsbIo->UsbGetSupportedLanguages (UsbIo, &LangIdTable, &TableSize); - if (EFI_ERROR (Status) || (TableSize == 0) || (LangIdTable == NULL)) { - return FALSE; - } - - // - // Serial number in USB WWID device path is the last 64-or-less UTF-16 characters. - // - CompareStr = (CHAR16 *) (UINTN) (UsbWwid + 1); - CompareLen = (DevicePathNodeLength (UsbWwid) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16); - if (CompareStr[CompareLen - 1] == L'\0') { - CompareLen--; - } - - // - // Compare serial number in each supported language. - // - for (Index = 0; Index < TableSize / sizeof (UINT16); Index++) { - SerialNumberStr = NULL; - Status = UsbIo->UsbGetStringDescriptor ( - UsbIo, - LangIdTable[Index], - DevDesc.StrSerialNumber, - &SerialNumberStr - ); - if (EFI_ERROR (Status) || (SerialNumberStr == NULL)) { - continue; - } - - Length = StrLen (SerialNumberStr); - if ((Length >= CompareLen) && - (CompareMem (SerialNumberStr + Length - CompareLen, CompareStr, CompareLen * sizeof (CHAR16)) == 0)) { - FreePool (SerialNumberStr); - return TRUE; - } - - FreePool (SerialNumberStr); - } - - return FALSE; -} - -/** - Find a USB device path which match the specified short-form device path start - with USB Class or USB WWID device path and load the boot file then return the - image handle. If ParentDevicePath is NULL, this function will search in all USB - devices of the platform. If ParentDevicePath is not NULL,this function will only - search in its child devices. - - @param ParentDevicePath The device path of the parent. - @param ShortFormDevicePath The USB Class or USB WWID device path to match. - - @return The image Handle if find load file from specified short-form device path - or NULL if not found. - -**/ -EFI_HANDLE * -BdsFindUsbDevice ( - IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL *ShortFormDevicePath - ) -{ - EFI_STATUS Status; - UINTN UsbIoHandleCount; - EFI_HANDLE *UsbIoHandleBuffer; - EFI_DEVICE_PATH_PROTOCOL *UsbIoDevicePath; - EFI_USB_IO_PROTOCOL *UsbIo; - UINTN Index; - UINTN ParentSize; - UINTN Size; - EFI_HANDLE ImageHandle; - EFI_HANDLE Handle; - EFI_DEVICE_PATH_PROTOCOL *FullDevicePath; - EFI_DEVICE_PATH_PROTOCOL *NextDevicePath; - - FullDevicePath = NULL; - ImageHandle = NULL; - - // - // Get all UsbIo Handles. - // - UsbIoHandleCount = 0; - UsbIoHandleBuffer = NULL; - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiUsbIoProtocolGuid, - NULL, - &UsbIoHandleCount, - &UsbIoHandleBuffer - ); - if (EFI_ERROR (Status) || (UsbIoHandleCount == 0) || (UsbIoHandleBuffer == NULL)) { - return NULL; - } - - ParentSize = (ParentDevicePath == NULL) ? 0 : GetDevicePathSize (ParentDevicePath); - for (Index = 0; Index < UsbIoHandleCount; Index++) { - // - // Get the Usb IO interface. - // - Status = gBS->HandleProtocol( - UsbIoHandleBuffer[Index], - &gEfiUsbIoProtocolGuid, - (VOID **) &UsbIo - ); - if (EFI_ERROR (Status)) { - continue; - } - - UsbIoDevicePath = DevicePathFromHandle (UsbIoHandleBuffer[Index]); - if (UsbIoDevicePath == NULL) { - continue; - } - - if (ParentDevicePath != NULL) { - // - // Compare starting part of UsbIoHandle's device path with ParentDevicePath. - // - Size = GetDevicePathSize (UsbIoDevicePath); - if ((Size < ParentSize) || - (CompareMem (UsbIoDevicePath, ParentDevicePath, ParentSize - END_DEVICE_PATH_LENGTH) != 0)) { - continue; - } - } - - if (BdsMatchUsbClass (UsbIo, (USB_CLASS_DEVICE_PATH *) ShortFormDevicePath) || - BdsMatchUsbWwid (UsbIo, (USB_WWID_DEVICE_PATH *) ShortFormDevicePath)) { - // - // Try to find if there is the boot file in this DevicePath - // - NextDevicePath = NextDevicePathNode (ShortFormDevicePath); - if (!IsDevicePathEnd (NextDevicePath)) { - FullDevicePath = AppendDevicePath (UsbIoDevicePath, NextDevicePath); - // - // Connect the full device path, so that Simple File System protocol - // could be installed for this USB device. - // - BdsLibConnectDevicePath (FullDevicePath); - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad)); - Status = gBS->LoadImage ( - TRUE, - gImageHandle, - FullDevicePath, - NULL, - 0, - &ImageHandle - ); - FreePool (FullDevicePath); - } else { - FullDevicePath = UsbIoDevicePath; - Status = EFI_NOT_FOUND; - } - - // - // If we didn't find an image directly, we need to try as if it is a removable device boot option - // and load the image according to the default boot behavior for removable device. - // - if (EFI_ERROR (Status)) { - // - // check if there is a bootable removable media could be found in this device path , - // and get the bootable media handle - // - Handle = BdsLibGetBootableHandle(UsbIoDevicePath); - if (Handle == NULL) { - continue; - } - // - // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media - // machinename is ia32, ia64, x64, ... - // - FullDevicePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME); - if (FullDevicePath != NULL) { - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad)); - Status = gBS->LoadImage ( - TRUE, - gImageHandle, - FullDevicePath, - NULL, - 0, - &ImageHandle - ); - if (EFI_ERROR (Status)) { - // - // The DevicePath failed, and it's not a valid - // removable media device. - // - continue; - } - } else { - continue; - } - } - break; - } - } - - FreePool (UsbIoHandleBuffer); - return ImageHandle; -} - -/** - Expand USB Class or USB WWID device path node to be full device path of a USB - device in platform then load the boot file on this full device path and return the - image handle. - - This function support following 4 cases: - 1) Boot Option device path starts with a USB Class or USB WWID device path, - and there is no Media FilePath device path in the end. - In this case, it will follow Removable Media Boot Behavior. - 2) Boot Option device path starts with a USB Class or USB WWID device path, - and ended with Media FilePath device path. - 3) Boot Option device path starts with a full device path to a USB Host Controller, - contains a USB Class or USB WWID device path node, while not ended with Media - FilePath device path. In this case, it will follow Removable Media Boot Behavior. - 4) Boot Option device path starts with a full device path to a USB Host Controller, - contains a USB Class or USB WWID device path node, and ended with Media - FilePath device path. - - @param DevicePath The Boot Option device path. - - @return The image handle of boot file, or NULL if there is no boot file found in - the specified USB Class or USB WWID device path. - -**/ -EFI_HANDLE * -BdsExpandUsbShortFormDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - EFI_HANDLE *ImageHandle; - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - EFI_DEVICE_PATH_PROTOCOL *ShortFormDevicePath; - - // - // Search for USB Class or USB WWID device path node. - // - ShortFormDevicePath = NULL; - ImageHandle = NULL; - TempDevicePath = DevicePath; - while (!IsDevicePathEnd (TempDevicePath)) { - if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) && - ((DevicePathSubType (TempDevicePath) == MSG_USB_CLASS_DP) || - (DevicePathSubType (TempDevicePath) == MSG_USB_WWID_DP))) { - ShortFormDevicePath = TempDevicePath; - break; - } - TempDevicePath = NextDevicePathNode (TempDevicePath); - } - - if (ShortFormDevicePath == NULL) { - // - // No USB Class or USB WWID device path node found, do nothing. - // - return NULL; - } - - if (ShortFormDevicePath == DevicePath) { - // - // Boot Option device path starts with USB Class or USB WWID device path. - // - ImageHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath); - if (ImageHandle == NULL) { - // - // Failed to find a match in existing devices, connect the short form USB - // device path and try again. - // - BdsLibConnectUsbDevByShortFormDP (0xff, ShortFormDevicePath); - ImageHandle = BdsFindUsbDevice (NULL, ShortFormDevicePath); - } - } else { - // - // Boot Option device path contains USB Class or USB WWID device path node. - // - - // - // Prepare the parent device path for search. - // - TempDevicePath = DuplicateDevicePath (DevicePath); - ASSERT (TempDevicePath != NULL); - SetDevicePathEndNode (((UINT8 *) TempDevicePath) + ((UINTN) ShortFormDevicePath - (UINTN) DevicePath)); - - // - // The USB Host Controller device path is already in Boot Option device path - // and USB Bus driver already support RemainingDevicePath starts with USB - // Class or USB WWID device path, so just search in existing USB devices and - // doesn't perform ConnectController here. - // - ImageHandle = BdsFindUsbDevice (TempDevicePath, ShortFormDevicePath); - FreePool (TempDevicePath); - } - - return ImageHandle; -} - -/** - Process the boot option follow the UEFI specification and - special treat the legacy boot option with BBS_DEVICE_PATH. - - @param Option The boot option need to be processed - @param DevicePath The device path which describe where to load the - boot image or the legacy BBS device path to boot - the legacy OS - @param ExitDataSize The size of exit data. - @param ExitData Data returned when Boot image failed. - - @retval EFI_SUCCESS Boot from the input boot option successfully. - @retval EFI_NOT_FOUND If the Device Path is not found in the system - -**/ -EFI_STATUS -EFIAPI -BdsLibBootViaBootOption ( - IN BDS_COMMON_OPTION *Option, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - OUT UINTN *ExitDataSize, - OUT CHAR16 **ExitData OPTIONAL - ) -{ - EFI_STATUS Status; - EFI_STATUS StatusLogo; - EFI_HANDLE Handle; - EFI_HANDLE ImageHandle; - EFI_DEVICE_PATH_PROTOCOL *FilePath; - EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; - EFI_DEVICE_PATH_PROTOCOL *WorkingDevicePath; - LIST_ENTRY TempBootLists; - EFI_BOOT_LOGO_PROTOCOL *BootLogo; - EFI_BOOT_MODE BootMode; - - Status = EFI_SUCCESS; - *ExitDataSize = 0; - *ExitData = NULL; - - // - // If it's Device Path that starts with a hard drive path, append it with the front part to compose a - // full device path - // - WorkingDevicePath = NULL; - if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) && - (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP)) { - WorkingDevicePath = BdsExpandPartitionPartialDevicePathToFull ( - (HARDDRIVE_DEVICE_PATH *)DevicePath - ); - if (WorkingDevicePath != NULL) { - DevicePath = WorkingDevicePath; - } - } - - // - // Set Boot Current - // - if (IsBootOptionValidNVVarialbe (Option)) { - // - // For a temporary boot (i.e. a boot by selected a EFI Shell using "Boot From File"), Boot Current is actually not valid. - // In this case, "BootCurrent" is not created. - // Only create the BootCurrent variable when it points to a valid Boot#### variable. - // - SetVariableAndReportStatusCodeOnError ( - L"BootCurrent", - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - sizeof (UINT16), - &Option->BootCurrent - ); - } - - // - // Signal the EVT_SIGNAL_READY_TO_BOOT event - // - EfiSignalEventReadyToBoot(); - - // - // Get current Boot Mode - // - BootMode = GetBootModeHob(); - - if ((BootMode != BOOT_WITH_MINIMAL_CONFIGURATION) && (BootMode != BOOT_ASSUMING_NO_CONFIGURATION_CHANGES)) { - // - // Connect Storage Device.(eg:SATA Device and SDCard Device) - // - PlatformBdsConnectStorageDevice(); - } else { - // - // If it is Fast Boot, we only connect SATA Devices or SD Card Devices. Otherwise, we do nothing. - // - PlatformBdsConnectStorageDeviceFromDevicePath (DevicePath); - } - - // - // Report Status Code to indicate ReadyToBoot event was signalled - // - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT)); - - // - // Expand USB Class or USB WWID device path node to be full device path of a USB - // device in platform then load the boot file on this full device path and get the - // image handle. - // - ImageHandle = BdsExpandUsbShortFormDevicePath (DevicePath); - - // - // Adjust the different type memory page number just before booting - // and save the updated info into the variable for next boot to use - // - BdsSetMemoryTypeInformationVariable (); - - // - // By expanding the USB Class or WWID device path, the ImageHandle has returnned. - // Here get the ImageHandle for the non USB class or WWID device path. - // - if (ImageHandle == NULL) { - ASSERT (Option->DevicePath != NULL); - if ((DevicePathType (Option->DevicePath) == BBS_DEVICE_PATH) && - (DevicePathSubType (Option->DevicePath) == BBS_BBS_DP) - ) { - // - // Check to see if we should legacy BOOT. If yes then do the legacy boot - // - return BdsLibDoLegacyBoot (Option); - } - - // - // If the boot option point to Internal FV shell, make sure it is valid - // - Status = BdsLibUpdateFvFileDevicePath (&DevicePath, PcdGetPtr(PcdShellFile)); - if (!EFI_ERROR(Status)) { - if (Option->DevicePath != NULL) { - FreePool(Option->DevicePath); - } - Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath)); - ASSERT(Option->DevicePath != NULL); - CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath)); - // - // Update the shell boot option - // - InitializeListHead (&TempBootLists); - BdsLibRegisterNewOption (&TempBootLists, DevicePath, L"EFI Internal Shell", L"BootOrder"); - - // - // free the temporary device path created by BdsLibUpdateFvFileDevicePath() - // - FreePool (DevicePath); - DevicePath = Option->DevicePath; - } - - DEBUG_CODE_BEGIN(); - - if (Option->Description == NULL) { - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting from unknown device path\n")); - } else { - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Booting %S\n", Option->Description)); - } - - DEBUG_CODE_END(); - - // - // Report status code for OS Loader LoadImage. - // - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad)); - Status = gBS->LoadImage ( - TRUE, - gImageHandle, - DevicePath, - NULL, - 0, - &ImageHandle - ); - - // - // If we didn't find an image directly, we need to try as if it is a removable device boot option - // and load the image according to the default boot behavior for removable device. - // - if (EFI_ERROR (Status)) { - // - // check if there is a bootable removable media could be found in this device path , - // and get the bootable media handle - // - Handle = BdsLibGetBootableHandle(DevicePath); - if (Handle != NULL) { - // - // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media - // machinename is ia32, ia64, x64, ... - // - FilePath = FileDevicePath (Handle, EFI_REMOVABLE_MEDIA_FILE_NAME); - if (FilePath != NULL) { - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderLoad)); - Status = gBS->LoadImage ( - TRUE, - gImageHandle, - FilePath, - NULL, - 0, - &ImageHandle - ); - } - } - } - } - // - // Provide the image with it's load options - // - if ((ImageHandle == NULL) || (EFI_ERROR(Status))) { - // - // Report Status Code to indicate that the failure to load boot option - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR) - ); - goto Done; - } - - Status = gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo); - ASSERT_EFI_ERROR (Status); - - if (Option->LoadOptionsSize != 0) { - ImageInfo->LoadOptionsSize = Option->LoadOptionsSize; - ImageInfo->LoadOptions = Option->LoadOptions; - } - - // - // Clean to NULL because the image is loaded directly from the firmwares boot manager. - // - ImageInfo->ParentHandle = NULL; - - // - // Before calling the image, enable the Watchdog Timer for - // the 5 Minute period - // - gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL); - - // - // Write boot to OS performance data for UEFI boot - // - PERF_CODE ( - WriteBootToOsPerformanceData (NULL, NULL); - ); - - // - // Report status code for OS Loader StartImage. - // - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PcdGet32 (PcdProgressCodeOsLoaderStart)); - - Status = gBS->StartImage (ImageHandle, ExitDataSize, ExitData); - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Image Return Status = %r\n", Status)); - if (EFI_ERROR (Status)) { - // - // Report Status Code to indicate that boot failure - // - REPORT_STATUS_CODE ( - EFI_ERROR_CODE | EFI_ERROR_MINOR, - (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED) - ); - } - - // - // Clear the Watchdog Timer after the image returns - // - gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL); - -Done: - // - // Set Logo status invalid after trying one boot option - // - BootLogo = NULL; - StatusLogo = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo); - if (!EFI_ERROR (StatusLogo) && (BootLogo != NULL)) { - BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0); - } - - // - // Clear Boot Current - // Deleting variable with current implementation shouldn't fail. - // - gRT->SetVariable ( - L"BootCurrent", - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - 0, - NULL - ); - - return Status; -} - - -/** - Expand a device path that starts with a hard drive media device path node to be a - full device path that includes the full hardware path to the device. We need - to do this so it can be booted. As an optimization the front match (the part point - to the partition node. E.g. ACPI() /PCI()/ATA()/Partition() ) is saved in a variable - so a connect all is not required on every boot. All successful history device path - which point to partition node (the front part) will be saved. - - @param HardDriveDevicePath EFI Device Path to boot, if it starts with a hard - drive media device path. - @return A Pointer to the full device path or NULL if a valid Hard Drive devic path - cannot be found. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -EFIAPI -BdsExpandPartitionPartialDevicePathToFull ( - IN HARDDRIVE_DEVICE_PATH *HardDriveDevicePath - ) -{ - EFI_STATUS Status; - UINTN BlockIoHandleCount; - EFI_HANDLE *BlockIoBuffer; - EFI_DEVICE_PATH_PROTOCOL *FullDevicePath; - EFI_DEVICE_PATH_PROTOCOL *BlockIoDevicePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - UINTN Index; - UINTN InstanceNum; - EFI_DEVICE_PATH_PROTOCOL *CachedDevicePath; - EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath; - UINTN CachedDevicePathSize; - BOOLEAN DeviceExist; - BOOLEAN NeedAdjust; - EFI_DEVICE_PATH_PROTOCOL *Instance; - UINTN Size; - - FullDevicePath = NULL; - // - // Check if there is prestore HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable. - // If exist, search the front path which point to partition node in the variable instants. - // If fail to find or HD_BOOT_DEVICE_PATH_VARIABLE_NAME not exist, reconnect all and search in all system - // - GetVariable2 ( - HD_BOOT_DEVICE_PATH_VARIABLE_NAME, - &gHdBootDevicePathVariablGuid, - (VOID **) &CachedDevicePath, - &CachedDevicePathSize - ); - - // - // Delete the invalid HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable. - // - if ((CachedDevicePath != NULL) && !IsDevicePathValid (CachedDevicePath, CachedDevicePathSize)) { - FreePool (CachedDevicePath); - CachedDevicePath = NULL; - Status = gRT->SetVariable ( - HD_BOOT_DEVICE_PATH_VARIABLE_NAME, - &gHdBootDevicePathVariablGuid, - 0, - 0, - NULL - ); - ASSERT_EFI_ERROR (Status); - } - - if (CachedDevicePath != NULL) { - TempNewDevicePath = CachedDevicePath; - DeviceExist = FALSE; - NeedAdjust = FALSE; - do { - // - // Check every instance of the variable - // First, check whether the instance contain the partition node, which is needed for distinguishing multi - // partial partition boot option. Second, check whether the instance could be connected. - // - Instance = GetNextDevicePathInstance (&TempNewDevicePath, &Size); - if (MatchPartitionDevicePathNode (Instance, HardDriveDevicePath)) { - // - // Connect the device path instance, the device path point to hard drive media device path node - // e.g. ACPI() /PCI()/ATA()/Partition() - // - Status = BdsLibConnectDevicePath (Instance); - if (!EFI_ERROR (Status)) { - DeviceExist = TRUE; - break; - } - } - // - // Come here means the first instance is not matched - // - NeedAdjust = TRUE; - FreePool(Instance); - } while (TempNewDevicePath != NULL); - - if (DeviceExist) { - // - // Find the matched device path. - // Append the file path information from the boot option and return the fully expanded device path. - // - DevicePath = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath); - FullDevicePath = AppendDevicePath (Instance, DevicePath); - - // - // Adjust the HD_BOOT_DEVICE_PATH_VARIABLE_NAME instances sequence if the matched one is not first one. - // - if (NeedAdjust) { - // - // First delete the matched instance. - // - TempNewDevicePath = CachedDevicePath; - CachedDevicePath = BdsLibDelPartMatchInstance (CachedDevicePath, Instance ); - FreePool (TempNewDevicePath); - - // - // Second, append the remaining path after the matched instance - // - TempNewDevicePath = CachedDevicePath; - CachedDevicePath = AppendDevicePathInstance (Instance, CachedDevicePath ); - FreePool (TempNewDevicePath); - // - // Save the matching Device Path so we don't need to do a connect all next time - // Failure to set the variable only impacts the performance when next time expanding the short-form device path. - // - Status = gRT->SetVariable ( - HD_BOOT_DEVICE_PATH_VARIABLE_NAME, - &gHdBootDevicePathVariablGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, - GetDevicePathSize (CachedDevicePath), - CachedDevicePath - ); - } - - FreePool (Instance); - FreePool (CachedDevicePath); - return FullDevicePath; - } - } - - // - // If we get here we fail to find or HD_BOOT_DEVICE_PATH_VARIABLE_NAME not exist, and now we need - // to search all devices in the system for a matched partition - // - BdsLibConnectAllDriversToAllControllers (); - Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &BlockIoHandleCount, &BlockIoBuffer); - if (EFI_ERROR (Status) || BlockIoHandleCount == 0 || BlockIoBuffer == NULL) { - // - // If there was an error or there are no device handles that support - // the BLOCK_IO Protocol, then return. - // - return NULL; - } - // - // Loop through all the device handles that support the BLOCK_IO Protocol - // - for (Index = 0; Index < BlockIoHandleCount; Index++) { - - Status = gBS->HandleProtocol (BlockIoBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID *) &BlockIoDevicePath); - if (EFI_ERROR (Status) || BlockIoDevicePath == NULL) { - continue; - } - - if (MatchPartitionDevicePathNode (BlockIoDevicePath, HardDriveDevicePath)) { - // - // Find the matched partition device path - // - DevicePath = NextDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *) HardDriveDevicePath); - FullDevicePath = AppendDevicePath (BlockIoDevicePath, DevicePath); - - // - // Save the matched partition device path in HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable - // - if (CachedDevicePath != NULL) { - // - // Save the matched partition device path as first instance of HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable - // - if (BdsLibMatchDevicePaths (CachedDevicePath, BlockIoDevicePath)) { - TempNewDevicePath = CachedDevicePath; - CachedDevicePath = BdsLibDelPartMatchInstance (CachedDevicePath, BlockIoDevicePath); - FreePool(TempNewDevicePath); - } - - if (CachedDevicePath != NULL) { - TempNewDevicePath = CachedDevicePath; - CachedDevicePath = AppendDevicePathInstance (BlockIoDevicePath, CachedDevicePath); - FreePool(TempNewDevicePath); - } else { - CachedDevicePath = DuplicateDevicePath (BlockIoDevicePath); - } - - // - // Here limit the device path instance number to 12, which is max number for a system support 3 IDE controller - // If the user try to boot many OS in different HDs or partitions, in theory, - // the HD_BOOT_DEVICE_PATH_VARIABLE_NAME variable maybe become larger and larger. - // - InstanceNum = 0; - ASSERT (CachedDevicePath != NULL); - TempNewDevicePath = CachedDevicePath; - while (!IsDevicePathEnd (TempNewDevicePath)) { - TempNewDevicePath = NextDevicePathNode (TempNewDevicePath); - // - // Parse one instance - // - while (!IsDevicePathEndType (TempNewDevicePath)) { - TempNewDevicePath = NextDevicePathNode (TempNewDevicePath); - } - InstanceNum++; - // - // If the CachedDevicePath variable contain too much instance, only remain 12 instances. - // - if (InstanceNum >= 12) { - SetDevicePathEndNode (TempNewDevicePath); - break; - } - } - } else { - CachedDevicePath = DuplicateDevicePath (BlockIoDevicePath); - } - - // - // Save the matching Device Path so we don't need to do a connect all next time - // Failure to set the variable only impacts the performance when next time expanding the short-form device path. - // - Status = gRT->SetVariable ( - HD_BOOT_DEVICE_PATH_VARIABLE_NAME, - &gHdBootDevicePathVariablGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, - GetDevicePathSize (CachedDevicePath), - CachedDevicePath - ); - - break; - } - } - - if (CachedDevicePath != NULL) { - FreePool (CachedDevicePath); - } - if (BlockIoBuffer != NULL) { - FreePool (BlockIoBuffer); - } - return FullDevicePath; -} - -/** - Check whether there is a instance in BlockIoDevicePath, which contain multi device path - instances, has the same partition node with HardDriveDevicePath device path - - @param BlockIoDevicePath Multi device path instances which need to check - @param HardDriveDevicePath A device path which starts with a hard drive media - device path. - - @retval TRUE There is a matched device path instance. - @retval FALSE There is no matched device path instance. - -**/ -BOOLEAN -EFIAPI -MatchPartitionDevicePathNode ( - IN EFI_DEVICE_PATH_PROTOCOL *BlockIoDevicePath, - IN HARDDRIVE_DEVICE_PATH *HardDriveDevicePath - ) -{ - HARDDRIVE_DEVICE_PATH *TmpHdPath; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - BOOLEAN Match; - EFI_DEVICE_PATH_PROTOCOL *BlockIoHdDevicePathNode; - - if ((BlockIoDevicePath == NULL) || (HardDriveDevicePath == NULL)) { - return FALSE; - } - - // - // Make PreviousDevicePath == the device path node before the end node - // - DevicePath = BlockIoDevicePath; - BlockIoHdDevicePathNode = NULL; - - // - // find the partition device path node - // - while (!IsDevicePathEnd (DevicePath)) { - if ((DevicePathType (DevicePath) == MEDIA_DEVICE_PATH) && - (DevicePathSubType (DevicePath) == MEDIA_HARDDRIVE_DP) - ) { - BlockIoHdDevicePathNode = DevicePath; - break; - } - - DevicePath = NextDevicePathNode (DevicePath); - } - - if (BlockIoHdDevicePathNode == NULL) { - return FALSE; - } - // - // See if the harddrive device path in blockio matches the orig Hard Drive Node - // - TmpHdPath = (HARDDRIVE_DEVICE_PATH *) BlockIoHdDevicePathNode; - Match = FALSE; - - // - // Check for the match - // - if ((TmpHdPath->MBRType == HardDriveDevicePath->MBRType) && - (TmpHdPath->SignatureType == HardDriveDevicePath->SignatureType)) { - switch (TmpHdPath->SignatureType) { - case SIGNATURE_TYPE_GUID: - Match = CompareGuid ((EFI_GUID *)TmpHdPath->Signature, (EFI_GUID *)HardDriveDevicePath->Signature); - break; - case SIGNATURE_TYPE_MBR: - Match = (BOOLEAN)(*((UINT32 *)(&(TmpHdPath->Signature[0]))) == ReadUnaligned32((UINT32 *)(&(HardDriveDevicePath->Signature[0])))); - break; - default: - Match = FALSE; - break; - } - } - - return Match; -} - -/** - Delete the boot option associated with the handle passed in. - - @param Handle The handle which present the device path to create - boot option - - @retval EFI_SUCCESS Delete the boot option success - @retval EFI_NOT_FOUND If the Device Path is not found in the system - @retval EFI_OUT_OF_RESOURCES Lack of memory resource - @retval Other Error return value from SetVariable() - -**/ -EFI_STATUS -BdsLibDeleteOptionFromHandle ( - IN EFI_HANDLE Handle - ) -{ - UINT16 *BootOrder; - UINT8 *BootOptionVar; - UINTN BootOrderSize; - UINTN BootOptionSize; - EFI_STATUS Status; - UINTN Index; - UINT16 BootOption[BOOT_OPTION_MAX_CHAR]; - UINTN DevicePathSize; - UINTN OptionDevicePathSize; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath; - UINT8 *TempPtr; - - Status = EFI_SUCCESS; - BootOrder = NULL; - BootOrderSize = 0; - - // - // Check "BootOrder" variable, if no, means there is no any boot order. - // - BootOrder = BdsLibGetVariableAndSize ( - L"BootOrder", - &gEfiGlobalVariableGuid, - &BootOrderSize - ); - if (BootOrder == NULL) { - return EFI_NOT_FOUND; - } - - // - // Convert device handle to device path protocol instance - // - DevicePath = DevicePathFromHandle (Handle); - if (DevicePath == NULL) { - return EFI_NOT_FOUND; - } - DevicePathSize = GetDevicePathSize (DevicePath); - - // - // Loop all boot order variable and find the matching device path - // - Index = 0; - while (Index < BootOrderSize / sizeof (UINT16)) { - UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]); - BootOptionVar = BdsLibGetVariableAndSize ( - BootOption, - &gEfiGlobalVariableGuid, - &BootOptionSize - ); - - if (BootOptionVar == NULL) { - FreePool (BootOrder); - return EFI_OUT_OF_RESOURCES; - } - - if (!ValidateOption(BootOptionVar, BootOptionSize)) { - BdsDeleteBootOption (BootOrder[Index], BootOrder, &BootOrderSize); - FreePool (BootOptionVar); - Index++; - continue; - } - - TempPtr = BootOptionVar; - TempPtr += sizeof (UINT32) + sizeof (UINT16); - TempPtr += StrSize ((CHAR16 *) TempPtr); - OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr; - OptionDevicePathSize = GetDevicePathSize (OptionDevicePath); - - // - // Check whether the device path match - // - if ((OptionDevicePathSize == DevicePathSize) && - (CompareMem (DevicePath, OptionDevicePath, DevicePathSize) == 0)) { - BdsDeleteBootOption (BootOrder[Index], BootOrder, &BootOrderSize); - FreePool (BootOptionVar); - break; - } - - FreePool (BootOptionVar); - Index++; - } - - // - // Adjust number of boot option for "BootOrder" variable. - // - Status = gRT->SetVariable ( - L"BootOrder", - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, - BootOrderSize, - BootOrder - ); - // - // Shrinking variable with existing variable implementation shouldn't fail. - // - ASSERT_EFI_ERROR (Status); - - FreePool (BootOrder); - - return Status; -} - - -/** - Delete all invalid EFI boot options. - - @retval EFI_SUCCESS Delete all invalid boot option success - @retval EFI_NOT_FOUND Variable "BootOrder" is not found - @retval EFI_OUT_OF_RESOURCES Lack of memory resource - @retval Other Error return value from SetVariable() - -**/ -EFI_STATUS -BdsDeleteAllInvalidEfiBootOption ( - VOID - ) -{ - UINT16 *BootOrder; - UINT8 *BootOptionVar; - UINTN BootOrderSize; - UINTN BootOptionSize; - EFI_STATUS Status; - UINTN Index; - UINTN Index2; - UINT16 BootOption[BOOT_OPTION_MAX_CHAR]; - EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath; - UINT8 *TempPtr; - CHAR16 *Description; - BOOLEAN Corrupted; - - Status = EFI_SUCCESS; - BootOrder = NULL; - Description = NULL; - OptionDevicePath = NULL; - BootOrderSize = 0; - Corrupted = FALSE; - - // - // Check "BootOrder" variable firstly, this variable hold the number of boot options - // - BootOrder = BdsLibGetVariableAndSize ( - L"BootOrder", - &gEfiGlobalVariableGuid, - &BootOrderSize - ); - if (NULL == BootOrder) { - return EFI_NOT_FOUND; - } - - Index = 0; - while (Index < BootOrderSize / sizeof (UINT16)) { - UnicodeSPrint (BootOption, sizeof (BootOption), L"Boot%04x", BootOrder[Index]); - BootOptionVar = BdsLibGetVariableAndSize ( - BootOption, - &gEfiGlobalVariableGuid, - &BootOptionSize - ); - if (NULL == BootOptionVar) { - FreePool (BootOrder); - return EFI_OUT_OF_RESOURCES; - } - - if (!ValidateOption(BootOptionVar, BootOptionSize)) { - Corrupted = TRUE; - } else { - TempPtr = BootOptionVar; - TempPtr += sizeof (UINT32) + sizeof (UINT16); - Description = (CHAR16 *) TempPtr; - TempPtr += StrSize ((CHAR16 *) TempPtr); - OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr; - - // - // Skip legacy boot option (BBS boot device) - // - if ((DevicePathType (OptionDevicePath) == BBS_DEVICE_PATH) && - (DevicePathSubType (OptionDevicePath) == BBS_BBS_DP)) { - FreePool (BootOptionVar); - Index++; - continue; - } - } - - if (Corrupted || !BdsLibIsValidEFIBootOptDevicePathExt (OptionDevicePath, FALSE, Description)) { - // - // Delete this invalid boot option "Boot####" - // - Status = gRT->SetVariable ( - BootOption, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, - 0, - NULL - ); - // - // Deleting variable with current variable implementation shouldn't fail. - // - ASSERT_EFI_ERROR (Status); - // - // Mark this boot option in boot order as deleted - // - BootOrder[Index] = 0xffff; - Corrupted = FALSE; - } - - FreePool (BootOptionVar); - Index++; - } - - // - // Adjust boot order array - // - Index2 = 0; - for (Index = 0; Index < BootOrderSize / sizeof (UINT16); Index++) { - if (BootOrder[Index] != 0xffff) { - BootOrder[Index2] = BootOrder[Index]; - Index2 ++; - } - } - Status = gRT->SetVariable ( - L"BootOrder", - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, - Index2 * sizeof (UINT16), - BootOrder - ); - // - // Shrinking variable with current variable implementation shouldn't fail. - // - ASSERT_EFI_ERROR (Status); - - FreePool (BootOrder); - - return Status; -} - - -/** - For EFI boot option, BDS separate them as six types: - 1. Network - The boot option points to the SimpleNetworkProtocol device. - Bds will try to automatically create this type boot option when enumerate. - 2. Shell - The boot option points to internal flash shell. - Bds will try to automatically create this type boot option when enumerate. - 3. Removable BlockIo - The boot option only points to the removable media - device, like USB flash disk, DVD, Floppy etc. - These device should contain a *removable* blockIo - protocol in their device handle. - Bds will try to automatically create this type boot option - when enumerate. - 4. Fixed BlockIo - The boot option only points to a Fixed blockIo device, - like HardDisk. - These device should contain a *fixed* blockIo - protocol in their device handle. - BDS will skip fixed blockIo devices, and NOT - automatically create boot option for them. But BDS - will help to delete those fixed blockIo boot option, - whose description rule conflict with other auto-created - boot options. - 5. Non-BlockIo Simplefile - The boot option points to a device whose handle - has SimpleFileSystem Protocol, but has no blockio - protocol. These devices do not offer blockIo - protocol, but BDS still can get the - \EFI\BOOT\boot{machinename}.EFI by SimpleFileSystem - Protocol. - 6. File - The boot option points to a file. These boot options are usually - created by user manually or OS loader. BDS will not delete or modify - these boot options. - - This function will enumerate all possible boot device in the system, and - automatically create boot options for Network, Shell, Removable BlockIo, - and Non-BlockIo Simplefile devices. - It will only execute once of every boot. - - @param BdsBootOptionList The header of the link list which indexed all - current boot options - - @retval EFI_SUCCESS Finished all the boot device enumerate and create - the boot option base on that boot device - - @retval EFI_OUT_OF_RESOURCES Failed to enumerate the boot device and create the boot option list -**/ -EFI_STATUS -EFIAPI -BdsLibEnumerateAllBootOption ( - IN OUT LIST_ENTRY *BdsBootOptionList - ) -{ - EFI_STATUS Status; - UINT16 FloppyNumber; - UINT16 HarddriveNumber; - UINT16 CdromNumber; - UINT16 UsbNumber; - UINT16 MiscNumber; - UINT16 ScsiNumber; - UINT16 NonBlockNumber; - UINTN NumberBlockIoHandles; - EFI_HANDLE *BlockIoHandles; - EFI_BLOCK_IO_PROTOCOL *BlkIo; - BOOLEAN Removable[2]; - UINTN RemovableIndex; - UINTN Index; - UINTN NumOfLoadFileHandles; - EFI_HANDLE *LoadFileHandles; - UINTN FvHandleCount; - EFI_HANDLE *FvHandleBuffer; - EFI_FV_FILETYPE Type; - UINTN Size; - EFI_FV_FILE_ATTRIBUTES Attributes; - UINT32 AuthenticationStatus; - EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - UINTN DevicePathType; - CHAR16 Buffer[40]; - EFI_HANDLE *FileSystemHandles; - UINTN NumberFileSystemHandles; - BOOLEAN NeedDelete; - EFI_IMAGE_DOS_HEADER DosHeader; - CHAR8 *PlatLang; - CHAR8 *LastLang; - EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - - FloppyNumber = 0; - HarddriveNumber = 0; - CdromNumber = 0; - UsbNumber = 0; - MiscNumber = 0; - ScsiNumber = 0; - PlatLang = NULL; - LastLang = NULL; - ZeroMem (Buffer, sizeof (Buffer)); - - // - // If the boot device enumerate happened, just get the boot - // device from the boot order variable - // - if (mEnumBootDevice) { - GetVariable2 (LAST_ENUM_LANGUAGE_VARIABLE_NAME, &gLastEnumLangGuid, (VOID**)&LastLang, NULL); - GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatLang, NULL); - ASSERT (PlatLang != NULL); - if ((LastLang != NULL) && (AsciiStrCmp (LastLang, PlatLang) == 0)) { - Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder"); - FreePool (LastLang); - FreePool (PlatLang); - return Status; - } else { - Status = gRT->SetVariable ( - LAST_ENUM_LANGUAGE_VARIABLE_NAME, - &gLastEnumLangGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, - AsciiStrSize (PlatLang), - PlatLang - ); - // - // Failure to set the variable only impacts the performance next time enumerating the boot options. - // - - if (LastLang != NULL) { - FreePool (LastLang); - } - FreePool (PlatLang); - } - } - - // - // Notes: this dirty code is to get the legacy boot option from the - // BBS table and create to variable as the EFI boot option, it should - // be removed after the CSM can provide legacy boot option directly - // - REFRESH_LEGACY_BOOT_OPTIONS; - - // - // Delete invalid boot option - // - BdsDeleteAllInvalidEfiBootOption (); - - // - // Parse removable media followed by fixed media. - // The Removable[] array is used by the for-loop below to create removable media boot options - // at first, and then to create fixed media boot options. - // - Removable[0] = FALSE; - Removable[1] = TRUE; - - gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiBlockIoProtocolGuid, - NULL, - &NumberBlockIoHandles, - &BlockIoHandles - ); - - for (RemovableIndex = 0; RemovableIndex < 2; RemovableIndex++) { - for (Index = 0; Index < NumberBlockIoHandles; Index++) { - Status = gBS->HandleProtocol ( - BlockIoHandles[Index], - &gEfiBlockIoProtocolGuid, - (VOID **) &BlkIo - ); - // - // skip the logical partition - // - if (EFI_ERROR (Status) || BlkIo->Media->LogicalPartition) { - continue; - } - - // - // firstly fixed block io then the removable block io - // - if (BlkIo->Media->RemovableMedia == Removable[RemovableIndex]) { - continue; - } - DevicePath = DevicePathFromHandle (BlockIoHandles[Index]); - DevicePathType = BdsGetBootTypeFromDevicePath (DevicePath); - - switch (DevicePathType) { - case BDS_EFI_ACPI_FLOPPY_BOOT: - if (FloppyNumber != 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY)), FloppyNumber); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_FLOPPY))); - } - BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); - FloppyNumber++; - break; - - // - // Assume a removable SATA device should be the DVD/CD device, a fixed SATA device should be the Hard Drive device. - // - case BDS_EFI_MESSAGE_ATAPI_BOOT: - case BDS_EFI_MESSAGE_SATA_BOOT: - if (BlkIo->Media->RemovableMedia) { - if (CdromNumber != 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD)), CdromNumber); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_CD_DVD))); - } - CdromNumber++; - } else { - if (HarddriveNumber != 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE)), HarddriveNumber); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_HARDDRIVE))); - } - HarddriveNumber++; - } - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Buffer: %S\n", Buffer)); - BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); - break; - - case BDS_EFI_MESSAGE_USB_DEVICE_BOOT: - if (UsbNumber != 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB)), UsbNumber); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_USB))); - } - BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); - UsbNumber++; - break; - - case BDS_EFI_MESSAGE_SCSI_BOOT: - if (ScsiNumber != 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI)), ScsiNumber); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_SCSI))); - } - BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); - ScsiNumber++; - break; - - case BDS_EFI_MESSAGE_MISC_BOOT: - default: - if (MiscNumber != 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC)), MiscNumber); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_MISC))); - } - BdsLibBuildOptionFromHandle (BlockIoHandles[Index], BdsBootOptionList, Buffer); - MiscNumber++; - break; - } - } - } - - if (NumberBlockIoHandles != 0) { - FreePool (BlockIoHandles); - } - - // - // If there is simple file protocol which does not consume block Io protocol, create a boot option for it here. - // - NonBlockNumber = 0; - gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleFileSystemProtocolGuid, - NULL, - &NumberFileSystemHandles, - &FileSystemHandles - ); - for (Index = 0; Index < NumberFileSystemHandles; Index++) { - Status = gBS->HandleProtocol ( - FileSystemHandles[Index], - &gEfiBlockIoProtocolGuid, - (VOID **) &BlkIo - ); - if (!EFI_ERROR (Status)) { - // - // Skip if the file system handle supports a BlkIo protocol, - // - continue; - } - - // - // Do the removable Media thing. \EFI\BOOT\boot{machinename}.EFI - // machinename is ia32, ia64, x64, ... - // - Hdr.Union = &HdrData; - NeedDelete = TRUE; - Status = BdsLibGetImageHeader ( - FileSystemHandles[Index], - EFI_REMOVABLE_MEDIA_FILE_NAME, - &DosHeader, - Hdr - ); - if (!EFI_ERROR (Status) && - EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) && - Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) { - NeedDelete = FALSE; - } - - if (NeedDelete) { - // - // No such file or the file is not a EFI application, delete this boot option - // - BdsLibDeleteOptionFromHandle (FileSystemHandles[Index]); - } else { - if (NonBlockNumber != 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK)), NonBlockNumber); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NON_BLOCK))); - } - BdsLibBuildOptionFromHandle (FileSystemHandles[Index], BdsBootOptionList, Buffer); - NonBlockNumber++; - } - } - - if (NumberFileSystemHandles != 0) { - FreePool (FileSystemHandles); - } - - // - // Parse Network Boot Device - // - NumOfLoadFileHandles = 0; - // - // Search Load File protocol for PXE boot option. - // - gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiLoadFileProtocolGuid, - NULL, - &NumOfLoadFileHandles, - &LoadFileHandles - ); - - for (Index = 0; Index < NumOfLoadFileHandles; Index++) { - if (Index != 0) { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s %d", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)), Index); - } else { - UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK))); - } - BdsLibBuildOptionFromHandle (LoadFileHandles[Index], BdsBootOptionList, Buffer); - } - - if (NumOfLoadFileHandles != 0) { - FreePool (LoadFileHandles); - } - - // - // Check if we have on flash shell - // - gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiFirmwareVolume2ProtocolGuid, - NULL, - &FvHandleCount, - &FvHandleBuffer - ); - for (Index = 0; Index < FvHandleCount; Index++) { - gBS->HandleProtocol ( - FvHandleBuffer[Index], - &gEfiFirmwareVolume2ProtocolGuid, - (VOID **) &Fv - ); - - Status = Fv->ReadFile ( - Fv, - PcdGetPtr(PcdShellFile), - NULL, - &Size, - &Type, - &Attributes, - &AuthenticationStatus - ); - if (EFI_ERROR (Status)) { - // - // Skip if no shell file in the FV - // - continue; - } - // - // Build the shell boot option - // - BdsLibBuildOptionFromShell (FvHandleBuffer[Index], BdsBootOptionList); - } - - if (FvHandleCount != 0) { - FreePool (FvHandleBuffer); - } - // - // Make sure every boot only have one time - // boot device enumerate - // - Status = BdsLibBuildOptionFromVar (BdsBootOptionList, L"BootOrder"); - mEnumBootDevice = TRUE; - - return Status; -} - -/** - Build the boot option with the handle parsed in - - @param Handle The handle which present the device path to create - boot option - @param BdsBootOptionList The header of the link list which indexed all - current boot options - @param String The description of the boot option. - -**/ -VOID -EFIAPI -BdsLibBuildOptionFromHandle ( - IN EFI_HANDLE Handle, - IN LIST_ENTRY *BdsBootOptionList, - IN CHAR16 *String - ) -{ - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - - DevicePath = DevicePathFromHandle (Handle); - - // - // Create and register new boot option - // - BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, String, L"BootOrder"); -} - - -/** - Build the on flash shell boot option with the handle parsed in. - - @param Handle The handle which present the device path to create - on flash shell boot option - @param BdsBootOptionList The header of the link list which indexed all - current boot options - -**/ -VOID -EFIAPI -BdsLibBuildOptionFromShell ( - IN EFI_HANDLE Handle, - IN OUT LIST_ENTRY *BdsBootOptionList - ) -{ - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ShellNode; - - DevicePath = DevicePathFromHandle (Handle); - - // - // Build the shell device path - // - EfiInitializeFwVolDevicepathNode (&ShellNode, PcdGetPtr(PcdShellFile)); - - DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &ShellNode); - - // - // Create and register the shell boot option - // - BdsLibRegisterNewOption (BdsBootOptionList, DevicePath, L"EFI Internal Shell", L"BootOrder"); - -} - -/** - Boot from the UEFI spec defined "BootNext" variable. - -**/ -VOID -EFIAPI -BdsLibBootNext ( - VOID - ) -{ - EFI_STATUS Status; - UINT16 *BootNext; - UINTN BootNextSize; - CHAR16 Buffer[20]; - BDS_COMMON_OPTION *BootOption; - LIST_ENTRY TempList; - UINTN ExitDataSize; - CHAR16 *ExitData; - - // - // Init the boot option name buffer and temp link list - // - InitializeListHead (&TempList); - ZeroMem (Buffer, sizeof (Buffer)); - - BootNext = BdsLibGetVariableAndSize ( - L"BootNext", - &gEfiGlobalVariableGuid, - &BootNextSize - ); - - // - // Clear the boot next variable first - // - if (BootNext != NULL) { - Status = gRT->SetVariable ( - L"BootNext", - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, - 0, - NULL - ); - // - // Deleting variable with current variable implementation shouldn't fail. - // - ASSERT_EFI_ERROR (Status); - - // - // Start to build the boot option and try to boot - // - UnicodeSPrint (Buffer, sizeof (Buffer), L"Boot%04x", *BootNext); - BootOption = BdsLibVariableToOption (&TempList, Buffer); - ASSERT (BootOption != NULL); - BdsLibConnectDevicePath (BootOption->DevicePath); - BdsLibBootViaBootOption (BootOption, BootOption->DevicePath, &ExitDataSize, &ExitData); - FreePool(BootOption); - FreePool(BootNext); - } - -} - -/** - Return the bootable media handle. - First, check the device is connected - Second, check whether the device path point to a device which support SimpleFileSystemProtocol, - Third, detect the the default boot file in the Media, and return the removable Media handle. - - @param DevicePath Device Path to a bootable device - - @return The bootable media handle. If the media on the DevicePath is not bootable, NULL will return. - -**/ -EFI_HANDLE -EFIAPI -BdsLibGetBootableHandle ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - EFI_STATUS Status; - EFI_TPL OldTpl; - EFI_DEVICE_PATH_PROTOCOL *UpdatedDevicePath; - EFI_DEVICE_PATH_PROTOCOL *DupDevicePath; - EFI_HANDLE Handle; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - VOID *Buffer; - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - UINTN Size; - UINTN TempSize; - EFI_HANDLE ReturnHandle; - EFI_HANDLE *SimpleFileSystemHandles; - - UINTN NumberSimpleFileSystemHandles; - UINTN Index; - EFI_IMAGE_DOS_HEADER DosHeader; - EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData; - EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; - - UpdatedDevicePath = DevicePath; - - // - // Enter to critical section to protect the acquired BlockIo instance - // from getting released due to the USB mass storage hotplug event - // - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - // - // Check whether the device is connected - // - Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &UpdatedDevicePath, &Handle); - if (EFI_ERROR (Status)) { - // - // Skip the case that the boot option point to a simple file protocol which does not consume block Io protocol, - // - Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &UpdatedDevicePath, &Handle); - if (EFI_ERROR (Status)) { - // - // Fail to find the proper BlockIo and simple file protocol, maybe because device not present, we need to connect it firstly - // - UpdatedDevicePath = DevicePath; - Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &UpdatedDevicePath, &Handle); - gBS->ConnectController (Handle, NULL, NULL, TRUE); - } - } else { - // - // For removable device boot option, its contained device path only point to the removable device handle, - // should make sure all its children handles (its child partion or media handles) are created and connected. - // - gBS->ConnectController (Handle, NULL, NULL, TRUE); - // - // Get BlockIo protocol and check removable attribute - // - Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo); - ASSERT_EFI_ERROR (Status); - - // - // Issue a dummy read to the device to check for media change. - // When the removable media is changed, any Block IO read/write will - // cause the BlockIo protocol be reinstalled and EFI_MEDIA_CHANGED is - // returned. After the Block IO protocol is reinstalled, subsequent - // Block IO read/write will success. - // - Buffer = AllocatePool (BlockIo->Media->BlockSize); - if (Buffer != NULL) { - BlockIo->ReadBlocks ( - BlockIo, - BlockIo->Media->MediaId, - 0, - BlockIo->Media->BlockSize, - Buffer - ); - FreePool(Buffer); - } - } - - // - // Detect the the default boot file from removable Media - // - - // - // If fail to get bootable handle specified by a USB boot option, the BDS should try to find other bootable device in the same USB bus - // Try to locate the USB node device path first, if fail then use its previous PCI node to search - // - DupDevicePath = DuplicateDevicePath (DevicePath); - ASSERT (DupDevicePath != NULL); - - UpdatedDevicePath = DupDevicePath; - Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &UpdatedDevicePath, &Handle); - // - // if the resulting device path point to a usb node, and the usb node is a dummy node, should only let device path only point to the previous Pci node - // Acpi()/Pci()/Usb() --> Acpi()/Pci() - // - if ((DevicePathType (UpdatedDevicePath) == MESSAGING_DEVICE_PATH) && - (DevicePathSubType (UpdatedDevicePath) == MSG_USB_DP)) { - // - // Remove the usb node, let the device path only point to PCI node - // - SetDevicePathEndNode (UpdatedDevicePath); - UpdatedDevicePath = DupDevicePath; - } else { - UpdatedDevicePath = DevicePath; - } - - // - // Get the device path size of boot option - // - Size = GetDevicePathSize(UpdatedDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL); // minus the end node - ReturnHandle = NULL; - gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleFileSystemProtocolGuid, - NULL, - &NumberSimpleFileSystemHandles, - &SimpleFileSystemHandles - ); - for (Index = 0; Index < NumberSimpleFileSystemHandles; Index++) { - // - // Get the device path size of SimpleFileSystem handle - // - TempDevicePath = DevicePathFromHandle (SimpleFileSystemHandles[Index]); - TempSize = GetDevicePathSize (TempDevicePath)- sizeof (EFI_DEVICE_PATH_PROTOCOL); // minus the end node - // - // Check whether the device path of boot option is part of the SimpleFileSystem handle's device path - // - if (Size <= TempSize && CompareMem (TempDevicePath, UpdatedDevicePath, Size)==0) { - // - // Load the default boot file \EFI\BOOT\boot{machinename}.EFI from removable Media - // machinename is ia32, ia64, x64, ... - // - Hdr.Union = &HdrData; - Status = BdsLibGetImageHeader ( - SimpleFileSystemHandles[Index], - EFI_REMOVABLE_MEDIA_FILE_NAME, - &DosHeader, - Hdr - ); - if (!EFI_ERROR (Status) && - EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Hdr.Pe32->FileHeader.Machine) && - Hdr.Pe32->OptionalHeader.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) { - ReturnHandle = SimpleFileSystemHandles[Index]; - break; - } - } - } - - FreePool(DupDevicePath); - - if (SimpleFileSystemHandles != NULL) { - FreePool(SimpleFileSystemHandles); - } - - gBS->RestoreTPL (OldTpl); - - return ReturnHandle; -} - -/** - Check to see if the network cable is plugged in. If the DevicePath is not - connected it will be connected. - - @param DevicePath Device Path to check - - @retval TRUE DevicePath points to an Network that is connected - @retval FALSE DevicePath does not point to a bootable network - -**/ -BOOLEAN -BdsLibNetworkBootWithMediaPresent ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *UpdatedDevicePath; - EFI_HANDLE Handle; - EFI_SIMPLE_NETWORK_PROTOCOL *Snp; - BOOLEAN MediaPresent; - UINT32 InterruptStatus; - - MediaPresent = FALSE; - - UpdatedDevicePath = DevicePath; - // - // Locate Load File Protocol for PXE boot option first - // - Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &UpdatedDevicePath, &Handle); - if (EFI_ERROR (Status)) { - // - // Device not present so see if we need to connect it - // - Status = BdsLibConnectDevicePath (DevicePath); - if (!EFI_ERROR (Status)) { - // - // This one should work after we did the connect - // - Status = gBS->LocateDevicePath (&gEfiLoadFileProtocolGuid, &UpdatedDevicePath, &Handle); - } - } - - if (!EFI_ERROR (Status)) { - Status = gBS->HandleProtocol (Handle, &gEfiSimpleNetworkProtocolGuid, (VOID **)&Snp); - if (EFI_ERROR (Status)) { - // - // Failed to open SNP from this handle, try to get SNP from parent handle - // - UpdatedDevicePath = DevicePathFromHandle (Handle); - if (UpdatedDevicePath != NULL) { - Status = gBS->LocateDevicePath (&gEfiSimpleNetworkProtocolGuid, &UpdatedDevicePath, &Handle); - if (!EFI_ERROR (Status)) { - // - // SNP handle found, get SNP from it - // - Status = gBS->HandleProtocol (Handle, &gEfiSimpleNetworkProtocolGuid, (VOID **) &Snp); - } - } - } - - if (!EFI_ERROR (Status)) { - if (Snp->Mode->MediaPresentSupported) { - if (Snp->Mode->State == EfiSimpleNetworkInitialized) { - // - // Invoke Snp->GetStatus() to refresh the media status - // - Snp->GetStatus (Snp, &InterruptStatus, NULL); - - // - // In case some one else is using the SNP check to see if it's connected - // - MediaPresent = Snp->Mode->MediaPresent; - } else { - // - // No one is using SNP so we need to Start and Initialize so - // MediaPresent will be valid. - // - Status = Snp->Start (Snp); - if (!EFI_ERROR (Status)) { - Status = Snp->Initialize (Snp, 0, 0); - if (!EFI_ERROR (Status)) { - MediaPresent = Snp->Mode->MediaPresent; - Snp->Shutdown (Snp); - } - Snp->Stop (Snp); - } - } - } else { - MediaPresent = TRUE; - } - } - } - - return MediaPresent; -} - -/** - For a bootable Device path, return its boot type. - - @param DevicePath The bootable device Path to check - - @retval BDS_EFI_MEDIA_HD_BOOT If given device path contains MEDIA_DEVICE_PATH type device path node - which subtype is MEDIA_HARDDRIVE_DP - @retval BDS_EFI_MEDIA_CDROM_BOOT If given device path contains MEDIA_DEVICE_PATH type device path node - which subtype is MEDIA_CDROM_DP - @retval BDS_EFI_ACPI_FLOPPY_BOOT If given device path contains ACPI_DEVICE_PATH type device path node - which HID is floppy device. - @retval BDS_EFI_MESSAGE_ATAPI_BOOT If given device path contains MESSAGING_DEVICE_PATH type device path node - and its last device path node's subtype is MSG_ATAPI_DP. - @retval BDS_EFI_MESSAGE_SCSI_BOOT If given device path contains MESSAGING_DEVICE_PATH type device path node - and its last device path node's subtype is MSG_SCSI_DP. - @retval BDS_EFI_MESSAGE_USB_DEVICE_BOOT If given device path contains MESSAGING_DEVICE_PATH type device path node - and its last device path node's subtype is MSG_USB_DP. - @retval BDS_EFI_MESSAGE_MISC_BOOT If the device path not contains any media device path node, and - its last device path node point to a message device path node. - @retval BDS_LEGACY_BBS_BOOT If given device path contains BBS_DEVICE_PATH type device path node. - @retval BDS_EFI_UNSUPPORT An EFI Removable BlockIO device path not point to a media and message device, - -**/ -UINT32 -EFIAPI -BdsGetBootTypeFromDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - ACPI_HID_DEVICE_PATH *Acpi; - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode; - UINT32 BootType; - - if (NULL == DevicePath) { - return BDS_EFI_UNSUPPORT; - } - - TempDevicePath = DevicePath; - - while (!IsDevicePathEndType (TempDevicePath)) { - switch (DevicePathType (TempDevicePath)) { - case BBS_DEVICE_PATH: - return BDS_LEGACY_BBS_BOOT; - case MEDIA_DEVICE_PATH: - if (DevicePathSubType (TempDevicePath) == MEDIA_HARDDRIVE_DP) { - return BDS_EFI_MEDIA_HD_BOOT; - } else if (DevicePathSubType (TempDevicePath) == MEDIA_CDROM_DP) { - return BDS_EFI_MEDIA_CDROM_BOOT; - } - break; - case ACPI_DEVICE_PATH: - Acpi = (ACPI_HID_DEVICE_PATH *) TempDevicePath; - if (EISA_ID_TO_NUM (Acpi->HID) == 0x0604) { - return BDS_EFI_ACPI_FLOPPY_BOOT; - } - break; - case MESSAGING_DEVICE_PATH: - // - // Get the last device path node - // - LastDeviceNode = NextDevicePathNode (TempDevicePath); - if (DevicePathSubType(LastDeviceNode) == MSG_DEVICE_LOGICAL_UNIT_DP) { - // - // if the next node type is Device Logical Unit, which specify the Logical Unit Number (LUN), - // skip it - // - LastDeviceNode = NextDevicePathNode (LastDeviceNode); - } - // - // if the device path not only point to driver device, it is not a messaging device path, - // - if (!IsDevicePathEndType (LastDeviceNode)) { - break; - } - - switch (DevicePathSubType (TempDevicePath)) { - case MSG_ATAPI_DP: - BootType = BDS_EFI_MESSAGE_ATAPI_BOOT; - break; - - case MSG_USB_DP: - BootType = BDS_EFI_MESSAGE_USB_DEVICE_BOOT; - break; - - case MSG_SCSI_DP: - BootType = BDS_EFI_MESSAGE_SCSI_BOOT; - break; - - case MSG_SATA_DP: - BootType = BDS_EFI_MESSAGE_SATA_BOOT; - break; - - case MSG_MAC_ADDR_DP: - case MSG_VLAN_DP: - case MSG_IPv4_DP: - case MSG_IPv6_DP: - BootType = BDS_EFI_MESSAGE_MAC_BOOT; - break; - - default: - BootType = BDS_EFI_MESSAGE_MISC_BOOT; - break; - } - return BootType; - - default: - break; - } - TempDevicePath = NextDevicePathNode (TempDevicePath); - } - - return BDS_EFI_UNSUPPORT; -} - -/** - Check whether the Device path in a boot option point to a valid bootable device, - And if CheckMedia is true, check the device is ready to boot now. - - @param DevPath the Device path in a boot option - @param CheckMedia if true, check the device is ready to boot now. - - @retval TRUE the Device path is valid - @retval FALSE the Device path is invalid . - -**/ -BOOLEAN -EFIAPI -BdsLibIsValidEFIBootOptDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevPath, - IN BOOLEAN CheckMedia - ) -{ - return BdsLibIsValidEFIBootOptDevicePathExt (DevPath, CheckMedia, NULL); -} - -/** - Check whether the Device path in a boot option point to a valid bootable device, - And if CheckMedia is true, check the device is ready to boot now. - If Description is not NULL and the device path point to a fixed BlockIo - device, check the description whether conflict with other auto-created - boot options. - - @param DevPath the Device path in a boot option - @param CheckMedia if true, check the device is ready to boot now. - @param Description the description in a boot option - - @retval TRUE the Device path is valid - @retval FALSE the Device path is invalid . - -**/ -BOOLEAN -EFIAPI -BdsLibIsValidEFIBootOptDevicePathExt ( - IN EFI_DEVICE_PATH_PROTOCOL *DevPath, - IN BOOLEAN CheckMedia, - IN CHAR16 *Description - ) -{ - EFI_STATUS Status; - EFI_HANDLE Handle; - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode; - EFI_BLOCK_IO_PROTOCOL *BlockIo; - - TempDevicePath = DevPath; - LastDeviceNode = DevPath; - - // - // Check if it's a valid boot option for network boot device. - // Check if there is EfiLoadFileProtocol installed. - // If yes, that means there is a boot option for network. - // - Status = gBS->LocateDevicePath ( - &gEfiLoadFileProtocolGuid, - &TempDevicePath, - &Handle - ); - if (EFI_ERROR (Status)) { - // - // Device not present so see if we need to connect it - // - TempDevicePath = DevPath; - BdsLibConnectDevicePath (TempDevicePath); - Status = gBS->LocateDevicePath ( - &gEfiLoadFileProtocolGuid, - &TempDevicePath, - &Handle - ); - } - - if (!EFI_ERROR (Status)) { - if (!IsDevicePathEnd (TempDevicePath)) { - // - // LoadFile protocol is not installed on handle with exactly the same DevPath - // - return FALSE; - } - - if (CheckMedia) { - // - // Test if it is ready to boot now - // - if (BdsLibNetworkBootWithMediaPresent(DevPath)) { - return TRUE; - } - } else { - return TRUE; - } - } - - // - // If the boot option point to a file, it is a valid EFI boot option, - // and assume it is ready to boot now - // - while (!IsDevicePathEnd (TempDevicePath)) { - // - // If there is USB Class or USB WWID device path node, treat it as valid EFI - // Boot Option. BdsExpandUsbShortFormDevicePath () will be used to expand it - // to full device path. - // - if ((DevicePathType (TempDevicePath) == MESSAGING_DEVICE_PATH) && - ((DevicePathSubType (TempDevicePath) == MSG_USB_CLASS_DP) || - (DevicePathSubType (TempDevicePath) == MSG_USB_WWID_DP))) { - return TRUE; - } - - LastDeviceNode = TempDevicePath; - TempDevicePath = NextDevicePathNode (TempDevicePath); - } - if ((DevicePathType (LastDeviceNode) == MEDIA_DEVICE_PATH) && - (DevicePathSubType (LastDeviceNode) == MEDIA_FILEPATH_DP)) { - return TRUE; - } - - // - // Check if it's a valid boot option for internal FV application - // - if (EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode) != NULL) { - // - // If the boot option point to internal FV application, make sure it is valid - // - TempDevicePath = DevPath; - Status = BdsLibUpdateFvFileDevicePath ( - &TempDevicePath, - EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode) - ); - if (Status == EFI_ALREADY_STARTED) { - return TRUE; - } else { - if (Status == EFI_SUCCESS) { - FreePool (TempDevicePath); - } - return FALSE; - } - } - - // - // If the boot option point to a blockIO device: - // if it is a removable blockIo device, it is valid. - // if it is a fixed blockIo device, check its description confliction. - // - TempDevicePath = DevPath; - Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle); - if (EFI_ERROR (Status)) { - // - // Device not present so see if we need to connect it - // - Status = BdsLibConnectDevicePath (DevPath); - if (!EFI_ERROR (Status)) { - // - // Try again to get the Block Io protocol after we did the connect - // - TempDevicePath = DevPath; - Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &TempDevicePath, &Handle); - } - } - - if (!EFI_ERROR (Status)) { - Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo); - if (!EFI_ERROR (Status)) { - if (CheckMedia) { - // - // Test if it is ready to boot now - // - if (BdsLibGetBootableHandle (DevPath) != NULL) { - return TRUE; - } - } else { - return TRUE; - } - } - } else { - // - // if the boot option point to a simple file protocol which does not consume block Io protocol, it is also a valid EFI boot option, - // - Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &TempDevicePath, &Handle); - if (!EFI_ERROR (Status)) { - if (CheckMedia) { - // - // Test if it is ready to boot now - // - if (BdsLibGetBootableHandle (DevPath) != NULL) { - return TRUE; - } - } else { - return TRUE; - } - } - } - - return FALSE; -} - - -/** - According to a file guild, check a Fv file device path is valid. If it is invalid, - try to return the valid device path. - FV address maybe changes for memory layout adjust from time to time, use this function - could promise the Fv file device path is right. - - @param DevicePath on input, the Fv file device path need to check on - output, the updated valid Fv file device path - @param FileGuid the Fv file guild - - @retval EFI_INVALID_PARAMETER the input DevicePath or FileGuid is invalid - parameter - @retval EFI_UNSUPPORTED the input DevicePath does not contain Fv file - guild at all - @retval EFI_ALREADY_STARTED the input DevicePath has pointed to Fv file, it is - valid - @retval EFI_SUCCESS has successfully updated the invalid DevicePath, - and return the updated device path in DevicePath - -**/ -EFI_STATUS -EFIAPI -BdsLibUpdateFvFileDevicePath ( - IN OUT EFI_DEVICE_PATH_PROTOCOL ** DevicePath, - IN EFI_GUID *FileGuid - ) -{ - EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; - EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode; - EFI_STATUS Status; - EFI_GUID *GuidPoint; - UINTN Index; - UINTN FvHandleCount; - EFI_HANDLE *FvHandleBuffer; - EFI_FV_FILETYPE Type; - UINTN Size; - EFI_FV_FILE_ATTRIBUTES Attributes; - UINT32 AuthenticationStatus; - BOOLEAN FindFvFile; - EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; - EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; - MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileNode; - EFI_HANDLE FoundFvHandle; - EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; - - if ((DevicePath == NULL) || (*DevicePath == NULL)) { - return EFI_INVALID_PARAMETER; - } - if (FileGuid == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Check whether the device path point to the default the input Fv file - // - TempDevicePath = *DevicePath; - LastDeviceNode = TempDevicePath; - while (!IsDevicePathEnd (TempDevicePath)) { - LastDeviceNode = TempDevicePath; - TempDevicePath = NextDevicePathNode (TempDevicePath); - } - GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode ( - (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode - ); - if (GuidPoint == NULL) { - // - // if this option does not points to a Fv file, just return EFI_UNSUPPORTED - // - return EFI_UNSUPPORTED; - } - if (!CompareGuid (GuidPoint, FileGuid)) { - // - // If the Fv file is not the input file guid, just return EFI_UNSUPPORTED - // - return EFI_UNSUPPORTED; - } - - // - // Check whether the input Fv file device path is valid - // - TempDevicePath = *DevicePath; - FoundFvHandle = NULL; - Status = gBS->LocateDevicePath ( - &gEfiFirmwareVolume2ProtocolGuid, - &TempDevicePath, - &FoundFvHandle - ); - if (!EFI_ERROR (Status)) { - Status = gBS->HandleProtocol ( - FoundFvHandle, - &gEfiFirmwareVolume2ProtocolGuid, - (VOID **) &Fv - ); - if (!EFI_ERROR (Status)) { - // - // Set FV ReadFile Buffer as NULL, only need to check whether input Fv file exist there - // - Status = Fv->ReadFile ( - Fv, - FileGuid, - NULL, - &Size, - &Type, - &Attributes, - &AuthenticationStatus - ); - if (!EFI_ERROR (Status)) { - return EFI_ALREADY_STARTED; - } - } - } - - // - // Look for the input wanted FV file in current FV - // First, try to look for in Bds own FV. Bds and input wanted FV file usually are in the same FV - // - FindFvFile = FALSE; - FoundFvHandle = NULL; - Status = gBS->HandleProtocol ( - gImageHandle, - &gEfiLoadedImageProtocolGuid, - (VOID **) &LoadedImage - ); - if (!EFI_ERROR (Status)) { - Status = gBS->HandleProtocol ( - LoadedImage->DeviceHandle, - &gEfiFirmwareVolume2ProtocolGuid, - (VOID **) &Fv - ); - if (!EFI_ERROR (Status)) { - Status = Fv->ReadFile ( - Fv, - FileGuid, - NULL, - &Size, - &Type, - &Attributes, - &AuthenticationStatus - ); - if (!EFI_ERROR (Status)) { - FindFvFile = TRUE; - FoundFvHandle = LoadedImage->DeviceHandle; - } - } - } - // - // Second, if fail to find, try to enumerate all FV - // - if (!FindFvFile) { - FvHandleBuffer = NULL; - gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiFirmwareVolume2ProtocolGuid, - NULL, - &FvHandleCount, - &FvHandleBuffer - ); - for (Index = 0; Index < FvHandleCount; Index++) { - gBS->HandleProtocol ( - FvHandleBuffer[Index], - &gEfiFirmwareVolume2ProtocolGuid, - (VOID **) &Fv - ); - - Status = Fv->ReadFile ( - Fv, - FileGuid, - NULL, - &Size, - &Type, - &Attributes, - &AuthenticationStatus - ); - if (EFI_ERROR (Status)) { - // - // Skip if input Fv file not in the FV - // - continue; - } - FindFvFile = TRUE; - FoundFvHandle = FvHandleBuffer[Index]; - break; - } - - if (FvHandleBuffer != NULL) { - FreePool (FvHandleBuffer); - } - } - - if (FindFvFile) { - // - // Build the shell device path - // - NewDevicePath = DevicePathFromHandle (FoundFvHandle); - EfiInitializeFwVolDevicepathNode (&FvFileNode, FileGuid); - NewDevicePath = AppendDevicePathNode (NewDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &FvFileNode); - ASSERT (NewDevicePath != NULL); - *DevicePath = NewDevicePath; - return EFI_SUCCESS; - } - return EFI_NOT_FOUND; -} diff --git a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConnect.c b/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConnect.c deleted file mode 100644 index 1970c84aee..0000000000 --- a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConnect.c +++ /dev/null @@ -1,435 +0,0 @@ -/** @file - BDS Lib functions which relate with connect the device - -Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which 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 "InternalBdsLib.h" - - -/** - This function will connect all the system driver to controller - first, and then special connect the default console, this make - sure all the system controller available and the platform default - console connected. - -**/ -VOID -EFIAPI -BdsLibConnectAll ( - VOID - ) -{ - // - // Connect the platform console first - // - BdsLibConnectAllDefaultConsoles (); - - // - // Generic way to connect all the drivers - // - BdsLibConnectAllDriversToAllControllers (); - - // - // Here we have the assumption that we have already had - // platform default console - // - BdsLibConnectAllDefaultConsoles (); -} - - -/** - This function will connect all the system drivers to all controllers - first, and then connect all the console devices the system current - have. After this we should get all the device work and console available - if the system have console device. - -**/ -VOID -BdsLibGenericConnectAll ( - VOID - ) -{ - // - // Most generic way to connect all the drivers - // - BdsLibConnectAllDriversToAllControllers (); - BdsLibConnectAllConsoles (); -} - -/** - This function will create all handles associate with every device - path node. If the handle associate with one device path node can not - be created successfully, then still give chance to do the dispatch, - which load the missing drivers if possible. - - @param DevicePathToConnect The device path which will be connected, it can be - a multi-instance device path - - @retval EFI_SUCCESS All handles associate with every device path node - have been created - @retval EFI_OUT_OF_RESOURCES There is no resource to create new handles - @retval EFI_NOT_FOUND Create the handle associate with one device path - node failed - -**/ -EFI_STATUS -EFIAPI -BdsLibConnectDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath; - EFI_DEVICE_PATH_PROTOCOL *Instance; - EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath; - EFI_DEVICE_PATH_PROTOCOL *Next; - EFI_HANDLE Handle; - EFI_HANDLE PreviousHandle; - UINTN Size; - EFI_TPL CurrentTpl; - - if (DevicePathToConnect == NULL) { - return EFI_SUCCESS; - } - - CurrentTpl = EfiGetCurrentTpl (); - - DevicePath = DuplicateDevicePath (DevicePathToConnect); - if (DevicePath == NULL) { - return EFI_OUT_OF_RESOURCES; - } - CopyOfDevicePath = DevicePath; - - do { - // - // The outer loop handles multi instance device paths. - // Only console variables contain multiple instance device paths. - // - // After this call DevicePath points to the next Instance - // - Instance = GetNextDevicePathInstance (&DevicePath, &Size); - if (Instance == NULL) { - FreePool (CopyOfDevicePath); - return EFI_OUT_OF_RESOURCES; - } - - Next = Instance; - while (!IsDevicePathEndType (Next)) { - Next = NextDevicePathNode (Next); - } - - SetDevicePathEndNode (Next); - - // - // Start the real work of connect with RemainingDevicePath - // - PreviousHandle = NULL; - do { - // - // Find the handle that best matches the Device Path. If it is only a - // partial match the remaining part of the device path is returned in - // RemainingDevicePath. - // - RemainingDevicePath = Instance; - Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle); - - if (!EFI_ERROR (Status)) { - if (Handle == PreviousHandle) { - // - // If no forward progress is made try invoking the Dispatcher. - // A new FV may have been added to the system an new drivers - // may now be found. - // Status == EFI_SUCCESS means a driver was dispatched - // Status == EFI_NOT_FOUND means no new drivers were dispatched - // - if (CurrentTpl == TPL_APPLICATION) { - // - // Dispatch calls LoadImage/StartImage which cannot run at TPL > TPL_APPLICATION - // - Status = gDS->Dispatch (); - } else { - // - // Always return EFI_NOT_FOUND here - // to prevent dead loop when control handle is found but connection failded case - // - Status = EFI_NOT_FOUND; - } - } - - if (!EFI_ERROR (Status)) { - PreviousHandle = Handle; - // - // Connect all drivers that apply to Handle and RemainingDevicePath, - // the Recursive flag is FALSE so only one level will be expanded. - // - // Do not check the connect status here, if the connect controller fail, - // then still give the chance to do dispatch, because partial - // RemainingDevicepath may be in the new FV - // - // 1. If the connect fail, RemainingDevicepath and handle will not - // change, so next time will do the dispatch, then dispatch's status - // will take effect - // 2. If the connect success, the RemainingDevicepath and handle will - // change, then avoid the dispatch, we have chance to continue the - // next connection - // - gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE); - } - } - // - // Loop until RemainingDevicePath is an empty device path - // - } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath)); - - } while (DevicePath != NULL); - - if (CopyOfDevicePath != NULL) { - FreePool (CopyOfDevicePath); - } - // - // All handle with DevicePath exists in the handle database - // - return Status; -} - -/** - This function will connect all current system handles recursively. - - gBS->ConnectController() service is invoked for each handle exist in system handler buffer. - If the handle is bus type handler, all childrens also will be connected recursively - by gBS->ConnectController(). - - @retval EFI_SUCCESS All handles and it's child handle have been connected - @retval EFI_STATUS Error status returned by of gBS->LocateHandleBuffer(). - -**/ -EFI_STATUS -EFIAPI -BdsLibConnectAllEfi ( - VOID - ) -{ - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - - Status = gBS->LocateHandleBuffer ( - AllHandles, - NULL, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return Status; - } - - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); - } - - if (HandleBuffer != NULL) { - FreePool (HandleBuffer); - } - - return EFI_SUCCESS; -} - -/** - This function will disconnect all current system handles. - - gBS->DisconnectController() is invoked for each handle exists in system handle buffer. - If handle is a bus type handle, all childrens also are disconnected recursively by - gBS->DisconnectController(). - - @retval EFI_SUCCESS All handles have been disconnected - @retval EFI_STATUS Error status returned by of gBS->LocateHandleBuffer(). - -**/ -EFI_STATUS -EFIAPI -BdsLibDisconnectAllEfi ( - VOID - ) -{ - EFI_STATUS Status; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - UINTN Index; - - // - // Disconnect all - // - Status = gBS->LocateHandleBuffer ( - AllHandles, - NULL, - NULL, - &HandleCount, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return Status; - } - - for (Index = 0; Index < HandleCount; Index++) { - Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); - } - - if (HandleBuffer != NULL) { - FreePool (HandleBuffer); - } - - return EFI_SUCCESS; -} - - -/** - Connects all drivers to all controllers. - This function make sure all the current system driver will manage - the correspoinding controllers if have. And at the same time, make - sure all the system controllers have driver to manage it if have. - -**/ -VOID -EFIAPI -BdsLibConnectAllDriversToAllControllers ( - VOID - ) -{ - EFI_STATUS Status; - - do { - // - // Connect All EFI 1.10 drivers following EFI 1.10 algorithm - // - BdsLibConnectAllEfi (); - - // - // Check to see if it's possible to dispatch an more DXE drivers. - // The BdsLibConnectAllEfi () may have made new DXE drivers show up. - // If anything is Dispatched Status == EFI_SUCCESS and we will try - // the connect again. - // - Status = gDS->Dispatch (); - - } while (!EFI_ERROR (Status)); - -} - - -/** - Connect the specific Usb device which match the short form device path, - and whose bus is determined by Host Controller (Uhci or Ehci). - - @param HostControllerPI Uhci (0x00) or Ehci (0x20) or Both uhci and ehci - (0xFF) - @param RemainingDevicePath a short-form device path that starts with the first - element being a USB WWID or a USB Class device - path - - @return EFI_INVALID_PARAMETER RemainingDevicePath is NULL pointer. - RemainingDevicePath is not a USB device path. - Invalid HostControllerPI type. - @return EFI_SUCCESS Success to connect USB device - @return EFI_NOT_FOUND Fail to find handle for USB controller to connect. - -**/ -EFI_STATUS -EFIAPI -BdsLibConnectUsbDevByShortFormDP( - IN UINT8 HostControllerPI, - IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - ) -{ - EFI_STATUS Status; - EFI_HANDLE *HandleArray; - UINTN HandleArrayCount; - UINTN Index; - EFI_PCI_IO_PROTOCOL *PciIo; - UINT8 Class[3]; - BOOLEAN AtLeastOneConnected; - - // - // Check the passed in parameters - // - if (RemainingDevicePath == NULL) { - return EFI_INVALID_PARAMETER; - } - - if ((DevicePathType (RemainingDevicePath) != MESSAGING_DEVICE_PATH) || - ((DevicePathSubType (RemainingDevicePath) != MSG_USB_CLASS_DP) - && (DevicePathSubType (RemainingDevicePath) != MSG_USB_WWID_DP) - )) { - return EFI_INVALID_PARAMETER; - } - - if (HostControllerPI != 0xFF && - HostControllerPI != 0x00 && - HostControllerPI != 0x20) { - return EFI_INVALID_PARAMETER; - } - - // - // Find the usb host controller firstly, then connect with the remaining device path - // - AtLeastOneConnected = FALSE; - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiPciIoProtocolGuid, - NULL, - &HandleArrayCount, - &HandleArray - ); - if (!EFI_ERROR (Status)) { - for (Index = 0; Index < HandleArrayCount; Index++) { - Status = gBS->HandleProtocol ( - HandleArray[Index], - &gEfiPciIoProtocolGuid, - (VOID **)&PciIo - ); - if (!EFI_ERROR (Status)) { - // - // Check whether the Pci device is the wanted usb host controller - // - Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class); - if (!EFI_ERROR (Status)) { - if ((PCI_CLASS_SERIAL == Class[2]) && - (PCI_CLASS_SERIAL_USB == Class[1])) { - if (HostControllerPI == Class[0] || HostControllerPI == 0xFF) { - Status = gBS->ConnectController ( - HandleArray[Index], - NULL, - RemainingDevicePath, - FALSE - ); - if (!EFI_ERROR(Status)) { - AtLeastOneConnected = TRUE; - } - } - } - } - } - } - - if (HandleArray != NULL) { - FreePool (HandleArray); - } - - if (AtLeastOneConnected) { - return EFI_SUCCESS; - } - } - - return EFI_NOT_FOUND; -} diff --git a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c b/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c deleted file mode 100644 index 7832fc49c7..0000000000 --- a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsConsole.c +++ /dev/null @@ -1,1301 +0,0 @@ -/** @file - BDS Lib functions which contain all the code to connect console device - -Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which 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 "InternalBdsLib.h" -#include - - -/** - Check if we need to save the EFI variable with "ConVarName" as name - as NV type - If ConVarName is NULL, then ASSERT(). - - @param ConVarName The name of the EFI variable. - - @retval TRUE Set the EFI variable as NV type. - @retval FALSE EFI variable as NV type can be set NonNV. -**/ -BOOLEAN -IsNvNeed ( - IN CHAR16 *ConVarName - ) -{ - CHAR16 *Ptr; - - ASSERT (ConVarName != NULL); - - Ptr = ConVarName; - - // - // If the variable includes "Dev" at last, we consider - // it does not support NV attribute. - // - while (*Ptr != L'\0') { - Ptr++; - } - - if (((INTN)((UINTN)Ptr - (UINTN)ConVarName) / sizeof (CHAR16)) <= 3) { - return TRUE; - } - - if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) { - return FALSE; - } else { - return TRUE; - } -} - -/** - Fill console handle in System Table if there are no valid console handle in. - - Firstly, check the validation of console handle in System Table. If it is invalid, - update it by the first console device handle from EFI console variable. - - @param VarName The name of the EFI console variable. - @param ConsoleGuid Specified Console protocol GUID. - @param ConsoleHandle On IN, console handle in System Table to be checked. - On OUT, new console handle in system table. - @param ProtocolInterface On IN, console protocol on console handle in System Table to be checked. - On OUT, new console protocol on new console handle in system table. - - @retval TRUE System Table has been updated. - @retval FALSE System Table hasn't been updated. - -**/ -BOOLEAN -UpdateSystemTableConsole ( - IN CHAR16 *VarName, - IN EFI_GUID *ConsoleGuid, - IN OUT EFI_HANDLE *ConsoleHandle, - IN OUT VOID **ProtocolInterface - ) -{ - EFI_STATUS Status; - UINTN DevicePathSize; - EFI_DEVICE_PATH_PROTOCOL *FullDevicePath; - EFI_DEVICE_PATH_PROTOCOL *VarConsole; - EFI_DEVICE_PATH_PROTOCOL *Instance; - VOID *Interface; - EFI_HANDLE NewHandle; - EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TextOut; - - ASSERT (VarName != NULL); - ASSERT (ConsoleHandle != NULL); - ASSERT (ConsoleGuid != NULL); - ASSERT (ProtocolInterface != NULL); - - if (*ConsoleHandle != NULL) { - Status = gBS->HandleProtocol ( - *ConsoleHandle, - ConsoleGuid, - &Interface - ); - if (Status == EFI_SUCCESS && Interface == *ProtocolInterface) { - // - // If ConsoleHandle is valid and console protocol on this handle also - // also matched, just return. - // - return FALSE; - } - } - - // - // Get all possible consoles device path from EFI variable - // - VarConsole = BdsLibGetVariableAndSize ( - VarName, - &gEfiGlobalVariableGuid, - &DevicePathSize - ); - if (VarConsole == NULL) { - // - // If there is no any console device, just return. - // - return FALSE; - } - - FullDevicePath = VarConsole; - - do { - // - // Check every instance of the console variable - // - Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize); - if (Instance == NULL) { - FreePool (FullDevicePath); - ASSERT (FALSE); - } - - // - // Find console device handle by device path instance - // - Status = gBS->LocateDevicePath ( - ConsoleGuid, - &Instance, - &NewHandle - ); - if (!EFI_ERROR (Status)) { - // - // Get the console protocol on this console device handle - // - Status = gBS->HandleProtocol ( - NewHandle, - ConsoleGuid, - &Interface - ); - if (!EFI_ERROR (Status)) { - // - // Update new console handle in System Table. - // - *ConsoleHandle = NewHandle; - *ProtocolInterface = Interface; - if (CompareGuid (ConsoleGuid, &gEfiSimpleTextOutProtocolGuid)) { - // - // If it is console out device, set console mode 80x25 if current mode is invalid. - // - TextOut = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *) Interface; - if (TextOut->Mode->Mode == -1) { - TextOut->SetMode (TextOut, 0); - } - } - return TRUE; - } - } - - } while (Instance != NULL); - - // - // No any available console devcie found. - // - return FALSE; -} - -/** - This function update console variable based on ConVarName, it can - add or remove one specific console device path from the variable - - @param ConVarName Console related variable name, ConIn, ConOut, - ErrOut. - @param CustomizedConDevicePath The console device path which will be added to - the console variable ConVarName, this parameter - can not be multi-instance. - @param ExclusiveDevicePath The console device path which will be removed - from the console variable ConVarName, this - parameter can not be multi-instance. - - @retval EFI_UNSUPPORTED The added device path is same to the removed one. - @retval EFI_SUCCESS Success add or remove the device path from the - console variable. - -**/ -EFI_STATUS -EFIAPI -BdsLibUpdateConsoleVariable ( - IN CHAR16 *ConVarName, - IN EFI_DEVICE_PATH_PROTOCOL *CustomizedConDevicePath, - IN EFI_DEVICE_PATH_PROTOCOL *ExclusiveDevicePath - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *VarConsole; - UINTN DevicePathSize; - EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; - EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath; - UINT32 Attributes; - - VarConsole = NULL; - DevicePathSize = 0; - - // - // Notes: check the device path point, here should check - // with compare memory - // - if (CustomizedConDevicePath == ExclusiveDevicePath) { - return EFI_UNSUPPORTED; - } - // - // Delete the ExclusiveDevicePath from current default console - // - VarConsole = BdsLibGetVariableAndSize ( - ConVarName, - &gEfiGlobalVariableGuid, - &DevicePathSize - ); - - // - // Initialize NewDevicePath - // - NewDevicePath = VarConsole; - - // - // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it. - // In the end, NewDevicePath is the final device path. - // - if (ExclusiveDevicePath != NULL && VarConsole != NULL) { - NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath); - } - // - // Try to append customized device path to NewDevicePath. - // - if (CustomizedConDevicePath != NULL) { - if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) { - // - // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it. - // - NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath); - // - // In the first check, the default console variable will be _ModuleEntryPoint, - // just append current customized device path - // - TempNewDevicePath = NewDevicePath; - NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath); - if (TempNewDevicePath != NULL) { - FreePool(TempNewDevicePath); - } - } - } - - // - // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV. - // - if (IsNvNeed(ConVarName)) { - // - // ConVarName has NV attribute. - // - Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE; - } else { - // - // ConVarName does not have NV attribute. - // - Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; - } - - // - // Finally, Update the variable of the default console by NewDevicePath - // - DevicePathSize = GetDevicePathSize (NewDevicePath); - Status = SetVariableAndReportStatusCodeOnError ( - ConVarName, - &gEfiGlobalVariableGuid, - Attributes, - DevicePathSize, - NewDevicePath - ); - if ((DevicePathSize == 0) && (Status == EFI_NOT_FOUND)) { - Status = EFI_SUCCESS; - } - - if (VarConsole == NewDevicePath) { - if (VarConsole != NULL) { - FreePool(VarConsole); - } - } else { - if (VarConsole != NULL) { - FreePool(VarConsole); - } - if (NewDevicePath != NULL) { - FreePool(NewDevicePath); - } - } - - return Status; - -} - - -/** - Connect the console device base on the variable ConVarName, if - device path of the ConVarName is multi-instance device path and - anyone of the instances is connected success, then this function - will return success. - If the handle associate with one device path node can not - be created successfully, then still give chance to do the dispatch, - which load the missing drivers if possible.. - - @param ConVarName Console related variable name, ConIn, ConOut, - ErrOut. - - @retval EFI_NOT_FOUND There is not any console devices connected - success - @retval EFI_SUCCESS Success connect any one instance of the console - device path base on the variable ConVarName. - -**/ -EFI_STATUS -EFIAPI -BdsLibConnectConsoleVariable ( - IN CHAR16 *ConVarName - ) -{ - EFI_STATUS Status; - EFI_DEVICE_PATH_PROTOCOL *StartDevicePath; - UINTN VariableSize; - EFI_DEVICE_PATH_PROTOCOL *Instance; - EFI_DEVICE_PATH_PROTOCOL *Next; - EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath; - UINTN Size; - BOOLEAN DeviceExist; - - Status = EFI_SUCCESS; - DeviceExist = FALSE; - - // - // Check if the console variable exist - // - StartDevicePath = BdsLibGetVariableAndSize ( - ConVarName, - &gEfiGlobalVariableGuid, - &VariableSize - ); - if (StartDevicePath == NULL) { - return EFI_UNSUPPORTED; - } - - CopyOfDevicePath = StartDevicePath; - do { - // - // Check every instance of the console variable - // - Instance = GetNextDevicePathInstance (&CopyOfDevicePath, &Size); - if (Instance == NULL) { - FreePool (StartDevicePath); - return EFI_UNSUPPORTED; - } - - Next = Instance; - while (!IsDevicePathEndType (Next)) { - Next = NextDevicePathNode (Next); - } - - SetDevicePathEndNode (Next); - // - // Connect the USB console - // USB console device path is a short-form device path that - // starts with the first element being a USB WWID - // or a USB Class device path - // - if ((DevicePathType (Instance) == MESSAGING_DEVICE_PATH) && - ((DevicePathSubType (Instance) == MSG_USB_CLASS_DP) - || (DevicePathSubType (Instance) == MSG_USB_WWID_DP) - )) { - Status = BdsLibConnectUsbDevByShortFormDP (0xFF, Instance); - if (!EFI_ERROR (Status)) { - DeviceExist = TRUE; - } - } else { - // - // Connect the instance device path - // - Status = BdsLibConnectDevicePath (Instance); - - if (EFI_ERROR (Status)) { - // - // Delete the instance from the console varialbe - // - BdsLibUpdateConsoleVariable (ConVarName, NULL, Instance); - } else { - DeviceExist = TRUE; - } - } - FreePool(Instance); - } while (CopyOfDevicePath != NULL); - - FreePool (StartDevicePath); - - if (!DeviceExist) { - return EFI_NOT_FOUND; - } - - return EFI_SUCCESS; -} - -/** - This function will search every simpletext device in current system, - and make every simpletext device as pertantial console device. - -**/ -VOID -EFIAPI -BdsLibConnectAllConsoles ( - VOID - ) -{ - UINTN Index; - EFI_DEVICE_PATH_PROTOCOL *ConDevicePath; - UINTN HandleCount; - EFI_HANDLE *HandleBuffer; - - Index = 0; - HandleCount = 0; - HandleBuffer = NULL; - ConDevicePath = NULL; - - // - // Update all the console variables - // - gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleTextInProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - - for (Index = 0; Index < HandleCount; Index++) { - gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiDevicePathProtocolGuid, - (VOID **) &ConDevicePath - ); - BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL); - } - - if (HandleBuffer != NULL) { - FreePool(HandleBuffer); - HandleBuffer = NULL; - } - - gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiSimpleTextOutProtocolGuid, - NULL, - &HandleCount, - &HandleBuffer - ); - for (Index = 0; Index < HandleCount; Index++) { - gBS->HandleProtocol ( - HandleBuffer[Index], - &gEfiDevicePathProtocolGuid, - (VOID **) &ConDevicePath - ); - BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL); - BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL); - } - - if (HandleBuffer != NULL) { - FreePool(HandleBuffer); - } - - // - // Connect all console variables - // - BdsLibConnectAllDefaultConsoles (); - -} - -/** - This function will connect console device base on the console - device variable ConIn, ConOut and ErrOut. - - @retval EFI_SUCCESS At least one of the ConIn and ConOut device have - been connected success. - @retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable (). - -**/ -EFI_STATUS -EFIAPI -BdsLibConnectAllDefaultConsoles ( - VOID - ) -{ - EFI_STATUS Status; - BOOLEAN SystemTableUpdated; - - // - // Connect all default console variables - // - - // - // It seems impossible not to have any ConOut device on platform, - // so we check the status here. - // - Status = BdsLibConnectConsoleVariable (L"ConOut"); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Insert the performance probe for Console Out - // - PERF_START (NULL, "ConOut", "BDS", 1); - PERF_END (NULL, "ConOut", "BDS", 0); - - // - // Because possibly the platform is legacy free, in such case, - // ConIn devices (Serial Port and PS2 Keyboard ) does not exist, - // so we need not check the status. - // - BdsLibConnectConsoleVariable (L"ConIn"); - - // - // The _ModuleEntryPoint err out var is legal. - // - BdsLibConnectConsoleVariable (L"ErrOut"); - - SystemTableUpdated = FALSE; - // - // Fill console handles in System Table if no console device assignd. - // - if (UpdateSystemTableConsole (L"ConIn", &gEfiSimpleTextInProtocolGuid, &gST->ConsoleInHandle, (VOID **) &gST->ConIn)) { - SystemTableUpdated = TRUE; - } - if (UpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **) &gST->ConOut)) { - SystemTableUpdated = TRUE; - } - if (UpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **) &gST->StdErr)) { - SystemTableUpdated = TRUE; - } - - if (SystemTableUpdated) { - // - // Update the CRC32 in the EFI System Table header - // - gST->Hdr.CRC32 = 0; - gBS->CalculateCrc32 ( - (UINT8 *) &gST->Hdr, - gST->Hdr.HeaderSize, - &gST->Hdr.CRC32 - ); - } - - return EFI_SUCCESS; - -} - -/** - This function will connect console device except ConIn base on the console - device variable ConOut and ErrOut. - - @retval EFI_SUCCESS At least one of the ConOut device have - been connected success. - @retval EFI_STATUS Return the status of BdsLibConnectConsoleVariable (). - -**/ -EFI_STATUS -EFIAPI -BdsLibConnectAllDefaultConsolesWithOutConIn ( - VOID - ) -{ - EFI_STATUS Status; - BOOLEAN SystemTableUpdated; - - // - // Connect all default console variables except ConIn - // - - // - // It seems impossible not to have any ConOut device on platform, - // so we check the status here. - // - Status = BdsLibConnectConsoleVariable (L"ConOut"); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Insert the performance probe for Console Out - // - PERF_START (NULL, "ConOut", "BDS", 1); - PERF_END (NULL, "ConOut", "BDS", 0); - - // - // The _ModuleEntryPoint err out var is legal. - // - BdsLibConnectConsoleVariable (L"ErrOut"); - - SystemTableUpdated = FALSE; - // - // Fill console handles in System Table if no console device assignd. - // - if (UpdateSystemTableConsole (L"ConOut", &gEfiSimpleTextOutProtocolGuid, &gST->ConsoleOutHandle, (VOID **) &gST->ConOut)) { - SystemTableUpdated = TRUE; - } - if (UpdateSystemTableConsole (L"ErrOut", &gEfiSimpleTextOutProtocolGuid, &gST->StandardErrorHandle, (VOID **) &gST->StdErr)) { - SystemTableUpdated = TRUE; - } - - if (SystemTableUpdated) { - // - // Update the CRC32 in the EFI System Table header - // - gST->Hdr.CRC32 = 0; - gBS->CalculateCrc32 ( - (UINT8 *) &gST->Hdr, - gST->Hdr.HeaderSize, - &gST->Hdr.CRC32 - ); - } - - return EFI_SUCCESS; - -} - -/** - Convert a *.BMP graphics image to a GOP blt buffer. If a NULL Blt buffer - is passed in a GopBlt buffer will be allocated by this routine. If a GopBlt - buffer is passed in it will be used if it is big enough. - - @param BmpImage Pointer to BMP file - @param BmpImageSize Number of bytes in BmpImage - @param GopBlt Buffer containing GOP version of BmpImage. - @param GopBltSize Size of GopBlt in bytes. - @param PixelHeight Height of GopBlt/BmpImage in pixels - @param PixelWidth Width of GopBlt/BmpImage in pixels - - @retval EFI_SUCCESS GopBlt and GopBltSize are returned. - @retval EFI_UNSUPPORTED BmpImage is not a valid *.BMP image - @retval EFI_BUFFER_TOO_SMALL The passed in GopBlt buffer is not big enough. - GopBltSize will contain the required size. - @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate. - -**/ -EFI_STATUS -ConvertBmpToGopBlt ( - IN VOID *BmpImage, - IN UINTN BmpImageSize, - IN OUT VOID **GopBlt, - IN OUT UINTN *GopBltSize, - OUT UINTN *PixelHeight, - OUT UINTN *PixelWidth - ) -{ - UINT8 *Image; - UINT8 *ImageHeader; - BMP_IMAGE_HEADER *BmpHeader; - BMP_COLOR_MAP *BmpColorMap; - EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer; - EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; - UINT64 BltBufferSize; - UINTN Index; - UINTN Height; - UINTN Width; - UINTN ImageIndex; - UINT32 DataSizePerLine; - BOOLEAN IsAllocated; - UINT32 ColorMapNum; - - if (sizeof (BMP_IMAGE_HEADER) > BmpImageSize) { - return EFI_INVALID_PARAMETER; - } - - BmpHeader = (BMP_IMAGE_HEADER *) BmpImage; - - if (BmpHeader->CharB != 'B' || BmpHeader->CharM != 'M') { - return EFI_UNSUPPORTED; - } - - // - // Doesn't support compress. - // - if (BmpHeader->CompressionType != 0) { - return EFI_UNSUPPORTED; - } - - // - // Only support BITMAPINFOHEADER format. - // BITMAPFILEHEADER + BITMAPINFOHEADER = BMP_IMAGE_HEADER - // - if (BmpHeader->HeaderSize != sizeof (BMP_IMAGE_HEADER) - OFFSET_OF(BMP_IMAGE_HEADER, HeaderSize)) { - return EFI_UNSUPPORTED; - } - - // - // The data size in each line must be 4 byte alignment. - // - DataSizePerLine = ((BmpHeader->PixelWidth * BmpHeader->BitPerPixel + 31) >> 3) & (~0x3); - BltBufferSize = MultU64x32 (DataSizePerLine, BmpHeader->PixelHeight); - if (BltBufferSize > (UINT32) ~0) { - return EFI_INVALID_PARAMETER; - } - - if ((BmpHeader->Size != BmpImageSize) || - (BmpHeader->Size < BmpHeader->ImageOffset) || - (BmpHeader->Size - BmpHeader->ImageOffset != BmpHeader->PixelHeight * DataSizePerLine)) { - return EFI_INVALID_PARAMETER; - } - - // - // Calculate Color Map offset in the image. - // - Image = BmpImage; - BmpColorMap = (BMP_COLOR_MAP *) (Image + sizeof (BMP_IMAGE_HEADER)); - if (BmpHeader->ImageOffset < sizeof (BMP_IMAGE_HEADER)) { - return EFI_INVALID_PARAMETER; - } - - if (BmpHeader->ImageOffset > sizeof (BMP_IMAGE_HEADER)) { - switch (BmpHeader->BitPerPixel) { - case 1: - ColorMapNum = 2; - break; - case 4: - ColorMapNum = 16; - break; - case 8: - ColorMapNum = 256; - break; - default: - ColorMapNum = 0; - break; - } - // - // BMP file may has padding data between the bmp header section and the bmp data section. - // - if (BmpHeader->ImageOffset - sizeof (BMP_IMAGE_HEADER) < sizeof (BMP_COLOR_MAP) * ColorMapNum) { - return EFI_INVALID_PARAMETER; - } - } - - // - // Calculate graphics image data address in the image - // - Image = ((UINT8 *) BmpImage) + BmpHeader->ImageOffset; - ImageHeader = Image; - - // - // Calculate the BltBuffer needed size. - // - BltBufferSize = MultU64x32 ((UINT64) BmpHeader->PixelWidth, BmpHeader->PixelHeight); - // - // Ensure the BltBufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow - // - if (BltBufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) { - return EFI_UNSUPPORTED; - } - BltBufferSize = MultU64x32 (BltBufferSize, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); - - IsAllocated = FALSE; - if (*GopBlt == NULL) { - // - // GopBlt is not allocated by caller. - // - *GopBltSize = (UINTN) BltBufferSize; - *GopBlt = AllocatePool (*GopBltSize); - IsAllocated = TRUE; - if (*GopBlt == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } else { - // - // GopBlt has been allocated by caller. - // - if (*GopBltSize < (UINTN) BltBufferSize) { - *GopBltSize = (UINTN) BltBufferSize; - return EFI_BUFFER_TOO_SMALL; - } - } - - *PixelWidth = BmpHeader->PixelWidth; - *PixelHeight = BmpHeader->PixelHeight; - - // - // Convert image from BMP to Blt buffer format - // - BltBuffer = *GopBlt; - for (Height = 0; Height < BmpHeader->PixelHeight; Height++) { - Blt = &BltBuffer[(BmpHeader->PixelHeight - Height - 1) * BmpHeader->PixelWidth]; - for (Width = 0; Width < BmpHeader->PixelWidth; Width++, Image++, Blt++) { - switch (BmpHeader->BitPerPixel) { - case 1: - // - // Convert 1-bit (2 colors) BMP to 24-bit color - // - for (Index = 0; Index < 8 && Width < BmpHeader->PixelWidth; Index++) { - Blt->Red = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Red; - Blt->Green = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Green; - Blt->Blue = BmpColorMap[((*Image) >> (7 - Index)) & 0x1].Blue; - Blt++; - Width++; - } - - Blt--; - Width--; - break; - - case 4: - // - // Convert 4-bit (16 colors) BMP Palette to 24-bit color - // - Index = (*Image) >> 4; - Blt->Red = BmpColorMap[Index].Red; - Blt->Green = BmpColorMap[Index].Green; - Blt->Blue = BmpColorMap[Index].Blue; - if (Width < (BmpHeader->PixelWidth - 1)) { - Blt++; - Width++; - Index = (*Image) & 0x0f; - Blt->Red = BmpColorMap[Index].Red; - Blt->Green = BmpColorMap[Index].Green; - Blt->Blue = BmpColorMap[Index].Blue; - } - break; - - case 8: - // - // Convert 8-bit (256 colors) BMP Palette to 24-bit color - // - Blt->Red = BmpColorMap[*Image].Red; - Blt->Green = BmpColorMap[*Image].Green; - Blt->Blue = BmpColorMap[*Image].Blue; - break; - - case 24: - // - // It is 24-bit BMP. - // - Blt->Blue = *Image++; - Blt->Green = *Image++; - Blt->Red = *Image; - break; - - default: - // - // Other bit format BMP is not supported. - // - if (IsAllocated) { - FreePool (*GopBlt); - *GopBlt = NULL; - } - return EFI_UNSUPPORTED; - break; - }; - - } - - ImageIndex = (UINTN) (Image - ImageHeader); - if ((ImageIndex % 4) != 0) { - // - // Bmp Image starts each row on a 32-bit boundary! - // - Image = Image + (4 - (ImageIndex % 4)); - } - } - - return EFI_SUCCESS; -} - -/** - Use SystemTable Conout to stop video based Simple Text Out consoles from going - to the video device. Put up LogoFile on every video device that is a console. - - @param[in] LogoFile File name of logo to display on the center of the screen. - - @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed. - @retval EFI_UNSUPPORTED Logo not found - -**/ -EFI_STATUS -EFIAPI -EnableQuietBoot ( - IN EFI_GUID *LogoFile - ) -{ - EFI_STATUS Status; - EFI_OEM_BADGING_PROTOCOL *Badging; - UINT32 SizeOfX; - UINT32 SizeOfY; - INTN DestX; - INTN DestY; - UINT8 *ImageData; - UINTN ImageSize; - UINTN BltSize; - UINT32 Instance; - EFI_BADGING_FORMAT Format; - EFI_BADGING_DISPLAY_ATTRIBUTE Attribute; - UINTN CoordinateX; - UINTN CoordinateY; - UINTN Height; - UINTN Width; - EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; - EFI_UGA_DRAW_PROTOCOL *UgaDraw; - UINT32 ColorDepth; - UINT32 RefreshRate; - EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; - EFI_BOOT_LOGO_PROTOCOL *BootLogo; - UINTN NumberOfLogos; - EFI_GRAPHICS_OUTPUT_BLT_PIXEL *LogoBlt; - UINTN LogoDestX; - UINTN LogoDestY; - UINTN LogoHeight; - UINTN LogoWidth; - UINTN NewDestX; - UINTN NewDestY; - UINTN NewHeight; - UINTN NewWidth; - UINT64 BufferSize; - - UgaDraw = NULL; - // - // Try to open GOP first - // - Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID **) &GraphicsOutput); - if (EFI_ERROR (Status) && FeaturePcdGet (PcdUgaConsumeSupport)) { - GraphicsOutput = NULL; - // - // Open GOP failed, try to open UGA - // - Status = gBS->HandleProtocol (gST->ConsoleOutHandle, &gEfiUgaDrawProtocolGuid, (VOID **) &UgaDraw); - } - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - // - // Try to open Boot Logo Protocol. - // - BootLogo = NULL; - gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo); - - // - // Erase Cursor from screen - // - gST->ConOut->EnableCursor (gST->ConOut, FALSE); - - Badging = NULL; - Status = gBS->LocateProtocol (&gEfiOEMBadgingProtocolGuid, NULL, (VOID **) &Badging); - - if (GraphicsOutput != NULL) { - SizeOfX = GraphicsOutput->Mode->Info->HorizontalResolution; - SizeOfY = GraphicsOutput->Mode->Info->VerticalResolution; - - } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { - Status = UgaDraw->GetMode (UgaDraw, &SizeOfX, &SizeOfY, &ColorDepth, &RefreshRate); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - } else { - return EFI_UNSUPPORTED; - } - - Blt = NULL; - NumberOfLogos = 0; - LogoDestX = 0; - LogoDestY = 0; - LogoHeight = 0; - LogoWidth = 0; - NewDestX = 0; - NewDestY = 0; - NewHeight = 0; - NewWidth = 0; - Instance = 0; - while (1) { - ImageData = NULL; - ImageSize = 0; - - if (Badging != NULL) { - // - // Get image from OEMBadging protocol. - // - Status = Badging->GetImage ( - Badging, - &Instance, - &Format, - &ImageData, - &ImageSize, - &Attribute, - &CoordinateX, - &CoordinateY - ); - if (EFI_ERROR (Status)) { - goto Done; - } - - // - // Currently only support BMP format. - // - if (Format != EfiBadgingFormatBMP) { - if (ImageData != NULL) { - FreePool (ImageData); - } - continue; - } - } else { - // - // Get the specified image from FV. - // - Status = GetSectionFromAnyFv (LogoFile, EFI_SECTION_RAW, 0, (VOID **) &ImageData, &ImageSize); - if (EFI_ERROR (Status)) { - return EFI_UNSUPPORTED; - } - - CoordinateX = 0; - CoordinateY = 0; - if (!FeaturePcdGet(PcdBootlogoOnlyEnable)) { - Attribute = EfiBadgingDisplayAttributeCenter; - } else { - Attribute = EfiBadgingDisplayAttributeCustomized; - } - } - - if (Blt != NULL) { - FreePool (Blt); - } - Blt = NULL; - Status = ConvertBmpToGopBlt ( - ImageData, - ImageSize, - (VOID **) &Blt, - &BltSize, - &Height, - &Width - ); - if (EFI_ERROR (Status)) { - FreePool (ImageData); - - if (Badging == NULL) { - return Status; - } else { - continue; - } - } - - // - // Calculate the display position according to Attribute. - // - switch (Attribute) { - case EfiBadgingDisplayAttributeLeftTop: - DestX = CoordinateX; - DestY = CoordinateY; - break; - - case EfiBadgingDisplayAttributeCenterTop: - DestX = (SizeOfX - Width) / 2; - DestY = CoordinateY; - break; - - case EfiBadgingDisplayAttributeRightTop: - DestX = (SizeOfX - Width - CoordinateX); - DestY = CoordinateY;; - break; - - case EfiBadgingDisplayAttributeCenterRight: - DestX = (SizeOfX - Width - CoordinateX); - DestY = (SizeOfY - Height) / 2; - break; - - case EfiBadgingDisplayAttributeRightBottom: - DestX = (SizeOfX - Width - CoordinateX); - DestY = (SizeOfY - Height - CoordinateY); - break; - - case EfiBadgingDisplayAttributeCenterBottom: - DestX = (SizeOfX - Width) / 2; - DestY = (SizeOfY - Height - CoordinateY); - break; - - case EfiBadgingDisplayAttributeLeftBottom: - DestX = CoordinateX; - DestY = (SizeOfY - Height - CoordinateY); - break; - - case EfiBadgingDisplayAttributeCenterLeft: - DestX = CoordinateX; - DestY = (SizeOfY - Height) / 2; - break; - - case EfiBadgingDisplayAttributeCenter: - DestX = (SizeOfX - Width) / 2; - DestY = (SizeOfY - Height) / 2; - break; - - case EfiBadgingDisplayAttributeCustomized: - DestX = (SizeOfX - Width) / 2; - DestY = ((SizeOfY * 382) / 1000) - Height / 2; - break; - - default: - DestX = CoordinateX; - DestY = CoordinateY; - break; - } - - if ((DestX >= 0) && (DestY >= 0)) { - if (GraphicsOutput != NULL) { - Status = GraphicsOutput->Blt ( - GraphicsOutput, - Blt, - EfiBltBufferToVideo, - 0, - 0, - (UINTN) DestX, - (UINTN) DestY, - Width, - Height, - Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) - ); - } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { - Status = UgaDraw->Blt ( - UgaDraw, - (EFI_UGA_PIXEL *) Blt, - EfiUgaBltBufferToVideo, - 0, - 0, - (UINTN) DestX, - (UINTN) DestY, - Width, - Height, - Width * sizeof (EFI_UGA_PIXEL) - ); - } else { - Status = EFI_UNSUPPORTED; - } - - // - // Report displayed Logo information. - // - if (!EFI_ERROR (Status)) { - NumberOfLogos++; - - if (LogoWidth == 0) { - // - // The first Logo. - // - LogoDestX = (UINTN) DestX; - LogoDestY = (UINTN) DestY; - LogoWidth = Width; - LogoHeight = Height; - } else { - // - // Merge new logo with old one. - // - NewDestX = MIN ((UINTN) DestX, LogoDestX); - NewDestY = MIN ((UINTN) DestY, LogoDestY); - NewWidth = MAX ((UINTN) DestX + Width, LogoDestX + LogoWidth) - NewDestX; - NewHeight = MAX ((UINTN) DestY + Height, LogoDestY + LogoHeight) - NewDestY; - - LogoDestX = NewDestX; - LogoDestY = NewDestY; - LogoWidth = NewWidth; - LogoHeight = NewHeight; - } - } - } - - FreePool (ImageData); - - if (Badging == NULL) { - break; - } - } - -Done: - if (BootLogo == NULL || NumberOfLogos == 0) { - // - // No logo displayed. - // - if (Blt != NULL) { - FreePool (Blt); - } - - return Status; - } - - // - // Advertise displayed Logo information. - // - if (NumberOfLogos == 1) { - // - // Only one logo displayed, use its Blt buffer directly for BootLogo protocol. - // - LogoBlt = Blt; - Status = EFI_SUCCESS; - } else { - // - // More than one Logo displayed, get merged BltBuffer using VideoToBuffer operation. - // - if (Blt != NULL) { - FreePool (Blt); - } - - // - // Ensure the LogoHeight * LogoWidth doesn't overflow - // - if (LogoHeight > DivU64x64Remainder ((UINTN) ~0, LogoWidth, NULL)) { - return EFI_UNSUPPORTED; - } - BufferSize = MultU64x64 (LogoWidth, LogoHeight); - - // - // Ensure the BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) doesn't overflow - // - if (BufferSize > DivU64x32 ((UINTN) ~0, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) { - return EFI_UNSUPPORTED; - } - - LogoBlt = AllocateZeroPool ((UINTN)BufferSize * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); - if (LogoBlt == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - if (GraphicsOutput != NULL) { - Status = GraphicsOutput->Blt ( - GraphicsOutput, - LogoBlt, - EfiBltVideoToBltBuffer, - LogoDestX, - LogoDestY, - 0, - 0, - LogoWidth, - LogoHeight, - LogoWidth * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL) - ); - } else if (UgaDraw != NULL && FeaturePcdGet (PcdUgaConsumeSupport)) { - Status = UgaDraw->Blt ( - UgaDraw, - (EFI_UGA_PIXEL *) LogoBlt, - EfiUgaVideoToBltBuffer, - LogoDestX, - LogoDestY, - 0, - 0, - LogoWidth, - LogoHeight, - LogoWidth * sizeof (EFI_UGA_PIXEL) - ); - } else { - Status = EFI_UNSUPPORTED; - } - } - - if (!EFI_ERROR (Status)) { - BootLogo->SetBootLogo (BootLogo, LogoBlt, LogoDestX, LogoDestY, LogoWidth, LogoHeight); - } - FreePool (LogoBlt); - - return Status; -} - -/** - Use SystemTable Conout to turn on video based Simple Text Out consoles. The - Simple Text Out screens will now be synced up with all non video output devices - - @retval EFI_SUCCESS UGA devices are back in text mode and synced up. - -**/ -EFI_STATUS -EFIAPI -DisableQuietBoot ( - VOID - ) -{ - - // - // Enable Cursor on Screen - // - gST->ConOut->EnableCursor (gST->ConOut, TRUE); - return EFI_SUCCESS; -} - diff --git a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c b/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c deleted file mode 100644 index 29854563f5..0000000000 --- a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/BdsMisc.c +++ /dev/null @@ -1,1589 +0,0 @@ -/** @file - Misc BDS library function - -Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which 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 "InternalBdsLib.h" - - -#define MAX_STRING_LEN 200 - -BOOLEAN mFeaturerSwitch = TRUE; -BOOLEAN mResetRequired = FALSE; - -extern UINT16 gPlatformBootTimeOutDefault; - -/** - The function will go through the driver option link list, load and start - every driver the driver option device path point to. - - @param BdsDriverLists The header of the current driver option link list - -**/ -VOID -EFIAPI -BdsLibLoadDrivers ( - IN LIST_ENTRY *BdsDriverLists - ) -{ - EFI_STATUS Status; - LIST_ENTRY *Link; - BDS_COMMON_OPTION *Option; - EFI_HANDLE ImageHandle; - EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; - UINTN ExitDataSize; - CHAR16 *ExitData; - BOOLEAN ReconnectAll; - - ReconnectAll = FALSE; - - // - // Process the driver option - // - for (Link = BdsDriverLists->ForwardLink; Link != BdsDriverLists; Link = Link->ForwardLink) { - Option = CR (Link, BDS_COMMON_OPTION, Link, BDS_LOAD_OPTION_SIGNATURE); - - // - // If a load option is not marked as LOAD_OPTION_ACTIVE, - // the boot manager will not automatically load the option. - // - if (!IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_ACTIVE)) { - continue; - } - - // - // If a driver load option is marked as LOAD_OPTION_FORCE_RECONNECT, - // then all of the EFI drivers in the system will be disconnected and - // reconnected after the last driver load option is processed. - // - if (IS_LOAD_OPTION_TYPE (Option->Attribute, LOAD_OPTION_FORCE_RECONNECT)) { - ReconnectAll = TRUE; - } - - // - // Make sure the driver path is connected. - // - BdsLibConnectDevicePath (Option->DevicePath); - - // - // Load and start the image that Driver#### describes - // - Status = gBS->LoadImage ( - FALSE, - gImageHandle, - Option->DevicePath, - NULL, - 0, - &ImageHandle - ); - - if (!EFI_ERROR (Status)) { - gBS->HandleProtocol (ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &ImageInfo); - - // - // Verify whether this image is a driver, if not, - // exit it and continue to parse next load option - // - if (ImageInfo->ImageCodeType != EfiBootServicesCode && ImageInfo->ImageCodeType != EfiRuntimeServicesCode) { - gBS->Exit (ImageHandle, EFI_INVALID_PARAMETER, 0, NULL); - continue; - } - - if (Option->LoadOptionsSize != 0) { - ImageInfo->LoadOptionsSize = Option->LoadOptionsSize; - ImageInfo->LoadOptions = Option->LoadOptions; - } - // - // Before calling the image, enable the Watchdog Timer for - // the 5 Minute period - // - gBS->SetWatchdogTimer (5 * 60, 0x0000, 0x00, NULL); - - Status = gBS->StartImage (ImageHandle, &ExitDataSize, &ExitData); - DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Driver Return Status = %r\n", Status)); - - // - // Clear the Watchdog Timer after the image returns - // - gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL); - } - } - - // - // Process the LOAD_OPTION_FORCE_RECONNECT driver option - // - if (ReconnectAll) { - BdsLibDisconnectAllEfi (); - BdsLibConnectAll (); - } - -} - -/** - Get the Option Number that does not used. - Try to locate the specific option variable one by one utile find a free number. - - @param VariableName Indicate if the boot#### or driver#### option - - @return The Minimal Free Option Number - -**/ -UINT16 -BdsLibGetFreeOptionNumber ( - IN CHAR16 *VariableName - ) -{ - UINTN Index; - CHAR16 StrTemp[10]; - UINT16 *OptionBuffer; - UINTN OptionSize; - - // - // Try to find the minimum free number from 0, 1, 2, 3.... - // - Index = 0; - do { - if (*VariableName == 'B') { - UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Boot%04x", Index); - } else { - UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Driver%04x", Index); - } - // - // try if the option number is used - // - OptionBuffer = BdsLibGetVariableAndSize ( - StrTemp, - &gEfiGlobalVariableGuid, - &OptionSize - ); - if (OptionBuffer == NULL) { - break; - } - FreePool(OptionBuffer); - Index++; - } while (TRUE); - - return ((UINT16) Index); -} - - -/** - This function will register the new boot#### or driver#### option base on - the VariableName. The new registered boot#### or driver#### will be linked - to BdsOptionList and also update to the VariableName. After the boot#### or - driver#### updated, the BootOrder or DriverOrder will also be updated. - - @param BdsOptionList The header of the boot#### or driver#### link list - @param DevicePath The device path which the boot#### or driver#### - option present - @param String The description of the boot#### or driver#### - @param VariableName Indicate if the boot#### or driver#### option - - @retval EFI_SUCCESS The boot#### or driver#### have been success - registered - @retval EFI_STATUS Return the status of gRT->SetVariable (). - -**/ -EFI_STATUS -EFIAPI -BdsLibRegisterNewOption ( - IN LIST_ENTRY *BdsOptionList, - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN CHAR16 *String, - IN CHAR16 *VariableName - ) -{ - EFI_STATUS Status; - UINTN Index; - UINT16 RegisterOptionNumber; - UINT16 *TempOptionPtr; - UINTN TempOptionSize; - UINT16 *OptionOrderPtr; - VOID *OptionPtr; - UINTN OptionSize; - UINT8 *TempPtr; - EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath; - CHAR16 *Description; - CHAR16 OptionName[10]; - BOOLEAN UpdateDescription; - UINT16 BootOrderEntry; - UINTN OrderItemNum; - - if (DevicePath == NULL) { - return EFI_INVALID_PARAMETER; - } - - OptionPtr = NULL; - OptionSize = 0; - TempPtr = NULL; - OptionDevicePath = NULL; - Description = NULL; - OptionOrderPtr = NULL; - UpdateDescription = FALSE; - Status = EFI_SUCCESS; - ZeroMem (OptionName, sizeof (OptionName)); - - TempOptionSize = 0; - TempOptionPtr = BdsLibGetVariableAndSize ( - VariableName, - &gEfiGlobalVariableGuid, - &TempOptionSize - ); - // - // Compare with current option variable if the previous option is set in global variable. - // - for (Index = 0; Index < TempOptionSize / sizeof (UINT16); Index++) { - // - // TempOptionPtr must not be NULL if we have non-zero TempOptionSize. - // - ASSERT (TempOptionPtr != NULL); - - if (*VariableName == 'B') { - UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", TempOptionPtr[Index]); - } else { - UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", TempOptionPtr[Index]); - } - - OptionPtr = BdsLibGetVariableAndSize ( - OptionName, - &gEfiGlobalVariableGuid, - &OptionSize - ); - if (OptionPtr == NULL) { - continue; - } - - // - // Validate the variable. - // - if (!ValidateOption(OptionPtr, OptionSize)) { - FreePool(OptionPtr); - continue; - } - - TempPtr = OptionPtr; - TempPtr += sizeof (UINT32) + sizeof (UINT16); - Description = (CHAR16 *) TempPtr; - TempPtr += StrSize ((CHAR16 *) TempPtr); - OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr; - - // - // Notes: the description may will change base on the GetStringToken - // - if (CompareMem (OptionDevicePath, DevicePath, GetDevicePathSize (OptionDevicePath)) == 0) { - if (CompareMem (Description, String, StrSize (Description)) == 0) { - // - // Got the option, so just return - // - FreePool (OptionPtr); - FreePool (TempOptionPtr); - return EFI_SUCCESS; - } else { - // - // Option description changed, need update. - // - UpdateDescription = TRUE; - FreePool (OptionPtr); - break; - } - } - - FreePool (OptionPtr); - } - - OptionSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (String); - OptionSize += GetDevicePathSize (DevicePath); - OptionPtr = AllocateZeroPool (OptionSize); - ASSERT (OptionPtr != NULL); - - TempPtr = OptionPtr; - *(UINT32 *) TempPtr = LOAD_OPTION_ACTIVE; - TempPtr += sizeof (UINT32); - *(UINT16 *) TempPtr = (UINT16) GetDevicePathSize (DevicePath); - TempPtr += sizeof (UINT16); - CopyMem (TempPtr, String, StrSize (String)); - TempPtr += StrSize (String); - CopyMem (TempPtr, DevicePath, GetDevicePathSize (DevicePath)); - - if (UpdateDescription) { - // - // The number in option#### to be updated. - // In this case, we must have non-NULL TempOptionPtr. - // - ASSERT (TempOptionPtr != NULL); - RegisterOptionNumber = TempOptionPtr[Index]; - } else { - // - // The new option#### number - // - RegisterOptionNumber = BdsLibGetFreeOptionNumber(VariableName); - } - - if (*VariableName == 'B') { - UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", RegisterOptionNumber); - } else { - UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", RegisterOptionNumber); - } - - Status = gRT->SetVariable ( - OptionName, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, - OptionSize, - OptionPtr - ); - // - // Return if only need to update a changed description or fail to set option. - // - if (EFI_ERROR (Status) || UpdateDescription) { - FreePool (OptionPtr); - if (TempOptionPtr != NULL) { - FreePool (TempOptionPtr); - } - return Status; - } - - FreePool (OptionPtr); - - // - // Update the option order variable - // - - // - // If no option order - // - if (TempOptionSize == 0) { - BootOrderEntry = 0; - Status = gRT->SetVariable ( - VariableName, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, - sizeof (UINT16), - &BootOrderEntry - ); - if (TempOptionPtr != NULL) { - FreePool (TempOptionPtr); - } - return Status; - } - - // - // TempOptionPtr must not be NULL if TempOptionSize is not zero. - // - ASSERT (TempOptionPtr != NULL); - // - // Append the new option number to the original option order - // - OrderItemNum = (TempOptionSize / sizeof (UINT16)) + 1 ; - OptionOrderPtr = AllocateZeroPool ( OrderItemNum * sizeof (UINT16)); - ASSERT (OptionOrderPtr!= NULL); - CopyMem (OptionOrderPtr, TempOptionPtr, (OrderItemNum - 1) * sizeof (UINT16)); - - OptionOrderPtr[Index] = RegisterOptionNumber; - - Status = gRT->SetVariable ( - VariableName, - &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, - OrderItemNum * sizeof (UINT16), - OptionOrderPtr - ); - FreePool (TempOptionPtr); - FreePool (OptionOrderPtr); - - return Status; -} - -/** - Returns the size of a device path in bytes. - - This function returns the size, in bytes, of the device path data structure - specified by DevicePath including the end of device path node. If DevicePath - is NULL, then 0 is returned. If the length of the device path is bigger than - MaxSize, also return 0 to indicate this is an invalidate device path. - - @param DevicePath A pointer to a device path data structure. - @param MaxSize Max valid device path size. If big than this size, - return error. - - @retval 0 An invalid device path. - @retval Others The size of a device path in bytes. - -**/ -UINTN -GetDevicePathSizeEx ( - IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, - IN UINTN MaxSize - ) -{ - UINTN Size; - UINTN NodeSize; - - if (DevicePath == NULL) { - return 0; - } - - // - // Search for the end of the device path structure - // - Size = 0; - while (!IsDevicePathEnd (DevicePath)) { - NodeSize = DevicePathNodeLength (DevicePath); - if (NodeSize < END_DEVICE_PATH_LENGTH) { - return 0; - } - Size += NodeSize; - if (Size > MaxSize) { - return 0; - } - DevicePath = NextDevicePathNode (DevicePath); - } - Size += DevicePathNodeLength (DevicePath); - if (Size > MaxSize) { - return 0; - } - - return Size; -} - -/** - Returns the length of a Null-terminated Unicode string. If the length is - bigger than MaxStringLen, return length 0 to indicate that this is an - invalidate string. - - This function returns the byte length of Unicode characters in the Null-terminated - Unicode string specified by String. - - If String is NULL, then ASSERT(). - If String is not aligned on a 16-bit boundary, then ASSERT(). - - @param String A pointer to a Null-terminated Unicode string. - @param MaxStringLen Max string len in this string. - - @retval 0 An invalid string. - @retval Others The length of String. - -**/ -UINTN -StrSizeEx ( - IN CONST CHAR16 *String, - IN UINTN MaxStringLen - ) -{ - UINTN Length; - - ASSERT (String != NULL && MaxStringLen != 0); - ASSERT (((UINTN) String & BIT0) == 0); - - for (Length = 0; *String != L'\0' && MaxStringLen != Length; String++, Length+=2); - - if (*String != L'\0' && MaxStringLen == Length) { - return 0; - } - - return Length + 2; -} - -/** - Validate the EFI Boot#### variable (VendorGuid/Name) - - @param Variable Boot#### variable data. - @param VariableSize Returns the size of the EFI variable that was read - - @retval TRUE The variable data is correct. - @retval FALSE The variable data is corrupted. - -**/ -BOOLEAN -ValidateOption ( - UINT8 *Variable, - UINTN VariableSize - ) -{ - UINT16 FilePathSize; - UINT8 *TempPtr; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - UINTN TempSize; - - if (VariableSize <= sizeof (UINT16) + sizeof (UINT32)) { - return FALSE; - } - - // - // Skip the option attribute - // - TempPtr = Variable; - TempPtr += sizeof (UINT32); - - // - // Get the option's device path size - // - FilePathSize = *(UINT16 *) TempPtr; - TempPtr += sizeof (UINT16); - - // - // Get the option's description string size - // - TempSize = StrSizeEx ((CHAR16 *) TempPtr, VariableSize - sizeof (UINT16) - sizeof (UINT32)); - TempPtr += TempSize; - - // - // Get the option's device path - // - DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr; - TempPtr += FilePathSize; - - // - // Validation boot option variable. - // - if ((FilePathSize == 0) || (TempSize == 0)) { - return FALSE; - } - - if (TempSize + FilePathSize + sizeof (UINT16) + sizeof (UINT32) > VariableSize) { - return FALSE; - } - - return (BOOLEAN) (GetDevicePathSizeEx (DevicePath, FilePathSize) != 0); -} - -/** - Convert a single character to number. - It assumes the input Char is in the scope of L'0' ~ L'9' and L'A' ~ L'F' - - @param Char The input char which need to change to a hex number. - -**/ -UINTN -CharToUint ( - IN CHAR16 Char - ) -{ - if ((Char >= L'0') && (Char <= L'9')) { - return (UINTN) (Char - L'0'); - } - - if ((Char >= L'A') && (Char <= L'F')) { - return (UINTN) (Char - L'A' + 0xA); - } - - ASSERT (FALSE); - return 0; -} - -/** - Build the boot#### or driver#### option from the VariableName, the - build boot#### or driver#### will also be linked to BdsCommonOptionList. - - @param BdsCommonOptionList The header of the boot#### or driver#### option - link list - @param VariableName EFI Variable name indicate if it is boot#### or - driver#### - - @retval BDS_COMMON_OPTION Get the option just been created - @retval NULL Failed to get the new option - -**/ -BDS_COMMON_OPTION * -EFIAPI -BdsLibVariableToOption ( - IN OUT LIST_ENTRY *BdsCommonOptionList, - IN CHAR16 *VariableName - ) -{ - UINT32 Attribute; - UINT16 FilePathSize; - UINT8 *Variable; - UINT8 *TempPtr; - UINTN VariableSize; - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - BDS_COMMON_OPTION *Option; - VOID *LoadOptions; - UINT32 LoadOptionsSize; - CHAR16 *Description; - UINT8 NumOff; - - // - // Read the variable. We will never free this data. - // - Variable = BdsLibGetVariableAndSize ( - VariableName, - &gEfiGlobalVariableGuid, - &VariableSize - ); - if (Variable == NULL) { - return NULL; - } - - // - // Validate Boot#### variable data. - // - if (!ValidateOption(Variable, VariableSize)) { - FreePool (Variable); - return NULL; - } - - // - // Notes: careful defined the variable of Boot#### or - // Driver####, consider use some macro to abstract the code - // - // - // Get the option attribute - // - TempPtr = Variable; - Attribute = *(UINT32 *) Variable; - TempPtr += sizeof (UINT32); - - // - // Get the option's device path size - // - FilePathSize = *(UINT16 *) TempPtr; - TempPtr += sizeof (UINT16); - - // - // Get the option's description string - // - Description = (CHAR16 *) TempPtr; - - // - // Get the option's description string size - // - TempPtr += StrSize((CHAR16 *) TempPtr); - - // - // Get the option's device path - // - DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) TempPtr; - TempPtr += FilePathSize; - - // - // Get load opion data. - // - LoadOptions = TempPtr; - LoadOptionsSize = (UINT32) (VariableSize - (UINTN) (TempPtr - Variable)); - - // - // The Console variables may have multiple device paths, so make - // an Entry for each one. - // - Option = AllocateZeroPool (sizeof (BDS_COMMON_OPTION)); - if (Option == NULL) { - FreePool (Variable); - return NULL; - } - - Option->Signature = BDS_LOAD_OPTION_SIGNATURE; - Option->DevicePath = AllocateZeroPool (GetDevicePathSize (DevicePath)); - ASSERT(Option->DevicePath != NULL); - CopyMem (Option->DevicePath, DevicePath, GetDevicePathSize (DevicePath)); - - Option->Attribute = Attribute; - Option->Description = AllocateZeroPool (StrSize (Description)); - ASSERT(Option->Description != NULL); - CopyMem (Option->Description, Description, StrSize (Description)); - - Option->LoadOptions = AllocateZeroPool (LoadOptionsSize); - ASSERT(Option->LoadOptions != NULL); - CopyMem (Option->LoadOptions, LoadOptions, LoadOptionsSize); - Option->LoadOptionsSize = LoadOptionsSize; - - // - // Get the value from VariableName Unicode string - // since the ISO standard assumes ASCII equivalent abbreviations, we can be safe in converting this - // Unicode stream to ASCII without any loss in meaning. - // - if (*VariableName == 'B') { - NumOff = (UINT8) (sizeof (L"Boot") / sizeof (CHAR16) - 1); - Option->BootCurrent = (UINT16) (CharToUint (VariableName[NumOff+0]) * 0x1000) - + (UINT16) (CharToUint (VariableName[NumOff+1]) * 0x100) - + (UINT16) (CharToUint (VariableName[NumOff+2]) * 0x10) - + (UINT16) (CharToUint (VariableName[NumOff+3]) * 0x1); - } - InsertTailList (BdsCommonOptionList, &Option->Link); - FreePool (Variable); - return Option; -} - -/** - Process BootOrder, or DriverOrder variables, by calling - BdsLibVariableToOption () for each UINT16 in the variables. - - @param BdsCommonOptionList The header of the option list base on variable - VariableName - @param VariableName EFI Variable name indicate the BootOrder or - DriverOrder - - @retval EFI_SUCCESS Success create the boot option or driver option - list - @retval EFI_OUT_OF_RESOURCES Failed to get the boot option or driver option list - -**/ -EFI_STATUS -EFIAPI -BdsLibBuildOptionFromVar ( - IN LIST_ENTRY *BdsCommonOptionList, - IN CHAR16 *VariableName - ) -{ - UINT16 *OptionOrder; - UINTN OptionOrderSize; - UINTN Index; - BDS_COMMON_OPTION *Option; - CHAR16 OptionName[20]; - - // - // Zero Buffer in order to get all BOOT#### variables - // - ZeroMem (OptionName, sizeof (OptionName)); - - // - // Read the BootOrder, or DriverOrder variable. - // - OptionOrder = BdsLibGetVariableAndSize ( - VariableName, - &gEfiGlobalVariableGuid, - &OptionOrderSize - ); - if (OptionOrder == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - for (Index = 0; Index < OptionOrderSize / sizeof (UINT16); Index++) { - if (*VariableName == 'B') { - UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", OptionOrder[Index]); - } else { - UnicodeSPrint (OptionName, sizeof (OptionName), L"Driver%04x", OptionOrder[Index]); - } - - Option = BdsLibVariableToOption (BdsCommonOptionList, OptionName); - if (Option != NULL) { - Option->BootCurrent = OptionOrder[Index]; - } - } - - FreePool (OptionOrder); - - return EFI_SUCCESS; -} - -/** - Get boot mode by looking up configuration table and parsing HOB list - - @param BootMode Boot mode from PEI handoff HOB. - - @retval EFI_SUCCESS Successfully get boot mode - -**/ -EFI_STATUS -EFIAPI -BdsLibGetBootMode ( - OUT EFI_BOOT_MODE *BootMode - ) -{ - *BootMode = GetBootModeHob (); - - return EFI_SUCCESS; -} - -/** - Read the EFI variable (VendorGuid/Name) and return a dynamically allocated - buffer, and the size of the buffer. If failure return NULL. - - @param Name String part of EFI variable name - @param VendorGuid GUID part of EFI variable name - @param VariableSize Returns the size of the EFI variable that was read - - @return Dynamically allocated memory that contains a copy of the EFI variable - Caller is responsible freeing the buffer. - @retval NULL Variable was not read - -**/ -VOID * -EFIAPI -BdsLibGetVariableAndSize ( - IN CHAR16 *Name, - IN EFI_GUID *VendorGuid, - OUT UINTN *VariableSize - ) -{ - EFI_STATUS Status; - UINTN BufferSize; - VOID *Buffer; - - Buffer = NULL; - - // - // Pass in a zero size buffer to find the required buffer size. - // - BufferSize = 0; - Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer); - if (Status == EFI_BUFFER_TOO_SMALL) { - // - // Allocate the buffer to return - // - Buffer = AllocateZeroPool (BufferSize); - if (Buffer == NULL) { - *VariableSize = 0; - return NULL; - } - // - // Read variable into the allocated buffer. - // - Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer); - if (EFI_ERROR (Status)) { - FreePool (Buffer); - BufferSize = 0; - Buffer = NULL; - } - } - - ASSERT (((Buffer == NULL) && (BufferSize == 0)) || - ((Buffer != NULL) && (BufferSize != 0)) - ); - *VariableSize = BufferSize; - return Buffer; -} - -/** - Delete the instance in Multi which matches partly with Single instance - - @param Multi A pointer to a multi-instance device path data - structure. - @param Single A pointer to a single-instance device path data - structure. - - @return This function will remove the device path instances in Multi which partly - match with the Single, and return the result device path. If there is no - remaining device path as a result, this function will return NULL. - -**/ -EFI_DEVICE_PATH_PROTOCOL * -EFIAPI -BdsLibDelPartMatchInstance ( - IN EFI_DEVICE_PATH_PROTOCOL *Multi, - IN EFI_DEVICE_PATH_PROTOCOL *Single - ) -{ - EFI_DEVICE_PATH_PROTOCOL *Instance; - EFI_DEVICE_PATH_PROTOCOL *NewDevicePath; - EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath; - UINTN InstanceSize; - UINTN SingleDpSize; - UINTN Size; - - NewDevicePath = NULL; - TempNewDevicePath = NULL; - - if (Multi == NULL || Single == NULL) { - return Multi; - } - - Instance = GetNextDevicePathInstance (&Multi, &InstanceSize); - SingleDpSize = GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH; - InstanceSize -= END_DEVICE_PATH_LENGTH; - - while (Instance != NULL) { - - Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize; - - if ((CompareMem (Instance, Single, Size) != 0)) { - // - // Append the device path instance which does not match with Single - // - TempNewDevicePath = NewDevicePath; - NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance); - if (TempNewDevicePath != NULL) { - FreePool(TempNewDevicePath); - } - } - FreePool(Instance); - Instance = GetNextDevicePathInstance (&Multi, &InstanceSize); - InstanceSize -= END_DEVICE_PATH_LENGTH; - } - - return NewDevicePath; -} - -/** - Function compares a device path data structure to that of all the nodes of a - second device path instance. - - @param Multi A pointer to a multi-instance device path data - structure. - @param Single A pointer to a single-instance device path data - structure. - - @retval TRUE If the Single device path is contained within Multi device path. - @retval FALSE The Single device path is not match within Multi device path. - -**/ -BOOLEAN -EFIAPI -BdsLibMatchDevicePaths ( - IN EFI_DEVICE_PATH_PROTOCOL *Multi, - IN EFI_DEVICE_PATH_PROTOCOL *Single - ) -{ - EFI_DEVICE_PATH_PROTOCOL *DevicePath; - EFI_DEVICE_PATH_PROTOCOL *DevicePathInst; - UINTN Size; - - if (Multi == NULL || Single == NULL) { - return FALSE; - } - - DevicePath = Multi; - DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size); - - // - // Search for the match of 'Single' in 'Multi' - // - while (DevicePathInst != NULL) { - // - // If the single device path is found in multiple device paths, - // return success - // - if (CompareMem (Single, DevicePathInst, Size) == 0) { - FreePool (DevicePathInst); - return TRUE; - } - - FreePool (DevicePathInst); - DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size); - } - - return FALSE; -} - -/** - This function prints a series of strings. - - @param ConOut Pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL - @param ... A variable argument list containing series of - strings, the last string must be NULL. - - @retval EFI_SUCCESS Success print out the string using ConOut. - @retval EFI_STATUS Return the status of the ConOut->OutputString (). - -**/ -EFI_STATUS -EFIAPI -BdsLibOutputStrings ( - IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut, - ... - ) -{ - VA_LIST Args; - EFI_STATUS Status; - CHAR16 *String; - - Status = EFI_SUCCESS; - VA_START (Args, ConOut); - - while (!EFI_ERROR (Status)) { - // - // If String is NULL, then it's the end of the list - // - String = VA_ARG (Args, CHAR16 *); - if (String == NULL) { - break; - } - - Status = ConOut->OutputString (ConOut, String); - - if (EFI_ERROR (Status)) { - break; - } - } - - VA_END(Args); - return Status; -} - -// -// Following are BDS Lib functions which contain all the code about setup browser reset reminder feature. -// Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if -// user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection. -// - - -/** - Enable the setup browser reset reminder feature. - This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it. - -**/ -VOID -EFIAPI -EnableResetReminderFeature ( - VOID - ) -{ - mFeaturerSwitch = TRUE; -} - - -/** - Disable the setup browser reset reminder feature. - This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it. - -**/ -VOID -EFIAPI -DisableResetReminderFeature ( - VOID - ) -{ - mFeaturerSwitch = FALSE; -} - - -/** - Record the info that a reset is required. - A module boolean variable is used to record whether a reset is required. - -**/ -VOID -EFIAPI -EnableResetRequired ( - VOID - ) -{ - mResetRequired = TRUE; -} - - -/** - Record the info that no reset is required. - A module boolean variable is used to record whether a reset is required. - -**/ -VOID -EFIAPI -DisableResetRequired ( - VOID - ) -{ - mResetRequired = FALSE; -} - - -/** - Check whether platform policy enable the reset reminder feature. The default is enabled. - -**/ -BOOLEAN -EFIAPI -IsResetReminderFeatureEnable ( - VOID - ) -{ - return mFeaturerSwitch; -} - - -/** - Check if user changed any option setting which needs a system reset to be effective. - -**/ -BOOLEAN -EFIAPI -IsResetRequired ( - VOID - ) -{ - return mResetRequired; -} - - -/** - Check whether a reset is needed, and finish the reset reminder feature. - If a reset is needed, Popup a menu to notice user, and finish the feature - according to the user selection. - -**/ -VOID -EFIAPI -SetupResetReminder ( - VOID - ) -{ - EFI_INPUT_KEY Key; - CHAR16 *StringBuffer1; - CHAR16 *StringBuffer2; - - - // - //check any reset required change is applied? if yes, reset system - // - if (IsResetReminderFeatureEnable ()) { - if (IsResetRequired ()) { - - StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); - ASSERT (StringBuffer1 != NULL); - StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); - ASSERT (StringBuffer2 != NULL); - StrCpyS ( - StringBuffer1, - MAX_STRING_LEN, - L"Configuration changed. Reset to apply it Now." - ); - StrCpyS ( - StringBuffer2, - MAX_STRING_LEN, - L"Press ENTER to reset" - ); - // - // Popup a menu to notice user - // - do { - CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL); - } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); - - FreePool (StringBuffer1); - FreePool (StringBuffer2); - - gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); - } - } -} - -/** - Get the headers (dos, image, optional header) from an image - - @param Device SimpleFileSystem device handle - @param FileName File name for the image - @param DosHeader Pointer to dos header - @param Hdr The buffer in which to return the PE32, PE32+, or TE header. - - @retval EFI_SUCCESS Successfully get the machine type. - @retval EFI_NOT_FOUND The file is not found. - @retval EFI_LOAD_ERROR File is not a valid image file. - -**/ -EFI_STATUS -EFIAPI -BdsLibGetImageHeader ( - IN EFI_HANDLE Device, - IN CHAR16 *FileName, - OUT EFI_IMAGE_DOS_HEADER *DosHeader, - OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr - ) -{ - EFI_STATUS Status; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; - EFI_FILE_HANDLE Root; - EFI_FILE_HANDLE ThisFile; - UINTN BufferSize; - UINT64 FileSize; - EFI_FILE_INFO *Info; - - Root = NULL; - ThisFile = NULL; - // - // Handle the file system interface to the device - // - Status = gBS->HandleProtocol ( - Device, - &gEfiSimpleFileSystemProtocolGuid, - (VOID *) &Volume - ); - if (EFI_ERROR (Status)) { - goto Done; - } - - Status = Volume->OpenVolume ( - Volume, - &Root - ); - if (EFI_ERROR (Status)) { - Root = NULL; - goto Done; - } - ASSERT (Root != NULL); - Status = Root->Open (Root, &ThisFile, FileName, EFI_FILE_MODE_READ, 0); - if (EFI_ERROR (Status)) { - goto Done; - } - ASSERT (ThisFile != NULL); - - // - // Get file size - // - BufferSize = SIZE_OF_EFI_FILE_INFO + 200; - do { - Info = NULL; - Status = gBS->AllocatePool (EfiBootServicesData, BufferSize, (VOID **) &Info); - if (EFI_ERROR (Status)) { - goto Done; - } - Status = ThisFile->GetInfo ( - ThisFile, - &gEfiFileInfoGuid, - &BufferSize, - Info - ); - if (!EFI_ERROR (Status)) { - break; - } - if (Status != EFI_BUFFER_TOO_SMALL) { - FreePool (Info); - goto Done; - } - FreePool (Info); - } while (TRUE); - - FileSize = Info->FileSize; - FreePool (Info); - - // - // Read dos header - // - BufferSize = sizeof (EFI_IMAGE_DOS_HEADER); - Status = ThisFile->Read (ThisFile, &BufferSize, DosHeader); - if (EFI_ERROR (Status) || - BufferSize < sizeof (EFI_IMAGE_DOS_HEADER) || - FileSize <= DosHeader->e_lfanew || - DosHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE) { - Status = EFI_LOAD_ERROR; - goto Done; - } - - // - // Move to PE signature - // - Status = ThisFile->SetPosition (ThisFile, DosHeader->e_lfanew); - if (EFI_ERROR (Status)) { - Status = EFI_LOAD_ERROR; - goto Done; - } - - // - // Read and check PE signature - // - BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION); - Status = ThisFile->Read (ThisFile, &BufferSize, Hdr.Pe32); - if (EFI_ERROR (Status) || - BufferSize < sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION) || - Hdr.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) { - Status = EFI_LOAD_ERROR; - goto Done; - } - - // - // Check PE32 or PE32+ magic - // - if (Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC && - Hdr.Pe32->OptionalHeader.Magic != EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { - Status = EFI_LOAD_ERROR; - goto Done; - } - - Done: - if (ThisFile != NULL) { - ThisFile->Close (ThisFile); - } - if (Root != NULL) { - Root->Close (Root); - } - return Status; -} - -/** - This routine adjust the memory information for different memory type and - save them into the variables for next boot. -**/ -VOID -BdsSetMemoryTypeInformationVariable ( - VOID - ) -{ - EFI_STATUS Status; - EFI_MEMORY_TYPE_INFORMATION *PreviousMemoryTypeInformation; - EFI_MEMORY_TYPE_INFORMATION *CurrentMemoryTypeInformation; - UINTN VariableSize; - UINTN Index; - UINTN Index1; - UINT32 Previous; - UINT32 Current; - UINT32 Next; - EFI_HOB_GUID_TYPE *GuidHob; - BOOLEAN MemoryTypeInformationModified; - BOOLEAN MemoryTypeInformationVariableExists; - EFI_BOOT_MODE BootMode; - - MemoryTypeInformationModified = FALSE; - MemoryTypeInformationVariableExists = FALSE; - - - BootMode = GetBootModeHob (); - // - // In BOOT_IN_RECOVERY_MODE, Variable region is not reliable. - // - if (BootMode == BOOT_IN_RECOVERY_MODE) { - return; - } - - // - // Only check the the Memory Type Information variable in the boot mode - // other than BOOT_WITH_DEFAULT_SETTINGS because the Memory Type - // Information is not valid in this boot mode. - // - if (BootMode != BOOT_WITH_DEFAULT_SETTINGS) { - VariableSize = 0; - Status = gRT->GetVariable ( - EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, - &gEfiMemoryTypeInformationGuid, - NULL, - &VariableSize, - NULL - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - MemoryTypeInformationVariableExists = TRUE; - } - } - - // - // Retrieve the current memory usage statistics. If they are not found, then - // no adjustments can be made to the Memory Type Information variable. - // - Status = EfiGetSystemConfigurationTable ( - &gEfiMemoryTypeInformationGuid, - (VOID **) &CurrentMemoryTypeInformation - ); - if (EFI_ERROR (Status) || CurrentMemoryTypeInformation == NULL) { - return; - } - - // - // Get the Memory Type Information settings from Hob if they exist, - // PEI is responsible for getting them from variable and build a Hob to save them. - // If the previous Memory Type Information is not available, then set defaults - // - GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid); - if (GuidHob == NULL) { - // - // If Platform has not built Memory Type Info into the Hob, just return. - // - return; - } - PreviousMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob); - VariableSize = GET_GUID_HOB_DATA_SIZE (GuidHob); - - // - // Use a heuristic to adjust the Memory Type Information for the next boot - // - DEBUG ((EFI_D_INFO, "Memory Previous Current Next \n")); - DEBUG ((EFI_D_INFO, " Type Pages Pages Pages \n")); - DEBUG ((EFI_D_INFO, "====== ======== ======== ========\n")); - - for (Index = 0; PreviousMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) { - - for (Index1 = 0; CurrentMemoryTypeInformation[Index1].Type != EfiMaxMemoryType; Index1++) { - if (PreviousMemoryTypeInformation[Index].Type == CurrentMemoryTypeInformation[Index1].Type) { - break; - } - } - if (CurrentMemoryTypeInformation[Index1].Type == EfiMaxMemoryType) { - continue; - } - - // - // Previous is the number of pages pre-allocated - // Current is the number of pages actually needed - // - Previous = PreviousMemoryTypeInformation[Index].NumberOfPages; - Current = CurrentMemoryTypeInformation[Index1].NumberOfPages; - Next = Previous; - - // - // Inconsistent Memory Reserved across bootings may lead to S4 fail - // Write next varible to 125% * current when the pre-allocated memory is: - // 1. More than 150% of needed memory and boot mode is BOOT_WITH_DEFAULT_SETTING - // 2. Less than the needed memory - // - if ((Current + (Current >> 1)) < Previous) { - if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { - Next = Current + (Current >> 2); - } - } else if (Current > Previous) { - Next = Current + (Current >> 2); - } - if (Next > 0 && Next < 4) { - Next = 4; - } - - if (Next != Previous) { - PreviousMemoryTypeInformation[Index].NumberOfPages = Next; - MemoryTypeInformationModified = TRUE; - } - - DEBUG ((EFI_D_INFO, " %02x %08x %08x %08x\n", PreviousMemoryTypeInformation[Index].Type, Previous, Current, Next)); - } - - // - // If any changes were made to the Memory Type Information settings, then set the new variable value; - // Or create the variable in first boot. - // - if (MemoryTypeInformationModified || !MemoryTypeInformationVariableExists) { - Status = SetVariableAndReportStatusCodeOnError ( - EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, - &gEfiMemoryTypeInformationGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, - VariableSize, - PreviousMemoryTypeInformation - ); - - if (!EFI_ERROR (Status)) { - // - // If the Memory Type Information settings have been modified, then reset the platform - // so the new Memory Type Information setting will be used to guarantee that an S4 - // entry/resume cycle will not fail. - // - if (MemoryTypeInformationModified && PcdGetBool (PcdResetOnMemoryTypeInformationChange)) { - DEBUG ((EFI_D_INFO, "Memory Type Information settings change. Warm Reset!!!\n")); - gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); - } - } else { - DEBUG ((EFI_D_ERROR, "Memory Type Information settings cannot be saved. OS S4 may fail!\n")); - } - } -} - -/** - This routine is kept for backward compatibility. -**/ -VOID -EFIAPI -BdsLibSaveMemoryTypeInformation ( - VOID - ) -{ -} - - -/** - Identify a user and, if authenticated, returns the current user profile handle. - - @param[out] User Point to user profile handle. - - @retval EFI_SUCCESS User is successfully identified, or user identification - is not supported. - @retval EFI_ACCESS_DENIED User is not successfully identified - -**/ -EFI_STATUS -EFIAPI -BdsLibUserIdentify ( - OUT EFI_USER_PROFILE_HANDLE *User - ) -{ - EFI_STATUS Status; - EFI_USER_MANAGER_PROTOCOL *Manager; - - Status = gBS->LocateProtocol ( - &gEfiUserManagerProtocolGuid, - NULL, - (VOID **) &Manager - ); - if (EFI_ERROR (Status)) { - return EFI_SUCCESS; - } - - return Manager->Identify (Manager, User); -} - -/** - Set the variable and report the error through status code upon failure. - - @param VariableName A Null-terminated string that is the name of the vendor's variable. - Each VariableName is unique for each VendorGuid. VariableName must - contain 1 or more characters. If VariableName is an empty string, - then EFI_INVALID_PARAMETER is returned. - @param VendorGuid A unique identifier for the vendor. - @param Attributes Attributes bitmask to set for the variable. - @param DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE, - EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero - causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is - set, then a SetVariable() call with a DataSize of zero will not cause any change to - the variable value (the timestamp associated with the variable may be updated however - even if no new data value is provided,see the description of the - EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not - be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated). - @param Data The contents for the variable. - - @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as - defined by the Attributes. - @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the - DataSize exceeds the maximum allowed. - @retval EFI_INVALID_PARAMETER VariableName is an empty string. - @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. - @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. - @retval EFI_WRITE_PROTECTED The variable in question is read-only. - @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. - @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS - or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo - does NOT pass the validation check carried out by the firmware. - - @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. -**/ -EFI_STATUS -SetVariableAndReportStatusCodeOnError ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - IN UINT32 Attributes, - IN UINTN DataSize, - IN VOID *Data - ) -{ - EFI_STATUS Status; - EDKII_SET_VARIABLE_STATUS *SetVariableStatus; - UINTN NameSize; - - Status = gRT->SetVariable ( - VariableName, - VendorGuid, - Attributes, - DataSize, - Data - ); - if (EFI_ERROR (Status)) { - NameSize = StrSize (VariableName); - SetVariableStatus = AllocatePool (sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize); - if (SetVariableStatus != NULL) { - CopyGuid (&SetVariableStatus->Guid, VendorGuid); - SetVariableStatus->NameSize = NameSize; - SetVariableStatus->DataSize = DataSize; - SetVariableStatus->SetStatus = Status; - SetVariableStatus->Attributes = Attributes; - CopyMem (SetVariableStatus + 1, VariableName, NameSize); - if ((Data != NULL) && (DataSize != 0)) { - CopyMem (((UINT8 *) (SetVariableStatus + 1)) + NameSize, Data, DataSize); - } - - REPORT_STATUS_CODE_EX ( - EFI_ERROR_CODE, - PcdGet32 (PcdErrorCodeSetVariable), - 0, - NULL, - &gEdkiiStatusCodeDataTypeVariableGuid, - SetVariableStatus, - sizeof (EDKII_SET_VARIABLE_STATUS) + NameSize + DataSize - ); - - FreePool (SetVariableStatus); - } - } - - return Status; -} - diff --git a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c b/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c deleted file mode 100644 index 2f22e7df7f..0000000000 --- a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/DevicePath.c +++ /dev/null @@ -1,33 +0,0 @@ -/** @file - BDS internal function define the default device path string, it can be - replaced by platform device path. - -Copyright (c) 2004 - 2013, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which 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 "InternalBdsLib.h" - -/** - This function converts an input device structure to a Unicode string. - - @param DevPath A pointer to the device path structure. - - @return A new allocated Unicode string that represents the device path. - -**/ -CHAR16 * -EFIAPI -DevicePathToStr ( - IN EFI_DEVICE_PATH_PROTOCOL *DevPath - ) -{ - return ConvertDevicePathToText (DevPath, TRUE, TRUE); -} diff --git a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf b/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf deleted file mode 100644 index a4c1165e30..0000000000 --- a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf +++ /dev/null @@ -1,144 +0,0 @@ -## @file -# General BDS library. -# -# General BDS defines and produce general interfaces for platform BDS driver including: -# 1) BDS boot policy interface; -# 2) BDS boot device connect interface; -# 3) BDS Misc interfaces for mainting boot variable, ouput string, etc. -# -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which 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 = 0x00010018 - BASE_NAME = GenericBdsLib - FILE_GUID = e405ec31-ccaa-4dd4-83e8-0aec01703f7e - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - LIBRARY_CLASS = GenericBdsLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION - CONSTRUCTOR = GenericBdsLibConstructor - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 IPF EBC -# - -[Sources] - DevicePath.c - Performance.c - BdsConnect.c - BdsMisc.c - BdsConsole.c - BdsBoot.c - InternalBdsLib.h - String.h - String.c - GenericBdsStrings.uni - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - IntelFrameworkPkg/IntelFrameworkPkg.dec - IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec - -[LibraryClasses] - DevicePathLib - PeCoffGetEntryPointLib - BaseLib - HobLib - UefiRuntimeServicesTableLib - DxeServicesTableLib - MemoryAllocationLib - UefiLib - UefiBootServicesTableLib - BaseMemoryLib - DebugLib - PrintLib - PcdLib - PerformanceLib - TimerLib - DxeServicesLib - HiiLib - ReportStatusCodeLib - -[Guids] - ## SOMETIMES_CONSUMES ## HOB # The hob holding memory type information - ## SOMETIMES_CONSUMES ## SystemTable # The identifier of memory type information type in system table - ## SOMETIMES_CONSUMES ## Variable:L"MemoryTypeInformation" - ## SOMETIMES_PRODUCES ## Variable:L"MemoryTypeInformation" - gEfiMemoryTypeInformationGuid - ## SOMETIMES_CONSUMES ## Variable:L"BootXXXX" # Boot option variable - ## SOMETIMES_PRODUCES ## Variable:L"BootXXXX" # Boot option variable - ## SOMETIMES_CONSUMES ## Variable:L"DriverXXXX" # Driver load option. - ## SOMETIMES_PRODUCES ## Variable:L"DriverXXXX" # Driver load option. - ## SOMETIMES_CONSUMES ## Variable:L"BootNext" # Next Boot Option - ## SOMETIMES_PRODUCES ## Variable:L"BootNext" # Next Boot Option - ## SOMETIMES_CONSUMES ## Variable:L"BootOrder" # The boot option array - ## SOMETIMES_PRODUCES ## Variable:L"BootOrder" # The boot option array - ## SOMETIMES_CONSUMES ## Variable:L"DriverOrder" # The driver order list - ## SOMETIMES_CONSUMES ## Variable:L"ConIn" # The device path of console in device - ## SOMETIMES_PRODUCES ## Variable:L"ConIn" # The device path of console in device - ## SOMETIMES_CONSUMES ## Variable:L"ConOut" # The device path of console out device - ## SOMETIMES_PRODUCES ## Variable:L"ConOut" # The device path of console out device - ## SOMETIMES_CONSUMES ## Variable:L"ErrOut" # The device path of error out device - ## SOMETIMES_PRODUCES ## Variable:L"ErrOut" # The device path of error out device - ## SOMETIMES_PRODUCES ## Variable:L"BootCurrent" # The boot option of current boot - ## SOMETIMES_PRODUCES ## Variable:L"BootNext" # The number of next boot option - gEfiGlobalVariableGuid - gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## GUID - gPerformanceProtocolGuid ## SOMETIMES_PRODUCES ## Variable:L"PerfDataMemAddr" # The ACPI address of performance data - gLastEnumLangGuid ## SOMETIMES_PRODUCES ## Variable:L"LastEnumLang" # Platform language at last time enumeration. - gHdBootDevicePathVariablGuid ## SOMETIMES_PRODUCES ## Variable:L"HDDP" # The device path of Boot file on Hard device. - gBdsLibStringPackageGuid ## CONSUMES ## HII # HII String PackageList Guid - ## SOMETIMES_PRODUCES ## Variable:L"LegacyDevOrder" - ## SOMETIMES_CONSUMES ## Variable:L"LegacyDevOrder" - gEfiLegacyDevOrderVariableGuid - gEdkiiStatusCodeDataTypeVariableGuid ## SOMETIMES_CONSUMES ## GUID - -[Protocols] - gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES - gEfiLoadFileProtocolGuid ## SOMETIMES_CONSUMES - gEfiSimpleTextOutProtocolGuid ## CONSUMES - gEfiPciIoProtocolGuid ## SOMETIMES_CONSUMES - gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES - gEfiSimpleNetworkProtocolGuid ## SOMETIMES_CONSUMES - gEfiDebugPortProtocolGuid ## SOMETIMES_CONSUMES - gEfiSimpleTextInProtocolGuid ## CONSUMES - gEfiBlockIoProtocolGuid ## SOMETIMES_CONSUMES - gEfiFirmwareVolume2ProtocolGuid ## SOMETIMES_CONSUMES - gEfiLegacyBiosProtocolGuid ## SOMETIMES_CONSUMES - gEfiCpuArchProtocolGuid ## CONSUMES - gEfiDevicePathProtocolGuid ## CONSUMES - gEfiGraphicsOutputProtocolGuid ## SOMETIMES_CONSUMES - gEfiUgaDrawProtocolGuid |gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport ## SOMETIMES_CONSUMES - gEfiOEMBadgingProtocolGuid ## SOMETIMES_CONSUMES - gEfiHiiFontProtocolGuid ## CONSUMES - gEfiUserManagerProtocolGuid ## SOMETIMES_CONSUMES - gEfiUsbIoProtocolGuid ## SOMETIMES_CONSUMES - gEfiBootLogoProtocolGuid ## SOMETIMES_CONSUMES - -[FeaturePcd] - gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport ## CONSUMES - gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootlogoOnlyEnable ## CONSUMES - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderLoad ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderStart ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable ## CONSUMES - gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile ## CONSUMES - -# -# [BootMode] -# RECOVERY_FULL ## SOMETIMES_CONSUMES # Memory Type Information variable -# - diff --git a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsStrings.uni b/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsStrings.uni deleted file mode 100644 index 568774b59a..0000000000 --- a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsStrings.uni +++ /dev/null @@ -1,36 +0,0 @@ -///** @file -// -// String definitions for Boot Option description. -// -// Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.
-// This program and the accompanying materials -// are licensed and made available under the terms and conditions of the BSD License -// which 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. -// -//**/ - -/=# - -#langdef en-US "English" -#langdef fr "Français" - -#string STR_DESCRIPTION_FLOPPY #language en-US "EFI Floppy" - #language fr "fr: EFI Floppy" -#string STR_DESCRIPTION_CD_DVD #language en-US "EFI DVD/CDROM" - #language fr "fr: EFI DVD/CDROM" -#string STR_DESCRIPTION_HARDDRIVE #language en-US "EFI Hard Drive" - #language fr "fr: EFI Hard Drive" -#string STR_DESCRIPTION_USB #language en-US "EFI USB Device" - #language fr "fr: EFI USB Device" -#string STR_DESCRIPTION_SCSI #language en-US "EFI SCSI Device" - #language fr "fr: EFI SCSI Device" -#string STR_DESCRIPTION_MISC #language en-US "EFI Misc Device" - #language fr "fr: EFI Misc Device" -#string STR_DESCRIPTION_NETWORK #language en-US "EFI Network" - #language fr "fr: EFI Network" -#string STR_DESCRIPTION_NON_BLOCK #language en-US "EFI Non-Block Boot Device" - #language fr "fr: EFI Non-Block Boot Device" diff --git a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h b/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h deleted file mode 100644 index 4f2817a284..0000000000 --- a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/InternalBdsLib.h +++ /dev/null @@ -1,194 +0,0 @@ -/** @file - BDS library definition, include the file and data structure - -Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which 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 _INTERNAL_BDS_LIB_H_ -#define _INTERNAL_BDS_LIB_H_ - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if !defined (EFI_REMOVABLE_MEDIA_FILE_NAME) - #if defined (MDE_CPU_EBC) - // - // Uefi specification only defines the default boot file name for IA32, X64 - // and IPF processor, so need define boot file name for EBC architecture here. - // - #define EFI_REMOVABLE_MEDIA_FILE_NAME L"\\EFI\\BOOT\\BOOTEBC.EFI" - #else - #error "Can not determine the default boot file name for unknown processor type!" - #endif -#endif - -/** - - Writes performance data of booting into the allocated memory. - OS can process these records. - - @param Event The triggered event. - @param Context Context for this event. - -**/ -VOID -EFIAPI -WriteBootToOsPerformanceData ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Get the headers (dos, image, optional header) from an image - - @param Device SimpleFileSystem device handle - @param FileName File name for the image - @param DosHeader Pointer to dos header - @param Hdr The buffer in which to return the PE32, PE32+, or TE header. - - @retval EFI_SUCCESS Successfully get the machine type. - @retval EFI_NOT_FOUND The file is not found. - @retval EFI_LOAD_ERROR File is not a valid image file. - -**/ -EFI_STATUS -EFIAPI -BdsLibGetImageHeader ( - IN EFI_HANDLE Device, - IN CHAR16 *FileName, - OUT EFI_IMAGE_DOS_HEADER *DosHeader, - OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr - ); - -/** - This routine adjust the memory information for different memory type and - save them into the variables for next boot. -**/ -VOID -BdsSetMemoryTypeInformationVariable ( - VOID - ); - -/** - Validate the EFI Boot#### or Driver#### variable (VendorGuid/Name) - - @param Variable Boot#### variable data. - @param VariableSize Returns the size of the EFI variable that was read - - @retval TRUE The variable data is correct. - @retval FALSE The variable data is corrupted. - -**/ -BOOLEAN -ValidateOption ( - UINT8 *Variable, - UINTN VariableSize - ); - -/** - Set the variable and report the error through status code upon failure. - - @param VariableName A Null-terminated string that is the name of the vendor's variable. - Each VariableName is unique for each VendorGuid. VariableName must - contain 1 or more characters. If VariableName is an empty string, - then EFI_INVALID_PARAMETER is returned. - @param VendorGuid A unique identifier for the vendor. - @param Attributes Attributes bitmask to set for the variable. - @param DataSize The size in bytes of the Data buffer. Unless the EFI_VARIABLE_APPEND_WRITE, - EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS, or - EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set, a size of zero - causes the variable to be deleted. When the EFI_VARIABLE_APPEND_WRITE attribute is - set, then a SetVariable() call with a DataSize of zero will not cause any change to - the variable value (the timestamp associated with the variable may be updated however - even if no new data value is provided,see the description of the - EFI_VARIABLE_AUTHENTICATION_2 descriptor below. In this case the DataSize will not - be zero since the EFI_VARIABLE_AUTHENTICATION_2 descriptor will be populated). - @param Data The contents for the variable. - - @retval EFI_SUCCESS The firmware has successfully stored the variable and its data as - defined by the Attributes. - @retval EFI_INVALID_PARAMETER An invalid combination of attribute bits, name, and GUID was supplied, or the - DataSize exceeds the maximum allowed. - @retval EFI_INVALID_PARAMETER VariableName is an empty string. - @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. - @retval EFI_DEVICE_ERROR The variable could not be retrieved due to a hardware error. - @retval EFI_WRITE_PROTECTED The variable in question is read-only. - @retval EFI_WRITE_PROTECTED The variable in question cannot be deleted. - @retval EFI_SECURITY_VIOLATION The variable could not be written due to EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS - or EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACESS being set, but the AuthInfo - does NOT pass the validation check carried out by the firmware. - - @retval EFI_NOT_FOUND The variable trying to be updated or deleted was not found. -**/ -EFI_STATUS -SetVariableAndReportStatusCodeOnError ( - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - IN UINT32 Attributes, - IN UINTN DataSize, - IN VOID *Data - ); - -#endif // _BDS_LIB_H_ diff --git a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c b/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c deleted file mode 100644 index 9786fc7e24..0000000000 --- a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c +++ /dev/null @@ -1,358 +0,0 @@ -/** @file - This file include the file which can help to get the system - performance, all the function will only include if the performance - switch is set. - -Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which 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 "InternalBdsLib.h" - -PERF_HEADER mPerfHeader; -PERF_DATA mPerfData; -EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase = 0x0FFFFFFFFULL; - -/** - Get the short verion of PDB file name to be - used in performance data logging. - - @param PdbFileName The long PDB file name. - @param GaugeString The output string to be logged by performance logger. - -**/ -VOID -GetShortPdbFileName ( - IN CONST CHAR8 *PdbFileName, - OUT CHAR8 *GaugeString - ) -{ - UINTN Index; - UINTN Index1; - UINTN StartIndex; - UINTN EndIndex; - - if (PdbFileName == NULL) { - AsciiStrCpyS (GaugeString, PERF_TOKEN_SIZE, " "); - } else { - StartIndex = 0; - for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++) - ; - - for (Index = 0; PdbFileName[Index] != 0; Index++) { - if (PdbFileName[Index] == '\\') { - StartIndex = Index + 1; - } - - if (PdbFileName[Index] == '.') { - EndIndex = Index; - } - } - - Index1 = 0; - for (Index = StartIndex; Index < EndIndex; Index++) { - GaugeString[Index1] = PdbFileName[Index]; - Index1++; - if (Index1 == PERF_TOKEN_LENGTH) { - break; - } - } - - GaugeString[Index1] = 0; - } - - return ; -} - -/** - Get the name from the Driver handle, which can be a handle with - EFI_LOADED_IMAGE_PROTOCOL or EFI_DRIVER_BINDING_PROTOCOL installed. - This name can be used in performance data logging. - - @param Handle Driver handle. - @param GaugeString The output string to be logged by performance logger. - -**/ -VOID -GetNameFromHandle ( - IN EFI_HANDLE Handle, - OUT CHAR8 *GaugeString - ) -{ - EFI_STATUS Status; - EFI_LOADED_IMAGE_PROTOCOL *Image; - CHAR8 *PdbFileName; - EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; - - AsciiStrCpyS (GaugeString, PERF_TOKEN_SIZE, " "); - - // - // Get handle name from image protocol - // - Status = gBS->HandleProtocol ( - Handle, - &gEfiLoadedImageProtocolGuid, - (VOID **) &Image - ); - - if (EFI_ERROR (Status)) { - Status = gBS->OpenProtocol ( - Handle, - &gEfiDriverBindingProtocolGuid, - (VOID **) &DriverBinding, - NULL, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return ; - } - // - // Get handle name from image protocol - // - Status = gBS->HandleProtocol ( - DriverBinding->ImageHandle, - &gEfiLoadedImageProtocolGuid, - (VOID **) &Image - ); - } - - PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase); - - if (PdbFileName != NULL) { - GetShortPdbFileName (PdbFileName, GaugeString); - } - - return ; -} - -/** - - Writes performance data of booting into the allocated memory. - OS can process these records. - - @param Event The triggered event. - @param Context Context for this event. - -**/ -VOID -EFIAPI -WriteBootToOsPerformanceData ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EFI_STATUS Status; - UINT32 LimitCount; - EFI_HANDLE *Handles; - UINTN NoHandles; - CHAR8 GaugeString[PERF_TOKEN_SIZE]; - UINT8 *Ptr; - UINT32 Index; - UINT64 Ticker; - UINT64 Freq; - UINT32 Duration; - UINTN LogEntryKey; - CONST VOID *Handle; - CONST CHAR8 *Token; - CONST CHAR8 *Module; - UINT64 StartTicker; - UINT64 EndTicker; - UINT64 StartValue; - UINT64 EndValue; - BOOLEAN CountUp; - UINTN EntryIndex; - UINTN NumPerfEntries; - // - // List of flags indicating PerfEntry contains DXE handle - // - BOOLEAN *PerfEntriesAsDxeHandle; - UINTN VarSize; - - // - // Record the performance data for End of BDS - // - PERF_END(NULL, "BDS", NULL, 0); - - // - // Retrieve time stamp count as early as possible - // - Ticker = GetPerformanceCounter (); - - Freq = GetPerformanceCounterProperties (&StartValue, &EndValue); - - Freq = DivU64x32 (Freq, 1000); - - mPerfHeader.CpuFreq = Freq; - - // - // Record BDS raw performance data - // - if (EndValue >= StartValue) { - mPerfHeader.BDSRaw = Ticker - StartValue; - CountUp = TRUE; - } else { - mPerfHeader.BDSRaw = StartValue - Ticker; - CountUp = FALSE; - } - - if (mAcpiLowMemoryBase == 0x0FFFFFFFF) { - VarSize = sizeof (EFI_PHYSICAL_ADDRESS); - Status = gRT->GetVariable ( - L"PerfDataMemAddr", - &gPerformanceProtocolGuid, - NULL, - &VarSize, - &mAcpiLowMemoryBase - ); - if (EFI_ERROR (Status)) { - // - // Fail to get the variable, return. - // - return; - } - } - - // - // Put Detailed performance data into memory - // - Handles = NULL; - Status = gBS->LocateHandleBuffer ( - AllHandles, - NULL, - NULL, - &NoHandles, - &Handles - ); - if (EFI_ERROR (Status)) { - return ; - } - - Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER)); - LimitCount = (UINT32) (PERF_DATA_MAX_LENGTH - sizeof (PERF_HEADER)) / sizeof (PERF_DATA); - - NumPerfEntries = 0; - LogEntryKey = 0; - while ((LogEntryKey = GetPerformanceMeasurement ( - LogEntryKey, - &Handle, - &Token, - &Module, - &StartTicker, - &EndTicker)) != 0) { - NumPerfEntries++; - } - PerfEntriesAsDxeHandle = AllocateZeroPool (NumPerfEntries * sizeof (BOOLEAN)); - ASSERT (PerfEntriesAsDxeHandle != NULL); - - // - // Get DXE drivers performance - // - for (Index = 0; Index < NoHandles; Index++) { - Ticker = 0; - LogEntryKey = 0; - EntryIndex = 0; - while ((LogEntryKey = GetPerformanceMeasurement ( - LogEntryKey, - &Handle, - &Token, - &Module, - &StartTicker, - &EndTicker)) != 0) { - if (Handle == Handles[Index] && !PerfEntriesAsDxeHandle[EntryIndex]) { - PerfEntriesAsDxeHandle[EntryIndex] = TRUE; - } - EntryIndex++; - if ((Handle == Handles[Index]) && (EndTicker != 0)) { - if (StartTicker == 1) { - StartTicker = StartValue; - } - if (EndTicker == 1) { - EndTicker = StartValue; - } - Ticker += CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker); - } - } - - Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq); - - if (Duration > 0) { - - GetNameFromHandle (Handles[Index], GaugeString); - - AsciiStrCpyS (mPerfData.Token, PERF_TOKEN_SIZE, GaugeString); - mPerfData.Duration = Duration; - - CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA)); - Ptr += sizeof (PERF_DATA); - - mPerfHeader.Count++; - if (mPerfHeader.Count == LimitCount) { - goto Done; - } - } - } - - // - // Get inserted performance data - // - LogEntryKey = 0; - EntryIndex = 0; - while ((LogEntryKey = GetPerformanceMeasurement ( - LogEntryKey, - &Handle, - &Token, - &Module, - &StartTicker, - &EndTicker)) != 0) { - if (!PerfEntriesAsDxeHandle[EntryIndex] && EndTicker != 0) { - - ZeroMem (&mPerfData, sizeof (PERF_DATA)); - - AsciiStrnCpyS (mPerfData.Token, PERF_TOKEN_SIZE, Token, PERF_TOKEN_LENGTH); - if (StartTicker == 1) { - StartTicker = StartValue; - } - if (EndTicker == 1) { - EndTicker = StartValue; - } - Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker); - - mPerfData.Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq); - - CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA)); - Ptr += sizeof (PERF_DATA); - - mPerfHeader.Count++; - if (mPerfHeader.Count == LimitCount) { - goto Done; - } - } - EntryIndex++; - } - -Done: - - FreePool (Handles); - FreePool (PerfEntriesAsDxeHandle); - - mPerfHeader.Signiture = PERFORMANCE_SIGNATURE; - - // - // Put performance data to Reserved memory - // - CopyMem ( - (UINTN *) (UINTN) mAcpiLowMemoryBase, - &mPerfHeader, - sizeof (PERF_HEADER) - ); - - return ; -} diff --git a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.c b/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.c deleted file mode 100644 index 762871605d..0000000000 --- a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.c +++ /dev/null @@ -1,32 +0,0 @@ -/** @file - String support - -Copyright (c) 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which 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 "String.h" - -/** - Get string by string id from HII Interface - - - @param Id String ID. - - @retval CHAR16 * String from ID. - @retval NULL If error occurs. - -**/ -CHAR16 * -BdsLibGetStringById ( - IN EFI_STRING_ID Id - ) -{ - return HiiGetString (gBdsLibStringPackHandle, Id, NULL); -} diff --git a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.h b/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.h deleted file mode 100644 index 13b745de87..0000000000 --- a/BraswellPlatformPkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/String.h +++ /dev/null @@ -1,48 +0,0 @@ -/** @file - String support - -Copyright (c) 2010, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which 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 _STRING_H_ -#define _STRING_H_ - -#include -#include -#include -#include -#include - -extern EFI_HII_HANDLE gBdsLibStringPackHandle; - -// -// This is the VFR compiler generated header file which defines the -// string identifiers. -// - -extern UINT8 GenericBdsLibStrings[]; - -/** - Get string by string id from HII Interface - - - @param Id String ID. - - @retval CHAR16 * String from ID. - @retval NULL If error occurs. - -**/ -CHAR16 * -BdsLibGetStringById ( - IN EFI_STRING_ID Id - ); - -#endif // _STRING_H_ diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c deleted file mode 100644 index 373cea2a23..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/FspPlatformSecLibSample.c +++ /dev/null @@ -1,149 +0,0 @@ -/** @file - Sample to provide FSP wrapper platform sec related function. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which 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 -#include -#include -#include -#include - -/** - This interface conveys state information out of the Security (SEC) phase into PEI. - - @param[in] PeiServices Pointer to the PEI Services Table. - @param[in,out] StructureSize Pointer to the variable describing size of the input buffer. - @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. - - @retval EFI_SUCCESS The data was successfully returned. - @retval EFI_BUFFER_TOO_SMALL The buffer was too small. - -**/ -EFI_STATUS -EFIAPI -SecPlatformInformation ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN OUT UINT64 *StructureSize, - OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord - ); - -/** - This interface conveys performance information out of the Security (SEC) phase into PEI. - - This service is published by the SEC phase. The SEC phase handoff has an optional - EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the - PEI Foundation. As such, if the platform supports collecting performance data in SEC, - this information is encapsulated into the data structure abstracted by this service. - This information is collected for the boot-strap processor (BSP) on IA-32. - - @param[in] PeiServices The pointer to the PEI Services Table. - @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI. - @param[out] Performance The pointer to performance data collected in SEC phase. - - @retval EFI_SUCCESS The data was successfully returned. - -**/ -EFI_STATUS -EFIAPI -SecGetPerformance ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN PEI_SEC_PERFORMANCE_PPI *This, - OUT FIRMWARE_SEC_PERFORMANCE *Performance - ); - -/** - This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into - permanent memory. - - @param[in] PeiServices Pointer to the PEI Services Table. - @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the - Temporary RAM contents. - @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the - Temporary RAM contents. - @param[in] CopySize Amount of memory to migrate from temporary to permanent memory. - - @retval EFI_SUCCESS The data was successfully returned. - @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when - TemporaryMemoryBase > PermanentMemoryBase. - -**/ -EFI_STATUS -EFIAPI -SecTemporaryRamSupport ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, - IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, - IN UINTN CopySize - ); - -EFI_SEC_PLATFORM_INFORMATION_PPI mSecPlatformInformationPpi = { - SecPlatformInformation -}; - -PEI_SEC_PERFORMANCE_PPI mSecPerformancePpi = { - SecGetPerformance -}; - -EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI gSecTemporaryRamSupportPpi = { - SecTemporaryRamSupport -}; - -EFI_PEI_PPI_DESCRIPTOR mPeiSecPlatformPpi[] = { - { - EFI_PEI_PPI_DESCRIPTOR_PPI, - &gEfiSecPlatformInformationPpiGuid, - &mSecPlatformInformationPpi - }, - { - EFI_PEI_PPI_DESCRIPTOR_PPI, - &gPeiSecPerformancePpiGuid, - &mSecPerformancePpi - }, - { - EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, - &gEfiTemporaryRamSupportPpiGuid, - &gSecTemporaryRamSupportPpi - }, -}; - -/** - A developer supplied function to perform platform specific operations. - - It's a developer supplied function to perform any operations appropriate to a - given platform. It's invoked just before passing control to PEI core by SEC - core. Platform developer may modify the SecCoreData passed to PEI Core. - It returns a platform specific PPI list that platform wishes to pass to PEI core. - The Generic SEC core module will merge this list to join the final list passed to - PEI core. - - @param[in,out] SecCoreData The same parameter as passing to PEI core. It - could be overridden by this function. - - @return The platform specific PPI list to be passed to PEI core or - NULL if there is no need of such platform specific PPI list. - -**/ -EFI_PEI_PPI_DESCRIPTOR * -EFIAPI -SecPlatformMain ( - IN OUT EFI_SEC_PEI_HAND_OFF *SecCoreData - ) -{ - EFI_PEI_PPI_DESCRIPTOR *PpiList; - - InitializeApicTimer (0, (UINT32) -1, TRUE, 5); - PpiList = &mPeiSecPlatformPpi[0]; - - return PpiList; -} diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S deleted file mode 100644 index 2f1cf6b5d0..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.S +++ /dev/null @@ -1,37 +0,0 @@ -## @file -# Save Sec Conext before call FspInit API -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which 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 -# -## - -#---------------------------------------------------------------------------- -# MMX Usage: -# MM0 = BIST State -# MM5 = Save time-stamp counter value high32bit -# MM6 = Save time-stamp counter value low32bit. -# -# It should be same as SecEntry.asm and PeiCoreEntry.asm. -#---------------------------------------------------------------------------- - -ASM_GLOBAL ASM_PFX(AsmSaveBistValue) -ASM_PFX(AsmSaveBistValue): - movl 4(%esp), %eax - movd %eax, %mm0 - ret - -ASM_GLOBAL ASM_PFX(AsmSaveTickerValue) -ASM_PFX(AsmSaveTickerValue): - movl 4(%esp), %eax - movd %eax, %mm6 - movl 8(%esp), %eax - movd %eax, %mm5 - ret diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm deleted file mode 100644 index 2f767a8264..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/AsmSaveSecContext.asm +++ /dev/null @@ -1,44 +0,0 @@ -;; @file -; Save Sec Conext before call FspInit API -; -; Copyright (c) 2015, Intel Corporation. All rights reserved.
-; -; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which 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. -; -;; - -.686p -.xmm -.model flat,c -.code - -;---------------------------------------------------------------------------- -; MMX Usage: -; MM0 = BIST State -; MM5 = Save time-stamp counter value high32bit -; MM6 = Save time-stamp counter value low32bit. -; -; It should be same as SecEntry.asm and PeiCoreEntry.asm. -;---------------------------------------------------------------------------- - -AsmSaveBistValue PROC PUBLIC - mov eax, [esp+4] - movd mm0, eax - ret -AsmSaveBistValue ENDP - -AsmSaveTickerValue PROC PUBLIC - mov eax, [esp+4] - movd mm6, eax - mov eax, [esp+8] - movd mm5, eax - ret -AsmSaveTickerValue ENDP - -END diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h deleted file mode 100644 index 606c14548f..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Fsp.h +++ /dev/null @@ -1,49 +0,0 @@ -/** @file - Fsp related definitions - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which 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 __FSP_H__ -#define __FSP_H__ - -// -// Fv Header -// -#define FVH_SIGINATURE_OFFSET 0x28 -#define FVH_SIGINATURE_VALID_VALUE 0x4856465F // valid signature:_FVH -#define FVH_HEADER_LENGTH_OFFSET 0x30 -#define FVH_EXTHEADER_OFFSET_OFFSET 0x34 -#define FVH_EXTHEADER_SIZE_OFFSET 0x10 - -// -// Ffs Header -// -#define FSP_HEADER_GUID_DWORD1 0x912740BE -#define FSP_HEADER_GUID_DWORD2 0x47342284 -#define FSP_HEADER_GUID_DWORD3 0xB08471B9 -#define FSP_HEADER_GUID_DWORD4 0x0C3F3527 -#define FFS_HEADER_SIZE_VALUE 0x18 - -// -// Section Header -// -#define SECTION_HEADER_TYPE_OFFSET 0x03 -#define RAW_SECTION_HEADER_SIZE_VALUE 0x04 - -// -// Fsp Header -// -#define FSP_HEADER_IMAGEBASE_OFFSET 0x1C -#define FSP_HEADER_TEMPRAMINIT_OFFSET 0x30 - -#endif diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S deleted file mode 100644 index da851d18f0..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.S +++ /dev/null @@ -1,124 +0,0 @@ -## @file -# Find and call SecStartup -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which 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 -# -## - -ASM_GLOBAL ASM_PFX(CallPeiCoreEntryPoint) -ASM_PFX(CallPeiCoreEntryPoint): - # - # Obtain the hob list pointer - # - movl 0x4(%esp), %eax - # - # Obtain the stack information - # ECX: start of range - # EDX: end of range - # - movl 0x8(%esp), %ecx - movl 0xC(%esp), %edx - - # - # Platform init - # - pushal - pushl %edx - pushl %ecx - pushl %eax - call ASM_PFX(PlatformInit) - popl %eax - popl %eax - popl %eax - popal - - # - # Set stack top pointer - # - movl %edx, %esp - - # - # Push the hob list pointer - # - pushl %eax - - # - # Save the value - # ECX: start of range - # EDX: end of range - # - movl %esp, %ebp - pushl %ecx - pushl %edx - - # - # Push processor count to stack first, then BIST status (AP then BSP) - # - movl $1, %eax - cpuid - shr $16, %ebx - andl $0x000000FF, %ebx - cmp $1, %bl - jae PushProcessorCount - - # - # Some processors report 0 logical processors. Effectively 0 = 1. - # So we fix up the processor count - # - inc %ebx - -PushProcessorCount: - pushl %ebx - - # - # We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST - # for all processor threads - # - xorl %ecx, %ecx - movb %bl, %cl -PushBist: - movd %mm0, %eax - pushl %eax - loop PushBist - - # Save Time-Stamp Counter - movd %mm5, %eax - pushl %eax - - movd %mm6, %eax - pushl %eax - - # - # Pass entry point of the PEI core - # - movl $0xFFFFFFE0, %edi - pushl %ds:(%edi) - - # - # Pass BFV into the PEI Core - # - movl $0xFFFFFFFC, %edi - pushl %ds:(%edi) - - # - # Pass stack size into the PEI Core - # - movl -4(%ebp), %ecx - movl -8(%ebp), %edx - pushl %ecx # RamBase - - subl %ecx, %edx - pushl %edx # RamSize - - # - # Pass Control into the PEI Core - # - call ASM_PFX(SecStartup) diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm deleted file mode 100644 index 808a21b2fc..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/PeiCoreEntry.asm +++ /dev/null @@ -1,134 +0,0 @@ -;; @file -; Find and call SecStartup -; -; Copyright (c) 2015, Intel Corporation. All rights reserved.
-; -; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which 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. -; -;; - -.686p -.xmm -.model flat, c -.code - -EXTRN SecStartup:NEAR -EXTRN PlatformInit:NEAR - -CallPeiCoreEntryPoint PROC PUBLIC - ; - ; Obtain the hob list pointer - ; - mov eax, [esp+4] - ; - ; Obtain the stack information - ; ECX: start of range - ; EDX: end of range - ; - mov ecx, [esp+8] - mov edx, [esp+0Ch] - - ; - ; Platform init - ; - pushad - push edx - push ecx - push eax - call PlatformInit - pop eax - pop eax - pop eax - popad - - ; - ; Set stack top pointer - ; - mov esp, edx - - ; - ; Push the hob list pointer - ; - push eax - - ; - ; Save the value - ; ECX: start of range - ; EDX: end of range - ; - mov ebp, esp - push ecx - push edx - - ; - ; Push processor count to stack first, then BIST status (AP then BSP) - ; - mov eax, 1 - cpuid - shr ebx, 16 - and ebx, 0000000FFh - cmp bl, 1 - jae PushProcessorCount - - ; - ; Some processors report 0 logical processors. Effectively 0 = 1. - ; So we fix up the processor count - ; - inc ebx - -PushProcessorCount: - push ebx - - ; - ; We need to implement a long-term solution for BIST capture. For now, we just copy BSP BIST - ; for all processor threads - ; - xor ecx, ecx - mov cl, bl -PushBist: - movd eax, mm0 - push eax - loop PushBist - - ; Save Time-Stamp Counter - movd eax, mm5 - push eax - - movd eax, mm6 - push eax - - ; - ; Pass entry point of the PEI core - ; - mov edi, 0FFFFFFE0h - push DWORD PTR ds:[edi] - - ; - ; Pass BFV into the PEI Core - ; - mov edi, 0FFFFFFFCh - push DWORD PTR ds:[edi] - - ; - ; Pass stack size into the PEI Core - ; - mov ecx, [ebp - 4] - mov edx, [ebp - 8] - push ecx ; RamBase - - sub edx, ecx - push edx ; RamSize - - ; - ; Pass Control into the PEI Core - ; - call SecStartup -CallPeiCoreEntryPoint ENDP - -END diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S deleted file mode 100644 index 52d897b1d3..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.S +++ /dev/null @@ -1,322 +0,0 @@ -## @file -# This is the code that goes from real-mode to protected mode. -# It consumes the reset vector, calls TempRamInit API from FSP binary. -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which 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 "Fsp.h" - -ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase) -ASM_GLOBAL ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize) - -ASM_GLOBAL ASM_PFX(_TEXT_REALMODE) -ASM_PFX(_TEXT_REALMODE): -#---------------------------------------------------------------------------- -# -# Procedure: _ModuleEntryPoint -# -# Input: None -# -# Output: None -# -# Destroys: Assume all registers -# -# Description: -# -# Transition to non-paged flat-model protected mode from a -# hard-coded GDT that provides exactly two descriptors. -# This is a bare bones transition to protected mode only -# used for a while in PEI and possibly DXE. -# -# After enabling protected mode, a far jump is executed to -# transfer to PEI using the newly loaded GDT. -# -# Return: None -# -# MMX Usage: -# MM0 = BIST State -# MM5 = Save time-stamp counter value high32bit -# MM6 = Save time-stamp counter value low32bit. -# -#---------------------------------------------------------------------------- - -.align 4 -ASM_GLOBAL ASM_PFX(_ModuleEntryPoint) -ASM_PFX(_ModuleEntryPoint): - fninit # clear any pending Floating point exceptions - # - # Store the BIST value in mm0 - # - movd %eax, %mm0 - - # - # Save time-stamp counter value - # rdtsc load 64bit time-stamp counter to EDX:EAX - # - rdtsc - movd %edx, %mm5 - movd %ecx, %mm6 - - # - # Load the GDT table in GdtDesc - # - movl $GdtDesc, %esi - .byte 0x66 - lgdt %cs:(%si) - - # - # Transition to 16 bit protected mode - # - movl %cr0, %eax # Get control register 0 - orl $0x00000003, %eax # Set PE bit (bit #0) & MP bit (bit #1) - movl %eax, %cr0 # Activate protected mode - - movl %cr4, %eax # Get control register 4 - orl $0x00000600, %eax # Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) - movl %eax, %cr4 - - # - # Now we're in 16 bit protected mode - # Set up the selectors for 32 bit protected mode entry - # - movw SYS_DATA_SEL, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movw %ax, %ss - - # - # Transition to Flat 32 bit protected mode - # The jump to a far pointer causes the transition to 32 bit mode - # - movl ASM_PFX(ProtectedModeEntryLinearAddress), %esi - jmp *%cs:(%si) - -ASM_GLOBAL ASM_PFX(_TEXT_PROTECTED_MODE) -ASM_PFX(_TEXT_PROTECTED_MODE): - -#---------------------------------------------------------------------------- -# -# Procedure: ProtectedModeEntryPoint -# -# Input: None -# -# Output: None -# -# Destroys: Assume all registers -# -# Description: -# -# This function handles: -# Call two basic APIs from FSP binary -# Initializes stack with some early data (BIST, PEI entry, etc) -# -# Return: None -# -#---------------------------------------------------------------------------- - -.align 4 -ASM_GLOBAL ASM_PFX(ProtectedModeEntryPoint) -ASM_PFX(ProtectedModeEntryPoint): - - # Find the fsp info header - movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspBase), %edi - movl ASM_PFX(_gPcd_FixedAtBuild_PcdFlashFvFspSize), %ecx - - movl FVH_SIGINATURE_OFFSET(%edi), %eax - cmp $FVH_SIGINATURE_VALID_VALUE, %eax - jnz FspHeaderNotFound - - xorl %eax, %eax - movw FVH_EXTHEADER_OFFSET_OFFSET(%edi), %ax - cmp %ax, 0 - jnz FspFvExtHeaderExist - - xorl %eax, %eax - movw FVH_HEADER_LENGTH_OFFSET(%edi), %ax # Bypass Fv Header - addl %eax, %edi - jmp FspCheckFfsHeader - -FspFvExtHeaderExist: - addl %eax, %edi - movl FVH_EXTHEADER_SIZE_OFFSET(%edi), %eax # Bypass Ext Fv Header - addl %eax, %edi - - # Round up to 8 byte alignment - movl %edi, %eax - andb $0x07, %al - jz FspCheckFfsHeader - - and $0xFFFFFFF8, %edi - add $0x08, %edi - -FspCheckFfsHeader: - # Check the ffs guid - movl (%edi), %eax - cmp $FSP_HEADER_GUID_DWORD1, %eax - jnz FspHeaderNotFound - - movl 0x4(%edi), %eax - cmp $FSP_HEADER_GUID_DWORD2, %eax - jnz FspHeaderNotFound - - movl 0x08(%edi), %eax - cmp $FSP_HEADER_GUID_DWORD3, %eax - jnz FspHeaderNotFound - - movl 0x0c(%edi), %eax - cmp $FSP_HEADER_GUID_DWORD4, %eax - jnz FspHeaderNotFound - - add $FFS_HEADER_SIZE_VALUE, %edi # Bypass the ffs header - - # Check the section type as raw section - movb SECTION_HEADER_TYPE_OFFSET(%edi), %al - cmp $0x19, %al - jnz FspHeaderNotFound - - addl $RAW_SECTION_HEADER_SIZE_VALUE, %edi # Bypass the section header - jmp FspHeaderFound - -FspHeaderNotFound: - jmp . - -FspHeaderFound: - # Get the fsp TempRamInit Api address - movl FSP_HEADER_IMAGEBASE_OFFSET(%edi), %eax - addl FSP_HEADER_TEMPRAMINIT_OFFSET(%edi), %eax - - # Setup the hardcode stack - movl $TempRamInitStack, %esp - - # Call the fsp TempRamInit Api - jmp *%eax - -TempRamInitDone: - cmp $0x0, %eax - jnz FspApiFailed - - # ECX: start of range - # EDX: end of range - movl %edx, %esp - pushl %edx - pushl %ecx - pushl %eax # zero - no hob list yet - call ASM_PFX(CallPeiCoreEntryPoint) - -FspApiFailed: - jmp . - -.align 0x10 -TempRamInitStack: - .long TempRamInitDone - .long ASM_PFX(TempRamInitParams) - -# -# ROM-based Global-Descriptor Table for the Tiano PEI Phase -# -.align 16 - -# -# GDT[0]: 0x00: Null entry, never used. -# -.equ NULL_SEL, . - GDT_BASE # Selector [0] -GDT_BASE: -BootGdtTable: .long 0 - .long 0 -# -# Linear data segment descriptor -# -.equ LINEAR_SEL, . - GDT_BASE # Selector [0x8] - .word 0xFFFF # limit 0xFFFFF - .word 0 # base 0 - .byte 0 - .byte 0x92 # present, ring 0, data, expand-up, writable - .byte 0xCF # page-granular, 32-bit - .byte 0 -# -# Linear code segment descriptor -# -.equ LINEAR_CODE_SEL, . - GDT_BASE # Selector [0x10] - .word 0xFFFF # limit 0xFFFFF - .word 0 # base 0 - .byte 0 - .byte 0x9B # present, ring 0, data, expand-up, not-writable - .byte 0xCF # page-granular, 32-bit - .byte 0 -# -# System data segment descriptor -# -.equ SYS_DATA_SEL, . - GDT_BASE # Selector [0x18] - .word 0xFFFF # limit 0xFFFFF - .word 0 # base 0 - .byte 0 - .byte 0x93 # present, ring 0, data, expand-up, not-writable - .byte 0xCF # page-granular, 32-bit - .byte 0 - -# -# System code segment descriptor -# -.equ SYS_CODE_SEL, . - GDT_BASE # Selector [0x20] - .word 0xFFFF # limit 0xFFFFF - .word 0 # base 0 - .byte 0 - .byte 0x9A # present, ring 0, data, expand-up, writable - .byte 0xCF # page-granular, 32-bit - .byte 0 -# -# Spare segment descriptor -# -.equ SYS16_CODE_SEL, . - GDT_BASE # Selector [0x28] - .word 0xFFFF # limit 0xFFFFF - .word 0 # base 0 - .byte 0x0E # Changed from F000 to E000. - .byte 0x9B # present, ring 0, code, expand-up, writable - .byte 0x00 # byte-granular, 16-bit - .byte 0 -# -# Spare segment descriptor -# -.equ SYS16_DATA_SEL, . - GDT_BASE # Selector [0x30] - .word 0xFFFF # limit 0xFFFF - .word 0 # base 0 - .byte 0 - .byte 0x93 # present, ring 0, data, expand-up, not-writable - .byte 0x00 # byte-granular, 16-bit - .byte 0 - -# -# Spare segment descriptor -# -.equ SPARE5_SEL, . - GDT_BASE # Selector [0x38] - .word 0 # limit 0 - .word 0 # base 0 - .byte 0 - .byte 0 # present, ring 0, data, expand-up, writable - .byte 0 # page-granular, 32-bit - .byte 0 -.equ GDT_SIZE, . - BootGdtTable # Size, in bytes - -# -# GDT Descriptor -# -GdtDesc: # GDT descriptor - .word GDT_SIZE - 1 # GDT limit - .long BootGdtTable # GDT base address - -ASM_PFX(ProtectedModeEntryLinearAddress): -ProtectedModeEntryLinearOffset: - .long ASM_PFX(ProtectedModeEntryPoint) # Offset of our 32 bit code - .word LINEAR_CODE_SEL diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm deleted file mode 100644 index 9b2a526549..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/SecEntry.asm +++ /dev/null @@ -1,340 +0,0 @@ -;; @file -; This is the code that goes from real-mode to protected mode. -; It consumes the reset vector, calls TempRamInit API from FSP binary. -; -; Copyright (c) 2015, Intel Corporation. All rights reserved.
-; -; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which 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 "Fsp.h" - -.686p -.xmm -.model small, c - -EXTRN CallPeiCoreEntryPoint:NEAR -EXTRN TempRamInitParams:FAR - -; Pcds -EXTRN PcdGet32 (PcdFlashFvFspBase):DWORD -EXTRN PcdGet32 (PcdFlashFvFspSize):DWORD - -_TEXT_REALMODE SEGMENT PARA PUBLIC USE16 'CODE' - ASSUME CS:_TEXT_REALMODE, DS:_TEXT_REALMODE - -;---------------------------------------------------------------------------- -; -; Procedure: _ModuleEntryPoint -; -; Input: None -; -; Output: None -; -; Destroys: Assume all registers -; -; Description: -; -; Transition to non-paged flat-model protected mode from a -; hard-coded GDT that provides exactly two descriptors. -; This is a bare bones transition to protected mode only -; used for a while in PEI and possibly DXE. -; -; After enabling protected mode, a far jump is executed to -; transfer to PEI using the newly loaded GDT. -; -; Return: None -; -; MMX Usage: -; MM0 = BIST State -; MM5 = Save time-stamp counter value high32bit -; MM6 = Save time-stamp counter value low32bit. -; -;---------------------------------------------------------------------------- - -align 4 -_ModuleEntryPoint PROC NEAR C PUBLIC - fninit ; clear any pending Floating point exceptions - ; - ; Store the BIST value in mm0 - ; - movd mm0, eax - - ; - ; Save time-stamp counter value - ; rdtsc load 64bit time-stamp counter to EDX:EAX - ; - rdtsc - movd mm5, edx - movd mm6, eax - - ; - ; Load the GDT table in GdtDesc - ; - mov esi, OFFSET GdtDesc - DB 66h - lgdt fword ptr cs:[si] - - ; - ; Transition to 16 bit protected mode - ; - mov eax, cr0 ; Get control register 0 - or eax, 00000003h ; Set PE bit (bit #0) & MP bit (bit #1) - mov cr0, eax ; Activate protected mode - - mov eax, cr4 ; Get control register 4 - or eax, 00000600h ; Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10) - mov cr4, eax - - ; - ; Now we're in 16 bit protected mode - ; Set up the selectors for 32 bit protected mode entry - ; - mov ax, SYS_DATA_SEL - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - - ; - ; Transition to Flat 32 bit protected mode - ; The jump to a far pointer causes the transition to 32 bit mode - ; - mov esi, offset ProtectedModeEntryLinearAddress - jmp fword ptr cs:[si] - -_ModuleEntryPoint ENDP -_TEXT_REALMODE ENDS - -_TEXT_PROTECTED_MODE SEGMENT PARA PUBLIC USE32 'CODE' - ASSUME CS:_TEXT_PROTECTED_MODE, DS:_TEXT_PROTECTED_MODE - -;---------------------------------------------------------------------------- -; -; Procedure: ProtectedModeEntryPoint -; -; Input: None -; -; Output: None -; -; Destroys: Assume all registers -; -; Description: -; -; This function handles: -; Call two basic APIs from FSP binary -; Initializes stack with some early data (BIST, PEI entry, etc) -; -; Return: None -; -;---------------------------------------------------------------------------- - -align 4 -ProtectedModeEntryPoint PROC NEAR PUBLIC - - ; Find the fsp info header - mov edi, PcdGet32 (PcdFlashFvFspBase) - mov ecx, PcdGet32 (PcdFlashFvFspSize) - - mov eax, dword ptr [edi + FVH_SIGINATURE_OFFSET] - cmp eax, FVH_SIGINATURE_VALID_VALUE - jnz FspHeaderNotFound - - xor eax, eax - mov ax, word ptr [edi + FVH_EXTHEADER_OFFSET_OFFSET] - cmp ax, 0 - jnz FspFvExtHeaderExist - - xor eax, eax - mov ax, word ptr [edi + FVH_HEADER_LENGTH_OFFSET] ; Bypass Fv Header - add edi, eax - jmp FspCheckFfsHeader - -FspFvExtHeaderExist: - add edi, eax - mov eax, dword ptr [edi + FVH_EXTHEADER_SIZE_OFFSET] ; Bypass Ext Fv Header - add edi, eax - - ; Round up to 8 byte alignment - mov eax, edi - and al, 07h - jz FspCheckFfsHeader - - and edi, 0FFFFFFF8h - add edi, 08h - -FspCheckFfsHeader: - ; Check the ffs guid - mov eax, dword ptr [edi] - cmp eax, FSP_HEADER_GUID_DWORD1 - jnz FspHeaderNotFound - - mov eax, dword ptr [edi + 4] - cmp eax, FSP_HEADER_GUID_DWORD2 - jnz FspHeaderNotFound - - mov eax, dword ptr [edi + 8] - cmp eax, FSP_HEADER_GUID_DWORD3 - jnz FspHeaderNotFound - - mov eax, dword ptr [edi + 0Ch] - cmp eax, FSP_HEADER_GUID_DWORD4 - jnz FspHeaderNotFound - - add edi, FFS_HEADER_SIZE_VALUE ; Bypass the ffs header - - ; Check the section type as raw section - mov al, byte ptr [edi + SECTION_HEADER_TYPE_OFFSET] - cmp al, 019h - jnz FspHeaderNotFound - - add edi, RAW_SECTION_HEADER_SIZE_VALUE ; Bypass the section header - jmp FspHeaderFound - -FspHeaderNotFound: - jmp $ - -FspHeaderFound: - ; Get the fsp TempRamInit Api address - mov eax, dword ptr [edi + FSP_HEADER_IMAGEBASE_OFFSET] - add eax, dword ptr [edi + FSP_HEADER_TEMPRAMINIT_OFFSET] - - ; Setup the hardcode stack - mov esp, OFFSET TempRamInitStack - - ; Call the fsp TempRamInit Api - jmp eax - -TempRamInitDone: - cmp eax, 0 - jnz FspApiFailed - - ; ECX: start of range - ; EDX: end of range - mov esp, edx - push edx - push ecx - push eax ; zero - no hob list yet - call CallPeiCoreEntryPoint - -FspApiFailed: - jmp $ - -align 10h -TempRamInitStack: - DD OFFSET TempRamInitDone - DD OFFSET TempRamInitParams - -ProtectedModeEntryPoint ENDP - -; -; ROM-based Global-Descriptor Table for the Tiano PEI Phase -; -align 16 -PUBLIC BootGdtTable - -; -; GDT[0]: 0x00: Null entry, never used. -; -NULL_SEL EQU $ - GDT_BASE ; Selector [0] -GDT_BASE: -BootGdtTable DD 0 - DD 0 -; -; Linear data segment descriptor -; -LINEAR_SEL EQU $ - GDT_BASE ; Selector [0x8] - DW 0FFFFh ; limit 0xFFFFF - DW 0 ; base 0 - DB 0 - DB 092h ; present, ring 0, data, expand-up, writable - DB 0CFh ; page-granular, 32-bit - DB 0 -; -; Linear code segment descriptor -; -LINEAR_CODE_SEL EQU $ - GDT_BASE ; Selector [0x10] - DW 0FFFFh ; limit 0xFFFFF - DW 0 ; base 0 - DB 0 - DB 09Bh ; present, ring 0, data, expand-up, not-writable - DB 0CFh ; page-granular, 32-bit - DB 0 -; -; System data segment descriptor -; -SYS_DATA_SEL EQU $ - GDT_BASE ; Selector [0x18] - DW 0FFFFh ; limit 0xFFFFF - DW 0 ; base 0 - DB 0 - DB 093h ; present, ring 0, data, expand-up, not-writable - DB 0CFh ; page-granular, 32-bit - DB 0 - -; -; System code segment descriptor -; -SYS_CODE_SEL EQU $ - GDT_BASE ; Selector [0x20] - DW 0FFFFh ; limit 0xFFFFF - DW 0 ; base 0 - DB 0 - DB 09Ah ; present, ring 0, data, expand-up, writable - DB 0CFh ; page-granular, 32-bit - DB 0 -; -; Spare segment descriptor -; -SYS16_CODE_SEL EQU $ - GDT_BASE ; Selector [0x28] - DW 0FFFFh ; limit 0xFFFFF - DW 0 ; base 0 - DB 0Eh ; Changed from F000 to E000. - DB 09Bh ; present, ring 0, code, expand-up, writable - DB 00h ; byte-granular, 16-bit - DB 0 -; -; Spare segment descriptor -; -SYS16_DATA_SEL EQU $ - GDT_BASE ; Selector [0x30] - DW 0FFFFh ; limit 0xFFFF - DW 0 ; base 0 - DB 0 - DB 093h ; present, ring 0, data, expand-up, not-writable - DB 00h ; byte-granular, 16-bit - DB 0 - -; -; Spare segment descriptor -; -SPARE5_SEL EQU $ - GDT_BASE ; Selector [0x38] - DW 0 ; limit 0 - DW 0 ; base 0 - DB 0 - DB 0 ; present, ring 0, data, expand-up, writable - DB 0 ; page-granular, 32-bit - DB 0 -GDT_SIZE EQU $ - BootGdtTable ; Size, in bytes - -; -; GDT Descriptor -; -GdtDesc: ; GDT descriptor - DW GDT_SIZE - 1 ; GDT limit - DD OFFSET BootGdtTable ; GDT base address - - -ProtectedModeEntryLinearAddress LABEL FWORD -ProtectedModeEntryLinearOffset LABEL DWORD - DD OFFSET ProtectedModeEntryPoint ; Offset of our 32 bit code - DW LINEAR_CODE_SEL - -_TEXT_PROTECTED_MODE ENDS -END diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S deleted file mode 100644 index bbfdc11ebf..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.S +++ /dev/null @@ -1,74 +0,0 @@ -## @file -# Switch the stack from temporary memory to permenent memory. -# -# Copyright (c) 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which 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 -# -## - -#------------------------------------------------------------------------------ -# VOID -# EFIAPI -# SecSwitchStack ( -# UINT32 TemporaryMemoryBase, -# UINT32 PermenentMemoryBase -# )# -#------------------------------------------------------------------------------ -ASM_GLOBAL ASM_PFX (SecSwitchStack) -ASM_PFX(SecSwitchStack): - # - # Save standard registers so they can be used to change stack - # - pushl %eax - pushl %ebx - pushl %ecx - pushl %edx - - # - # !!CAUTION!! this function address's is pushed into stack after - # migration of whole temporary memory, so need save it to permenent - # memory at first! - # - movl 20(%esp), %ebx # Save the first parameter - movl 24(%esp), %ecx # Save the second parameter - - # - # Save this function's return address into permenent memory at first. - # Then, Fixup the esp point to permenent memory - # - movl %esp, %eax - subl %ebx, %eax - addl %ecx, %eax - movl 0(%esp), %edx # copy pushed register's value to permenent memory - movl %edx, 0(%eax) - movl 4(%esp), %edx - movl %edx, 4(%eax) - movl 8(%esp), %edx - movl %edx, 8(%eax) - movl 12(%esp), %edx - movl %edx, 12(%eax) - movl 16(%esp), %edx # Update this function's return address into permenent memory - movl %edx, 16(%eax) - movl %eax, %esp # From now, esp is pointed to permenent memory - - # - # Fixup the ebp point to permenent memory - # - movl %ebp, %eax - subl %ebx, %eax - addl %ecx, %eax - movl %eax, %ebp # From now, ebp is pointed to permenent memory - - popl %edx - popl %ecx - popl %ebx - popl %eax - ret - diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm deleted file mode 100644 index e9618fc34a..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/Ia32/Stack.asm +++ /dev/null @@ -1,80 +0,0 @@ -;; @file -; Switch the stack from temporary memory to permenent memory. -; -; Copyright (c) 2015, Intel Corporation. All rights reserved.
-; -; This program and the accompanying materials -; are licensed and made available under the terms and conditions of the BSD License -; which 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. -; -;; - - .586p - .model flat,C - .code - -;------------------------------------------------------------------------------ -; VOID -; EFIAPI -; SecSwitchStack ( -; UINT32 TemporaryMemoryBase, -; UINT32 PermenentMemoryBase -; ); -;------------------------------------------------------------------------------ -SecSwitchStack PROC - ; - ; Save three register: eax, ebx, ecx - ; - push eax - push ebx - push ecx - push edx - - ; - ; !!CAUTION!! this function address's is pushed into stack after - ; migration of whole temporary memory, so need save it to permenent - ; memory at first! - ; - - mov ebx, [esp + 20] ; Save the first parameter - mov ecx, [esp + 24] ; Save the second parameter - - ; - ; Save this function's return address into permenent memory at first. - ; Then, Fixup the esp point to permenent memory - ; - mov eax, esp - sub eax, ebx - add eax, ecx - mov edx, dword ptr [esp] ; copy pushed register's value to permenent memory - mov dword ptr [eax], edx - mov edx, dword ptr [esp + 4] - mov dword ptr [eax + 4], edx - mov edx, dword ptr [esp + 8] - mov dword ptr [eax + 8], edx - mov edx, dword ptr [esp + 12] - mov dword ptr [eax + 12], edx - mov edx, dword ptr [esp + 16] ; Update this function's return address into permenent memory - mov dword ptr [eax + 16], edx - mov esp, eax ; From now, esp is pointed to permenent memory - - ; - ; Fixup the ebp point to permenent memory - ; - mov eax, ebp - sub eax, ebx - add eax, ecx - mov ebp, eax ; From now, ebp is pointed to permenent memory - - pop edx - pop ecx - pop ebx - pop eax - ret -SecSwitchStack ENDP - - END diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c deleted file mode 100644 index a9703b6d1a..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/PlatformInit.c +++ /dev/null @@ -1,45 +0,0 @@ -/** @file - Sample to provide platform init function. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which 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 -#include - -/** - Platform initialization. - - @param[in] FspHobList HobList produced by FSP. - @param[in] StartOfRange Start of temporary RAM. - @param[in] EndOfRange End of temporary RAM. - -**/ -VOID -EFIAPI -PlatformInit ( - IN VOID *FspHobList, - IN VOID *StartOfRange, - IN VOID *EndOfRange - ) -{ - // - // Platform initialization - // Enable Serial port here - // - - DEBUG ((DEBUG_INFO, "PrintPeiCoreEntryPointParam\n")); - DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList)); - DEBUG ((DEBUG_INFO, "StartOfRange - 0x%x\n", StartOfRange)); - DEBUG ((DEBUG_INFO, "EndOfRange - 0x%x\n", EndOfRange)); -} diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c deleted file mode 100644 index 8f875fe6a4..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SaveSecContext.c +++ /dev/null @@ -1,114 +0,0 @@ -/** @file - Sample to provide SaveSecContext function. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which 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 -#include -#include -#include - -/** - Save BIST value before call FspInit. - - @param[in] Bist BIST value. - -**/ -VOID -AsmSaveBistValue ( - IN UINT32 Bist - ); - -/** - Save Ticker value before call FspInit. - - @param[in] Ticker Ticker value. - -**/ -VOID -AsmSaveTickerValue ( - IN UINT64 Ticker - ); - -/** - Save SEC context before call FspInit. - - @param[in] PeiServices Pointer to PEI Services Table. - -**/ -VOID -EFIAPI -SaveSecContext ( - IN CONST EFI_PEI_SERVICES **PeiServices - ) -{ - UINT32 *Bist; - UINT64 *Ticker; - UINT32 Size; - UINT32 Count; - UINT32 TopOfTemporaryRam; - VOID *TopOfTemporaryRamPpi; - EFI_STATUS Status; - - DEBUG ((DEBUG_INFO, "SaveSecContext - 0x%x\n", PeiServices)); - - Status = (*PeiServices)->LocatePpi ( - PeiServices, - &gTopOfTemporaryRamPpiGuid, - 0, - NULL, - (VOID **) &TopOfTemporaryRamPpi - ); - if (EFI_ERROR (Status)) { - return ; - } - - DEBUG ((DEBUG_INFO, "TopOfTemporaryRamPpi - 0x%x\n", TopOfTemporaryRamPpi)); - - // - // The entries of BIST information, together with the number of them, - // reside in the bottom of stack, left untouched by normal stack operation. - // This routine copies the BIST information to the buffer pointed by - // PlatformInformationRecord for output. - // - // |--------------| <- TopOfTemporaryRam - // |Number of BSPs| - // |--------------| - // | BIST | - // |--------------| - // | .... | - // |--------------| - // | TSC[63:32] | - // |--------------| - // | TSC[31:00] | - // |--------------| - // - - TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof(UINT32); - TopOfTemporaryRam -= sizeof(UINT32) * 2; - DEBUG ((DEBUG_INFO, "TopOfTemporaryRam - 0x%x\n", TopOfTemporaryRam)); - Count = *(UINT32 *)(UINTN)(TopOfTemporaryRam - sizeof(UINT32)); - DEBUG ((DEBUG_INFO, "Count - 0x%x\n", Count)); - Size = Count * sizeof (IA32_HANDOFF_STATUS); - DEBUG ((DEBUG_INFO, "Size - 0x%x\n", Size)); - - Bist = (UINT32 *)(UINTN)(TopOfTemporaryRam - sizeof(UINT32) - Size); - DEBUG ((DEBUG_INFO, "Bist - 0x%x\n", *Bist)); - Ticker = (UINT64 *)(UINTN)(TopOfTemporaryRam - sizeof(UINT32) - Size - sizeof(UINT64)); - DEBUG ((DEBUG_INFO, "Ticker - 0x%lx\n", *Ticker)); - - // Just need record BSP - AsmSaveBistValue (*Bist); - AsmSaveTickerValue (*Ticker); -} diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c deleted file mode 100644 index d6085b73c7..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecGetPerformance.c +++ /dev/null @@ -1,89 +0,0 @@ -/** @file - Sample to provide SecGetPerformance function. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which 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 -#include -#include -#include -#include -#include - -/** - This interface conveys performance information out of the Security (SEC) phase into PEI. - - This service is published by the SEC phase. The SEC phase handoff has an optional - EFI_PEI_PPI_DESCRIPTOR list as its final argument when control is passed from SEC into the - PEI Foundation. As such, if the platform supports collecting performance data in SEC, - this information is encapsulated into the data structure abstracted by this service. - This information is collected for the boot-strap processor (BSP) on IA-32. - - @param[in] PeiServices The pointer to the PEI Services Table. - @param[in] This The pointer to this instance of the PEI_SEC_PERFORMANCE_PPI. - @param[out] Performance The pointer to performance data collected in SEC phase. - - @retval EFI_SUCCESS The data was successfully returned. - -**/ -EFI_STATUS -EFIAPI -SecGetPerformance ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN PEI_SEC_PERFORMANCE_PPI *This, - OUT FIRMWARE_SEC_PERFORMANCE *Performance - ) -{ - UINT32 Size; - UINT32 Count; - UINT32 TopOfTemporaryRam; - UINT64 Ticker; - VOID *TopOfTemporaryRamPpi; - EFI_STATUS Status; - - DEBUG ((DEBUG_INFO, "SecGetPerformance\n")); - - Status = (*PeiServices)->LocatePpi ( - PeiServices, - &gTopOfTemporaryRamPpiGuid, - 0, - NULL, - (VOID **) &TopOfTemporaryRamPpi - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - // - // |--------------| <- TopOfTemporaryRam - // |Number of BSPs| - // |--------------| - // | BIST | - // |--------------| - // | .... | - // |--------------| - // | TSC[63:32] | - // |--------------| - // | TSC[31:00] | - // |--------------| - // - TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof(UINT32); - TopOfTemporaryRam -= sizeof(UINT32) * 2; - Count = *(UINT32 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32)); - Size = Count * sizeof (UINT64); - - Ticker = *(UINT64 *) (UINTN) (TopOfTemporaryRam - sizeof (UINT32) - Size - sizeof (UINT32) * 2); - Performance->ResetEnd = GetTimeInNanoSecond (Ticker); - - return EFI_SUCCESS; -} diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf deleted file mode 100644 index 8d019d827d..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPeiFspPlatformSecLibSample.inf +++ /dev/null @@ -1,94 +0,0 @@ -## @file -# Sample to provide FSP wrapper platform sec related function. -# -# Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.
-# -# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which 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 Section - statements that will be processed to create a Makefile. -# -################################################################################ -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = SecPeiFspPlatformSecLibSample - FILE_GUID = 5B2B6493-BEBB-4d44-8278-35F40F5289BC - MODULE_TYPE = SEC - VERSION_STRING = 1.0 - LIBRARY_CLASS = FspPlatformSecLib - - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -################################################################################ -# -# Sources Section - list of files that are required for the build to succeed. -# -################################################################################ - -[Sources] - FspPlatformSecLibSample.c - SecRamInitData.c - SaveSecContext.c - SecPlatformInformation.c - SecGetPerformance.c - SecTempRamSupport.c - PlatformInit.c - -[Sources.IA32] - Ia32/SecEntry.asm - Ia32/PeiCoreEntry.asm - Ia32/AsmSaveSecContext.asm - Ia32/Stack.asm - Ia32/Fsp.h - Ia32/SecEntry.S - Ia32/PeiCoreEntry.S - Ia32/AsmSaveSecContext.S - Ia32/Stack.S - -################################################################################ -# -# Package Dependency Section - list of Package files that are required for -# this module. -# -################################################################################ - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - UefiCpuPkg/UefiCpuPkg.dec - IntelFspPkg/IntelFspPkg.dec - IntelFspWrapperPkg/IntelFspWrapperPkg.dec - -[LibraryClasses] - LocalApicLib - -[Ppis] - gEfiSecPlatformInformationPpiGuid ## CONSUMES - gPeiSecPerformancePpiGuid ## CONSUMES - gEfiTemporaryRamSupportPpiGuid ## CONSUMES - -[Pcd] - gFspWrapperTokenSpaceGuid.PcdPeiTemporaryRamStackSize ## CONSUMES - gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase ## CONSUMES - gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize ## CONSUMES - -[FixedPcd] - gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchAddress ## CONSUMES - gFspWrapperTokenSpaceGuid.PcdCpuMicrocodePatchRegionSize ## CONSUMES - gFspWrapperTokenSpaceGuid.PcdFlashMicroCodeOffset ## CONSUMES - gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheAddress ## CONSUMES - gFspWrapperTokenSpaceGuid.PcdFlashCodeCacheSize ## CONSUMES diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c deleted file mode 100644 index ebf3d12ddc..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecPlatformInformation.c +++ /dev/null @@ -1,83 +0,0 @@ -/** @file - Sample to provide SecPlatformInformation function. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which 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 -#include -#include -#include -#include - -/** - This interface conveys state information out of the Security (SEC) phase into PEI. - - @param[in] PeiServices Pointer to the PEI Services Table. - @param[in,out] StructureSize Pointer to the variable describing size of the input buffer. - @param[out] PlatformInformationRecord Pointer to the EFI_SEC_PLATFORM_INFORMATION_RECORD. - - @retval EFI_SUCCESS The data was successfully returned. - @retval EFI_BUFFER_TOO_SMALL The buffer was too small. - -**/ -EFI_STATUS -EFIAPI -SecPlatformInformation ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN OUT UINT64 *StructureSize, - OUT EFI_SEC_PLATFORM_INFORMATION_RECORD *PlatformInformationRecord - ) -{ - UINT32 *Bist; - UINT32 Size; - UINT32 Count; - UINT32 TopOfTemporaryRam; - VOID *TopOfTemporaryRamPpi; - EFI_STATUS Status; - - DEBUG ((DEBUG_INFO, "SecPlatformInformation\n")); - - Status = (*PeiServices)->LocatePpi ( - PeiServices, - &gTopOfTemporaryRamPpiGuid, - 0, - NULL, - (VOID **) &TopOfTemporaryRamPpi - ); - if (EFI_ERROR (Status)) { - return EFI_NOT_FOUND; - } - - // - // The entries of BIST information, together with the number of them, - // reside in the bottom of stack, left untouched by normal stack operation. - // This routine copies the BIST information to the buffer pointed by - // PlatformInformationRecord for output. - // - TopOfTemporaryRam = (UINT32)(UINTN)TopOfTemporaryRamPpi - sizeof (UINT32); - TopOfTemporaryRam -= sizeof(UINT32) * 2; - Count = *((UINT32 *)(UINTN) (TopOfTemporaryRam - sizeof (UINT32))); - Size = Count * sizeof (IA32_HANDOFF_STATUS); - - if ((*StructureSize) < (UINT64) Size) { - *StructureSize = Size; - return EFI_BUFFER_TOO_SMALL; - } - - *StructureSize = Size; - Bist = (UINT32 *) (TopOfTemporaryRam - sizeof (UINT32) - Size); - - CopyMem (PlatformInformationRecord, Bist, Size); - - return EFI_SUCCESS; -} diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c deleted file mode 100644 index 26fed03611..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecRamInitData.c +++ /dev/null @@ -1,23 +0,0 @@ -/** @file - Sample to provide TempRamInitParams data. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which 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 - -GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT32 TempRamInitParams[4] = { - ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchAddress) + FixedPcdGet32 (PcdFlashMicroCodeOffset)), - ((UINT32)FixedPcdGet64 (PcdCpuMicrocodePatchRegionSize) - FixedPcdGet32 (PcdFlashMicroCodeOffset)), - FixedPcdGet32 (PcdFlashCodeCacheAddress), - FixedPcdGet32 (PcdFlashCodeCacheSize) -}; diff --git a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c b/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c deleted file mode 100644 index 419cf9c8e4..0000000000 --- a/BraswellPlatformPkg/Override/IntelFspWrapperPkg/Library/SecPeiFspPlatformSecLibSample/SecTempRamSupport.c +++ /dev/null @@ -1,154 +0,0 @@ -/** @file - Sample to provide SecTemporaryRamSupport function. - - Copyright (c) 2015, Intel Corporation. All rights reserved.
- - This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which 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 -#include -#include -#include -#include -#include - -/** - Switch the stack in the temporary memory to the one in the permanent memory. - - This function must be invoked after the memory migration immediately. The relative - position of the stack in the temporary and permanent memory is same. - - @param[in] TemporaryMemoryBase Base address of the temporary memory. - @param[in] PermenentMemoryBase Base address of the permanent memory. - -**/ -VOID -EFIAPI -SecSwitchStack ( - IN UINT32 TemporaryMemoryBase, - IN UINT32 PermenentMemoryBase - ); - -/** - This service of the TEMPORARY_RAM_SUPPORT_PPI that migrates temporary RAM into - permanent memory. - - @param[in] PeiServices Pointer to the PEI Services Table. - @param[in] TemporaryMemoryBase Source Address in temporary memory from which the SEC or PEIM will copy the - Temporary RAM contents. - @param[in] PermanentMemoryBase Destination Address in permanent memory into which the SEC or PEIM will copy the - Temporary RAM contents. - @param[in] CopySize Amount of memory to migrate from temporary to permanent memory. - - @retval EFI_SUCCESS The data was successfully returned. - @retval EFI_INVALID_PARAMETER PermanentMemoryBase + CopySize > TemporaryMemoryBase when - TemporaryMemoryBase > PermanentMemoryBase. - -**/ -EFI_STATUS -EFIAPI -SecTemporaryRamSupport ( - IN CONST EFI_PEI_SERVICES **PeiServices, - IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, - IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, - IN UINTN CopySize - ) -{ - IA32_DESCRIPTOR IdtDescriptor; - VOID* OldHeap; - VOID* NewHeap; - VOID* OldStack; - VOID* NewStack; - DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext; - BOOLEAN OldStatus; - UINTN PeiStackSize; - - PeiStackSize = (UINTN)PcdGet32 (PcdPeiTemporaryRamStackSize); - if (PeiStackSize == 0) { - PeiStackSize = (CopySize >> 1); - } - - ASSERT (PeiStackSize < CopySize); - - // - // |-------------------|----> - // | Stack | PeiStackSize - // |-------------------|----> - // | Heap | PeiTemporayRamSize - // |-------------------|----> TempRamBase - // - // |-------------------|----> - // | Heap | PeiTemporayRamSize - // |-------------------|----> - // | Stack | PeiStackSize - // |-------------------|----> PermanentMemoryBase - // - - OldHeap = (VOID*)(UINTN)TemporaryMemoryBase; - NewHeap = (VOID*)((UINTN)PermanentMemoryBase + PeiStackSize); - - OldStack = (VOID*)((UINTN)TemporaryMemoryBase + CopySize - PeiStackSize); - NewStack = (VOID*)(UINTN)PermanentMemoryBase; - - DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap; - DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack; - - OldStatus = SaveAndSetDebugTimerInterrupt (FALSE); - // - // Initialize Debug Agent to support source level debug in PEI phase after memory ready. - // It will build HOB and fix up the pointer in IDT table. - // - InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL); - - // - // Migrate Heap - // - CopyMem (NewHeap, OldHeap, CopySize - PeiStackSize); - - // - // Migrate Stack - // - CopyMem (NewStack, OldStack, PeiStackSize); - - - // - // We need *not* fix the return address because currently, - // The PeiCore is executed in flash. - // - - // - // Rebase IDT table in permanent memory - // - AsmReadIdtr (&IdtDescriptor); - IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack; - - AsmWriteIdtr (&IdtDescriptor); - - - // - // Program MTRR - // - - // - // SecSwitchStack function must be invoked after the memory migration - // immediatly, also we need fixup the stack change caused by new call into - // permenent memory. - // - SecSwitchStack ( - (UINT32) (UINTN) OldStack, - (UINT32) (UINTN) NewStack - ); - - SaveAndSetDebugTimerInterrupt (OldStatus); - - return EFI_SUCCESS; -} - diff --git a/BraswellPlatformPkg/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c b/BraswellPlatformPkg/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c deleted file mode 100644 index bc7ba44dee..0000000000 --- a/BraswellPlatformPkg/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.c +++ /dev/null @@ -1,1094 +0,0 @@ -/** @file - 16550 UART Serial Port library functions - - (C) Copyright 2014 Hewlett-Packard Development Company, L.P.
- Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
- This program and the accompanying materials - are licensed and made available under the terms and conditions of the BSD License - which 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 -#include -#include -#include -#include -#include -#include -#include - -// -// PCI Defintions. -// -#define PCI_BRIDGE_32_BIT_IO_SPACE 0x01 - -// -// 16550 UART register offsets and bitfields -// -#define R_UART_RXBUF 0 -#define R_UART_TXBUF 0 -#define R_UART_BAUD_LOW 0 -#define R_UART_BAUD_HIGH 1 -#define R_UART_FCR 2 -#define B_UART_FCR_FIFOE BIT0 -#define B_UART_FCR_FIFO64 BIT5 -#define R_UART_LCR 3 -#define B_UART_LCR_DLAB BIT7 -#define R_UART_MCR 4 -#define B_UART_MCR_DTRC BIT0 -#define B_UART_MCR_RTS BIT1 -#define R_UART_LSR 5 -#define B_UART_LSR_RXRDY BIT0 -#define B_UART_LSR_TXRDY BIT5 -#define B_UART_LSR_TEMT BIT6 -#define R_UART_MSR 6 -#define B_UART_MSR_CTS BIT4 -#define B_UART_MSR_DSR BIT5 -#define B_UART_MSR_RI BIT6 -#define B_UART_MSR_DCD BIT7 - -// -// 4-byte structure for each PCI node in PcdSerialPciDeviceInfo -// -typedef struct { - UINT8 Device; - UINT8 Function; - UINT16 PowerManagementStatusAndControlRegister; -} PCI_UART_DEVICE_INFO; - -/** - Read an 8-bit 16550 register. If PcdSerialUseMmio is TRUE, then the value is read from - MMIO space. If PcdSerialUseMmio is FALSE, then the value is read from I/O space. The - parameter Offset is added to the base address of the 16550 registers that is specified - by PcdSerialRegisterBase. - - @param Base The base address register of UART device. - @param Offset The offset of the 16550 register to read. - - @return The value read from the 16550 register. - -**/ -UINT8 -SerialPortReadRegister ( - UINTN Base, - UINTN Offset - ) -{ - if (PcdGetBool (PcdSerialUseMmio)) { - return MmioRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride)); - } else { - return IoRead8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride)); - } -} - -/** - Write an 8-bit 16550 register. If PcdSerialUseMmio is TRUE, then the value is written to - MMIO space. If PcdSerialUseMmio is FALSE, then the value is written to I/O space. The - parameter Offset is added to the base address of the 16550 registers that is specified - by PcdSerialRegisterBase. - - @param Base The base address register of UART device. - @param Offset The offset of the 16550 register to write. - @param Value The value to write to the 16550 register specified by Offset. - - @return The value written to the 16550 register. - -**/ -UINT8 -SerialPortWriteRegister ( - UINTN Base, - UINTN Offset, - UINT8 Value - ) -{ - if (PcdGetBool (PcdSerialUseMmio)) { - return MmioWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), Value); - } else { - return IoWrite8 (Base + Offset * PcdGet32 (PcdSerialRegisterStride), Value); - } -} - -/** - Update the value of an 16-bit PCI configuration register in a PCI device. If the - PCI Configuration register specified by PciAddress is already programmed with a - non-zero value, then return the current value. Otherwise update the PCI configuration - register specified by PciAddress with the value specified by Value and return the - value programmed into the PCI configuration register. All values must be masked - using the bitmask specified by Mask. - - @param PciAddress PCI Library address of the PCI Configuration register to update. - @param Value The value to program into the PCI Configuration Register. - @param Mask Bitmask of the bits to check and update in the PCI configuration register. - -**/ -UINT16 -SerialPortLibUpdatePciRegister16 ( - UINTN PciAddress, - UINT16 Value, - UINT16 Mask - ) -{ - UINT16 CurrentValue; - - CurrentValue = PciRead16 (PciAddress) & Mask; - if (CurrentValue != 0) { - return CurrentValue; - } - return PciWrite16 (PciAddress, Value & Mask); -} - -/** - Update the value of an 32-bit PCI configuration register in a PCI device. If the - PCI Configuration register specified by PciAddress is already programmed with a - non-zero value, then return the current value. Otherwise update the PCI configuration - register specified by PciAddress with the value specified by Value and return the - value programmed into the PCI configuration register. All values must be masked - using the bitmask specified by Mask. - - @param PciAddress PCI Library address of the PCI Configuration register to update. - @param Value The value to program into the PCI Configuration Register. - @param Mask Bitmask of the bits to check and update in the PCI configuration register. - - @return The Secondary bus number that is actually programed into the PCI to PCI Bridge device. - -**/ -UINT32 -SerialPortLibUpdatePciRegister32 ( - UINTN PciAddress, - UINT32 Value, - UINT32 Mask - ) -{ - UINT32 CurrentValue; - - CurrentValue = PciRead32 (PciAddress) & Mask; - if (CurrentValue != 0) { - return CurrentValue; - } - return PciWrite32 (PciAddress, Value & Mask); -} - -/** - Retrieve the I/O or MMIO base address register for the PCI UART device. - - This function assumes Root Bus Numer is Zero, and enables I/O and MMIO in PCI UART - Device if they are not already enabled. - - @return The base address register of the UART device. - -**/ -UINTN -GetSerialRegisterBase ( - VOID - ) -{ - UINTN PciLibAddress; - UINTN BusNumber; - UINTN SubordinateBusNumber; - UINT32 ParentIoBase; - UINT32 ParentIoLimit; - UINT16 ParentMemoryBase; - UINT16 ParentMemoryLimit; - UINT32 IoBase; - UINT32 IoLimit; - UINT16 MemoryBase; - UINT16 MemoryLimit; - UINTN SerialRegisterBase; - UINTN BarIndex; - UINT32 RegisterBaseMask; - PCI_UART_DEVICE_INFO *DeviceInfo; - - // - // Get PCI Device Info - // - DeviceInfo = (PCI_UART_DEVICE_INFO *) PcdGetPtr (PcdSerialPciDeviceInfo); - - // - // If PCI Device Info is empty, then assume fixed address UART and return PcdSerialRegisterBase - // - if (DeviceInfo->Device == 0xff) { - return (UINTN)PcdGet64 (PcdSerialRegisterBase); - } - - // - // Assume PCI Bus 0 I/O window is 0-64KB and MMIO windows is 0-4GB - // - ParentMemoryBase = 0 >> 16; - ParentMemoryLimit = 0xfff00000 >> 16; - ParentIoBase = 0 >> 12; - ParentIoLimit = 0xf000 >> 12; - - // - // Enable I/O and MMIO in PCI Bridge - // Assume Root Bus Numer is Zero. - // - for (BusNumber = 0; (DeviceInfo + 1)->Device != 0xff; DeviceInfo++) { - // - // Compute PCI Lib Address to PCI to PCI Bridge - // - PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device, DeviceInfo->Function, 0); - - // - // Retrieve and verify the bus numbers in the PCI to PCI Bridge - // - BusNumber = PciRead8 (PciLibAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET); - SubordinateBusNumber = PciRead8 (PciLibAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET); - if (BusNumber == 0 || BusNumber > SubordinateBusNumber) { - return 0; - } - - // - // Retrieve and verify the I/O or MMIO decode window in the PCI to PCI Bridge - // - if (PcdGetBool (PcdSerialUseMmio)) { - MemoryLimit = PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryLimit)) & 0xfff0; - MemoryBase = PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.MemoryBase)) & 0xfff0; - - // - // If PCI Bridge MMIO window is disabled, then return 0 - // - if (MemoryLimit < MemoryBase) { - return 0; - } - - // - // If PCI Bridge MMIO window is not in the address range decoded by the parent PCI Bridge, then return 0 - // - if (MemoryBase < ParentMemoryBase || MemoryBase > ParentMemoryLimit || MemoryLimit > ParentMemoryLimit) { - return 0; - } - ParentMemoryBase = MemoryBase; - ParentMemoryLimit = MemoryLimit; - } else { - IoLimit = PciRead8 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimit)); - if ((IoLimit & PCI_BRIDGE_32_BIT_IO_SPACE ) == 0) { - IoLimit = IoLimit >> 4; - } else { - IoLimit = (PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoLimitUpper16)) << 4) | (IoLimit >> 4); - } - IoBase = PciRead8 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBase)); - if ((IoBase & PCI_BRIDGE_32_BIT_IO_SPACE ) == 0) { - IoBase = IoBase >> 4; - } else { - IoBase = (PciRead16 (PciLibAddress + OFFSET_OF (PCI_TYPE01, Bridge.IoBaseUpper16)) << 4) | (IoBase >> 4); - } - - // - // If PCI Bridge I/O window is disabled, then return 0 - // - if (IoLimit < IoBase) { - return 0; - } - - // - // If PCI Bridge I/O window is not in the address range decoded by the parent PCI Bridge, then return 0 - // - if (IoBase < ParentIoBase || IoBase > ParentIoLimit || IoLimit > ParentIoLimit) { - return 0; - } - ParentIoBase = IoBase; - ParentIoLimit = IoLimit; - } - } - - // - // Compute PCI Lib Address to PCI UART - // - PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device, DeviceInfo->Function, 0); - - // - // Find the first IO or MMIO BAR - // - RegisterBaseMask = 0xFFFFFFF0; - for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex ++) { - SerialRegisterBase = PciRead32 (PciLibAddress + PCI_BASE_ADDRESSREG_OFFSET + BarIndex * 4); - if (PcdGetBool (PcdSerialUseMmio) && ((SerialRegisterBase & BIT0) == 0)) { - // - // MMIO BAR is found - // - RegisterBaseMask = 0xFFFFFFF0; - break; - } - - if ((!PcdGetBool (PcdSerialUseMmio)) && ((SerialRegisterBase & BIT0) != 0)) { - // - // IO BAR is found - // - RegisterBaseMask = 0xFFFFFFF8; - break; - } - } - - // - // MMIO or IO BAR is not found. - // - if (BarIndex == PCI_MAX_BAR) { - return 0; - } - - // - // Program UART BAR - // - SerialRegisterBase = SerialPortLibUpdatePciRegister32 ( - PciLibAddress + PCI_BASE_ADDRESSREG_OFFSET + BarIndex * 4, - (UINT32)PcdGet64 (PcdSerialRegisterBase), - RegisterBaseMask - ); - - // - // Verify that the UART BAR is in the address range decoded by the parent PCI Bridge - // - if (PcdGetBool (PcdSerialUseMmio)) { - if (((SerialRegisterBase >> 16) & 0xfff0) < ParentMemoryBase || ((SerialRegisterBase >> 16) & 0xfff0) > ParentMemoryLimit) { - return 0; - } - } else { - if ((SerialRegisterBase >> 12) < ParentIoBase || (SerialRegisterBase >> 12) > ParentIoLimit) { - return 0; - } - } - - // - // Enable I/O and MMIO in PCI UART Device if they are not already enabled - // - PciOr16 ( - PciLibAddress + PCI_COMMAND_OFFSET, - PcdGetBool (PcdSerialUseMmio) ? EFI_PCI_COMMAND_MEMORY_SPACE : EFI_PCI_COMMAND_IO_SPACE - ); - - // - // Force D0 state if a Power Management and Status Register is specified - // - if (DeviceInfo->PowerManagementStatusAndControlRegister != 0x00) { - if ((PciRead16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister) & (BIT0 | BIT1)) != 0x00) { - PciAnd16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister, (UINT16)~(BIT0 | BIT1)); - // - // If PCI UART was not in D0, then make sure FIFOs are enabled, but do not reset FIFOs - // - SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64))); - } - } - - // - // Get PCI Device Info - // - DeviceInfo = (PCI_UART_DEVICE_INFO *) PcdGetPtr (PcdSerialPciDeviceInfo); - - // - // Enable I/O or MMIO in PCI Bridge - // Assume Root Bus Numer is Zero. - // - for (BusNumber = 0; (DeviceInfo + 1)->Device != 0xff; DeviceInfo++) { - // - // Compute PCI Lib Address to PCI to PCI Bridge - // - PciLibAddress = PCI_LIB_ADDRESS (BusNumber, DeviceInfo->Device, DeviceInfo->Function, 0); - - // - // Enable the I/O or MMIO decode windows in the PCI to PCI Bridge - // - PciOr16 ( - PciLibAddress + PCI_COMMAND_OFFSET, - PcdGetBool (PcdSerialUseMmio) ? EFI_PCI_COMMAND_MEMORY_SPACE : EFI_PCI_COMMAND_IO_SPACE - ); - - // - // Force D0 state if a Power Management and Status Register is specified - // - if (DeviceInfo->PowerManagementStatusAndControlRegister != 0x00) { - if ((PciRead16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister) & (BIT0 | BIT1)) != 0x00) { - PciAnd16 (PciLibAddress + DeviceInfo->PowerManagementStatusAndControlRegister, (UINT16)~(BIT0 | BIT1)); - } - } - - BusNumber = PciRead8 (PciLibAddress + PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET); - } - - return SerialRegisterBase; -} - -/** - Return whether the hardware flow control signal allows writing. - - @param SerialRegisterBase The base address register of UART device. - - @retval TRUE The serial port is writable. - @retval FALSE The serial port is not writable. -**/ -BOOLEAN -SerialPortWritable ( - UINTN SerialRegisterBase - ) -{ - if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { - if (PcdGetBool (PcdSerialDetectCable)) { - // - // Wait for both DSR and CTS to be set - // DSR is set if a cable is connected. - // CTS is set if it is ok to transmit data - // - // DSR CTS Description Action - // === === ======================================== ======== - // 0 0 No cable connected. Wait - // 0 1 No cable connected. Wait - // 1 0 Cable connected, but not clear to send. Wait - // 1 1 Cable connected, and clear to send. Transmit - // - return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) == (B_UART_MSR_DSR | B_UART_MSR_CTS)); - } else { - // - // Wait for both DSR and CTS to be set OR for DSR to be clear. - // DSR is set if a cable is connected. - // CTS is set if it is ok to transmit data - // - // DSR CTS Description Action - // === === ======================================== ======== - // 0 0 No cable connected. Transmit - // 0 1 No cable connected. Transmit - // 1 0 Cable connected, but not clear to send. Wait - // 1 1 Cable connected, and clar to send. Transmit - // - return (BOOLEAN) ((SerialPortReadRegister (SerialRegisterBase, R_UART_MSR) & (B_UART_MSR_DSR | B_UART_MSR_CTS)) != (B_UART_MSR_DSR)); - } - } - - return TRUE; -} - -/** - Initialize the serial device hardware. - - If no initialization is required, then return RETURN_SUCCESS. - If the serial device was successfully initialized, then return RETURN_SUCCESS. - If the serial device could not be initialized, then return RETURN_DEVICE_ERROR. - - @retval RETURN_SUCCESS The serial device was initialized. - @retval RETURN_DEVICE_ERROR The serial device could not be initialized. - -**/ -RETURN_STATUS -EFIAPI -SerialPortInitialize ( - VOID - ) -{ - RETURN_STATUS Status; - UINTN SerialRegisterBase; - UINT32 Divisor; - UINT32 CurrentDivisor; - BOOLEAN Initialized; - - // - // Perform platform specific initialization required to enable use of the 16550 device - // at the location specified by PcdSerialUseMmio and PcdSerialRegisterBase. - // - Status = PlatformHookSerialPortInitialize (); - if (RETURN_ERROR (Status)) { - return Status; - } - - // - // Calculate divisor for baud generator - // Ref_Clk_Rate / Baud_Rate / 16 - // - Divisor = PcdGet32 (PcdSerialClockRate) / (PcdGet32 (PcdSerialBaudRate) * 16); - if ((PcdGet32 (PcdSerialClockRate) % (PcdGet32 (PcdSerialBaudRate) * 16)) >= PcdGet32 (PcdSerialBaudRate) * 8) { - Divisor++; - } - - // - // Get the base address of the serial port in either I/O or MMIO space - // - SerialRegisterBase = GetSerialRegisterBase (); - if (SerialRegisterBase ==0) { - return RETURN_DEVICE_ERROR; - } - - // - // See if the serial port is already initialized - // - Initialized = TRUE; - if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & 0x3F) != (PcdGet8 (PcdSerialLineControl) & 0x3F)) { - Initialized = FALSE; - } - SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) | B_UART_LCR_DLAB)); - CurrentDivisor = SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_HIGH) << 8; - CurrentDivisor |= (UINT32) SerialPortReadRegister (SerialRegisterBase, R_UART_BAUD_LOW); - SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_LCR) & ~B_UART_LCR_DLAB)); - if (CurrentDivisor != Divisor) { - Initialized = FALSE; - } - if (Initialized) { - return RETURN_SUCCESS; - } - - // - // Wait for the serial port to be ready. - // Verify that both the transmit FIFO and the shift register are empty. - // - while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)); - - // - // Configure baud rate - // - SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB); - SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8) (Divisor >> 8)); - SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8) (Divisor & 0xff)); - - // - // Clear DLAB and configure Data Bits, Parity, and Stop Bits. - // Strip reserved bits from PcdSerialLineControl - // - SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8)(PcdGet8 (PcdSerialLineControl) & 0x3F)); - - // - // Enable and reset FIFOs - // Strip reserved bits from PcdSerialFifoControl - // - SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, 0x00); - SerialPortWriteRegister (SerialRegisterBase, R_UART_FCR, (UINT8)(PcdGet8 (PcdSerialFifoControl) & (B_UART_FCR_FIFOE | B_UART_FCR_FIFO64))); - - // - // Put Modem Control Register(MCR) into its reset state of 0x00. - // - SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, 0x00); - - return RETURN_SUCCESS; -} - -/** - Write data from buffer to serial device. - - Writes NumberOfBytes data bytes from Buffer to the serial device. - The number of bytes actually written to the serial device is returned. - If the return value is less than NumberOfBytes, then the write operation failed. - - If Buffer is NULL, then ASSERT(). - - If NumberOfBytes is zero, then return 0. - - @param Buffer Pointer to the data buffer to be written. - @param NumberOfBytes Number of bytes to written to the serial device. - - @retval 0 NumberOfBytes is 0. - @retval >0 The number of bytes written to the serial device. - If this value is less than NumberOfBytes, then the read operation failed. - -**/ -UINTN -EFIAPI -SerialPortWrite ( - IN UINT8 *Buffer, - IN UINTN NumberOfBytes - ) -{ - UINTN SerialRegisterBase; - UINTN Result; - UINTN Index; - UINTN FifoSize; - - if (Buffer == NULL) { - return 0; - } - - SerialRegisterBase = GetSerialRegisterBase (); - if (SerialRegisterBase ==0) { - return 0; - } - - if (NumberOfBytes == 0) { - // - // Flush the hardware - // - - // - // Wait for both the transmit FIFO and shift register empty. - // - while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) != (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)); - - // - // Wait for the hardware flow control signal - // - while (!SerialPortWritable (SerialRegisterBase)); - return 0; - } - - // - // Compute the maximum size of the Tx FIFO - // - FifoSize = 1; - if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFOE) != 0) { - if ((PcdGet8 (PcdSerialFifoControl) & B_UART_FCR_FIFO64) == 0) { - FifoSize = 16; - } else { - FifoSize = PcdGet32 (PcdSerialExtendedTxFifoSize); - } - } - - Result = NumberOfBytes; - while (NumberOfBytes != 0) { - // - // Wait for the serial port to be ready, to make sure both the transmit FIFO - // and shift register empty. - // - while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_TEMT) == 0); - - // - // Fill then entire Tx FIFO - // - for (Index = 0; Index < FifoSize && NumberOfBytes != 0; Index++, NumberOfBytes--, Buffer++) { - // - // Wait for the hardware flow control signal - // - while (!SerialPortWritable (SerialRegisterBase)); - - // - // Write byte to the transmit buffer. - // - SerialPortWriteRegister (SerialRegisterBase, R_UART_TXBUF, *Buffer); - } - } - return Result; -} - -/** - Reads data from a serial device into a buffer. - - @param Buffer Pointer to the data buffer to store the data read from the serial device. - @param NumberOfBytes Number of bytes to read from the serial device. - - @retval 0 NumberOfBytes is 0. - @retval >0 The number of bytes read from the serial device. - If this value is less than NumberOfBytes, then the read operation failed. - -**/ -UINTN -EFIAPI -SerialPortRead ( - OUT UINT8 *Buffer, - IN UINTN NumberOfBytes - ) -{ - UINTN SerialRegisterBase; - UINTN Result; - UINT8 Mcr; - - if (NULL == Buffer) { - return 0; - } - - SerialRegisterBase = GetSerialRegisterBase (); - if (SerialRegisterBase ==0) { - return 0; - } - - Mcr = (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) & ~B_UART_MCR_RTS); - - for (Result = 0; NumberOfBytes-- != 0; Result++, Buffer++) { - // - // Wait for the serial port to have some data. - // - while ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_RXRDY) == 0) { - if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { - // - // Set RTS to let the peer send some data - // - SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(Mcr | B_UART_MCR_RTS)); - } - } - if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { - // - // Clear RTS to prevent peer from sending data - // - SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr); - } - - // - // Read byte from the receive buffer. - // - *Buffer = SerialPortReadRegister (SerialRegisterBase, R_UART_RXBUF); - } - - return Result; -} - - -/** - Polls a serial device to see if there is any data waiting to be read. - - Polls aserial device to see if there is any data waiting to be read. - If there is data waiting to be read from the serial device, then TRUE is returned. - If there is no data waiting to be read from the serial device, then FALSE is returned. - - @retval TRUE Data is waiting to be read from the serial device. - @retval FALSE There is no data waiting to be read from the serial device. - -**/ -BOOLEAN -EFIAPI -SerialPortPoll ( - VOID - ) -{ - UINTN SerialRegisterBase; - - SerialRegisterBase = GetSerialRegisterBase (); - if (SerialRegisterBase ==0) { - return FALSE; - } - - // - // Read the serial port status - // - if ((SerialPortReadRegister (SerialRegisterBase, R_UART_LSR) & B_UART_LSR_RXRDY) != 0) { - if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { - // - // Clear RTS to prevent peer from sending data - // - SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) & ~B_UART_MCR_RTS)); - } - return TRUE; - } - - if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { - // - // Set RTS to let the peer send some data - // - SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, (UINT8)(SerialPortReadRegister (SerialRegisterBase, R_UART_MCR) | B_UART_MCR_RTS)); - } - - return FALSE; -} - -/** - Sets the control bits on a serial device. - - @param Control Sets the bits of Control that are settable. - - @retval RETURN_SUCCESS The new control bits were set on the serial device. - @retval RETURN_UNSUPPORTED The serial device does not support this operation. - @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. - -**/ -RETURN_STATUS -EFIAPI -SerialPortSetControl ( - IN UINT32 Control - ) -{ - UINTN SerialRegisterBase; - UINT8 Mcr; - - // - // First determine the parameter is invalid. - // - if ((Control & (~(EFI_SERIAL_REQUEST_TO_SEND | EFI_SERIAL_DATA_TERMINAL_READY | - EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE))) != 0) { - return RETURN_UNSUPPORTED; - } - - SerialRegisterBase = GetSerialRegisterBase (); - if (SerialRegisterBase ==0) { - return RETURN_UNSUPPORTED; - } - - // - // Read the Modem Control Register. - // - Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR); - Mcr &= (~(B_UART_MCR_DTRC | B_UART_MCR_RTS)); - - if ((Control & EFI_SERIAL_DATA_TERMINAL_READY) == EFI_SERIAL_DATA_TERMINAL_READY) { - Mcr |= B_UART_MCR_DTRC; - } - - if ((Control & EFI_SERIAL_REQUEST_TO_SEND) == EFI_SERIAL_REQUEST_TO_SEND) { - Mcr |= B_UART_MCR_RTS; - } - - // - // Write the Modem Control Register. - // - SerialPortWriteRegister (SerialRegisterBase, R_UART_MCR, Mcr); - - return RETURN_SUCCESS; -} - -/** - Retrieve the status of the control bits on a serial device. - - @param Control A pointer to return the current control signals from the serial device. - - @retval RETURN_SUCCESS The control bits were read from the serial device. - @retval RETURN_UNSUPPORTED The serial device does not support this operation. - @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. - -**/ -RETURN_STATUS -EFIAPI -SerialPortGetControl ( - OUT UINT32 *Control - ) -{ - UINTN SerialRegisterBase; - UINT8 Msr; - UINT8 Mcr; - UINT8 Lsr; - - SerialRegisterBase = GetSerialRegisterBase (); - if (SerialRegisterBase ==0) { - return RETURN_UNSUPPORTED; - } - - *Control = 0; - - // - // Read the Modem Status Register. - // - Msr = SerialPortReadRegister (SerialRegisterBase, R_UART_MSR); - - if ((Msr & B_UART_MSR_CTS) == B_UART_MSR_CTS) { - *Control |= EFI_SERIAL_CLEAR_TO_SEND; - } - - if ((Msr & B_UART_MSR_DSR) == B_UART_MSR_DSR) { - *Control |= EFI_SERIAL_DATA_SET_READY; - } - - if ((Msr & B_UART_MSR_RI) == B_UART_MSR_RI) { - *Control |= EFI_SERIAL_RING_INDICATE; - } - - if ((Msr & B_UART_MSR_DCD) == B_UART_MSR_DCD) { - *Control |= EFI_SERIAL_CARRIER_DETECT; - } - - // - // Read the Modem Control Register. - // - Mcr = SerialPortReadRegister (SerialRegisterBase, R_UART_MCR); - - if ((Mcr & B_UART_MCR_DTRC) == B_UART_MCR_DTRC) { - *Control |= EFI_SERIAL_DATA_TERMINAL_READY; - } - - if ((Mcr & B_UART_MCR_RTS) == B_UART_MCR_RTS) { - *Control |= EFI_SERIAL_REQUEST_TO_SEND; - } - - if (PcdGetBool (PcdSerialUseHardwareFlowControl)) { - *Control |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE; - } - - // - // Read the Line Status Register. - // - Lsr = SerialPortReadRegister (SerialRegisterBase, R_UART_LSR); - - if ((Lsr & (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) == (B_UART_LSR_TEMT | B_UART_LSR_TXRDY)) { - *Control |= EFI_SERIAL_OUTPUT_BUFFER_EMPTY; - } - - if ((Lsr & B_UART_LSR_RXRDY) == 0) { - *Control |= EFI_SERIAL_INPUT_BUFFER_EMPTY; - } - - return RETURN_SUCCESS; -} - -/** - Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, - data bits, and stop bits on a serial device. - - @param BaudRate The requested baud rate. A BaudRate value of 0 will use the - device's default interface speed. - On output, the value actually set. - @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the - serial interface. A ReceiveFifoDepth value of 0 will use - the device's default FIFO depth. - On output, the value actually set. - @param Timeout The requested time out for a single character in microseconds. - This timeout applies to both the transmit and receive side of the - interface. A Timeout value of 0 will use the device's default time - out value. - On output, the value actually set. - @param Parity The type of parity to use on this serial device. A Parity value of - DefaultParity will use the device's default parity value. - On output, the value actually set. - @param DataBits The number of data bits to use on the serial device. A DataBits - vaule of 0 will use the device's default data bit setting. - On output, the value actually set. - @param StopBits The number of stop bits to use on this serial device. A StopBits - value of DefaultStopBits will use the device's default number of - stop bits. - On output, the value actually set. - - @retval RETURN_SUCCESS The new attributes were set on the serial device. - @retval RETURN_UNSUPPORTED The serial device does not support this operation. - @retval RETURN_INVALID_PARAMETER One or more of the attributes has an unsupported value. - @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. - -**/ -RETURN_STATUS -EFIAPI -SerialPortSetAttributes ( - IN OUT UINT64 *BaudRate, - IN OUT UINT32 *ReceiveFifoDepth, - IN OUT UINT32 *Timeout, - IN OUT EFI_PARITY_TYPE *Parity, - IN OUT UINT8 *DataBits, - IN OUT EFI_STOP_BITS_TYPE *StopBits - ) -{ - UINTN SerialRegisterBase; - UINT32 SerialBaudRate; - UINTN Divisor; - UINT8 Lcr; - UINT8 LcrData; - UINT8 LcrParity; - UINT8 LcrStop; - - SerialRegisterBase = GetSerialRegisterBase (); - if (SerialRegisterBase ==0) { - return RETURN_UNSUPPORTED; - } - - // - // Check for default settings and fill in actual values. - // - if (*BaudRate == 0) { - *BaudRate = PcdGet32 (PcdSerialBaudRate); - } - SerialBaudRate = (UINT32) *BaudRate; - - if (*DataBits == 0) { - LcrData = (UINT8) (PcdGet8 (PcdSerialLineControl) & 0x3); - *DataBits = LcrData + 5; - } else { - if ((*DataBits < 5) || (*DataBits > 8)) { - return RETURN_INVALID_PARAMETER; - } - // - // Map 5..8 to 0..3 - // - LcrData = (UINT8) (*DataBits - (UINT8) 5); - } - - if (*Parity == DefaultParity) { - LcrParity = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 3) & 0x7); - switch (LcrParity) { - case 0: - *Parity = NoParity; - break; - - case 3: - *Parity = EvenParity; - break; - - case 1: - *Parity = OddParity; - break; - - case 7: - *Parity = SpaceParity; - break; - - case 5: - *Parity = MarkParity; - break; - - default: - break; - } - } else { - switch (*Parity) { - case NoParity: - LcrParity = 0; - break; - - case EvenParity: - LcrParity = 3; - break; - - case OddParity: - LcrParity = 1; - break; - - case SpaceParity: - LcrParity = 7; - break; - - case MarkParity: - LcrParity = 5; - break; - - default: - return RETURN_INVALID_PARAMETER; - } - } - - if (*StopBits == DefaultStopBits) { - LcrStop = (UINT8) ((PcdGet8 (PcdSerialLineControl) >> 2) & 0x1); - switch (LcrStop) { - case 0: - *StopBits = OneStopBit; - break; - - case 1: - if (*DataBits == 5) { - *StopBits = OneFiveStopBits; - } else { - *StopBits = TwoStopBits; - } - break; - - default: - break; - } - } else { - switch (*StopBits) { - case OneStopBit: - LcrStop = 0; - break; - - case OneFiveStopBits: - case TwoStopBits: - LcrStop = 1; - break; - - default: - return RETURN_INVALID_PARAMETER; - } - } - - // - // Calculate divisor for baud generator - // Ref_Clk_Rate / Baud_Rate / 16 - // - Divisor = PcdGet32 (PcdSerialClockRate) / (SerialBaudRate * 16); - if ((PcdGet32 (PcdSerialClockRate) % (SerialBaudRate * 16)) >= SerialBaudRate * 8) { - Divisor++; - } - - // - // Configure baud rate - // - SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, B_UART_LCR_DLAB); - SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_HIGH, (UINT8) (Divisor >> 8)); - SerialPortWriteRegister (SerialRegisterBase, R_UART_BAUD_LOW, (UINT8) (Divisor & 0xff)); - - // - // Clear DLAB and configure Data Bits, Parity, and Stop Bits. - // Strip reserved bits from line control value - // - Lcr = (UINT8) ((LcrParity << 3) | (LcrStop << 2) | LcrData); - SerialPortWriteRegister (SerialRegisterBase, R_UART_LCR, (UINT8) (Lcr & 0x3F)); - - return RETURN_SUCCESS; -} - diff --git a/BraswellPlatformPkg/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf b/BraswellPlatformPkg/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf deleted file mode 100644 index 42feb21059..0000000000 --- a/BraswellPlatformPkg/Override/MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf +++ /dev/null @@ -1,48 +0,0 @@ -## @file -# SerialPortLib instance for 16550 UART. -# -# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.
-# This program and the accompanying materials -# are licensed and made available under the terms and conditions of the BSD License -# which 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 = 0x00010018 - BASE_NAME = BaseSerialPortLib16550 - FILE_GUID = 9E7C00CF-355A-4d4e-BF60-0428CFF95540 - MODULE_TYPE = BASE - VERSION_STRING = 1.1 - LIBRARY_CLASS = SerialPortLib - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - BraswellPlatformPkg/BraswellPlatformPkg.dec - -[LibraryClasses] - PcdLib - IoLib - PlatformHookLib - PciLib - -[Sources] - BaseSerialPortLib16550.c - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseHardwareFlowControl ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialDetectCable ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialLineControl ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialClockRate ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialPciDeviceInfo ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize ## CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride ## CONSUMES -- cgit v1.2.3