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