+++ /dev/null
-/** @file\r
-This file include all platform action which can be customized\r
-by IBV/OEM.\r
-\r
-Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "PlatformBootManager.h"\r
-\r
-/**\r
- Return the index of the load option in the load option array.\r
-\r
- The function consider two load options are equal when the\r
- OptionType, Attributes, Description, FilePath and OptionalData are equal.\r
-\r
- @param Key Pointer to the load option to be found.\r
- @param Array Pointer to the array of load options to be found.\r
- @param Count Number of entries in the Array.\r
-\r
- @retval -1 Key wasn't found in the Array.\r
- @retval 0 ~ Count-1 The index of the Key in the Array.\r
-**/\r
-INTN\r
-PlatformFindLoadOption (\r
- IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key,\r
- IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array,\r
- IN UINTN Count\r
- )\r
-{\r
- UINTN Index;\r
-\r
- for (Index = 0; Index < Count; Index++) {\r
- if ((Key->OptionType == Array[Index].OptionType) &&\r
- (Key->Attributes == Array[Index].Attributes) &&\r
- (StrCmp (Key->Description, Array[Index].Description) == 0) &&\r
- (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) &&\r
- (Key->OptionalDataSize == Array[Index].OptionalDataSize) &&\r
- (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 0)) {\r
- return (INTN) Index;\r
- }\r
- }\r
-\r
- return -1;\r
-}\r
-\r
-VOID\r
-PlatformRegisterFvBootOption (\r
- EFI_GUID *FileGuid,\r
- CHAR16 *Description,\r
- UINT32 Attributes\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_HANDLE *HandleBuffer;\r
- UINTN HandleCount;\r
- UINTN IndexFv;\r
- EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
- CHAR16 *UiSection;\r
- UINTN UiSectionLength;\r
- UINT32 AuthenticationStatus;\r
- EFI_HANDLE FvHandle;\r
- MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;\r
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
- EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions;\r
- UINTN BootOptionCount;\r
- UINTN OptionIndex;\r
- EFI_BOOT_MANAGER_LOAD_OPTION NewOption;\r
-\r
- //\r
- // Locate all available FVs.\r
- //\r
- HandleBuffer = NULL;\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiFirmwareVolume2ProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuffer\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return;\r
- }\r
-\r
- //\r
- // Go through FVs one by one to find the required FFS file\r
- //\r
- for (IndexFv = 0, FvHandle = NULL; IndexFv < HandleCount && FvHandle == NULL; IndexFv++) {\r
- Status = gBS->HandleProtocol (\r
- HandleBuffer[IndexFv],\r
- &gEfiFirmwareVolume2ProtocolGuid,\r
- (VOID **)&Fv\r
- );\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
-\r
- //\r
- // Attempt to read a EFI_SECTION_USER_INTERFACE section from the required FFS file\r
- //\r
- UiSection = NULL;\r
- Status = Fv->ReadSection (\r
- Fv,\r
- FileGuid,\r
- EFI_SECTION_USER_INTERFACE,\r
- 0,\r
- (VOID **) &UiSection,\r
- &UiSectionLength,\r
- &AuthenticationStatus\r
- );\r
- if (EFI_ERROR (Status)) {\r
- continue;\r
- }\r
- FreePool (UiSection);\r
-\r
- //\r
- // Save the handle of the FV where the FFS file was found\r
- //\r
- FvHandle = HandleBuffer[IndexFv];\r
- }\r
-\r
- //\r
- // Free the buffer of FV handles\r
- //\r
- FreePool (HandleBuffer);\r
-\r
- //\r
- // If the FFS file was not found, then return\r
- //\r
- if (FvHandle == NULL) {\r
- return;\r
- }\r
-\r
- //\r
- // Create a device path for the FFS file that was found\r
- //\r
- EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);\r
- DevicePath = AppendDevicePathNode (\r
- DevicePathFromHandle (FvHandle),\r
- (EFI_DEVICE_PATH_PROTOCOL *) &FileNode\r
- );\r
-\r
- //\r
- // Create and add a new load option for the FFS file that was found\r
- //\r
- Status = EfiBootManagerInitializeLoadOption (\r
- &NewOption,\r
- LoadOptionNumberUnassigned,\r
- LoadOptionTypeBoot,\r
- Attributes,\r
- Description,\r
- DevicePath,\r
- NULL,\r
- 0\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);\r
-\r
- OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount);\r
-\r
- if (OptionIndex == -1) {\r
- Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1);\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
- EfiBootManagerFreeLoadOption (&NewOption);\r
- EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);\r
- }\r
-}\r
-\r
-VOID\r
-EFIAPI\r
-InternalBdsEmptyCallbackFuntion (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- return;\r
-}\r
-\r
-/**\r
- Do the platform specific action before the console is connected.\r
-\r
- Such as:\r
- Update console variable;\r
- Register new Driver#### or Boot####;\r
- Signal ReadyToLock event.\r
-**/\r
-VOID\r
-EFIAPI\r
-PlatformBootManagerBeforeConsole (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN Index;\r
- EFI_INPUT_KEY Enter;\r
- EFI_INPUT_KEY F2;\r
- EFI_BOOT_MANAGER_LOAD_OPTION BootOption;\r
- ESRT_MANAGEMENT_PROTOCOL *EsrtManagement;\r
- EFI_BOOT_MODE BootMode;\r
- EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;\r
- EFI_HANDLE Handle;\r
- EFI_EVENT EndOfDxeEvent;\r
-\r
- //\r
- // Update the console variables.\r
- //\r
- for (Index = 0; gPlatformConsole[Index].DevicePath != NULL; Index++) {\r
- if ((gPlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {\r
- EfiBootManagerUpdateConsoleVariable (ConIn, gPlatformConsole[Index].DevicePath, NULL);\r
- }\r
-\r
- if ((gPlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {\r
- EfiBootManagerUpdateConsoleVariable (ConOut, gPlatformConsole[Index].DevicePath, NULL);\r
- }\r
-\r
- if ((gPlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {\r
- EfiBootManagerUpdateConsoleVariable (ErrOut, gPlatformConsole[Index].DevicePath, NULL);\r
- }\r
- }\r
-\r
- //\r
- // Register ENTER as CONTINUE key\r
- //\r
- Enter.ScanCode = SCAN_NULL;\r
- Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;\r
- EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL);\r
-\r
- //\r
- // Map F2 to Boot Manager Menu\r
- //\r
- F2.ScanCode = SCAN_F2;\r
- F2.UnicodeChar = CHAR_NULL;\r
- EfiBootManagerGetBootManagerMenu (&BootOption);\r
- EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL);\r
-\r
- //\r
- // Register UEFI Shell\r
- //\r
- PlatformRegisterFvBootOption (&gUefiShellFileGuid, L"UEFI Shell", LOAD_OPTION_ACTIVE);\r
-\r
- Status = gBS->LocateProtocol(&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtManagement);\r
- if (EFI_ERROR(Status)) {\r
- EsrtManagement = NULL;\r
- }\r
-\r
- BootMode = GetBootModeHob();\r
- switch (BootMode) {\r
- case BOOT_ON_FLASH_UPDATE:\r
- DEBUG((DEBUG_INFO, "ProcessCapsules Before EndOfDxe ......\n"));\r
- Status = ProcessCapsules ();\r
- DEBUG((DEBUG_INFO, "ProcessCapsules %r\n", Status));\r
- break;\r
- case BOOT_IN_RECOVERY_MODE:\r
- break;\r
- case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:\r
- case BOOT_WITH_MINIMAL_CONFIGURATION:\r
- case BOOT_ON_S4_RESUME:\r
- if (EsrtManagement != NULL) {\r
- //\r
- // Lock ESRT cache repository before EndofDxe if ESRT sync is not needed\r
- //\r
- EsrtManagement->LockEsrtRepository();\r
- }\r
- break;\r
- default:\r
- //\r
- // Require to sync ESRT from FMP in a new boot\r
- //\r
- if (EsrtManagement != NULL) {\r
- EsrtManagement->SyncEsrtFmp();\r
- }\r
- break;\r
- }\r
-\r
- //\r
- // Prepare for S3\r
- //\r
- Status = gBS->LocateProtocol (&gEfiAcpiS3SaveProtocolGuid, NULL, (VOID **)&AcpiS3Save);\r
- if (!EFI_ERROR (Status)) {\r
- AcpiS3Save->S3Save (AcpiS3Save, NULL);\r
- }\r
-\r
- //\r
- // Inform PI SMM drivers that BDS may run 3rd party code\r
- // Create and signal End of DXE event group\r
- //\r
- Status = gBS->CreateEventEx (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
- InternalBdsEmptyCallbackFuntion,\r
- NULL,\r
- &gEfiEndOfDxeEventGroupGuid,\r
- &EndOfDxeEvent\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- gBS->SignalEvent (EndOfDxeEvent);\r
- gBS->CloseEvent (EndOfDxeEvent);\r
-\r
- DEBUG((EFI_D_INFO,"All EndOfDxe callbacks have returned successfully\n"));\r
-\r
- //\r
- // Install SMM Ready To Lock protocol so all resources can be locked down\r
- // before BDS runs 3rd party code. This action must be done last so all\r
- // other SMM driver signals are processed before this final lock down action.\r
- //\r
- Handle = NULL;\r
- Status = gBS->InstallProtocolInterface (\r
- &Handle,\r
- &gEfiDxeSmmReadyToLockProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Dispatch deferred images after EndOfDxe event and ReadyToLock installation.\r
- //\r
- EfiBootManagerDispatchDeferredImages ();\r
-}\r
-\r
-/**\r
- Do the platform specific action after the console is connected.\r
-\r
- Such as:\r
- Dynamically switch output mode;\r
- Signal console ready platform customized event;\r
- Run diagnostics like memory testing;\r
- Connect certain devices;\r
- Dispatch additional option ROMs\r
-**/\r
-VOID\r
-EFIAPI\r
-PlatformBootManagerAfterConsole (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_BOOT_MODE BootMode;\r
- ESRT_MANAGEMENT_PROTOCOL *EsrtManagement;\r
- VOID *Buffer;\r
- UINTN Size;\r
-\r
- Status = gBS->LocateProtocol(&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtManagement);\r
- if (EFI_ERROR(Status)) {\r
- EsrtManagement = NULL;\r
- }\r
-\r
- BootMode = GetBootModeHob();\r
-\r
- DEBUG((DEBUG_INFO, "PlatformBootManagerAfterConsole(): BootMode = %02x\n", BootMode));\r
-\r
- switch (BootMode) {\r
- case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:\r
- case BOOT_WITH_MINIMAL_CONFIGURATION:\r
- case BOOT_ON_S4_RESUME:\r
- EfiBootManagerRefreshAllBootOption ();\r
- break;\r
-\r
- case BOOT_ON_FLASH_UPDATE:\r
- if (FeaturePcdGet(PcdSupportUpdateCapsuleReset)) {\r
- EfiBootManagerConnectAll ();\r
- EfiBootManagerRefreshAllBootOption ();\r
-\r
- //\r
- // Always sync ESRT Cache from FMP Instances after connect all and before capsule process\r
- //\r
- if (EsrtManagement != NULL) {\r
- EsrtManagement->SyncEsrtFmp();\r
- }\r
-\r
- DEBUG((DEBUG_INFO, "ProcessCapsules After ConnectAll ......\n"));\r
- Status = ProcessCapsules();\r
- DEBUG((DEBUG_INFO, "ProcessCapsules %r\n", Status));\r
- }\r
- break;\r
-\r
- default:\r
- EfiBootManagerConnectAll ();\r
- EfiBootManagerRefreshAllBootOption ();\r
-\r
- //\r
- // Sync ESRT Cache from FMP Instance on demand after Connect All\r
- //\r
- if (EsrtManagement != NULL) {\r
- EsrtManagement->SyncEsrtFmp();\r
- }\r
- break;\r
- }\r
-\r
- Print (\r
- L"\n"\r
- L"F2 to enter Boot Manager Menu.\n"\r
- L"ENTER to boot directly.\n"\r
- L"\n"\r
- );\r
-\r
- //\r
- // Check if the platform is using test key.\r
- //\r
- Status = GetSectionFromAnyFv(\r
- PcdGetPtr(PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid),\r
- EFI_SECTION_RAW,\r
- 0,\r
- &Buffer,\r
- &Size\r
- );\r
- if (!EFI_ERROR(Status)) {\r
- if ((Size == PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer)) &&\r
- (CompareMem(Buffer, PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer), Size) == 0)) {\r
- Print(L"WARNING: Recovery Test Key is used.\n");\r
- PcdSetBoolS(PcdTestKeyUsed, TRUE);\r
- }\r
- FreePool(Buffer);\r
- }\r
- Status = GetSectionFromAnyFv(\r
- PcdGetPtr(PcdEdkiiPkcs7TestPublicKeyFileGuid),\r
- EFI_SECTION_RAW,\r
- 0,\r
- &Buffer,\r
- &Size\r
- );\r
- if (!EFI_ERROR(Status)) {\r
- if ((Size == PcdGetSize(PcdPkcs7CertBuffer)) &&\r
- (CompareMem(Buffer, PcdGetPtr(PcdPkcs7CertBuffer), Size) == 0)) {\r
- Print(L"WARNING: Capsule Test Key is used.\n");\r
- PcdSetBoolS(PcdTestKeyUsed, TRUE);\r
- }\r
- FreePool(Buffer);\r
- }\r
-\r
- //\r
- // Use a DynamicHii type pcd to save the boot status, which is used to\r
- // control configuration mode, such as FULL/MINIMAL/NO_CHANGES configuration.\r
- //\r
- if (PcdGetBool(PcdBootState)) {\r
- Status = PcdSetBoolS (PcdBootState, FALSE);\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
-}\r
-\r
-/**\r
- This function is called each second during the boot manager waits the timeout.\r
-\r
- @param TimeoutRemain The remaining timeout.\r
-**/\r
-VOID\r
-EFIAPI\r
-PlatformBootManagerWaitCallback (\r
- UINT16 TimeoutRemain\r
- )\r
-{\r
- Print (L"\r%-2d seconds remained...", TimeoutRemain);\r
-}\r
-\r
-/**\r
- The function is called when no boot option could be launched,\r
- including platform recovery options and options pointing to applications\r
- built into firmware volumes.\r
-\r
- If this function returns, BDS attempts to enter an infinite loop.\r
-**/\r
-VOID\r
-EFIAPI\r
-PlatformBootManagerUnableToBoot (\r
- VOID\r
- )\r
-{\r
- return;\r
-}\r
-\r