X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=OvmfPkg%2FLibrary%2FPlatformBootManagerLib%2FBdsPlatform.c;h=b155639f3c97096c3a80a40e0c82d1a867ed7f10;hp=7ef4d3de16295fe466f7f43750fe4cd3f68a8a42;hb=fe1b9e8e085bede968958f494cba0be5ab3add99;hpb=7f89929f7fb2f4d75c30fd6838daad61dc996eb5 diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c index 7ef4d3de16..b155639f3c 100644 --- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c +++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c @@ -2,19 +2,20 @@ Platform BDS customizations. Copyright (c) 2004 - 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 + 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. + 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 "BdsPlatform.h" +#include #include -#include +#include // @@ -36,11 +37,6 @@ CONST UINT8 PciHostIrqs[] = { 0x0a, 0x0a, 0x0b, 0x0b }; -// -// Array Size macro -// -#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) - // // Type definitions // @@ -149,6 +145,134 @@ PlatformRegisterFvBootOption ( EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); } +/** + Remove all MemoryMapped(...)/FvFile(...) and Fv(...)/FvFile(...) boot options + whose device paths do not resolve exactly to an FvFile in the system. + + This removes any boot options that point to binaries built into the firmware + and have become stale due to any of the following: + - DXEFV's base address or size changed (historical), + - DXEFV's FvNameGuid changed, + - the FILE_GUID of the pointed-to binary changed, + - the referenced binary is no longer built into the firmware. + + EfiBootManagerFindLoadOption() used in PlatformRegisterFvBootOption() only + avoids exact duplicates. +**/ +VOID +RemoveStaleFvFileOptions ( + VOID + ) +{ + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN BootOptionCount; + UINTN Index; + + BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, + LoadOptionTypeBoot); + + for (Index = 0; Index < BootOptionCount; ++Index) { + EFI_DEVICE_PATH_PROTOCOL *Node1, *Node2, *SearchNode; + EFI_STATUS Status; + EFI_HANDLE FvHandle; + + // + // If the device path starts with neither MemoryMapped(...) nor Fv(...), + // then keep the boot option. + // + Node1 = BootOptions[Index].FilePath; + if (!(DevicePathType (Node1) == HARDWARE_DEVICE_PATH && + DevicePathSubType (Node1) == HW_MEMMAP_DP) && + !(DevicePathType (Node1) == MEDIA_DEVICE_PATH && + DevicePathSubType (Node1) == MEDIA_PIWG_FW_VOL_DP)) { + continue; + } + + // + // If the second device path node is not FvFile(...), then keep the boot + // option. + // + Node2 = NextDevicePathNode (Node1); + if (DevicePathType (Node2) != MEDIA_DEVICE_PATH || + DevicePathSubType (Node2) != MEDIA_PIWG_FW_FILE_DP) { + continue; + } + + // + // Locate the Firmware Volume2 protocol instance that is denoted by the + // boot option. If this lookup fails (i.e., the boot option references a + // firmware volume that doesn't exist), then we'll proceed to delete the + // boot option. + // + SearchNode = Node1; + Status = gBS->LocateDevicePath (&gEfiFirmwareVolume2ProtocolGuid, + &SearchNode, &FvHandle); + + if (!EFI_ERROR (Status)) { + // + // The firmware volume was found; now let's see if it contains the FvFile + // identified by GUID. + // + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFileNode; + UINTN BufferSize; + EFI_FV_FILETYPE FoundType; + EFI_FV_FILE_ATTRIBUTES FileAttributes; + UINT32 AuthenticationStatus; + + Status = gBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, + (VOID **)&FvProtocol); + ASSERT_EFI_ERROR (Status); + + FvFileNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)Node2; + // + // Buffer==NULL means we request metadata only: BufferSize, FoundType, + // FileAttributes. + // + Status = FvProtocol->ReadFile ( + FvProtocol, + &FvFileNode->FvFileName, // NameGuid + NULL, // Buffer + &BufferSize, + &FoundType, + &FileAttributes, + &AuthenticationStatus + ); + if (!EFI_ERROR (Status)) { + // + // The FvFile was found. Keep the boot option. + // + continue; + } + } + + // + // Delete the boot option. + // + Status = EfiBootManagerDeleteLoadOptionVariable ( + BootOptions[Index].OptionNumber, LoadOptionTypeBoot); + DEBUG_CODE ( + CHAR16 *DevicePathString; + + DevicePathString = ConvertDevicePathToText(BootOptions[Index].FilePath, + FALSE, FALSE); + DEBUG (( + EFI_ERROR (Status) ? EFI_D_WARN : EFI_D_VERBOSE, + "%a: removing stale Boot#%04x %s: %r\n", + __FUNCTION__, + (UINT32)BootOptions[Index].OptionNumber, + DevicePathString == NULL ? L"" : DevicePathString, + Status + )); + if (DevicePathString != NULL) { + FreePool (DevicePathString); + } + ); + } + + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); +} + VOID PlatformRegisterOptionsAndKeys ( VOID @@ -185,12 +309,6 @@ PlatformRegisterOptionsAndKeys ( NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL ); ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED); - // - // Register UEFI Shell - // - PlatformRegisterFvBootOption ( - PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE - ); } EFI_STATUS @@ -210,28 +328,28 @@ SaveS3BootScript ( // // BDS Platform Functions // +/** + Do the platform init, can be customized by OEM/IBV + + Possible things that can be done in PlatformBootManagerBeforeConsole: + + > Update console variable: 1. include hot-plug devices; + > 2. Clear ConIn and add SOL for AMT + > Register new Driver#### or Boot#### + > Register new Key####: e.g.: F12 + > Signal ReadyToLock event + > Authentication action: 1. connect Auth devices; + > 2. Identify auto logon user. +**/ VOID EFIAPI PlatformBootManagerBeforeConsole ( VOID ) -/*++ - -Routine Description: - - Platform Bds init. Incude the platform firmware vendor, revision - and so crc check. - -Arguments: - -Returns: - - None. - ---*/ { - EFI_HANDLE Handle; - EFI_STATUS Status; + EFI_HANDLE Handle; + EFI_STATUS Status; + RETURN_STATUS PcdStatus; DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n")); InstallDevicePathCallback (); @@ -270,8 +388,16 @@ Returns: NULL); ASSERT_EFI_ERROR (Status); + // + // Dispatch deferred images after EndOfDxe event and ReadyToLock + // installation. + // + EfiBootManagerDispatchDeferredImages (); + PlatformInitializeConsole (gPlatformConsole); - PcdSet16 (PcdPlatformBootTimeOut, GetFrontPageTimeoutFromQemu ()); + PcdStatus = PcdSet16S (PcdPlatformBootTimeOut, + GetFrontPageTimeoutFromQemu ()); + ASSERT_RETURN_ERROR (PcdStatus); PlatformRegisterOptionsAndKeys (); } @@ -302,28 +428,21 @@ ConnectRootBridge ( } +/** + Add IsaKeyboard to ConIn; add IsaSerial to ConOut, ConIn, ErrOut. + + @param[in] DeviceHandle Handle of the LPC Bridge device. + + @retval EFI_SUCCESS Console devices on the LPC bridge have been added to + ConOut, ConIn, and ErrOut. + + @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing + from DeviceHandle. +**/ EFI_STATUS PrepareLpcBridgeDevicePath ( IN EFI_HANDLE DeviceHandle ) -/*++ - -Routine Description: - - Add IsaKeyboard to ConIn, - add IsaSerial to ConOut, ConIn, ErrOut. - LPC Bridge: 06 01 00 - -Arguments: - - DeviceHandle - Handle of PCIIO protocol. - -Returns: - - EFI_SUCCESS - LPC bridge is added to ConOut, ConIn, and ErrOut. - EFI_STATUS - No LPC bridge is added. - ---*/ { EFI_STATUS Status; EFI_DEVICE_PATH_PROTOCOL *DevicePath; @@ -344,7 +463,8 @@ Returns: // // Register Keyboard // - DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *)&gPnpPs2KeyboardDeviceNode); EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL); @@ -354,9 +474,12 @@ Returns: DevicePath = TempDevicePath; gPnp16550ComPortDeviceNode.UID = 0; - DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode); - DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); - DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode); // // Print Device Path @@ -383,9 +506,12 @@ Returns: DevicePath = TempDevicePath; gPnp16550ComPortDeviceNode.UID = 1; - DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode); - DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); - DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *)&gPnp16550ComPortDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode); // // Print Device Path @@ -443,7 +569,7 @@ GetGopDevicePath ( } // - // Try to connect this handle, so that GOP dirver could start on this + // Try to connect this handle, so that GOP driver could start on this // device and create child handles with GraphicsOutput Protocol installed // on them, then we get device paths of these child handles and select // them as possible console device. @@ -462,7 +588,8 @@ GetGopDevicePath ( // Add all the child handles as possible Console Device // for (Index = 0; Index < GopHandleCount; Index++) { - Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath); + Status = gBS->HandleProtocol (GopHandleBuffer[Index], + &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath); if (EFI_ERROR (Status)) { continue; } @@ -475,14 +602,14 @@ GetGopDevicePath ( // In current implementation, we only enable one of the child handles // as console device, i.e. sotre one of the child handle's device // path to variable "ConOut" - // In futhure, we could select all child handles to be console device + // In future, we could select all child handles to be console device // *GopDevicePath = TempDevicePath; // - // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath() - // Add the integrity GOP device path. + // Delete the PCI device's path that added by + // GetPlugInPciVgaDevicePath(). Add the integrity GOP device path. // EfiBootManagerUpdateConsoleVariable (ConOutDev, NULL, PciDevicePath); EfiBootManagerUpdateConsoleVariable (ConOutDev, TempDevicePath, NULL); @@ -494,27 +621,20 @@ GetGopDevicePath ( return EFI_SUCCESS; } -EFI_STATUS -PreparePciVgaDevicePath ( - IN EFI_HANDLE DeviceHandle - ) -/*++ - -Routine Description: - - Add PCI VGA to ConOut. - PCI VGA: 03 00 00 - -Arguments: - - DeviceHandle - Handle of PCIIO protocol. +/** + Add PCI display to ConOut. -Returns: + @param[in] DeviceHandle Handle of the PCI display device. - EFI_SUCCESS - PCI VGA is added to ConOut. - EFI_STATUS - No PCI VGA device is added. + @retval EFI_SUCCESS The PCI display device has been added to ConOut. ---*/ + @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing + from DeviceHandle. +**/ +EFI_STATUS +PreparePciDisplayDevicePath ( + IN EFI_HANDLE DeviceHandle + ) { EFI_STATUS Status; EFI_DEVICE_PATH_PROTOCOL *DevicePath; @@ -539,27 +659,21 @@ Returns: return EFI_SUCCESS; } -EFI_STATUS -PreparePciSerialDevicePath ( - IN EFI_HANDLE DeviceHandle - ) -/*++ - -Routine Description: - +/** Add PCI Serial to ConOut, ConIn, ErrOut. - PCI Serial: 07 00 02 -Arguments: + @param[in] DeviceHandle Handle of the PCI serial device. - DeviceHandle - Handle of PCIIO protocol. + @retval EFI_SUCCESS The PCI serial device has been added to ConOut, ConIn, + ErrOut. -Returns: - - EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut. - EFI_STATUS - No PCI Serial device is added. - ---*/ + @return Error codes, due to EFI_DEVICE_PATH_PROTOCOL missing + from DeviceHandle. +**/ +EFI_STATUS +PreparePciSerialDevicePath ( + IN EFI_HANDLE DeviceHandle + ) { EFI_STATUS Status; EFI_DEVICE_PATH_PROTOCOL *DevicePath; @@ -574,8 +688,10 @@ Returns: return Status; } - DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); - DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, + (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode); EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL); @@ -691,7 +807,8 @@ VisitAllPciInstances ( @param[in] PciIo - PCI IO protocol instance @param[in] Pci - PCI Header register block - @retval EFI_SUCCESS - PCI Device check and Console variable update successfully. + @retval EFI_SUCCESS - PCI Device check and Console variable update + successfully. @retval EFI_STATUS - PCI Device check or Console variable update fail. **/ @@ -745,14 +862,14 @@ DetectAndPreparePlatformPciDevicePath ( } // - // Here we decide which VGA device to enable in PCI bus + // Here we decide which display device to enable in PCI bus // - if (IS_PCI_VGA (Pci)) { + if (IS_PCI_DISPLAY (Pci)) { // // Add them to ConOut. // - DEBUG ((EFI_D_INFO, "Found PCI VGA device\n")); - PreparePciVgaDevicePath (Handle); + DEBUG ((EFI_D_INFO, "Found PCI display device\n")); + PreparePciDisplayDevicePath (Handle); return EFI_SUCCESS; } @@ -765,7 +882,8 @@ DetectAndPreparePlatformPciDevicePath ( @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE. - @retval EFI_SUCCESS - PCI Device check and Console variable update successfully. + @retval EFI_SUCCESS - PCI Device check and Console variable update + successfully. @retval EFI_STATUS - PCI Device check or Console variable update fail. **/ @@ -779,21 +897,17 @@ DetectAndPreparePlatformPciDevicePaths ( } +/** + Connect the predefined platform default console device. + + Always try to find and enable PCI display devices. + + @param[in] PlatformConsole Predefined platform default console device array. +**/ VOID PlatformInitializeConsole ( IN PLATFORM_CONSOLE_CONNECT_ENTRY *PlatformConsole ) -/*++ - -Routine Description: - - Connect the predefined platform default console device. Always try to find - and enable the vga device if have. - -Arguments: - - PlatformConsole - Predfined platform default console device array. ---*/ { UINTN Index; EFI_DEVICE_PATH_PROTOCOL *VarConout; @@ -802,18 +916,20 @@ Arguments: // // Connect RootBridge // - GetEfiGlobalVariable2 (EFI_CON_OUT_VARIABLE_NAME, (VOID **) &VarConout, NULL); + GetEfiGlobalVariable2 (EFI_CON_OUT_VARIABLE_NAME, (VOID **) &VarConout, + NULL); GetEfiGlobalVariable2 (EFI_CON_IN_VARIABLE_NAME, (VOID **) &VarConin, NULL); if (VarConout == NULL || VarConin == NULL) { // - // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut + // Do platform specific PCI Device check and add them to ConOut, ConIn, + // ErrOut // DetectAndPreparePlatformPciDevicePaths (FALSE); // // Have chance to connect the platform default console, - // the platform default console is the minimue device group + // the platform default console is the minimum device group // the platform should support // for (Index = 0; PlatformConsole[Index].DevicePath != NULL; ++Index) { @@ -821,13 +937,16 @@ Arguments: // Update the console variable with the connect type // if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) { - EfiBootManagerUpdateConsoleVariable (ConIn, PlatformConsole[Index].DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ConIn, + PlatformConsole[Index].DevicePath, NULL); } if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) { - EfiBootManagerUpdateConsoleVariable (ConOut, PlatformConsole[Index].DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ConOut, + PlatformConsole[Index].DevicePath, NULL); } if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) { - EfiBootManagerUpdateConsoleVariable (ErrOut, PlatformConsole[Index].DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ErrOut, + PlatformConsole[Index].DevicePath, NULL); } } } else { @@ -1044,6 +1163,37 @@ PciAcpiInitialization ( IoOr16 ((PciRead32 (Pmba) & ~BIT0) + 4, BIT0); } +/** + This function detects if OVMF is running on Xen. + +**/ +STATIC +BOOLEAN +XenDetected ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + STATIC INTN FoundHob = -1; + + if (FoundHob == 0) { + return FALSE; + } else if (FoundHob == 1) { + return TRUE; + } + + // + // See if a XenInfo HOB is available + // + GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid); + if (GuidHob == NULL) { + FoundHob = 0; + return FALSE; + } + + FoundHob = 1; + return TRUE; +} EFI_STATUS EFIAPI @@ -1057,7 +1207,11 @@ ConnectRecursivelyIfPciMassStorage ( EFI_DEVICE_PATH_PROTOCOL *DevicePath; CHAR16 *DevPathStr; - if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE)) { + // + // Recognize PCI Mass Storage, and Xen PCI devices + // + if (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE) || + (XenDetected() && IS_CLASS2 (PciHeader, 0xFF, 0x80))) { DevicePath = NULL; Status = gBS->HandleProtocol ( Handle, @@ -1075,7 +1229,11 @@ ConnectRecursivelyIfPciMassStorage ( if (DevPathStr != NULL) { DEBUG(( EFI_D_INFO, - "Found Mass Storage device: %s\n", + "Found %s device: %s\n", + (IS_CLASS1 (PciHeader, PCI_CLASS_MASS_STORAGE) ? + L"Mass Storage" : + L"Xen" + ), DevPathStr )); FreePool(DevPathStr); @@ -1096,8 +1254,8 @@ ConnectRecursivelyIfPciMassStorage ( This notification function is invoked when the EMU Variable FVB has been changed. - @param Event The event that occured - @param Context For EFI compatiblity. Not used. + @param Event The event that occurred + @param Context For EFI compatibility. Not used. **/ VOID @@ -1122,6 +1280,7 @@ VisitingFileSystemInstance ( { EFI_STATUS Status; STATIC BOOLEAN ConnectedToFileSystem = FALSE; + RETURN_STATUS PcdStatus; if (ConnectedToFileSystem) { return EFI_ALREADY_STARTED; @@ -1141,7 +1300,9 @@ VisitingFileSystemInstance ( NULL, &mEmuVariableEventReg ); - PcdSet64 (PcdEmuVariableEvent, (UINT64)(UINTN) mEmuVariableEvent); + PcdStatus = PcdSet64S (PcdEmuVariableEvent, + (UINT64)(UINTN) mEmuVariableEvent); + ASSERT_RETURN_ERROR (PcdStatus); return EFI_SUCCESS; } @@ -1160,29 +1321,18 @@ PlatformBdsRestoreNvVarsFromHardDisk ( } +/** + Connect with predefined platform connect sequence. + The OEM/IBV can customize with their own connect sequence. +**/ VOID PlatformBdsConnectSequence ( VOID ) -/*++ - -Routine Description: - - Connect with predeined platform connect sequence, - the OEM/IBV can customize with their own connect sequence. - -Arguments: - - None. - -Returns: - - None. - ---*/ { - UINTN Index; + UINTN Index; + RETURN_STATUS Status; DEBUG ((EFI_D_INFO, "PlatformBdsConnectSequence\n")); @@ -1197,103 +1347,21 @@ Returns: // // Build the platform boot option // - BdsLibConnectDevicePath (gPlatformConnectSequence[Index]); + EfiBootManagerConnectDevicePath (gPlatformConnectSequence[Index], NULL); Index++; } - // - // Just use the simple policy to connect all devices - // - BdsLibConnectAll (); - - PciAcpiInitialization (); - - // - // Clear the logo after all devices are connected. - // - gST->ConOut->ClearScreen (gST->ConOut); -} - -VOID -PlatformBdsGetDriverOption ( - IN OUT LIST_ENTRY *BdsDriverLists - ) -/*++ - -Routine Description: - - Load the predefined driver option, OEM/IBV can customize this - to load their own drivers - -Arguments: - - BdsDriverLists - The header of the driver option link list. - -Returns: - - None. - ---*/ -{ - DEBUG ((EFI_D_INFO, "PlatformBdsGetDriverOption\n")); - return; -} - -VOID -PlatformBdsDiagnostics ( - IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel, - IN BOOLEAN QuietBoot, - IN BASEM_MEMORY_TEST BaseMemoryTest - ) -/*++ - -Routine Description: - - Perform the platform diagnostic, such like test memory. OEM/IBV also - can customize this fuction to support specific platform diagnostic. - -Arguments: - - MemoryTestLevel - The memory test intensive level - - QuietBoot - Indicate if need to enable the quiet boot - - BaseMemoryTest - A pointer to BaseMemoryTest() - -Returns: - - None. - ---*/ -{ - EFI_STATUS Status; - - DEBUG ((EFI_D_INFO, "PlatformBdsDiagnostics\n")); - - // - // Here we can decide if we need to show - // the diagnostics screen - // Notes: this quiet boot code should be remove - // from the graphic lib - // - if (QuietBoot) { - EnableQuietBoot (PcdGetPtr(PcdLogoFile)); + Status = ConnectDevicesFromQemu (); + if (RETURN_ERROR (Status)) { // - // Perform system diagnostic + // Just use the simple policy to connect all devices // - Status = BaseMemoryTest (MemoryTestLevel); - if (EFI_ERROR (Status)) { - DisableQuietBoot (); - } - - return ; + DEBUG ((DEBUG_INFO, "EfiBootManagerConnectAll\n")); + EfiBootManagerConnectAll (); } - // - // Perform system diagnostic - // - Status = BaseMemoryTest (MemoryTestLevel); -} + PciAcpiInitialization (); +} /** Save the S3 boot script. @@ -1327,22 +1395,25 @@ SaveS3BootScript ( } +/** + Do the platform specific action after the console is ready + + Possible things that can be done in PlatformBootManagerAfterConsole: + + > Console post action: + > Dynamically switch output mode from 100x31 to 80x25 for certain senarino + > Signal console ready platform customized event + > Run diagnostics like memory testing + > Connect certain devices + > Dispatch aditional option roms + > Special boot: e.g.: USB boot, enter UI +**/ VOID EFIAPI PlatformBootManagerAfterConsole ( VOID ) -/*++ - -Routine Description: - - The function will excute with as the platform policy, current policy - is driven by boot mode. IBV/OEM can customize this code for their specific - policy action. - ---*/ { - EFI_STATUS Status; EFI_BOOT_MODE BootMode; DEBUG ((EFI_D_INFO, "PlatformBootManagerAfterConsole\n")); @@ -1358,16 +1429,11 @@ Routine Description: PlatformBdsRestoreNvVarsFromHardDisk (); } - // - // Load the driver option as the driver option list - // - PlatformBdsGetDriverOption (DriverOptionList); - // // Get current Boot Mode // - Status = BdsLibGetBootMode (&BootMode); - DEBUG ((EFI_D_ERROR, "Boot Mode:%x\n", BootMode)); + BootMode = GetBootModeHob (); + DEBUG ((DEBUG_INFO, "Boot Mode:%x\n", BootMode)); // // Go the different platform policy with different boot mode @@ -1376,9 +1442,9 @@ Routine Description: ASSERT (BootMode == BOOT_WITH_FULL_CONFIGURATION); // - // Memory test and Logo show + // Logo show // - PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest); + BootLogoEnableLogo (); // // Perform some platform specific connect sequence @@ -1390,24 +1456,25 @@ Routine Description: // TryRunningQemuKernel (); - DEBUG ((EFI_D_INFO, "BdsLibConnectAll\n")); - BdsLibConnectAll (); - BdsLibEnumerateAllBootOption (BootOptionList); + EfiBootManagerRefreshAllBootOption (); - SetBootOrderFromQemu (BootOptionList); // - // The BootOrder variable may have changed, reload the in-memory list with - // it. + // Register UEFI Shell // - BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder"); + PlatformRegisterFvBootOption ( + PcdGetPtr (PcdShellFile), L"EFI Internal Shell", LOAD_OPTION_ACTIVE + ); + + RemoveStaleFvFileOptions (); + SetBootOrderFromQemu (); } /** This notification function is invoked when an instance of the EFI_DEVICE_PATH_PROTOCOL is produced. - @param Event The event that occured - @param Context For EFI compatiblity. Not used. + @param Event The event that occurred + @param Context For EFI compatibility. Not used. **/ VOID @@ -1453,7 +1520,8 @@ NotifyDevPath ( // // Get the DevicePath protocol on that handle // - Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, (VOID **)&DevPathNode); + Status = gBS->HandleProtocol (Handle, &gEfiDevicePathProtocolGuid, + (VOID **)&DevPathNode); ASSERT_EFI_ERROR (Status); while (!IsDevicePathEnd (DevPathNode)) { @@ -1503,7 +1571,8 @@ InstallDevicePathCallback ( } /** - This function is called each second during the boot manager waits the timeout. + This function is called each second during the boot manager waits the + timeout. @param TimeoutRemain The remaining timeout. **/ @@ -1513,5 +1582,22 @@ PlatformBootManagerWaitCallback ( UINT16 TimeoutRemain ) { + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White; + UINT16 Timeout; + + Timeout = PcdGet16 (PcdPlatformBootTimeOut); + + Black.Raw = 0x00000000; + White.Raw = 0x00FFFFFF; + + BootLogoUpdateProgress ( + White.Pixel, + Black.Pixel, + L"Start boot option", + White.Pixel, + (Timeout - TimeoutRemain) * 100 / Timeout, + 0 + ); }