/** @file | |
Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR> | |
This program and the accompanying materials are licensed and made available under | |
the terms and conditions of the BSD License that accompanies this distribution. | |
The full text of the license may be found at | |
http://opensource.org/licenses/bsd-license.php. | |
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
Module Name: | |
BdsPlatform.c | |
Abstract: | |
This file include all platform action which can be customized | |
by IBV/OEM. | |
--*/ | |
#include "BdsPlatform.h" | |
#include "SetupMode.h" | |
#include <Guid/SetupVariable.h> | |
#include <Library/TcgPhysicalPresenceLib.h> | |
#include <Library/TrEEPhysicalPresenceLib.h> | |
#include <Protocol/I2cMasterMcg.h> | |
#include <TianoApi.h> | |
#include <PlatformBaseAddresses.h> | |
#include <Protocol/GlobalNvsArea.h> | |
#include <Library/DxeServicesTableLib.h> | |
#include <Protocol/BlockIo.h> | |
#include <PchRegs/PchRegsPcu.h> | |
#include <Library/S3BootScriptLib.h> | |
#include "PchAccess.h" | |
#include "PchRegs/PchRegsSata.h" | |
#include <Library/SerialPortLib.h> | |
#include <Library/DebugLib.h> | |
#include <Library/GenericBdsLib/InternalBdsLib.h> | |
#include <Library/GenericBdsLib/String.h> | |
#include <Library/NetLib.h> | |
#include <Library/CapsuleLib.h> | |
#include <Protocol/EsrtManagement.h> | |
EFI_GUID *ConnectDriverTable[] = { | |
&gEfiMmioDeviceProtocolGuid, | |
&gEfiI2cMasterProtocolGuid, | |
&gEfiI2cHostProtocolGuid | |
}; | |
#define SHELL_ENVIRONMENT_INTERFACE_PROTOCOL \ | |
{ \ | |
0x47c7b221, 0xc42a, 0x11d2, 0x8e, 0x57, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \ | |
} | |
VOID *mShellImageCallbackReg = NULL; | |
EFI_USER_PROFILE_HANDLE mCurrentUser = NULL; | |
EFI_EVENT mHotKeyTimerEvent = NULL; | |
EFI_EVENT mHitHotkeyEvent = NULL; | |
EFI_EVENT mUsbKeyboardConnectEvent = NULL; | |
BOOLEAN mHotKeyPressed = FALSE; | |
VOID *mHitHotkeyRegistration; | |
#define KEYBOARD_TIMER_INTERVAL 20000 // 0.02s | |
VOID | |
ConnectUSBController ( | |
VOID | |
); | |
EFI_STATUS | |
PlatformBdsConnectSimpleConsole ( | |
IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole | |
); | |
VOID | |
BootIntoFirmwareInterface( | |
VOID | |
); | |
VOID | |
EFIAPI | |
PlatformBdsInitHotKeyEvent ( | |
VOID | |
); | |
VOID | |
EFIAPI | |
DisableAhciCtlr ( | |
IN EFI_EVENT Event, | |
IN VOID *Context | |
) | |
{ | |
UINT32 PmcDisableAddress; | |
UINT8 SataStorageAmount; | |
UINT32 SataBase; | |
UINT16 SataPortStatus; | |
DEBUG ((EFI_D_INFO, "Disable AHCI event is signalled\n")); | |
SataStorageAmount = 0; | |
SataBase = *(UINT32*) Context; | |
// | |
// BayTrail-M EDS chapter 16 ---- PCI IO Register Offset 92 (SATA Port Control and Status) | |
// | |
SataPortStatus = MmioRead16 (SataBase + R_PCH_SATA_PCS); | |
// | |
// Bit 8 EN: Port 0 Present | |
// | |
if ((SataPortStatus & 0x100) == 0x100) { | |
SataStorageAmount++; | |
} | |
// | |
// Bit 9 EN: Port 1 Present | |
// | |
if ((SataPortStatus & 0x200) == 0x200) { | |
SataStorageAmount++; | |
} | |
// | |
// Disable SATA controller when it sets to AHCI mode without carrying any devices | |
// in order to prevent AHCI yellow bang under Win device manager. | |
// | |
if (SataStorageAmount == 0) { | |
PmcDisableAddress = (MmioRead32 ((PCH_PCI_EXPRESS_BASE_ADDRESS + (UINT32) (31 << 15)) + R_PCH_LPC_PMC_BASE) & B_PCH_LPC_PMC_BASE_BAR) + R_PCH_PMC_FUNC_DIS; | |
MmioOr32 (PmcDisableAddress, B_PCH_PMC_FUNC_DIS_SATA); | |
S3BootScriptSaveMemWrite ( | |
EfiBootScriptWidthUint32, | |
(UINTN) PmcDisableAddress, | |
1, | |
(VOID *) (UINTN) PmcDisableAddress | |
); | |
} | |
} | |
VOID | |
InstallReadyToLock ( | |
VOID | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_HANDLE Handle; | |
EFI_SMM_ACCESS2_PROTOCOL *SmmAccess; | |
EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save; | |
// | |
// Install DxeSmmReadyToLock protocol prior to the processing of boot options | |
// | |
Status = gBS->LocateProtocol ( | |
&gEfiSmmAccess2ProtocolGuid, | |
NULL, | |
(VOID **) &SmmAccess | |
); | |
if (!EFI_ERROR (Status)) { | |
// | |
// Prepare S3 information, this MUST be done before DxeSmmReadyToLock | |
// | |
Status = gBS->LocateProtocol ( | |
&gEfiAcpiS3SaveProtocolGuid, | |
NULL, | |
(VOID **)&AcpiS3Save | |
); | |
if (!EFI_ERROR (Status)) { | |
AcpiS3Save->S3Save (AcpiS3Save, NULL); | |
} | |
Handle = NULL; | |
Status = gBS->InstallProtocolInterface ( | |
&Handle, | |
&gExitPmAuthProtocolGuid, | |
EFI_NATIVE_INTERFACE, | |
NULL | |
); | |
ASSERT_EFI_ERROR (Status); | |
// | |
// Signal EndOfDxe PI Event | |
// | |
EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid); | |
Handle = NULL; | |
Status = gBS->InstallProtocolInterface ( | |
&Handle, | |
&gEfiDxeSmmReadyToLockProtocolGuid, | |
EFI_NATIVE_INTERFACE, | |
NULL | |
); | |
ASSERT_EFI_ERROR (Status); | |
} | |
return ; | |
} | |
VOID | |
EFIAPI | |
ShellImageCallback ( | |
IN EFI_EVENT Event, | |
IN VOID *Context | |
) | |
{ | |
BdsSetConsoleMode (TRUE); | |
DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n")); | |
} | |
// | |
// BDS Platform Functions | |
// | |
/** | |
Platform Bds init. Include the platform firmware vendor, revision | |
and so crc check. | |
@param VOID | |
@retval None. | |
**/ | |
VOID | |
EFIAPI | |
PlatformBdsInit ( | |
VOID | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_EVENT ShellImageEvent; | |
EFI_GUID ShellEnvProtocol = SHELL_ENVIRONMENT_INTERFACE_PROTOCOL; | |
#ifdef __GNUC__ | |
SerialPortWrite((UINT8 *)">>>>BdsEntry[GCC]\r\n", 19); | |
#else | |
SerialPortWrite((UINT8 *)">>>>BdsEntry\r\n", 14); | |
#endif | |
BdsLibSaveMemoryTypeInformation (); | |
// | |
// Before user authentication, the user identification devices need be connected | |
// from the platform customized device paths | |
// | |
PlatformBdsConnectAuthDevice (); | |
// | |
// As console is not ready, the auto logon user will be identified. | |
// | |
BdsLibUserIdentify (&mCurrentUser); | |
// | |
// Change Gop mode when boot into Shell | |
// | |
if (mShellImageCallbackReg == NULL) { | |
Status = gBS->CreateEvent ( | |
EFI_EVENT_NOTIFY_SIGNAL, | |
EFI_TPL_CALLBACK, | |
ShellImageCallback, | |
NULL, | |
&ShellImageEvent | |
); | |
if (!EFI_ERROR (Status)) { | |
Status = gBS->RegisterProtocolNotify ( | |
&ShellEnvProtocol, | |
ShellImageEvent, | |
&mShellImageCallbackReg | |
); | |
DEBUG ((EFI_D_INFO, "BdsEntry ShellImageCallback \n")); | |
} | |
} | |
} | |
EFI_STATUS | |
GetGopDevicePath ( | |
IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath, | |
OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath | |
) | |
{ | |
UINTN Index; | |
EFI_STATUS Status; | |
EFI_HANDLE PciDeviceHandle; | |
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; | |
EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath; | |
UINTN GopHandleCount; | |
EFI_HANDLE *GopHandleBuffer; | |
UINTN VarSize; | |
SYSTEM_CONFIGURATION mSystemConfiguration; | |
if (PciDevicePath == NULL || GopDevicePath == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
// | |
// Initialize the GopDevicePath to be PciDevicePath | |
// | |
*GopDevicePath = PciDevicePath; | |
TempPciDevicePath = PciDevicePath; | |
Status = gBS->LocateDevicePath ( | |
&gEfiDevicePathProtocolGuid, | |
&TempPciDevicePath, | |
&PciDeviceHandle | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// 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. | |
// | |
// | |
// Select display devices | |
// | |
VarSize = sizeof(SYSTEM_CONFIGURATION); | |
Status = gRT->GetVariable( | |
L"Setup", | |
&gEfiNormalSetupGuid, | |
NULL, | |
&VarSize, | |
&mSystemConfiguration | |
); | |
if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) { | |
//The setup variable is corrupted | |
VarSize = sizeof(SYSTEM_CONFIGURATION); | |
Status = gRT->GetVariable( | |
L"SetupRecovery", | |
&gEfiNormalSetupGuid, | |
NULL, | |
&VarSize, | |
&mSystemConfiguration | |
); | |
ASSERT_EFI_ERROR (Status); | |
} | |
if(mSystemConfiguration.BootDisplayDevice != 0x0) | |
{ | |
ACPI_ADR_DEVICE_PATH AcpiAdr; | |
EFI_DEVICE_PATH_PROTOCOL *MyDevicePath = NULL; | |
AcpiAdr.Header.Type = ACPI_DEVICE_PATH; | |
AcpiAdr.Header.SubType = ACPI_ADR_DP; | |
switch (mSystemConfiguration.BootDisplayDevice) { | |
case 1: | |
AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0); //CRT Device | |
break; | |
case 2: | |
AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_HDMI, 0); //HDMI Device Port B | |
break; | |
case 3: | |
AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_B_DP, 0); //DP PortB | |
break; | |
case 4: | |
AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_EXTERNAL_DIGITAL, PORT_C_DP, 0); //DP PortC | |
break; | |
case 5: | |
AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_C_DP, 0); //eDP Port C | |
break; | |
case 6: | |
AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_A, 0); //DSI Port A | |
break; | |
case 7: | |
AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, PORT_MIPI_C, 0); //DSI Port C | |
break; | |
default: | |
AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, PORT_CRT, 0); | |
break; | |
} | |
SetDevicePathNodeLength (&AcpiAdr.Header, sizeof (ACPI_ADR_DEVICE_PATH)); | |
MyDevicePath = AppendDevicePathNode(MyDevicePath, (EFI_DEVICE_PATH_PROTOCOL*)&AcpiAdr); | |
gBS->ConnectController ( | |
PciDeviceHandle, | |
NULL, | |
MyDevicePath, | |
FALSE | |
); | |
FreePool(MyDevicePath); | |
} | |
else | |
{ | |
gBS->ConnectController ( | |
PciDeviceHandle, | |
NULL, | |
NULL, | |
FALSE | |
); | |
} | |
Status = gBS->LocateHandleBuffer ( | |
ByProtocol, | |
&gEfiGraphicsOutputProtocolGuid, | |
NULL, | |
&GopHandleCount, | |
&GopHandleBuffer | |
); | |
if (!EFI_ERROR (Status)) { | |
// | |
// Add all the child handles as possible Console Device | |
// | |
for (Index = 0; Index < GopHandleCount; Index++) { | |
Status = gBS->HandleProtocol ( | |
GopHandleBuffer[Index], | |
&gEfiDevicePathProtocolGuid, | |
(VOID**)&TempDevicePath | |
); | |
if (EFI_ERROR (Status)) { | |
continue; | |
} | |
if (CompareMem ( | |
PciDevicePath, | |
TempDevicePath, | |
GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH | |
) == 0) { | |
// | |
// 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 future, we could select all child handles to be console device | |
// | |
*GopDevicePath = TempDevicePath; | |
} | |
} | |
gBS->FreePool (GopHandleBuffer); | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
Search out all the platform pci or agp video device. The function may will | |
find multiple video device, and return all enabled device path. | |
@param PlugInPciVgaDevicePath Return the platform plug in pci video device | |
path if the system have plug in pci video device. | |
@param OnboardPciVgaDevicePath Return the platform active agp video device path | |
if the system have plug in agp video device or on | |
chip agp device. | |
@retval EFI_SUCCSS Get all platform active video device path. | |
@retval EFI_STATUS Return the status of gBS->LocateDevicePath (), | |
gBS->ConnectController (), | |
and gBS->LocateHandleBuffer (). | |
**/ | |
EFI_STATUS | |
GetPlugInPciVgaDevicePath ( | |
IN OUT EFI_DEVICE_PATH_PROTOCOL **PlugInPciVgaDevicePath, | |
IN OUT EFI_DEVICE_PATH_PROTOCOL **OnboardPciVgaDevicePath | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_HANDLE RootHandle; | |
UINTN HandleCount; | |
EFI_HANDLE *HandleBuffer; | |
UINTN Index; | |
UINTN Index1; | |
EFI_DEVICE_PATH_PROTOCOL *DevicePath; | |
BOOLEAN PlugInPciVga; | |
EFI_PCI_IO_PROTOCOL *PciIo; | |
PCI_TYPE00 Pci; | |
DevicePath = NULL; | |
PlugInPciVga = TRUE; | |
HandleCount = 0; | |
HandleBuffer = NULL; | |
// | |
// Make all the PCI_IO protocols on PCI Seg 0 show up | |
// | |
BdsLibConnectDevicePath (gPlatformRootBridges[0]); | |
Status = gBS->LocateDevicePath ( | |
&gEfiDevicePathProtocolGuid, | |
&gPlatformRootBridges[0], | |
&RootHandle | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Status = gBS->ConnectController ( | |
RootHandle, | |
NULL, | |
NULL, | |
FALSE | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// Start to check all the pci io to find all possible VGA device | |
// | |
HandleCount = 0; | |
HandleBuffer = NULL; | |
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 | |
); | |
if (!EFI_ERROR (Status)) { | |
// | |
// Check for all VGA device | |
// | |
Status = PciIo->Pci.Read ( | |
PciIo, | |
EfiPciIoWidthUint32, | |
0, | |
sizeof (Pci) / sizeof (UINT32), | |
&Pci | |
); | |
if (EFI_ERROR (Status)) { | |
continue; | |
} | |
// | |
// Here we decide which VGA device to enable in PCI bus | |
// | |
// The first plugin PCI VGA card device will be present as PCI VGA | |
// The onchip AGP or AGP card will be present as AGP VGA | |
// | |
if (!IS_PCI_VGA (&Pci)) { | |
continue; | |
} | |
// | |
// Set the device as the possible console out device, | |
// | |
// Below code will make every VGA device to be one | |
// of the possibe console out device | |
// | |
PlugInPciVga = TRUE; | |
gBS->HandleProtocol ( | |
HandleBuffer[Index], | |
&gEfiDevicePathProtocolGuid, | |
(VOID**)&DevicePath | |
); | |
Index1 = 0; | |
while (gPlatformAllPossiblePciVgaConsole[Index1] != NULL) { | |
if (CompareMem ( | |
DevicePath, | |
gPlatformAllPossiblePciVgaConsole[Index1], | |
GetDevicePathSize (gPlatformAllPossiblePciVgaConsole[Index1]) | |
) == 0) { | |
// | |
// This device is an AGP device | |
// | |
*OnboardPciVgaDevicePath = DevicePath; | |
PlugInPciVga = FALSE; | |
break; | |
} | |
Index1 ++; | |
} | |
if (PlugInPciVga) { | |
*PlugInPciVgaDevicePath = DevicePath; | |
} | |
} | |
} | |
FreePool (HandleBuffer); | |
return EFI_SUCCESS; | |
} | |
/** | |
Find the platform active vga, and base on the policy to enable the vga as | |
the console out device. The policy is driven by one setup variable "VBIOS". | |
None. | |
@param EFI_UNSUPPORTED There is no active vga device | |
@retval EFI_STATUS Return the status of BdsLibGetVariableAndSize () | |
**/ | |
EFI_STATUS | |
PlatformBdsForceActiveVga ( | |
VOID | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_DEVICE_PATH_PROTOCOL *PlugInPciVgaDevicePath; | |
EFI_DEVICE_PATH_PROTOCOL *OnboardPciVgaDevicePath; | |
EFI_DEVICE_PATH_PROTOCOL *DevicePathFirst; | |
EFI_DEVICE_PATH_PROTOCOL *DevicePathSecond; | |
EFI_DEVICE_PATH_PROTOCOL *GopDevicePath; | |
UINTN VarSize; | |
SYSTEM_CONFIGURATION mSystemConfiguration; | |
Status = EFI_SUCCESS; | |
PlugInPciVgaDevicePath = NULL; | |
OnboardPciVgaDevicePath = NULL; | |
// | |
// Check the policy which is the first enabled VGA | |
// | |
GetPlugInPciVgaDevicePath (&PlugInPciVgaDevicePath, &OnboardPciVgaDevicePath); | |
if (PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath == NULL) { | |
return EFI_UNSUPPORTED; | |
} | |
VarSize = sizeof(SYSTEM_CONFIGURATION); | |
Status = gRT->GetVariable( | |
L"Setup", | |
&gEfiNormalSetupGuid, | |
NULL, | |
&VarSize, | |
&mSystemConfiguration | |
); | |
if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) { | |
//The setup variable is corrupted | |
VarSize = sizeof(SYSTEM_CONFIGURATION); | |
Status = gRT->GetVariable( | |
L"SetupRecovery", | |
&gEfiNormalSetupGuid, | |
NULL, | |
&VarSize, | |
&mSystemConfiguration | |
); | |
ASSERT_EFI_ERROR (Status); | |
} | |
if ((PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath != NULL) ) { | |
DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA ...\n")); | |
DevicePathFirst = OnboardPciVgaDevicePath; | |
DevicePathSecond = PlugInPciVgaDevicePath; | |
goto UpdateConOut; | |
} | |
if(OnboardPciVgaDevicePath != NULL && mSystemConfiguration.PrimaryVideoAdaptor == 0) { | |
DEBUG ((EFI_D_ERROR,"Update onboard PCI VGA When set primary!!!...\n")); | |
DevicePathFirst = OnboardPciVgaDevicePath; | |
DevicePathSecond = PlugInPciVgaDevicePath; | |
goto UpdateConOut; | |
} | |
DEBUG ((EFI_D_ERROR,"Update plug in PCI VGA ...\n")); | |
DevicePathFirst = PlugInPciVgaDevicePath; | |
DevicePathSecond = OnboardPciVgaDevicePath; | |
UpdateConOut: | |
GetGopDevicePath (DevicePathFirst, &GopDevicePath); | |
DevicePathFirst = GopDevicePath; | |
Status = BdsLibUpdateConsoleVariable ( | |
L"ConOut", | |
DevicePathFirst, | |
DevicePathSecond | |
); | |
return Status; | |
} | |
VOID | |
UpdateConsoleResolution( | |
VOID | |
) | |
{ | |
UINT32 HorizontalResolution; | |
UINT32 VerticalResolution; | |
SYSTEM_CONFIGURATION SystemConfiguration; | |
UINTN VarSize; | |
EFI_STATUS Status; | |
HorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution); | |
VerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution); | |
VarSize = sizeof(SYSTEM_CONFIGURATION); | |
Status = gRT->GetVariable( | |
L"Setup", | |
&gEfiNormalSetupGuid, | |
NULL, | |
&VarSize, | |
&SystemConfiguration | |
); | |
if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) { | |
//The setup variable is corrupted | |
VarSize = sizeof(SYSTEM_CONFIGURATION); | |
Status = gRT->GetVariable( | |
L"SetupRecovery", | |
&gEfiNormalSetupGuid, | |
NULL, | |
&VarSize, | |
&SystemConfiguration | |
); | |
ASSERT_EFI_ERROR (Status); | |
} | |
switch (SystemConfiguration.IgdFlatPanel) { | |
case 0: | |
// | |
// Use the detault PCD values. | |
// | |
break; | |
case 1: | |
HorizontalResolution = 640; | |
VerticalResolution = 480; | |
break; | |
case 2: | |
HorizontalResolution = 800; | |
VerticalResolution = 600; | |
break; | |
case 3: | |
HorizontalResolution = 1024; | |
VerticalResolution = 768; | |
break; | |
case 4: | |
HorizontalResolution = 1280; | |
VerticalResolution = 1024; | |
break; | |
case 5: | |
HorizontalResolution = 1366; | |
VerticalResolution = 768; | |
break; | |
case 6: | |
HorizontalResolution = 1680; | |
VerticalResolution = 1050; | |
break; | |
case 7: | |
HorizontalResolution = 1920; | |
VerticalResolution = 1200; | |
break; | |
case 8: | |
HorizontalResolution = 1280; | |
VerticalResolution = 800; | |
break; | |
} | |
PcdSet32 (PcdSetupVideoHorizontalResolution, HorizontalResolution); | |
PcdSet32 (PcdSetupVideoVerticalResolution, VerticalResolution); | |
DEBUG ((EFI_D_ERROR, "HorizontalResolution = %x; VerticalResolution = %x", HorizontalResolution, VerticalResolution)); | |
return; | |
} | |
/** | |
Connect the predefined platform default console device. Always try to find | |
and enable the vga device if have. | |
@param PlatformConsole Predefined platform default console device array. | |
@retval EFI_SUCCESS Success connect at least one ConIn and ConOut | |
device, there must have one ConOut device is | |
active vga device. | |
@retval EFI_STATUS Return the status of | |
BdsLibConnectAllDefaultConsoles () | |
**/ | |
EFI_STATUS | |
PlatformBdsConnectConsole ( | |
IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole | |
) | |
{ | |
EFI_STATUS Status; | |
UINTN Index; | |
EFI_DEVICE_PATH_PROTOCOL *VarConout; | |
EFI_DEVICE_PATH_PROTOCOL *VarConin; | |
UINTN DevicePathSize; | |
UpdateConsoleResolution(); | |
Index = 0; | |
Status = EFI_SUCCESS; | |
DevicePathSize = 0; | |
VarConout = BdsLibGetVariableAndSize ( | |
L"ConOut", | |
&gEfiGlobalVariableGuid, | |
&DevicePathSize | |
); | |
VarConin = BdsLibGetVariableAndSize ( | |
L"ConIn", | |
&gEfiGlobalVariableGuid, | |
&DevicePathSize | |
); | |
if (VarConout == NULL || VarConin == NULL) { | |
// | |
// Have chance to connect the platform default console, | |
// the platform default console is the minimum device group | |
// the platform should support | |
// | |
while (PlatformConsole[Index].DevicePath != NULL) { | |
// | |
// Update the console variable with the connect type | |
// | |
if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) { | |
BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL); | |
} | |
if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) { | |
BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL); | |
} | |
if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) { | |
BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL); | |
} | |
Index ++; | |
} | |
} | |
// | |
// Make sure we have at least one active VGA, and have the right | |
// active VGA in console variable | |
// | |
Status = PlatformBdsForceActiveVga (); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
DEBUG ((EFI_D_INFO, "DISPLAY INIT DONE\n")); | |
// | |
// Connect the all the default console with current console variable | |
// | |
Status = BdsLibConnectAllDefaultConsoles (); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
Connect with predefined platform connect sequence, | |
the OEM/IBV can customize with their own connect sequence. | |
@param None. | |
@retval None. | |
**/ | |
VOID | |
PlatformBdsConnectSequence ( | |
VOID | |
) | |
{ | |
UINTN Index; | |
Index = 0; | |
// | |
// Here we can get the customized platform connect sequence | |
// Notes: we can connect with new variable which record the | |
// last time boots connect device path sequence | |
// | |
while (gPlatformConnectSequence[Index] != NULL) { | |
// | |
// Build the platform boot option | |
// | |
BdsLibConnectDevicePath (gPlatformConnectSequence[Index]); | |
Index ++; | |
} | |
// | |
// Just use the simple policy to connect all devices | |
// There should be no difference between debug tip and release tip, or it will be extremely hard to debug. | |
// | |
// There is case that IdeController driver will write boot script in driver model Start() function. It will be rejected by boot script save. | |
// It is only found when DEBUG disabled, because we are using BdsLibConnectAll() when DEBUG enabled. | |
// | |
// So we use BdsLibConnectAll() here to make sure IdeController.Start() is invoked before InstallReadyToLock(). | |
// We may also consider to connect SataController only later if needed. | |
// | |
BdsLibConnectAll (); | |
} | |
/** | |
Load the predefined driver option, OEM/IBV can customize this | |
to load their own drivers | |
@param BdsDriverLists The header of the driver option link list. | |
@retval None. | |
**/ | |
VOID | |
PlatformBdsGetDriverOption ( | |
IN OUT LIST_ENTRY *BdsDriverLists | |
) | |
{ | |
UINTN Index; | |
Index = 0; | |
// | |
// Here we can get the customized platform driver option | |
// | |
while (gPlatformDriverOption[Index] != NULL) { | |
// | |
// Build the platform boot option | |
// | |
BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder"); | |
Index ++; | |
} | |
} | |
/** | |
This function is used for some critical time if the the system | |
have no any boot option, and there is no time out for user to add | |
the new boot option. This can also treat as the platform default | |
boot option. | |
@param BdsBootOptionList The header of the boot option link list. | |
@retval None. | |
**/ | |
VOID | |
PlatformBdsPredictBootOption ( | |
IN OUT LIST_ENTRY *BdsBootOptionList | |
) | |
{ | |
UINTN Index; | |
Index = 0; | |
// | |
// Here give chance to get platform boot option data | |
// | |
while (gPlatformBootOption[Index] != NULL) { | |
// | |
// Build the platform boot option | |
// | |
BdsLibRegisterNewOption (BdsBootOptionList, gPlatformBootOption[Index], NULL, L"BootOrder"); | |
Index ++; | |
} | |
} | |
/** | |
Perform the platform diagnostic, such like test memory. OEM/IBV also | |
can customize this fuction to support specific platform diagnostic. | |
@param MemoryTestLevel The memory test intensive level | |
@param QuietBoot Indicate if need to enable the quiet boot | |
@param BaseMemoryTest A pointer to BdsMemoryTest() | |
@retval None. | |
**/ | |
VOID | |
PlatformBdsDiagnostics ( | |
IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel, | |
IN BOOLEAN QuietBoot, | |
IN BASEM_MEMORY_TEST BaseMemoryTest | |
) | |
{ | |
EFI_STATUS Status; | |
// | |
// 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)); | |
// | |
// Perform system diagnostic | |
// | |
Status = BaseMemoryTest (MemoryTestLevel); | |
if (EFI_ERROR (Status)) { | |
DisableQuietBoot (); | |
} | |
return; | |
} | |
// | |
// Perform system diagnostic | |
// | |
Status = BaseMemoryTest (MemoryTestLevel); | |
} | |
/** | |
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 | |
PlatformBdsLibEnumerateAllBootOption ( | |
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; | |
CHAR16 *MacStr; | |
CHAR16 *IPverStr; | |
EFI_HANDLE *NetworkHandles; | |
UINTN BufferSize; | |
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); | |
} | |
// | |
// 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); | |
} | |
// | |
// 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++) { | |
// | |
//Locate EFI_DEVICE_PATH_PROTOCOL to dynamically get IPv4/IPv6 protocol information. | |
// | |
Status = gBS->HandleProtocol ( | |
LoadFileHandles[Index], | |
&gEfiDevicePathProtocolGuid, | |
(VOID **) &DevicePath | |
); | |
ASSERT_EFI_ERROR (Status); | |
while (!IsDevicePathEnd (DevicePath)) { | |
if ((DevicePath->Type == MESSAGING_DEVICE_PATH) && | |
(DevicePath->SubType == MSG_IPv4_DP)) { | |
// | |
//Get handle infomation | |
// | |
BufferSize = 0; | |
NetworkHandles = NULL; | |
Status = gBS->LocateHandle ( | |
ByProtocol, | |
&gEfiSimpleNetworkProtocolGuid, | |
NULL, | |
&BufferSize, | |
NetworkHandles | |
); | |
if (Status == EFI_BUFFER_TOO_SMALL) { | |
NetworkHandles = AllocateZeroPool(BufferSize); | |
if (NetworkHandles == NULL) { | |
return (EFI_OUT_OF_RESOURCES); | |
} | |
Status = gBS->LocateHandle( | |
ByProtocol, | |
&gEfiSimpleNetworkProtocolGuid, | |
NULL, | |
&BufferSize, | |
NetworkHandles | |
); | |
} | |
// | |
//Get the MAC string | |
// | |
Status = NetLibGetMacString ( | |
*NetworkHandles, | |
NULL, | |
&MacStr | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
IPverStr = L" IPv4"; | |
UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr); | |
break; | |
} | |
if((DevicePath->Type == MESSAGING_DEVICE_PATH) && | |
(DevicePath->SubType == MSG_IPv6_DP)) { | |
// | |
//Get handle infomation | |
// | |
BufferSize = 0; | |
NetworkHandles = NULL; | |
Status = gBS->LocateHandle ( | |
ByProtocol, | |
&gEfiSimpleNetworkProtocolGuid, | |
NULL, | |
&BufferSize, | |
NetworkHandles | |
); | |
if (Status == EFI_BUFFER_TOO_SMALL) { | |
NetworkHandles = AllocateZeroPool(BufferSize); | |
if (NetworkHandles == NULL) { | |
return (EFI_OUT_OF_RESOURCES); | |
} | |
Status = gBS->LocateHandle( | |
ByProtocol, | |
&gEfiSimpleNetworkProtocolGuid, | |
NULL, | |
&BufferSize, | |
NetworkHandles | |
); | |
} | |
// | |
//Get the MAC string | |
// | |
Status = NetLibGetMacString ( | |
*NetworkHandles, | |
NULL, | |
&MacStr | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
IPverStr = L" IPv6"; | |
UnicodeSPrint (Buffer, sizeof (Buffer), L"%s%s%s", BdsLibGetStringById (STRING_TOKEN (STR_DESCRIPTION_NETWORK)),MacStr,IPverStr); | |
break; | |
} | |
DevicePath = NextDevicePathNode (DevicePath); | |
} | |
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; | |
} | |
/** | |
The function will execute with as the platform policy, current policy | |
is driven by boot mode. IBV/OEM can customize this code for their specific | |
policy action. | |
@param DriverOptionList - The header of the driver option link list | |
@param BootOptionList - The header of the boot option link list | |
@param ProcessCapsules - A pointer to ProcessCapsules() | |
@param BaseMemoryTest - A pointer to BaseMemoryTest() | |
@retval None. | |
**/ | |
VOID | |
EFIAPI | |
PlatformBdsPolicyBehavior ( | |
IN OUT LIST_ENTRY *DriverOptionList, | |
IN OUT LIST_ENTRY *BootOptionList, | |
IN PROCESS_CAPSULES BdsProcessCapsules, | |
IN BASEM_MEMORY_TEST BaseMemoryTest | |
) | |
{ | |
EFI_STATUS Status; | |
UINT16 Timeout; | |
EFI_BOOT_MODE BootMode; | |
BOOLEAN DeferredImageExist; | |
UINTN Index; | |
SYSTEM_CONFIGURATION SystemConfiguration; | |
UINTN VarSize; | |
PLATFORM_PCI_DEVICE_PATH *EmmcBootDevPath; | |
EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea; | |
EFI_HANDLE FvProtocolHandle; | |
UINTN HandleCount; | |
EFI_HANDLE *HandleBuffer; | |
UINTN Index1; | |
UINTN SataPciRegBase = 0; | |
UINT16 SataModeSelect = 0; | |
VOID *RegistrationExitPmAuth = NULL; | |
EFI_EVENT Event; | |
BOOLEAN IsFirstBoot; | |
UINT16 *BootOrder; | |
UINTN BootOrderSize; | |
ESRT_MANAGEMENT_PROTOCOL *EsrtManagement; | |
Timeout = PcdGet16 (PcdPlatformBootTimeOut); | |
if (Timeout > 10 ) { | |
//we think the Timeout variable is corrupted | |
Timeout = 10; | |
} | |
VarSize = sizeof(SYSTEM_CONFIGURATION); | |
Status = gRT->GetVariable( | |
NORMAL_SETUP_NAME, | |
&gEfiNormalSetupGuid, | |
NULL, | |
&VarSize, | |
&SystemConfiguration | |
); | |
if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) { | |
//The setup variable is corrupted | |
VarSize = sizeof(SYSTEM_CONFIGURATION); | |
Status = gRT->GetVariable( | |
L"SetupRecovery", | |
&gEfiNormalSetupGuid, | |
NULL, | |
&VarSize, | |
&SystemConfiguration | |
); | |
ASSERT_EFI_ERROR (Status); | |
} | |
// | |
// Load the driver option as the driver option list | |
// | |
PlatformBdsGetDriverOption (DriverOptionList); | |
// | |
// Get current Boot Mode | |
// | |
BootMode = GetBootModeHob(); | |
// | |
// No deferred images exist by default | |
// | |
DeferredImageExist = FALSE; | |
if ((BootMode != BOOT_WITH_MINIMAL_CONFIGURATION) && (PcdGet32(PcdFlashFvShellSize) > 0)){ | |
gDS->ProcessFirmwareVolume ( | |
(VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase), | |
PcdGet32(PcdFlashFvShellSize), | |
&FvProtocolHandle | |
); | |
} | |
if (SystemConfiguration.FastBoot == 1) { | |
BootOrder = BdsLibGetVariableAndSize ( | |
L"BootOrder", | |
&gEfiGlobalVariableGuid, | |
&BootOrderSize | |
); | |
if ((BootOrder != NULL) && (BootMode != BOOT_ON_FLASH_UPDATE)) { | |
// | |
// BootOrder exist, it means system has boot before. We can do fast boot. | |
// | |
BootMode = BOOT_WITH_MINIMAL_CONFIGURATION; | |
} | |
} | |
// | |
// Use eMMC to boot OS and turn on AHCI, when SATA HDD is diconnected, | |
// SATA AHCI CTLR device will show yellow bang, implement this solution to solve it. | |
// | |
SataPciRegBase = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_SATA, 0, 0); | |
SataModeSelect = MmioRead16 (SataPciRegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK; | |
Status = EFI_SUCCESS; | |
if (SataModeSelect != V_PCH_SATA_MAP_SMS_IDE) { | |
Status = gBS->CreateEvent ( | |
EVT_NOTIFY_SIGNAL, | |
TPL_CALLBACK, | |
DisableAhciCtlr, | |
&SataPciRegBase, | |
&Event | |
); | |
if (!EFI_ERROR (Status)) { | |
Status = gBS->RegisterProtocolNotify ( | |
&gExitPmAuthProtocolGuid, | |
Event, | |
&RegistrationExitPmAuth | |
); | |
} | |
} | |
Status = gBS->LocateProtocol(&gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtManagement); | |
if (EFI_ERROR(Status)) { | |
EsrtManagement = NULL; | |
} | |
switch (BootMode) { | |
case BOOT_WITH_MINIMAL_CONFIGURATION: | |
PlatformBdsInitHotKeyEvent (); | |
PlatformBdsConnectSimpleConsole (gPlatformSimpleConsole); | |
// | |
// Check to see if it's needed to dispatch more DXE drivers. | |
// | |
for (Index = 0; Index < sizeof(ConnectDriverTable)/sizeof(EFI_GUID *); Index++) { | |
Status = gBS->LocateHandleBuffer ( | |
ByProtocol, | |
ConnectDriverTable[Index], | |
NULL, | |
&HandleCount, | |
&HandleBuffer | |
); | |
if (!EFI_ERROR (Status)) { | |
for (Index1 = 0; Index1 < HandleCount; Index1++) { | |
gBS->ConnectController ( | |
HandleBuffer[Index1], | |
NULL, | |
NULL, | |
TRUE | |
); | |
} | |
} | |
if (HandleBuffer != NULL) { | |
FreePool (HandleBuffer); | |
} | |
gDS->Dispatch (); | |
} | |
// | |
// Locate the Global NVS Protocol. | |
// | |
Status = gBS->LocateProtocol ( | |
&gEfiGlobalNvsAreaProtocolGuid, | |
NULL, | |
(void **)&GlobalNvsArea | |
); | |
if (GlobalNvsArea->Area->emmcVersion == 0){ | |
EmmcBootDevPath = (PLATFORM_PCI_DEVICE_PATH *)gPlatformSimpleBootOption[0]; | |
EmmcBootDevPath->PciDevice.Device = 0x10; | |
} | |
// | |
// Connect boot device here to give time to read keyboard. | |
// | |
BdsLibConnectDevicePath (gPlatformSimpleBootOption[0]); | |
// | |
// This is a workround for dectecting hotkey from USB keyboard. | |
// | |
gBS->Stall(KEYBOARD_TIMER_INTERVAL); | |
if (mHotKeyTimerEvent != NULL) { | |
gBS->SetTimer ( | |
mHotKeyTimerEvent, | |
TimerCancel, | |
0 | |
); | |
gBS->CloseEvent (mHotKeyTimerEvent); | |
mHotKeyTimerEvent = NULL; | |
} | |
if (mHotKeyPressed) { | |
// | |
// Skip show progress count down | |
// | |
Timeout = 0xFFFF; | |
goto FULL_CONFIGURATION; | |
} | |
if (SystemConfiguration.QuietBoot) { | |
EnableQuietBoot (PcdGetPtr(PcdLogoFile)); | |
} else { | |
PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest); | |
} | |
#ifdef TPM_ENABLED | |
TcgPhysicalPresenceLibProcessRequest(); | |
#endif | |
#ifdef FTPM_ENABLE | |
TrEEPhysicalPresenceLibProcessRequest(NULL); | |
#endif | |
if (EsrtManagement != NULL) { | |
EsrtManagement->LockEsrtRepository(); | |
} | |
// | |
// Close boot script and install ready to lock | |
// | |
InstallReadyToLock (); | |
// | |
// Give one chance to enter the setup if we | |
// select Gummiboot "Reboot Into Firmware Interface" and Fast Boot is enabled. | |
// | |
BootIntoFirmwareInterface(); | |
break; | |
case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES: | |
// | |
// In no-configuration boot mode, we can connect the | |
// console directly. | |
// | |
BdsLibConnectAllDefaultConsoles (); | |
PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest); | |
// | |
// Perform some platform specific connect sequence | |
// | |
PlatformBdsConnectSequence (); | |
// | |
// As console is ready, perform user identification again. | |
// | |
if (mCurrentUser == NULL) { | |
PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist); | |
if (DeferredImageExist) { | |
// | |
// After user authentication, the deferred drivers was loaded again. | |
// Here, need to ensure the deferred images are connected. | |
// | |
BdsLibConnectAllDefaultConsoles (); | |
PlatformBdsConnectSequence (); | |
} | |
} | |
if (EsrtManagement != NULL) { | |
EsrtManagement->LockEsrtRepository(); | |
} | |
// | |
// Close boot script and install ready to lock | |
// | |
InstallReadyToLock (); | |
// | |
// Notes: current time out = 0 can not enter the | |
// front page | |
// | |
PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE); | |
// | |
// Check the boot option with the boot option list | |
// | |
BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder"); | |
break; | |
case BOOT_ON_FLASH_UPDATE: | |
// | |
// Boot with the specific configuration | |
// | |
PlatformBdsConnectConsole (gPlatformConsole); | |
PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest); | |
DEBUG((DEBUG_INFO, "ProcessCapsules Before EndOfDxe......\n")); | |
ProcessCapsules (); | |
DEBUG((DEBUG_INFO, "ProcessCapsules Done\n")); | |
// | |
// Close boot script and install ready to lock | |
// | |
InstallReadyToLock (); | |
BdsLibConnectAll (); | |
// | |
// Perform user identification | |
// | |
if (mCurrentUser == NULL) { | |
PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist); | |
if (DeferredImageExist) { | |
// | |
// After user authentication, the deferred drivers was loaded again. | |
// Here, need to ensure the deferred images are connected. | |
// | |
BdsLibConnectAll (); | |
} | |
} | |
if (EsrtManagement != NULL) { | |
EsrtManagement->SyncEsrtFmp(); | |
} | |
DEBUG((DEBUG_INFO, "ProcessCapsules After ConnectAll......\n")); | |
ProcessCapsules(); | |
DEBUG((DEBUG_INFO, "ProcessCapsules Done\n")); | |
break; | |
case BOOT_IN_RECOVERY_MODE: | |
// | |
// In recovery mode, just connect platform console | |
// and show up the front page | |
// | |
PlatformBdsConnectConsole (gPlatformConsole); | |
PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest); | |
BdsLibConnectAll (); | |
// | |
// Perform user identification | |
// | |
if (mCurrentUser == NULL) { | |
PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist); | |
if (DeferredImageExist) { | |
// | |
// After user authentication, the deferred drivers was loaded again. | |
// Here, need to ensure the deferred drivers are connected. | |
// | |
BdsLibConnectAll (); | |
} | |
} | |
// | |
// Close boot script and install ready to lock | |
// | |
InstallReadyToLock (); | |
// | |
// In recovery boot mode, we still enter to the | |
// frong page now | |
// | |
PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE); | |
break; | |
FULL_CONFIGURATION: | |
case BOOT_WITH_FULL_CONFIGURATION: | |
case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS: | |
case BOOT_WITH_DEFAULT_SETTINGS: | |
default: | |
// | |
// Connect platform console | |
// | |
Status = PlatformBdsConnectConsole (gPlatformConsole); | |
if (EFI_ERROR (Status)) { | |
// | |
// Here OEM/IBV can customize with defined action | |
// | |
PlatformBdsNoConsoleAction (); | |
} | |
// | |
// Chenyunh[TODO]: This is Workgroud to show the fs for uSDcard, | |
// Need to root cause this issue. | |
// | |
DEBUG ((DEBUG_ERROR, "Start to reconnect all driver.\n")); | |
BdsLibDisconnectAllEfi(); | |
BdsLibConnectAll (); | |
DEBUG ((DEBUG_ERROR, "End to reconnect all driver.\n")); | |
// | |
// Perform some platform specific connect sequence | |
// | |
PlatformBdsConnectSequence (); | |
if (SystemConfiguration.QuietBoot) { | |
EnableQuietBoot (PcdGetPtr(PcdLogoFile)); | |
} else { | |
PlatformBdsDiagnostics (IGNORE, FALSE, BaseMemoryTest); | |
} | |
// | |
// Do a pre-delay so Hard Disk can spin up and see more logo. | |
// | |
gBS->Stall(SystemConfiguration.HddPredelay * 1000000); | |
// | |
// Perform user identification | |
// | |
if (mCurrentUser == NULL) { | |
PlatformBdsUserIdentify (&mCurrentUser, &DeferredImageExist); | |
if (DeferredImageExist) { | |
// | |
// After user authentication, the deferred drivers was loaded again. | |
// Here, need to ensure the deferred drivers are connected. | |
// | |
Status = PlatformBdsConnectConsole (gPlatformConsole); | |
if (EFI_ERROR (Status)) { | |
PlatformBdsNoConsoleAction (); | |
} | |
PlatformBdsConnectSequence (); | |
} | |
} | |
#ifdef TPM_ENABLED | |
TcgPhysicalPresenceLibProcessRequest(); | |
#endif | |
#ifdef FTPM_ENABLE | |
TrEEPhysicalPresenceLibProcessRequest(NULL); | |
#endif | |
if (EsrtManagement != NULL) { | |
EsrtManagement->SyncEsrtFmp(); | |
} | |
// | |
// Close boot script and install ready to lock | |
// | |
InstallReadyToLock (); | |
// | |
// Here we have enough time to do the enumeration of boot device | |
// | |
PlatformBdsLibEnumerateAllBootOption (BootOptionList); | |
// | |
// Give one chance to enter the setup if we | |
// have the time out | |
// | |
PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE); | |
// | |
// Give one chance to enter the setup if we | |
// select Gummiboot "Reboot Into Firmware Interface" | |
// | |
BootIntoFirmwareInterface(); | |
// | |
// In default boot mode, always find all boot | |
// option and do enumerate all the default boot option | |
// | |
if (Timeout == 0) { | |
BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder"); | |
if (IsListEmpty(BootOptionList)) { | |
PlatformBdsPredictBootOption (BootOptionList); | |
} | |
return; | |
} | |
break; | |
} | |
IsFirstBoot = PcdGetBool(PcdBootState); | |
if (IsFirstBoot) { | |
PcdSetBool(PcdBootState, FALSE); | |
} | |
return; | |
} | |
/** | |
Hook point after a boot attempt succeeds. We don't expect a boot option to | |
return, so the UEFI 2.0 specification defines that you will default to an | |
interactive mode and stop processing the BootOrder list in this case. This | |
is alos a platform implementation and can be customized by IBV/OEM. | |
@param Option Pointer to Boot Option that succeeded to boot. | |
@retval None. | |
**/ | |
VOID | |
EFIAPI | |
PlatformBdsBootSuccess ( | |
IN BDS_COMMON_OPTION *Option | |
) | |
{ | |
CHAR16 *TmpStr; | |
// | |
// If Boot returned with EFI_SUCCESS and there is not in the boot device | |
// select loop then we need to pop up a UI and wait for user input. | |
// | |
TmpStr = Option->StatusString; | |
if (TmpStr != NULL) { | |
BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL); | |
FreePool(TmpStr); | |
} | |
} | |
/** | |
Hook point after a boot attempt fails. | |
@param Option - Pointer to Boot Option that failed to boot. | |
@param Status - Status returned from failed boot. | |
@param ExitData - Exit data returned from failed boot. | |
@param ExitDataSize - Exit data size returned from failed boot. | |
@retval None. | |
**/ | |
VOID | |
EFIAPI | |
PlatformBdsBootFail ( | |
IN BDS_COMMON_OPTION *Option, | |
IN EFI_STATUS Status, | |
IN CHAR16 *ExitData, | |
IN UINTN ExitDataSize | |
) | |
{ | |
CHAR16 *TmpStr; | |
EFI_HANDLE FvProtocolHandle; | |
// | |
// If Boot returned with failed status then we need to pop up a UI and wait | |
// for user input. | |
// | |
TmpStr = Option->StatusString; | |
if (TmpStr != NULL) { | |
BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL); | |
FreePool(TmpStr); | |
} | |
if (PcdGet32(PcdFlashFvShellSize) > 0){ | |
gDS->ProcessFirmwareVolume ( | |
(VOID *)(UINTN)PcdGet32(PcdFlashFvShellBase), | |
PcdGet32(PcdFlashFvShellSize), | |
&FvProtocolHandle | |
); | |
} | |
PlatformBdsConnectSequence (); | |
} | |
/** | |
This function is remained for IBV/OEM to do some platform action, | |
if there no console device can be connected. | |
@param None. | |
@retval EFI_SUCCESS Direct return success now. | |
**/ | |
EFI_STATUS | |
PlatformBdsNoConsoleAction ( | |
VOID | |
) | |
{ | |
return EFI_SUCCESS; | |
} | |
/** | |
This function locks the block | |
@param Base The base address flash region to be locked. | |
**/ | |
VOID | |
BdsLockFv ( | |
IN EFI_PHYSICAL_ADDRESS Base | |
) | |
{ | |
EFI_FV_BLOCK_MAP_ENTRY *BlockMap; | |
EFI_FIRMWARE_VOLUME_HEADER *FvHeader; | |
EFI_PHYSICAL_ADDRESS BaseAddress; | |
UINT32 BlockLength; | |
UINTN Index; | |
BaseAddress = Base - 0x400000 + 2; | |
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) ((UINTN) (Base)); | |
BlockMap = &(FvHeader->BlockMap[0]); | |
while ((BlockMap->NumBlocks != 0) && (BlockMap->Length != 0)) { | |
BlockLength = BlockMap->Length; | |
for (Index = 0; Index < BlockMap->NumBlocks; Index++) { | |
MmioOr8 ((UINTN) BaseAddress, 0x03); | |
BaseAddress += BlockLength; | |
} | |
BlockMap++; | |
} | |
} | |
VOID | |
EFIAPI | |
PlatformBdsLockNonUpdatableFlash ( | |
VOID | |
) | |
{ | |
EFI_PHYSICAL_ADDRESS Base; | |
Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvMainBase); | |
if (Base > 0) { | |
BdsLockFv (Base); | |
} | |
Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvRecoveryBase); | |
if (Base > 0) { | |
BdsLockFv (Base); | |
} | |
} | |
/** | |
Lock the ConsoleIn device in system table. All key | |
presses will be ignored until the Password is typed in. The only way to | |
disable the password is to type it in to a ConIn device. | |
@param Password Password used to lock ConIn device. | |
@retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully. | |
@retval EFI_UNSUPPORTED Password not found | |
**/ | |
EFI_STATUS | |
EFIAPI | |
LockKeyboards ( | |
IN CHAR16 *Password | |
) | |
{ | |
return EFI_UNSUPPORTED; | |
} | |
/** | |
Connect the predefined platform default authentication devices. | |
This function connects the predefined device path for authentication device, | |
and if the predefined device path has child device path, the child handle will | |
be connected too. But the child handle of the child will not be connected. | |
**/ | |
VOID | |
EFIAPI | |
PlatformBdsConnectAuthDevice ( | |
VOID | |
) | |
{ | |
EFI_STATUS Status; | |
UINTN Index; | |
UINTN HandleIndex; | |
UINTN HandleCount; | |
EFI_HANDLE *HandleBuffer; | |
EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath; | |
EFI_USER_MANAGER_PROTOCOL *Manager; | |
Status = gBS->LocateProtocol ( | |
&gEfiUserManagerProtocolGuid, | |
NULL, | |
(VOID **) &Manager | |
); | |
if (EFI_ERROR (Status)) { | |
// | |
// As user manager protocol is not installed, the authentication devices | |
// should not be connected. | |
// | |
return ; | |
} | |
Index = 0; | |
while (gUserAuthenticationDevice[Index] != NULL) { | |
// | |
// Connect the platform customized device paths | |
// | |
BdsLibConnectDevicePath (gUserAuthenticationDevice[Index]); | |
Index++; | |
} | |
// | |
// Find and connect the child device paths of the platform customized device paths | |
// | |
HandleBuffer = NULL; | |
for (Index = 0; gUserAuthenticationDevice[Index] != NULL; Index++) { | |
HandleCount = 0; | |
Status = gBS->LocateHandleBuffer ( | |
AllHandles, | |
NULL, | |
NULL, | |
&HandleCount, | |
&HandleBuffer | |
); | |
ASSERT (!EFI_ERROR (Status)); | |
// | |
// Find and connect the child device paths of gUserIdentificationDevice[Index] | |
// | |
for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) { | |
ChildDevicePath = NULL; | |
Status = gBS->HandleProtocol ( | |
HandleBuffer[HandleIndex], | |
&gEfiDevicePathProtocolGuid, | |
(VOID **) &ChildDevicePath | |
); | |
if (EFI_ERROR (Status) || ChildDevicePath == NULL) { | |
continue; | |
} | |
if (CompareMem ( | |
ChildDevicePath, | |
gUserAuthenticationDevice[Index], | |
(GetDevicePathSize (gUserAuthenticationDevice[Index]) - sizeof (EFI_DEVICE_PATH_PROTOCOL)) | |
) != 0) { | |
continue; | |
} | |
gBS->ConnectController ( | |
HandleBuffer[HandleIndex], | |
NULL, | |
NULL, | |
TRUE | |
); | |
} | |
} | |
if (HandleBuffer != NULL) { | |
FreePool (HandleBuffer); | |
} | |
} | |
/** | |
This function is to identify a user, and return whether deferred images exist. | |
@param[out] User Point to user profile handle. | |
@param[out] DeferredImageExist On return, points to TRUE if the deferred image | |
exist or FALSE if it did not exist. | |
**/ | |
VOID | |
EFIAPI | |
PlatformBdsUserIdentify ( | |
OUT EFI_USER_PROFILE_HANDLE *User, | |
OUT BOOLEAN *DeferredImageExist | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_DEFERRED_IMAGE_LOAD_PROTOCOL *DeferredImage; | |
UINTN HandleCount; | |
EFI_HANDLE *HandleBuf; | |
UINTN Index; | |
UINTN DriverIndex; | |
EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath; | |
VOID *DriverImage; | |
UINTN ImageSize; | |
BOOLEAN BootOption; | |
// | |
// Perform user identification | |
// | |
do { | |
Status = BdsLibUserIdentify (User); | |
} while (EFI_ERROR (Status)); | |
// | |
// After user authentication now, try to find whether deferred image exists | |
// | |
HandleCount = 0; | |
HandleBuf = NULL; | |
*DeferredImageExist = FALSE; | |
Status = gBS->LocateHandleBuffer ( | |
ByProtocol, | |
&gEfiDeferredImageLoadProtocolGuid, | |
NULL, | |
&HandleCount, | |
&HandleBuf | |
); | |
if (EFI_ERROR (Status)) { | |
return ; | |
} | |
for (Index = 0; Index < HandleCount; Index++) { | |
Status = gBS->HandleProtocol ( | |
HandleBuf[Index], | |
&gEfiDeferredImageLoadProtocolGuid, | |
(VOID **) &DeferredImage | |
); | |
if (!EFI_ERROR (Status)) { | |
// | |
// Find whether deferred image exists in this instance. | |
// | |
DriverIndex = 0; | |
Status = DeferredImage->GetImageInfo( | |
DeferredImage, | |
DriverIndex, | |
&ImageDevicePath, | |
(VOID **) &DriverImage, | |
&ImageSize, | |
&BootOption | |
); | |
if (!EFI_ERROR (Status)) { | |
// | |
// The deferred image is found. | |
// | |
FreePool (HandleBuf); | |
*DeferredImageExist = TRUE; | |
return ; | |
} | |
} | |
} | |
FreePool (HandleBuf); | |
} | |
UINTN gHotKey = 0; | |
EFI_STATUS | |
ShowProgressHotKey ( | |
IN UINT16 TimeoutDefault | |
) | |
{ | |
CHAR16 *TmpStr; | |
UINT16 TimeoutRemain; | |
EFI_STATUS Status; | |
EFI_INPUT_KEY Key; | |
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground; | |
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background; | |
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Color; | |
UINT32 GpioValue; | |
CHAR16 *TmpStr1; | |
CHAR16 *TmpStr2; | |
CHAR16 *TmpStr3; | |
UINTN TmpStrSize; | |
VOID *Buffer; | |
UINTN Size; | |
if (TimeoutDefault == 0) { | |
return EFI_TIMEOUT; | |
} | |
gST->ConOut->SetAttribute(gST->ConOut, EFI_TEXT_ATTR (EFI_LIGHTGRAY, EFI_BLACK)); | |
if (DebugAssertEnabled()) | |
{ | |
DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it, or press <F2> or <DEL> to enter setup page! ...Zzz....\n")); | |
} | |
else | |
{ | |
#ifdef __GNUC__ | |
SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)[GCC]", 76); | |
#else | |
SerialPortWrite((UINT8 *)"\n\n>>>>Start boot option, Press <F2> or <DEL> to enter setup page(5 Sec)", 71); | |
#endif | |
} | |
SetMem (&Foreground, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); | |
SetMem (&Background, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0x0); | |
SetMem (&Color, sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL), 0xff); | |
TmpStr2 = NULL; | |
TmpStr3 = NULL; | |
// | |
// Check if the platform is using test key. | |
// | |
Status = GetSectionFromAnyFv( | |
PcdGetPtr(PcdEdkiiRsa2048Sha256TestPublicKeyFileGuid), | |
EFI_SECTION_RAW, | |
0, | |
&Buffer, | |
&Size | |
); | |
if (!EFI_ERROR(Status)) { | |
if ((Size == PcdGetSize(PcdRsa2048Sha256PublicKeyBuffer)) && | |
(CompareMem(Buffer, PcdGetPtr(PcdRsa2048Sha256PublicKeyBuffer), Size) == 0)) { | |
TmpStr2 = L"WARNING: Recovery Test Key is used.\r\n"; | |
if (DebugAssertEnabled()) { | |
DEBUG ((DEBUG_INFO, "\n\nWARNING: Recovery Test Key is used.\n")); | |
} else { | |
SerialPortWrite((UINT8 *)"\n\nWARNING: Recovery Test Key is used.", sizeof("\n\nWARNING: Recovery Test Key is used.")); | |
} | |
PcdSetBoolS(PcdTestKeyUsed, TRUE); | |
} | |
FreePool(Buffer); | |
} | |
Status = GetSectionFromAnyFv( | |
PcdGetPtr(PcdEdkiiPkcs7TestPublicKeyFileGuid), | |
EFI_SECTION_RAW, | |
0, | |
&Buffer, | |
&Size | |
); | |
if (!EFI_ERROR(Status)) { | |
if ((Size == PcdGetSize(PcdPkcs7CertBuffer)) && | |
(CompareMem(Buffer, PcdGetPtr(PcdPkcs7CertBuffer), Size) == 0)) { | |
TmpStr3 = L"WARNING: Capsule Test Key is used.\r\n"; | |
if (DebugAssertEnabled()) { | |
DEBUG ((DEBUG_INFO, "\n\nWARNING: Capsule Test Key is used.\r\n")); | |
} else { | |
SerialPortWrite((UINT8 *)"\n\nWARNING: Capsule Test Key is used.", sizeof("\n\nWARNING: Capsule Test Key is used.")); | |
} | |
PcdSetBoolS(PcdTestKeyUsed, TRUE); | |
} | |
FreePool(Buffer); | |
} | |
// | |
// Clear the progress status bar first | |
// | |
TmpStr1 = L"Start boot option, Press <F2> or <DEL> to enter setup page.\r\n"; | |
TmpStrSize = StrSize(TmpStr1); | |
if (TmpStr2 != NULL) { | |
TmpStrSize += StrSize(TmpStr2); | |
} | |
if (TmpStr3 != NULL) { | |
TmpStrSize += StrSize(TmpStr3); | |
} | |
TmpStr = AllocatePool (TmpStrSize); | |
if (TmpStr == NULL) { | |
TmpStr = TmpStr1; | |
} else { | |
StrCpyS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr1); | |
if (TmpStr2 != NULL) { | |
StrCatS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr2); | |
} | |
if (TmpStr3 != NULL) { | |
StrCatS(TmpStr, TmpStrSize/sizeof(CHAR16), TmpStr3); | |
} | |
} | |
PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0); | |
TimeoutRemain = TimeoutDefault; | |
while (TimeoutRemain != 0) { | |
if (DebugAssertEnabled()) | |
{ | |
DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain)); | |
} | |
else | |
{ | |
SerialPortWrite ((UINT8 *)".", 1); | |
} | |
Status = WaitForSingleEvent (gST->ConIn->WaitForKey, ONE_SECOND); | |
if (Status != EFI_TIMEOUT) { | |
break; | |
} | |
TimeoutRemain--; | |
// | |
// Show progress | |
// | |
if (TmpStr != NULL) { | |
PlatformBdsShowProgress ( | |
Foreground, | |
Background, | |
TmpStr, | |
Color, | |
((TimeoutDefault - TimeoutRemain) * 100 / TimeoutDefault), | |
0 | |
); | |
} | |
} | |
// | |
// Timeout expired | |
// | |
if (TimeoutRemain == 0) { | |
if (DebugAssertEnabled()) | |
{ | |
} | |
else | |
{ | |
SerialPortWrite ((UINT8 *)"\r\n", 2); | |
} | |
return EFI_TIMEOUT; | |
} | |
// | |
// User pressed some key | |
// | |
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// Check Volume Up Key to enter Setup | |
// | |
GpioValue = MmioRead32 (IO_BASE_ADDRESS + 0x0668); // The value of GPIOC_5 | |
if (((GpioValue & BIT0) == 0) && (Key.ScanCode == SCAN_UP)) { | |
gHotKey = 0; | |
return EFI_SUCCESS; | |
} | |
if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { | |
// | |
// User pressed enter, equivalent to select "continue" | |
// | |
return EFI_TIMEOUT; | |
} | |
// | |
//F2 -- Front Page | |
//F5 -- Device Manager | |
//F7 -- Boot Manager | |
// do not use F8. generally people assume it is windows safe mode key. | |
//F9 -- Boot order | |
// | |
DEBUG ((EFI_D_INFO, "[Key Pressed]: ScanCode 0x%x\n", Key.ScanCode)); | |
switch(Key.ScanCode) { | |
case SCAN_F2: | |
gHotKey = 0; | |
break; | |
case SCAN_DELETE: | |
gHotKey = 0; | |
break; | |
case SCAN_F5: | |
gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER; | |
break; | |
case SCAN_F7: | |
gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER; | |
break; | |
case SCAN_F9: | |
gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN; | |
break; | |
default: | |
//set gHotKey to continue so that flow will not go into CallFrontPage | |
gHotKey = FRONT_PAGE_KEY_CONTINUE; | |
return EFI_TIMEOUT; | |
break; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
This function is the main entry of the platform setup entry. | |
The function will present the main menu of the system setup, | |
this is the platform reference part and can be customize. | |
@param TimeoutDefault The fault time out value before the system | |
continue to boot. | |
@param ConnectAllHappened The indicater to check if the connect all have | |
already happened. | |
**/ | |
VOID | |
PlatformBdsEnterFrontPageWithHotKey ( | |
IN UINT16 TimeoutDefault, | |
IN BOOLEAN ConnectAllHappened | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; | |
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut; | |
UINTN BootTextColumn; | |
UINTN BootTextRow; | |
GraphicsOutput = NULL; | |
SimpleTextOut = NULL; | |
PERF_START (NULL, "BdsTimeOut", "BDS", 0); | |
// | |
// Indicate if we need connect all in the platform setup | |
// | |
if (ConnectAllHappened) { | |
gConnectAllHappened = TRUE; | |
} | |
if (!mModeInitialized) { | |
// | |
// After the console is ready, get current video resolution | |
// and text mode before launching setup at first time. | |
// | |
Status = gBS->HandleProtocol ( | |
gST->ConsoleOutHandle, | |
&gEfiGraphicsOutputProtocolGuid, | |
(VOID**)&GraphicsOutput | |
); | |
if (EFI_ERROR (Status)) { | |
GraphicsOutput = NULL; | |
} | |
Status = gBS->HandleProtocol ( | |
gST->ConsoleOutHandle, | |
&gEfiSimpleTextOutProtocolGuid, | |
(VOID**)&SimpleTextOut | |
); | |
if (EFI_ERROR (Status)) { | |
SimpleTextOut = NULL; | |
} | |
if (GraphicsOutput != NULL) { | |
// | |
// Get current video resolution and text mode. | |
// | |
mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution; | |
mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution; | |
} | |
if (SimpleTextOut != NULL) { | |
Status = SimpleTextOut->QueryMode ( | |
SimpleTextOut, | |
SimpleTextOut->Mode->Mode, | |
&BootTextColumn, | |
&BootTextRow | |
); | |
mBootTextModeColumn = (UINT32)BootTextColumn; | |
mBootTextModeRow = (UINT32)BootTextRow; | |
} | |
// | |
// Get user defined text mode for setup. | |
// | |
mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution); | |
mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution); | |
mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn); | |
mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow); | |
mModeInitialized = TRUE; | |
} | |
if (TimeoutDefault != 0xffff) { | |
Status = ShowProgressHotKey (TimeoutDefault); | |
// | |
// Ensure screen is clear when switch Console from Graphics mode to Text mode | |
// | |
gST->ConOut->EnableCursor (gST->ConOut, TRUE); | |
gST->ConOut->ClearScreen (gST->ConOut); | |
if (EFI_ERROR (Status)) { | |
// | |
// Timeout or user press enter to continue | |
// | |
goto Exit; | |
} | |
} | |
// | |
// Install BM HiiPackages. | |
// Keep BootMaint HiiPackage, so that it can be covered by global setting. | |
// | |
InitBMPackage (); | |
do { | |
BdsSetConsoleMode (TRUE); | |
InitializeFrontPage (FALSE); | |
// | |
// Update Front Page strings | |
// | |
UpdateFrontPageStrings (); | |
Status = EFI_SUCCESS; | |
gCallbackKey = 0; | |
if (gHotKey == 0) { | |
Status = CallFrontPage (); | |
} else { | |
gCallbackKey = gHotKey; | |
gHotKey = 0; | |
} | |
// | |
// If gCallbackKey is greater than 1 and less or equal to 5, | |
// it will launch configuration utilities. | |
// 2 = set language | |
// 3 = boot manager | |
// 4 = device manager | |
// 5 = boot maintenance manager | |
// | |
if (gCallbackKey != 0) { | |
REPORT_STATUS_CODE ( | |
EFI_PROGRESS_CODE, | |
(EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP) | |
); | |
} | |
// | |
// Based on the key that was set, we can determine what to do | |
// | |
switch (gCallbackKey) { | |
// | |
// The first 4 entries in the Front Page are to be GUARANTEED to remain constant so IHV's can | |
// describe to their customers in documentation how to find their setup information (namely | |
// under the device manager and specific buckets) | |
// | |
// These entries consist of the Continue, Select language, Boot Manager, and Device Manager | |
// | |
case FRONT_PAGE_KEY_CONTINUE: | |
// | |
// User hit continue | |
// | |
break; | |
case FRONT_PAGE_KEY_LANGUAGE: | |
// | |
// User made a language setting change - display front page again | |
// | |
break; | |
case FRONT_PAGE_KEY_BOOT_MANAGER: | |
// | |
// Remove the installed BootMaint HiiPackages when exit. | |
// | |
FreeBMPackage (); | |
// | |
// User chose to run the Boot Manager | |
// | |
CallBootManager (); | |
// | |
// Reinstall BootMaint HiiPackages after exiting from Boot Manager. | |
// | |
InitBMPackage (); | |
break; | |
case FRONT_PAGE_KEY_DEVICE_MANAGER: | |
// | |
// Display the Device Manager | |
// | |
do { | |
CallDeviceManager (); | |
} while (gCallbackKey == FRONT_PAGE_KEY_DEVICE_MANAGER); | |
break; | |
case FRONT_PAGE_KEY_BOOT_MAINTAIN: | |
// | |
// Display the Boot Maintenance Manager | |
// | |
BdsStartBootMaint (); | |
break; | |
} | |
} while (((UINTN)gCallbackKey) != FRONT_PAGE_KEY_CONTINUE); | |
// | |
//Will leave browser, check any reset required change is applied? if yes, reset system | |
// | |
SetupResetReminder (); | |
// | |
// Remove the installed BootMaint HiiPackages when exit. | |
// | |
FreeBMPackage (); | |
Exit: | |
// | |
// Automatically load current entry | |
// Note: The following lines of code only execute when Auto boot | |
// takes affect | |
// | |
PERF_END (NULL, "BdsTimeOut", "BDS", 0); | |
} | |
VOID | |
BootIntoFirmwareInterface( | |
VOID | |
) | |
{ | |
EFI_STATUS Status; | |
UINTN DataSize; | |
UINT16 Timeout; | |
UINT64 OsIndication; | |
OsIndication = 0; | |
DataSize = sizeof(UINT64); | |
Status = gRT->GetVariable ( | |
L"OsIndications", | |
&gEfiGlobalVariableGuid, | |
NULL, | |
&DataSize, | |
&OsIndication | |
); | |
DEBUG ((EFI_D_INFO, "OSIndication Variable Value %d\n", OsIndication)); | |
// | |
//Goto FrontPage directly when bit EFI_OS_INDICATIONS_BOOT_TO_FW_UI in OSIndication Variable is setted. | |
// | |
if (!EFI_ERROR(Status) && (OsIndication != 0)) { | |
Timeout = 0xffff; | |
PlatformBdsEnterFrontPage (Timeout, FALSE); | |
} | |
} | |
EFI_STATUS | |
PlatformBdsConnectSimpleConsole ( | |
IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole | |
) | |
{ | |
EFI_STATUS Status; | |
UINTN Index; | |
EFI_DEVICE_PATH_PROTOCOL *VarConout; | |
EFI_DEVICE_PATH_PROTOCOL *VarConin; | |
UINTN DevicePathSize; | |
Index = 0; | |
Status = EFI_SUCCESS; | |
DevicePathSize = 0; | |
VarConout = BdsLibGetVariableAndSize ( | |
L"ConOut", | |
&gEfiGlobalVariableGuid, | |
&DevicePathSize | |
); | |
VarConin = BdsLibGetVariableAndSize ( | |
L"ConIn", | |
&gEfiGlobalVariableGuid, | |
&DevicePathSize | |
); | |
if (VarConout == NULL || VarConin == NULL) { | |
// | |
// Have chance to connect the platform default console, | |
// the platform default console is the minimum device group | |
// the platform should support | |
// | |
while (PlatformConsole[Index].DevicePath != NULL) { | |
// | |
// Update the console variable with the connect type | |
// | |
if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) { | |
BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL); | |
} | |
if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) { | |
BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL); | |
} | |
if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) { | |
BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL); | |
} | |
Index ++; | |
} | |
} | |
// | |
// Connect ConIn first to give keyboard time to parse hot key event. | |
// | |
Status = BdsLibConnectConsoleVariable (L"ConIn"); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// Make sure we have at least one active VGA, and have the right | |
// active VGA in console variable | |
// | |
Status = PlatformBdsForceActiveVga (); | |
// | |
// 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; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
Timer handler to convert the key from USB. | |
@param Event Indicates the event that invoke this function. | |
@param Context Indicates the calling context. | |
**/ | |
VOID | |
EFIAPI | |
HotKeyTimerHandler ( | |
IN EFI_EVENT Event, | |
IN VOID *Context | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_INPUT_KEY Key; | |
Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key); | |
if (EFI_ERROR (Status)) { | |
return; | |
} | |
switch(Key.ScanCode) { | |
case SCAN_F2: | |
gHotKey = 0; | |
mHotKeyPressed = TRUE; | |
break; | |
case SCAN_F5: | |
gHotKey = FRONT_PAGE_KEY_DEVICE_MANAGER; | |
mHotKeyPressed = TRUE; | |
break; | |
case SCAN_F7: | |
gHotKey = FRONT_PAGE_KEY_BOOT_MANAGER; | |
mHotKeyPressed = TRUE; | |
break; | |
case SCAN_F9: | |
gHotKey = FRONT_PAGE_KEY_BOOT_MAINTAIN; | |
mHotKeyPressed = TRUE; | |
break; | |
} | |
if (mHotKeyPressed) { | |
gBS->SetTimer ( | |
mHotKeyTimerEvent, | |
TimerCancel, | |
0 | |
); | |
gBS->CloseEvent (mHotKeyTimerEvent); | |
mHotKeyTimerEvent = NULL; | |
} | |
return; | |
} | |
/** | |
Callback function for SimpleTextInEx protocol install events | |
@param Event the event that is signaled. | |
@param Context not used here. | |
**/ | |
VOID | |
EFIAPI | |
HitHotkeyEvent ( | |
IN EFI_EVENT Event, | |
IN VOID *Context | |
) | |
{ | |
EFI_STATUS Status; | |
Status = gBS->CloseEvent(mHitHotkeyEvent); | |
if (EFI_ERROR (Status)) { | |
return; | |
} | |
Status = gBS->CreateEvent ( | |
EVT_TIMER | EVT_NOTIFY_SIGNAL, | |
TPL_NOTIFY, | |
HotKeyTimerHandler, | |
NULL, | |
&mHotKeyTimerEvent | |
); | |
if (EFI_ERROR (Status)) { | |
return; | |
} | |
Status = gBS->SetTimer ( | |
mHotKeyTimerEvent, | |
TimerPeriodic, | |
KEYBOARD_TIMER_INTERVAL | |
); | |
if (EFI_ERROR (Status)) { | |
return; | |
} | |
return; | |
} | |
VOID | |
EFIAPI | |
PlatformBdsInitHotKeyEvent ( | |
VOID | |
) | |
{ | |
EFI_STATUS Status; | |
// | |
// Register Protocol notify for Hotkey service | |
// | |
Status = gBS->CreateEvent ( | |
EVT_NOTIFY_SIGNAL, | |
TPL_CALLBACK, | |
HitHotkeyEvent, | |
NULL, | |
&mHitHotkeyEvent | |
); | |
ASSERT_EFI_ERROR (Status); | |
// | |
// Register for protocol notifications on this event | |
// | |
Status = gBS->RegisterProtocolNotify ( | |
&gEfiSimpleTextInputExProtocolGuid, | |
mHitHotkeyEvent, | |
&mHitHotkeyRegistration | |
); | |
ASSERT_EFI_ERROR (Status); | |
} |