summaryrefslogtreecommitdiff
path: root/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-12-23 13:33:16 +0800
committerGuo Mang <mang.guo@intel.com>2016-12-26 19:15:13 +0800
commita891a3c8d482b82c3836f87796ff622f46c48545 (patch)
treefe20e8981abbf0b903342e13d3fc8fe200b623b4 /Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib
parentd2a217ee6f815e569ea1ab8fd9f0070a80465f43 (diff)
downloadedk2-platforms-a891a3c8d482b82c3836f87796ff622f46c48545.tar.xz
BroxtonPlatformPkg: Add package Include and Library
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib')
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.c2401
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.h465
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.c586
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.h330
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.Asm54
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.S42
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.Asm49
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.S41
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipPrivate.h168
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipUtil.c247
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformBdsLib.inf142
-rw-r--r--Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformData.c242
12 files changed, 4767 insertions, 0 deletions
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.c
new file mode 100644
index 0000000000..af887e4cc9
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.c
@@ -0,0 +1,2401 @@
+/** @file
+ This file include all platform action which can be customized by IBV/OEM.
+
+ Copyright (c) 2006 - 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
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "BdsPlatform.h"
+#include "SetupMode.h"
+#include <Guid/SetupVariable.h>
+#include <Guid/EventGroup.h>
+#include <Library/TcgPhysicalPresenceLib.h>
+#include <Library/Tcg2PhysicalPresenceLib.h>
+#include <Guid/TpmInstance.h>
+#include <Guid/PttPTPInstanceGuid.h>
+#include <Library/IoLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Protocol/ExitPmAuth.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Library/CpuPlatformLib.h>
+#include <Library/CustomizedDisplayLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/TimerLib.h>
+#include "Guid/Tcg2PhysicalPresenceData.h"
+#include "Guid/PhysicalPresenceData.h"
+
+extern EFI_GUID gUndiDriverImageGuid;
+
+EFI_GUID gUefiShellFileGuid = { 0x7C04A583, 0x9E3E, 0x4f1c, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 };
+
+EFI_USER_PROFILE_HANDLE mCurrentUser = NULL;
+EFI_EVENT mHotKeyTimerEvent = NULL;
+EFI_EVENT mHitHotkeyEvent = NULL;
+BOOLEAN mHotKeyPressed = FALSE;
+VOID *mHitHotkeyRegistration;
+
+#define KEYBOARD_TIMER_INTERVAL 200000 // 0.02s
+
+extern EFI_STATUS
+IFWIUpdateHack (
+ );
+
+EFI_STATUS
+PlatformBdsConnectSimpleConsole (
+ IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
+ );
+
+VOID
+EFIAPI
+PlatformBdsInitHotKeyEvent (
+ VOID
+ );
+
+VOID
+EFIAPI
+UnloadNetworkDriver (
+ VOID
+ );
+
+
+/**
+ An empty function to pass error checking of CreateEventEx ().
+
+ This empty function ensures that EVT_NOTIFY_SIGNAL_ALL is error
+ checked correctly since it is now mapped into CreateEventEx() in UEFI 2.0.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context The pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+InternalBdsEmptyCallbackFuntion (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ return;
+}
+
+
+VOID
+InstallReadyToLock (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
+ EFI_ACPI_S3_SAVE_PROTOCOL *AcpiS3Save;
+ EFI_EVENT EndOfDxeEvent;
+ UINTN VarSize;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+
+ //
+ // Inform the SMM infrastructure that we're entering BDS and may run 3rd party code hereafter
+ // NOTE: We can NOT put it to PlatformBdsInit, because many boot script touch PCI BAR. :-(
+ // We have to connect PCI root bridge, allocate resource, then ExitPmAuth().
+ //
+ Handle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &Handle,
+ &gExitPmAuthProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Since PI1.2.1, we need signal EndOfDxe as ExitPmAuth
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ InternalBdsEmptyCallbackFuntion,
+ NULL,
+ &gEfiEndOfDxeEventGroupGuid,
+ &EndOfDxeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+ gBS->SignalEvent (EndOfDxeEvent);
+ gBS->CloseEvent (EndOfDxeEvent);
+ DEBUG ((DEBUG_INFO,"All EndOfDxe callbacks have returned successfully\n"));
+
+ //
+ // 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,
+ &gEfiDxeSmmReadyToLockProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ VarSize = sizeof (SYSTEM_CONFIGURATION);
+
+ Status = gRT->GetVariable (
+ L"Setup",
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VarSize,
+ &SystemConfiguration
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ return;
+}
+
+
+//
+// BDS Platform Functions
+//
+/**
+ Recursively connect all child devices to the handle that matches a given Device Path
+
+ @param[in] DevicePathToConnect The device path which will be connected
+
+ @retval EFI_SUCCESS All child handles have been created
+ @retval EFI_OUT_OF_RESOURCES There is no resource to create new handles
+ @retval EFI_NOT_FOUND Creating the child handles failed
+
+**/
+EFI_STATUS
+EFIAPI
+ConnectDevicePathRecursive (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *CopyOfDevicePath;
+ EFI_HANDLE Handle;
+
+ if (DevicePathToConnect == NULL) {
+ return EFI_SUCCESS;
+ }
+ DevicePath = DuplicateDevicePath (DevicePathToConnect);
+ if (DevicePath == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyOfDevicePath = DevicePath;
+ Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &Handle);
+ if (!EFI_ERROR (Status)) {
+ gBS->ConnectController (Handle, NULL, NULL, TRUE);
+ }
+
+ if (CopyOfDevicePath != NULL) {
+ FreePool (CopyOfDevicePath);
+ }
+ return Status;
+}
+
+
+/**
+ When FastBoot is enabled, all input devices may not be connected by default.
+ Hence, when entering into Setup menu, connecting all input consoles are required.
+
+ @param[in] Event The Event this notify function registered to.
+ @param[in] Context Pointer to the context data registerd to the
+ Event.
+
+ @return None.
+
+**/
+VOID
+ConnectAllConsolesForSetupMenu (
+ EFI_EVENT Event,
+ VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ VOID *Protocol;
+
+ Status = gBS->LocateProtocol(
+ &gSetupEnterGuid,
+ NULL,
+ &Protocol
+ );
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ gBS->CloseEvent (Event);
+
+ //
+ // Connect PS2 and USB KB if boot to SETUP menu
+ //
+ BdsLibUpdateConsoleVariable (L"ConIn", gPlatformSimpleUsbConInConsole[0].DevicePath, NULL);
+ BdsLibUpdateConsoleVariable (L"ConIn", gPlatformSimplePs2ConInConsole[0].DevicePath, NULL);
+ BdsLibConnectAll ();
+}
+
+
+/**
+ Check if current BootCurrent variable is internal shell boot option.
+
+ @retval TRUE BootCurrent is internal shell.
+ @retval FALSE BootCurrent is not internal shell.
+
+**/
+BOOLEAN
+BootCurrentIsInternalShell (
+ VOID
+ )
+{
+ UINTN VarSize;
+ UINT16 BootCurrent;
+ CHAR16 BootOptionName[16];
+ UINT8 *BootOption;
+ UINT8 *Ptr;
+ EFI_DEVICE_PATH_PROTOCOL *BootDevicePath;
+ BOOLEAN Result;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode;
+ EFI_GUID *GuidPoint;
+
+ BootOption = NULL;
+ BootDevicePath = NULL;
+ Result = FALSE;
+
+ //
+ // Get BootCurrent variable
+ //
+ VarSize = sizeof (UINT16);
+ Status = gRT->GetVariable (
+ L"BootCurrent",
+ &gEfiGlobalVariableGuid,
+ NULL,
+ &VarSize,
+ &BootCurrent
+ );
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ //
+ // Create boot option Bootxxxx from BootCurrent
+ //
+ UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04X", BootCurrent);
+
+ GetEfiGlobalVariable2 (BootOptionName, (VOID **) &BootOption, &VarSize);
+ if (BootOption == NULL || VarSize == 0) {
+ return FALSE;
+ }
+
+ Ptr = BootOption;
+ Ptr += sizeof (UINT32);
+ Ptr += sizeof (UINT16);
+ Ptr += StrSize ((CHAR16 *) Ptr);
+ TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+ LastDeviceNode = TempDevicePath;
+ while (!IsDevicePathEnd (TempDevicePath)) {
+ LastDeviceNode = TempDevicePath;
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ }
+ GuidPoint = EfiGetNameGuidFromFwVolDevicePathNode (
+ (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode
+ );
+ if ((GuidPoint != NULL) &&
+ ((CompareGuid (GuidPoint, PcdGetPtr(PcdShellFile))) ||
+ (CompareGuid (GuidPoint, &gUefiShellFileGuid)))
+ ) {
+ //
+ // if this option is internal shell, return TRUE
+ //
+ Result = TRUE;
+ }
+
+ if (BootOption != NULL) {
+ FreePool (BootOption);
+ BootOption = NULL;
+ }
+
+ return Result;
+}
+
+
+/**
+ ReadyToBoot callback to set video and text mode for internal shell boot.
+
+ When FastBoot is enabled, input devices will not be connected
+ by default. Hence, when booting to EFI shell, connecting input consoles are required.
+
+ @param[in] Event Pointer to this event
+ @param[in] Context Event hanlder private data
+
+ @retval None.
+
+**/
+VOID
+EFIAPI
+FastBootOnReadyToBootCallBack (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ //
+ // Connect PS2 and USB KB if boot to shell
+ //
+ if (BootCurrentIsInternalShell ()) {
+ BdsLibUpdateConsoleVariable (L"ConIn", gPlatformSimpleUsbConInConsole[0].DevicePath, NULL);
+ BdsLibUpdateConsoleVariable (L"ConIn", gPlatformSimplePs2ConInConsole[0].DevicePath, NULL);
+ BdsLibConnectAll ();
+ }
+}
+
+
+/**
+ Update ConIn by corresponding console input behavior.
+
+ @param none
+
+ @retval none
+
+**/
+VOID
+FastBootUpdateConInVarByConInBehavior (
+ IN SYSTEM_CONFIGURATION SystemConfiguration
+ )
+{
+ EFI_STATUS Status;
+ VOID *SetupRegistration;
+ EFI_EVENT Event;
+
+ DEBUG ((EFI_D_INFO,"ConInBehavior is %x\n", SystemConfiguration.ConInBehavior));
+ switch (SystemConfiguration.ConInBehavior) {
+ case PS2_CONSOLE:
+ //
+ // Remove all device path from ConIn first.
+ // Then create ConIn for PS2 or USB base on PS2 KB connected or not.
+ //
+ Status = gRT->SetVariable (
+ L"ConIn",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ 0,
+ NULL
+ );
+
+ PlatformBdsConnectSimpleConsole (gPlatformSimpleUsbConInConsole);
+ break;
+
+ case RECONNECT_LAST_GOOD_INPUT_CONSOLE:
+ PlatformBdsConnectConsole (gPlatformConsole);
+ break;
+
+ case WINDOWS_CONSOLE:
+ //
+ // Remove all device path from ConIn.
+ // BIOS should not enumerate any input devices when Windows Console behavior is used
+ //
+ Status = gRT->SetVariable (
+ L"ConIn",
+ &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ 0,
+ NULL
+ );
+ break;
+
+ default:
+ break;
+ }
+
+ //
+ // Create event to connect ConIn device for internal shell.
+ //
+ Status = EfiCreateEventReadyToBootEx (
+ TPL_CALLBACK,
+ FastBootOnReadyToBootCallBack,
+ NULL,
+ &Event
+ );
+
+ //
+ // Register notification event for enter setup event
+ //
+ EfiCreateProtocolNotifyEvent (
+ &gSetupEnterGuid,
+ TPL_CALLBACK,
+ ConnectAllConsolesForSetupMenu,
+ NULL,
+ &SetupRegistration
+ );
+
+}
+
+
+/**
+ Platform Bds init. Include the platform firmware vendor, revision
+ and so crc check.
+
+ @param None
+
+ @retval None.
+
+**/
+VOID
+EFIAPI
+PlatformBdsInit (
+ VOID
+ )
+{
+ //
+ // 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);
+}
+
+
+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 SystemConfiguration;
+
+ 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",
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VarSize,
+ &SystemConfiguration
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ if (SystemConfiguration.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 (SystemConfiguration.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. store 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[in, out] PlugInPciVgaDevicePath Return the platform plug in pci video device
+ path if the system have plug in pci video device
+ @param[in, out] 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 possible 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".
+
+ @param None.
+
+ @retval 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 SystemConfiguration;
+
+ Status = EFI_SUCCESS;
+ GopDevicePath = NULL;
+ PlugInPciVgaDevicePath = NULL;
+ OnboardPciVgaDevicePath = NULL;
+
+ //
+ // Check the policy which is the first enabled VGA
+ //
+ GetPlugInPciVgaDevicePath (&PlugInPciVgaDevicePath, &OnboardPciVgaDevicePath);
+
+ DEBUG ((EFI_D_INFO,"PlugInPciVgaDevicePath: 0x%x OnboardPciVgaDevicePath: 0x%x\n", PlugInPciVgaDevicePath, OnboardPciVgaDevicePath));
+
+ if (PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ VarSize = sizeof (SYSTEM_CONFIGURATION);
+
+ Status = gRT->GetVariable (
+ L"Setup",
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VarSize,
+ &SystemConfiguration
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ if ((PlugInPciVgaDevicePath == NULL && OnboardPciVgaDevicePath != NULL)) {
+ DEBUG ((EFI_D_INFO, "Update onboard PCI VGA ...\n"));
+ DevicePathFirst = OnboardPciVgaDevicePath;
+ DevicePathSecond = PlugInPciVgaDevicePath;
+ goto UpdateConOut;
+ }
+ if (OnboardPciVgaDevicePath != NULL && SystemConfiguration.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;
+}
+
+
+/**
+ Connect the predefined platform default console device. Always try to find
+ and enable the vga device if have.
+
+ @param[in] 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;
+
+ Index = 0;
+ Status = EFI_SUCCESS;
+ DevicePathSize = 0;
+ VarConout = BdsLibGetVariableAndSize (
+ L"ConOut",
+ &gEfiGlobalVariableGuid,
+ &DevicePathSize
+ );
+
+ VarConin = BdsLibGetVariableAndSize (
+ L"ConIn",
+ &gEfiGlobalVariableGuid,
+ &DevicePathSize
+ );
+
+ DEBUG ((EFI_D_INFO, "Enter PlatformBdsConnectConsole()\n"));
+ if (VarConout == NULL || VarConin == NULL) {
+ //
+ // Have chance to connect the platform default console,
+ // the platform default console is the minimue 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 to serial device. Needed by GOP driver, hence before BdsLibConnectAllDefaultConsoles().
+ //
+ BdsLibConnectDevicePath (gSerialIoConnect[0]);
+
+ //
+ // 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;
+ }
+
+ //
+ // Connect the all the default console with current console variable
+ //
+ Status = BdsLibConnectAllDefaultConsoles ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "DISPLAY INIT DONE\n"));
+
+ return EFI_SUCCESS;
+}
+
+
+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[in, out] 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[in, out] 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[in] MemoryTestLevel The memory test intensive level
+ @param[in] QuietBoot Indicate if need to enable the quiet boot
+ @param[in] 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);
+}
+
+
+/**
+ 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[in] DriverOptionList The header of the driver option link list
+ @param[in] BootOptionList The header of the boot option link list
+ @param[in] ProcessCapsules A pointer to ProcessCapsules()
+ @param[in] BaseMemoryTest A pointer to BaseMemoryTest()
+
+ @retval None.
+
+**/
+VOID
+EFIAPI
+PlatformBdsPolicyBehavior (
+ IN OUT LIST_ENTRY *DriverOptionList,
+ IN OUT LIST_ENTRY *BootOptionList,
+ IN PROCESS_CAPSULES ProcessCapsules,
+ IN BASEM_MEMORY_TEST BaseMemoryTest
+ )
+{
+ EFI_STATUS Status;
+ UINT16 Timeout;
+ EFI_BOOT_MODE BootMode;
+ BOOLEAN DeferredImageExist;
+ UINTN Index;
+ CHAR16 CapsuleVarName[30];
+ CHAR16 *TempVarName;
+ SYSTEM_CONFIGURATION SystemConfiguration;
+ UINTN VarSize;
+ UINT16 *BootOrder;
+ UINTN BootOrderSize;
+ UINT32 UcodeRevision;
+ EFI_INPUT_KEY Key;
+ CHAR16 *ErrorInfo = L"uCode/Punit patch is not being loaded.";
+ CHAR16 *PressKey = L"Press any key to continue...";
+ UINTN Tcg2PpDataSize;
+ EFI_TCG2_PHYSICAL_PRESENCE Tcg2PpData;
+ EFI_PHYSICAL_PRESENCE TcgPpData;
+ UINTN TcgPpDataSize;
+
+ Timeout = PcdGet16 (PcdPlatformBootTimeOut);
+
+ VarSize = sizeof (SYSTEM_CONFIGURATION);
+
+ Status = gRT->GetVariable (
+ L"Setup",
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VarSize,
+ &SystemConfiguration
+ );
+
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ //
+ // Load the driver option as the driver option list
+ //
+ PlatformBdsGetDriverOption (DriverOptionList);
+
+ //
+ // Get current Boot Mode
+ //
+ BootMode = GetBootModeHob ();
+
+ //
+ // Clear all the capsule variables CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...
+ // as early as possible which will avoid the next time boot after the capsule update
+ // will still into the capsule loop
+ //
+ StrCpyS (CapsuleVarName, sizeof (CapsuleVarName) / sizeof (CHAR16), EFI_CAPSULE_VARIABLE_NAME);
+ TempVarName = CapsuleVarName + StrLen (CapsuleVarName);
+ Index = 0;
+ while (TRUE) {
+ if (Index > 0) {
+ UnicodeValueToString (TempVarName, 0, Index, 0);
+ }
+ Status = gRT->SetVariable (
+ CapsuleVarName,
+ &gEfiCapsuleVendorGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 0,
+ (VOID *) NULL
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // There is no capsule variables, quit
+ //
+ break;
+ }
+ Index ++;
+ }
+
+ //
+ // No deferred images exist by default
+ //
+ DeferredImageExist = FALSE;
+
+ if (SystemConfiguration.FastBoot == 1) {
+ BootOrder = BdsLibGetVariableAndSize (
+ L"BootOrder",
+ &gEfiGlobalVariableGuid,
+ &BootOrderSize
+ );
+
+ if (BootOrder != NULL) {
+ //
+ // BootOrder exist, it means system has boot before. We can do fast boot.
+ //
+ BootMode = BOOT_WITH_MINIMAL_CONFIGURATION;
+ }
+ FastBootUpdateConInVarByConInBehavior (SystemConfiguration);
+ }
+
+ //
+ // Unload EFI network driver if it is disabled in setup
+ //
+ if ((!SystemConfiguration.EfiNetworkSupport) || (SystemConfiguration.FastBoot == 1)) {
+ UnloadNetworkDriver ();
+ }
+ //
+ // Display message to indicate Ucode patch fails.
+ //
+ UcodeRevision = GetCpuUcodeRevision ();
+ if ((UcodeRevision == 0 )){
+ PlatformBdsConnectConsole (gPlatformConsole);
+ CreateDialog (&Key, ErrorInfo, PressKey, NULL);
+ gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ gST->ConOut->ClearScreen (gST->ConOut);
+ }
+
+ //
+ // This will lock physical presence flag, therefore, need to do this before signal EndOfDxe
+ //
+ if ((BootMode != BOOT_WITH_MINIMAL_CONFIGURATION) &&
+ (BootMode != BOOT_ASSUMING_NO_CONFIGURATION_CHANGES) &&
+ (BootMode != BOOT_ON_FLASH_UPDATE) &&
+ (BootMode != BOOT_IN_RECOVERY_MODE)) {
+
+ //
+ // Initialize physical presence variable.
+ //
+ if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid) ||
+ CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gTpmDeviceInstanceTpm20PttPtpGuid)) {
+ Tcg2PpDataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+ Status = gRT->GetVariable (
+ TCG2_PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ NULL,
+ &Tcg2PpDataSize,
+ &Tcg2PpData
+ );
+
+ if (EFI_ERROR (Status)) {
+ ZeroMem ((VOID *) &Tcg2PpData, sizeof (Tcg2PpData));
+ Tcg2PpDataSize = sizeof (EFI_TCG2_PHYSICAL_PRESENCE);
+ Status = gRT->SetVariable (
+ TCG2_PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiTcg2PhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ Tcg2PpDataSize,
+ &Tcg2PpData
+ );
+ }
+ } else if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) {
+ TcgPpDataSize = sizeof (EFI_PHYSICAL_PRESENCE);
+ Status = gRT->GetVariable (
+ PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiPhysicalPresenceGuid,
+ NULL,
+ &TcgPpDataSize,
+ &TcgPpData
+ );
+
+ if (EFI_ERROR (Status)) {
+ ZeroMem ((VOID *) &TcgPpData, sizeof (TcgPpData));
+ TcgPpDataSize = sizeof (EFI_PHYSICAL_PRESENCE);
+ Status = gRT->SetVariable (
+ PHYSICAL_PRESENCE_VARIABLE,
+ &gEfiPhysicalPresenceGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ TcgPpDataSize,
+ &TcgPpData
+ );
+ }
+ }
+
+ if (!EFI_ERROR (Status) && ((Tcg2PpData.PPRequest != TCG2_PHYSICAL_PRESENCE_NO_ACTION) || (TcgPpData.PPRequest != TCG_PHYSICAL_PRESENCE_NO_ACTION))) {
+ //
+ // If it requests any action on TCG, need to connect console to display information.
+ //
+ PlatformBdsConnectConsole (gPlatformConsole);
+ }
+
+ if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm20DtpmGuid) ||
+ CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gTpmDeviceInstanceTpm20PttPtpGuid)) {
+ Tcg2PhysicalPresenceLibProcessRequest (NULL);
+ } else if (CompareGuid (PcdGetPtr (PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) {
+ TcgPhysicalPresenceLibProcessRequest ();
+ }
+ }
+
+ //
+ // Close boot script and install ready to lock.
+ // This needs to be done before option rom dispatched.
+ //
+ InstallReadyToLock ();
+
+ //
+ // Go the different platform policy with different boot mode
+ // Notes: this part code can be change with the table policy
+ //
+ DEBUG ((EFI_D_INFO, "PlatformBdsPolicyBehavior()__BootMode = %d\n", BootMode));
+ switch (BootMode) {
+ case BOOT_WITH_MINIMAL_CONFIGURATION:
+ PlatformBdsConnectSimpleConsole (gPlatformSimpleOnChipPciVgaConOutConsole);
+ //
+ // Connect boot device here to give time to read keyboard.
+ //
+ Index = 0;
+ while (gPlatformSimpleBootOption[Index] != NULL) {
+ BdsLibConnectDevicePath (gPlatformSimpleBootOption[Index]);
+ ConnectDevicePathRecursive (gPlatformSimpleBootOption[Index]);
+ Index ++;
+ }
+ 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 ();
+ }
+ }
+
+ //
+ // 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);
+ 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 ();
+ }
+ }
+
+ ProcessCapsules (BOOT_ON_FLASH_UPDATE);
+ 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 ();
+ }
+ }
+
+ //
+ // In recovery boot mode, we still enter to the
+ // frong page now
+ //
+ PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
+ break;
+
+ 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 ();
+ }
+
+ //
+ // Perform some platform specific connect sequence
+ //
+ PlatformBdsConnectSequence ();
+
+ //
+ // Perform memory test as appropriate in order to promote any untested memory
+ //
+ PlatformBdsDiagnostics (IGNORE, TRUE, 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 ();
+ }
+ }
+
+ //
+ // Give one chance to enter the setup if we
+ // have the time out
+ //
+ PlatformBdsEnterFrontPageWithHotKey (Timeout, FALSE);
+
+ //
+ // 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;
+ }
+
+ //
+ // Here we have enough time to do the enumeration of boot device
+ //
+ BdsLibEnumerateAllBootOption (BootOptionList);
+ break;
+ }
+ 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 also a platform implementation and can be customized by IBV/OEM.
+
+ @param[in] 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[in] Option Pointer to Boot Option that failed to boot.
+ @param[in] Status Status returned from failed boot.
+ @param[in] ExitData Exit data returned from failed boot.
+ @param[in] 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;
+
+ //
+ // 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);
+ }
+}
+
+
+EFI_STATUS
+PlatformBdsNoConsoleAction (
+ VOID
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function locks the block.
+
+ @param[in] 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;
+ UINT8 Data;
+ 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++) {
+ Data = MmioOr8 ((UINTN) BaseAddress, 0x03);
+ BaseAddress += BlockLength;
+ }
+ BlockMap++;
+ }
+}
+
+
+VOID
+EFIAPI
+PlatformBdsLockNonUpdatableFlash (
+ VOID
+ )
+{
+ EFI_PHYSICAL_ADDRESS Base;
+
+ Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvOBBBase);
+ if (Base > 0) {
+ BdsLockFv (Base);
+ }
+
+ Base = (EFI_PHYSICAL_ADDRESS) PcdGet32 (PcdFlashFvIBBMBase);
+ 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[in] Password Password used to lock ConIn device.
+
+ @retval EFI_SUCCESS Lock the Console In Splitter 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;
+
+ if (TimeoutDefault == 0) {
+ return EFI_TIMEOUT;
+ }
+
+ DEBUG ((EFI_D_INFO, "\n\nStart showing progress bar... Press any key to stop it! ...Zzz....\n"));
+
+ 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);
+
+ //
+ // Clear the progress status bar first
+ //
+ TmpStr = L"Start boot option";
+ PlatformBdsShowProgress (Foreground, Background, TmpStr, Color, 0, 0);
+
+ //
+ // TimeoutDefault is determined by PcdPlatformBootTimeOut in PcdsDynamicHii.Default.dsc
+ //
+ TimeoutRemain = TimeoutDefault;
+
+ while (TimeoutRemain != 0) {
+ DEBUG ((EFI_D_INFO, "Showing progress bar...Remaining %d second!\n", TimeoutRemain));
+
+ 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) {
+ return EFI_TIMEOUT;
+ }
+
+ //
+ // User pressed some key
+ //
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ 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_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[in] TimeoutDefault The fault time out value before the system
+ continue to boot.
+ @param[in] ConnectAllHappened The indicator 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;
+ }
+ }
+ 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:
+ FreeBMPackage ();
+ //
+ // User chose to run the Boot Manager
+ //
+ CallBootManager ();
+ 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 ();
+ 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);
+}
+
+
+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
+ );
+ DEBUG ((EFI_D_INFO, "Enter PlatformBdsConnectSimpleConsole()\n"));
+ 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);
+ //
+ // Make sure we have at least one active VGA, and have the right
+ // active VGA in console variable
+ //
+ Status = PlatformBdsForceActiveVga ();
+ }
+
+ 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;
+ }
+
+ //
+ // 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[in] Event Indicates the event that invoke this function.
+ @param[in] 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[in] Event The event that is signalled.
+ @param[in] Context Not used here.
+
+**/
+VOID
+EFIAPI
+HitHotkeyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ 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);
+}
+
+
+VOID
+EFIAPI
+UnloadNetworkDriver (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN DriverImageHandleCount;
+ EFI_HANDLE *DriverImageHandleBuffer;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_GUID *NameGuid;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode;
+
+ DriverImageHandleCount = 0;
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiLoadedImageProtocolGuid,
+ NULL,
+ &DriverImageHandleCount,
+ &DriverImageHandleBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ for (Index = 0; Index < DriverImageHandleCount; Index++) {
+ Status = gBS->HandleProtocol (
+ DriverImageHandleBuffer[Index],
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **) &LoadedImage
+ );
+ if (LoadedImage->FilePath == NULL) {
+ continue;
+ }
+
+ TempDevicePath = LoadedImage->FilePath;
+ LastDeviceNode = TempDevicePath;
+ while (!IsDevicePathEnd (TempDevicePath)) {
+ LastDeviceNode = TempDevicePath;
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ }
+ NameGuid = EfiGetNameGuidFromFwVolDevicePathNode (
+ (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode
+ );
+ if ((NameGuid != NULL) && (CompareGuid (NameGuid, &gUndiDriverImageGuid))) {
+ Status = gBS->UnloadImage (DriverImageHandleBuffer[Index]);
+ ASSERT_EFI_ERROR (Status);
+ break;
+ }
+ }
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.h b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.h
new file mode 100644
index 0000000000..18c5f88779
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/BdsPlatform.h
@@ -0,0 +1,465 @@
+/** @file
+ Header file for BDS Platform specific code.
+
+ Copyright (c) 2006 - 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
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _BDS_PLATFORM_H
+#define _BDS_PLATFORM_H
+
+#include <FrameworkDxe.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/LoadFile.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/SmmAccess2.h>
+#include <Protocol/DxeSmmReadyToLock.h>
+#include <Protocol/UserManager.h>
+#include <Protocol/DeferredImageLoad.h>
+#include <Protocol/AcpiS3Save.h>
+#include <Protocol/LoadedImage.h>
+#include <Guid/CapsuleVendor.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/GlobalVariable.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/GenericBdsLib.h>
+#include <Library/PlatformBdsLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiLib.h>
+#include <Library/HobLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PerformanceLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <IndustryStandard/Pci.h>
+
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformRootBridges [];
+extern BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole [];
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformAllPossiblePciVgaConsole [];
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence [];
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformDriverOption [];
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformBootOption [];
+extern EFI_DEVICE_PATH_PROTOCOL *gUserAuthenticationDevice[];
+extern BDS_CONSOLE_CONNECT_ENTRY gPlatformSimpleOnChipPciVgaConOutConsole [];
+extern BDS_CONSOLE_CONNECT_ENTRY gPlatformSimpleUsbConInConsole [];
+extern BDS_CONSOLE_CONNECT_ENTRY gPlatformSimplePs2ConInConsole [];
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformSimpleBootOption [];
+extern EFI_DEVICE_PATH_PROTOCOL *gSerialIoConnect[];
+
+//
+// the short form device path for Usb keyboard
+//
+#define CLASS_HID 3
+#define SUBCLASS_BOOT 1
+#define PROTOCOL_KEYBOARD 1
+
+#define PCI_DEVICE_PATH_NODE(Func, Dev) \
+ { \
+ HARDWARE_DEVICE_PATH, \
+ HW_PCI_DP, \
+ { \
+ (UINT8) (sizeof (PCI_DEVICE_PATH)), \
+ (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \
+ }, \
+ (Func), \
+ (Dev) \
+ }
+
+#define PNPID_DEVICE_PATH_NODE(PnpId) \
+ { \
+ { \
+ ACPI_DEVICE_PATH, \
+ ACPI_DP, \
+ { \
+ (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \
+ (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \
+ } \
+ }, \
+ EISA_PNP_ID((PnpId)), \
+ 0 \
+ }
+
+#define gUart(BaudRate, DataBits, Parity, StopBits) \
+ { \
+ { \
+ MESSAGING_DEVICE_PATH, \
+ MSG_UART_DP, \
+ { \
+ (UINT8) (sizeof (UART_DEVICE_PATH)), \
+ (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \
+ } \
+ }, \
+ 0, \
+ (BaudRate), \
+ (DataBits), \
+ (Parity), \
+ (StopBits) \
+ }
+
+#define gPcAnsiTerminal \
+ { \
+ { \
+ MESSAGING_DEVICE_PATH, \
+ MSG_VENDOR_DP, \
+ { \
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \
+ } \
+ }, \
+ DEVICE_PATH_MESSAGING_PC_ANSI \
+ }
+
+#define gUsbKeyboardMouse \
+ { \
+ { \
+ MESSAGING_DEVICE_PATH, \
+ MSG_USB_CLASS_DP, \
+ (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)), \
+ (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8) \
+ }, \
+ 0xffff, \
+ 0xffff, \
+ CLASS_HID, \
+ SUBCLASS_BOOT, \
+ PROTOCOL_KEYBOARD \
+ }
+
+#define gEndEntire \
+ { \
+ END_DEVICE_PATH_TYPE, \
+ END_ENTIRE_DEVICE_PATH_SUBTYPE, \
+ { \
+ END_DEVICE_PATH_LENGTH, \
+ 0 \
+ } \
+ }
+
+#define gPciRootBridge \
+ PNPID_DEVICE_PATH_NODE(0x0A03)
+
+#define gPnpPs2Keyboard \
+ PNPID_DEVICE_PATH_NODE(0x0303)
+
+#define gPnp16550ComPort \
+ PNPID_DEVICE_PATH_NODE(0x0501)
+
+#define gPciIsaBridge \
+ PCI_DEVICE_PATH_NODE(0, 0x1f)
+
+#define gPciSpiBridge \
+ PCI_DEVICE_PATH_NODE(1, 0x19)
+
+
+//
+// Platform Root Bridge
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_ROOT_BRIDGE_DEVICE_PATH;
+
+//
+// Below is the platform console device path
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH IsaBridge;
+ ACPI_HID_DEVICE_PATH Keyboard;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_ISA_KEYBOARD_DEVICE_PATH;
+
+typedef struct {
+ USB_CLASS_DEVICE_PATH UsbClass;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} USB_CLASS_FORMAT_DEVICE_PATH;
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH OnboardVga;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_ONBOARD_VGA_DEVICE_PATH;
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH AgpBridge;
+ PCI_DEVICE_PATH AgpDevice;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_OFFBOARD_VGA_DEVICE_PATH;
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH IsaBridge;
+ ACPI_HID_DEVICE_PATH IsaSerial;
+ UART_DEVICE_PATH Uart;
+ VENDOR_DEVICE_PATH TerminalType;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_ISA_SERIAL_DEVICE_PATH;
+
+//
+// Below is the boot option device path
+//
+typedef struct {
+ BBS_BBS_DEVICE_PATH LegacyHD;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} LEGACY_HD_DEVICE_PATH;
+
+//
+// Below is the platform IDE device path
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH IsaBridge;
+ ATAPI_DEVICE_PATH Ide;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_IDE_DEVICE_PATH;
+
+//
+// Floppy device path definition
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH IsaBridge;
+ ACPI_HID_DEVICE_PATH Floppy;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_FLOPPY_DEVICE_PATH;
+
+//
+// Below is the platform USB controller device path for
+// USB disk as user authentication device.
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH PciDevice;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_USB_DEVICE_PATH;
+
+//
+// Below is the platform PCI device path
+//
+typedef struct {
+ ACPI_HID_DEVICE_PATH PciRootBridge;
+ PCI_DEVICE_PATH PciDevice;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} PLATFORM_PCI_DEVICE_PATH;
+
+//
+// Platform BDS Functions
+//
+VOID
+PlatformBdsGetDriverOption (
+ IN LIST_ENTRY *BdsDriverLists
+ );
+
+VOID
+PlatformBdsPredictBootOption (
+ IN LIST_ENTRY *BdsBootOptionList
+ );
+
+EFI_STATUS
+PlatformBdsShowProgress (
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground,
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground,
+ CHAR16 *Title,
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor,
+ UINTN Progress,
+ UINTN PreviousValue
+ );
+
+VOID
+PlatformBdsConnectSequence (
+ VOID
+ );
+
+EFI_STATUS
+PlatformBdsConnectConsole (
+ IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
+ );
+
+EFI_STATUS
+PlatformBdsNoConsoleAction (
+ VOID
+ );
+
+VOID
+PlatformBdsEnterFrontPage (
+ IN UINT16 TimeoutDefault,
+ IN BOOLEAN ConnectAllHappened
+ );
+
+VOID
+EFIAPI
+PlatformBdsUserIdentify (
+ OUT EFI_USER_PROFILE_HANDLE *User,
+ OUT BOOLEAN *DeferredImage
+ );
+
+VOID
+EFIAPI
+PlatformBdsConnectAuthDevice (
+ VOID
+ );
+
+VOID
+PlatformBdsEnterFrontPageWithHotKey (
+ IN UINT16 TimeoutDefault,
+ IN BOOLEAN ConnectAllHappened
+ );
+
+EFI_STATUS
+ShowProgress (
+ IN UINT16 TimeoutDefault
+ );
+
+EFI_STATUS
+InitializeFrontPage (
+ IN BOOLEAN InitializeHiiData
+ );
+
+VOID
+UpdateFrontPageStrings (
+ VOID
+ );
+
+EFI_STATUS
+CallFrontPage (
+ VOID
+ );
+
+VOID
+CallBootManager (
+ VOID
+ );
+
+VOID
+CallDeviceManager (
+ VOID
+ );
+
+CHAR16 *
+GetStringById (
+ IN EFI_STRING_ID Id
+ );
+
+EFI_STATUS
+WaitForSingleEvent (
+ IN EFI_EVENT Event,
+ IN UINT64 Timeout OPTIONAL
+ );
+
+EFI_STATUS
+BdsBootAndroidFromUsb (
+ VOID
+ );
+
+EFI_STATUS
+BdsBootAndroidFromEmmc (
+ VOID
+ );
+
+EFI_STATUS
+BdsBootAndroid (
+ VOID
+ );
+
+EFI_STATUS
+InitBMPackage (
+ VOID
+ );
+
+/**
+ Remvoe the intalled BootMaint and FileExplorer HiiPackages.
+
+**/
+VOID
+FreeBMPackage (
+ VOID
+ );
+
+/**
+ Start boot maintenance manager
+
+ @retval EFI_SUCCESS If BMM is invoked successfully.
+ @return Other value If BMM return unsuccessfully.
+
+**/
+EFI_STATUS
+BdsStartBootMaint (
+ VOID
+ );
+
+#define ONE_SECOND 10000000
+#define FRONT_PAGE_KEY_CONTINUE 0x1000
+#define FRONT_PAGE_KEY_LANGUAGE 0x1234
+#define FRONT_PAGE_KEY_BOOT_MANAGER 0x1064
+#define FRONT_PAGE_KEY_DEVICE_MANAGER 0x8567
+#define FRONT_PAGE_KEY_BOOT_MAINTAIN 0x9876
+
+#define PORT_A_DVO 0 // DVO A
+#define PORT_B_DVO 1 // DVO B
+#define PORT_C_DVO 2 // DVO C
+#define PORT_D_DVO 3 // DVO D
+#define PORT_LVDS 4 // Integrated LVDS port
+#define PORT_ANALOG_TV 5 // Integrated TV port
+#define PORT_CRT 6 // integrated Analog port
+#define PORT_B_DP 7 // DisplayPort B
+#define PORT_C_DP 8 // DisplayPort C
+#define PORT_D_DP 9 // DisplayPort D
+#define PORT_A_DP 10 // DisplayPort A (for eDP on ILK)
+#define PORT_B_HDMI 11 // HDMI B
+#define PORT_C_HDMI 12 // HDMI C
+#define PORT_D_HDMI 13 // HDMI D
+#define PORT_B_DVI 14 // DVI B
+#define PORT_C_DVI 15 // DVI C
+#define PORT_D_DVI 16 // DVI D
+#define PORT_MIPI_A 21 // MIPI
+#define PORT_MIPI_B 22
+#define PORT_MIPI_C 23
+
+extern BOOLEAN gConnectAllHappened;
+extern UINTN gCallbackKey;
+
+VOID
+BdsBootDeviceSelect (
+ VOID
+ );
+
+VOID FastBoot(VOID);
+
+extern BOOLEAN mModeInitialized;
+
+//
+// Boot video resolution and text mode.
+//
+extern UINT32 mBootHorizontalResolution ;
+extern UINT32 mBootVerticalResolution ;
+extern UINT32 mBootTextModeColumn ;
+extern UINT32 mBootTextModeRow ;
+//
+// BIOS setup video resolution and text mode.
+//
+extern UINT32 mSetupTextModeColumn ;
+extern UINT32 mSetupTextModeRow ;
+extern UINT32 mSetupHorizontalResolution ;
+extern UINT32 mSetupVerticalResolution ;
+
+extern EFI_STATUS BdsSetConsoleMode (BOOLEAN);
+#endif // _BDS_PLATFORM_H
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.c
new file mode 100644
index 0000000000..4b99d0014f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.c
@@ -0,0 +1,586 @@
+/** @file
+ This file include all platform action which can be customized by IBV/OEM.
+
+ Copyright (c) 1999 - 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
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "EfiBootStub.h"
+#include "OsipPrivate.h"
+#include <Library/DxeServicesLib.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleFileSystem.h>
+
+//
+// Global descriptor table (GDT) Template
+//
+STATIC GDT_ENTRIES GdtTemplate = {
+ //
+ // NULL_SEL
+ //
+ {
+ 0x0, // limit 15:0
+ 0x0, // base 15:0
+ 0x0, // base 23:16
+ 0x0, // type
+ 0x0, // limit 19:16, flags
+ 0x0, // base 31:24
+ },
+
+ //
+ // NULL_SEL2
+ //
+ {
+ 0x0, // limit 15:0
+ 0x0, // base 15:0
+ 0x0, // base 23:16
+ 0x0, // type
+ 0x0, // limit 19:16, flags
+ 0x0, // base 31:24
+ },
+
+ //
+ // SYS_CODE_SEL
+ //
+ {
+ 0x0FFFF, // limit 0xFFFFF
+ 0x0, // base 0
+ 0x0,
+ 0x09B, // present, ring 0, data, expand-up, writable
+ 0x0CF, // page-granular, 32-bit
+ 0x0,
+ },
+
+ //
+ // SYS_DATA_SEL
+ //
+ {
+ 0x0FFFF, // limit 0xFFFFF
+ 0x0, // base 0
+ 0x0,
+ 0x093, // present, ring 0, data, expand-up, writable
+ 0x0CF, // page-granular, 32-bit
+ 0x0,
+ }
+};
+
+VOID
+AsmStartLinuxKernel (
+ UINT32 KernelEntry
+ );
+
+EFI_STATUS
+IsFileExistent (
+ IN EFI_HANDLE Device,
+ IN CONST CHAR16 *FileName
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
+ EFI_FILE_HANDLE Root;
+ EFI_FILE_HANDLE ThisFile;
+
+ Root = NULL;
+ ThisFile = NULL;
+ //
+ // Handle the file system interface to the device
+ //
+ Status = gBS->HandleProtocol (
+ Device,
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID **) &Volume
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ Status = Volume->OpenVolume (
+ Volume,
+ &Root
+ );
+ if (EFI_ERROR (Status)) {
+ Root = NULL;
+ goto Done;
+ }
+ ASSERT (Root != NULL);
+ Status = Root->Open (Root, &ThisFile, (CHAR16 *) FileName, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ ASSERT (ThisFile != NULL);
+
+Done:
+ if (ThisFile != NULL) {
+ ThisFile->Close (ThisFile);
+ }
+ if (Root != NULL) {
+ Root->Close (Root);
+ }
+ return Status;
+}
+
+
+EFI_STATUS
+LoadFileFromFileSystem (
+ IN CONST CHAR16 *FileName,
+ OUT VOID **FileBuffer,
+ OUT UINTN *FileSize
+ )
+{
+ EFI_HANDLE *FileSystemHandles;
+ UINTN NumberFileSystemHandles;
+ UINTN Index;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *FilePath;
+ UINT32 AuthenticationStatus;
+
+ *FileBuffer = NULL;
+ *FileSize = 0;
+ //
+ // If there is simple file protocol which does not consume block Io protocol,
+ // create a boot option for it here.
+ //
+ FileSystemHandles = NULL;
+ gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiSimpleFileSystemProtocolGuid,
+ NULL,
+ &NumberFileSystemHandles,
+ &FileSystemHandles
+ );
+
+ for (Index = 0; Index < NumberFileSystemHandles; Index++) {
+ Status = IsFileExistent (FileSystemHandles[Index], FileName);
+ if (!EFI_ERROR (Status)) {
+ FilePath = FileDevicePath (FileSystemHandles[Index], FileName);
+ *FileBuffer = GetFileBufferByFilePath (TRUE, FilePath, FileSize,&AuthenticationStatus);
+ FreePool (FilePath);
+
+ if (*FileBuffer != NULL)
+ break;
+ }
+ }
+
+ if (FileSystemHandles) {
+ FreePool (FileSystemHandles);
+ }
+
+ if (*FileBuffer == NULL)
+ return EFI_NOT_FOUND;
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+setup_boot_params (
+ IN struct boot_params *bp,
+ struct setup_header *sh,
+ IN VOID *CmdLine,
+ IN VOID *InitrdPtr,
+ IN UINTN InitrdSize
+ )
+{
+ UINT8 Index;
+
+ ZeroMem (bp, sizeof (struct boot_params));
+ bp->screen_info.orig_video_mode = 0;
+ bp->screen_info.orig_video_lines = 0;
+ bp->screen_info.orig_video_cols = 0;
+ bp->alt_mem_k = 128 * 1024; // hard coded 128M mem here, since SFI will override it
+ CopyMem (&bp->hdr, sh, sizeof (struct setup_header));
+ bp->hdr.cmd_line_ptr = (UINT32) (UINTN) CmdLine;
+ bp->hdr.cmdline_size = (UINT32) (AsciiStrLen ((CONST CHAR8 *) (UINTN) CmdLine));
+ bp->hdr.type_of_loader = 0xff; //bootstub is unknown bootloader for kernel :)
+ bp->hdr.ramdisk_size = (UINT32) InitrdSize;
+ bp->hdr.ramdisk_image = (bp->alt_mem_k * 1024 - bp->hdr.ramdisk_size) & 0xFFFFF000;
+ bp->hdr.hardware_subarch = X86_SUBARCH_MRST;
+
+ DEBUG ((EFI_D_INFO, "Relocating initramfs to high memory ...\n"));
+ CopyMem ((UINT8 *) (UINTN) bp->hdr.ramdisk_image, (UINT8 *) InitrdPtr, (UINTN) bp->hdr.ramdisk_size);
+
+ //
+ // Prepare the e820 , hard code now
+ //
+ Index = 0;
+ bp->e820_map[Index].addr = 0x00000;
+ bp->e820_map[Index].size = 0x8f000;
+ bp->e820_map[Index++].type = 1;
+
+ bp->e820_map[Index].addr = 0x8f000;
+ bp->e820_map[Index].size = 0x90000 - 0x8f000;
+ bp->e820_map[Index++].type = 2;
+
+ bp->e820_map[Index].addr = 0x90000;
+ bp->e820_map[Index].size = 0xa0000 - 0x90000;
+ bp->e820_map[Index++].type = 1;
+
+ bp->e820_map[Index].addr = 0x100000;
+ bp->e820_map[Index].size = 0x3afcf000 - 0x100000;
+ bp->e820_map[Index++].type = 1;
+
+ bp->e820_map[Index].addr = 0x3afcf000;
+ bp->e820_map[Index].size = 0x3b7ff000 - 0x3afcf000;
+ bp->e820_map[Index++].type = 2;
+
+ bp->e820_map[Index].addr = 0x3b7ff000;
+ bp->e820_map[Index].size = 0x3b800000 - 0x3b7ff000;
+ bp->e820_map[Index++].type = 2;
+
+ bp->e820_entries = Index;
+
+}
+
+
+UINT32
+get_32bit_entry (
+ unsigned char *ptr
+ )
+{
+ while (1){
+ if (*(UINT32 *) ptr == SETUP_SIGNATURE && *(UINT32 *) (ptr+4) == 0)
+ break;
+ ptr++;
+ }
+ ptr+=4;
+ return (UINT32) (((UINTN) ptr + 511) / 512) * 512;
+}
+
+
+EFI_STATUS
+EfiBootStub (
+ IN VOID *CmdLine,
+ IN VOID *KernelPtr,
+ IN UINTN KernelSize,
+ IN VOID *InitrdPtr,
+ IN UINTN InitrdSize
+ )
+{
+ GDT_ENTRIES *gdt;
+ IA32_DESCRIPTOR gdtPtr;
+ IA32_DESCRIPTOR idtPtr = {0, 0};
+ UINT32 KernelEntry;
+
+ setup_boot_params (
+ (struct boot_params *) (UINTN) BOOT_PARAMS_OFFSET,
+ (struct setup_header *) (UINTN) SETUP_HEADER_OFFSET,
+ CmdLine,
+ InitrdPtr,
+ InitrdSize
+ );
+
+ SetInterruptState (FALSE);
+
+ //
+ // Load idt and gdt
+ //
+ AsmWriteIdtr (&idtPtr);
+
+ gdt = (GDT_ENTRIES *) (UINTN) ((UINTN) CmdLine - 0x1000);
+ CopyMem (gdt, &GdtTemplate, sizeof (GdtTemplate));
+
+ //
+ // Write GDT register
+ //
+ gdtPtr.Base = (UINT32) (UINTN) (VOID *) gdt;
+ gdtPtr.Limit = (UINT16) (sizeof (GdtTemplate) - 1);
+ AsmWriteGdtr (&gdtPtr);
+
+ //
+ // Jmp to the kernel entry
+ //
+#if X64_BUILD_ENABLE
+ //
+ //put X64 jump here...
+ //
+ KernelEntry = 0;
+#else
+ KernelEntry = get_32bit_entry ((unsigned char *) (UINTN) BZIMAGE_OFFSET);
+ AsmStartLinuxKernel (KernelEntry);
+#endif
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+EFI_STATUS
+BdsBootAndroidFromUsb (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ VOID *KernelFileBuffer;
+ UINTN KernelFileSize;
+ VOID *InitrdFileBuffer;
+ UINTN InitrdFileSize;
+ UINT8 *CmdPtr;
+ CHAR8 DefaultCmdLine [] = "console=ttyS0,115200 console=logk0 earlyprintk=nologger loglevel=8 kmemleak=off androidboot.bootmedia=sdcard androidboot.hardware=baylake emmc_ipanic.ipanic_part_number=1 vga=current i915.modeset=1 drm.vblankoffdelay=1 acpi_backlight=vendor";
+ CHAR8 MainBootMode [] = "androidboot.wakesrc=00 androidboot.mode=main";
+
+ //
+ // Load the kernel image
+ //
+ KernelFileBuffer = NULL;
+ KernelFileSize = 0;
+ Status = LoadFileFromFileSystem (L"\\kernel.img", &KernelFileBuffer, &KernelFileSize);
+ if (EFI_ERROR (Status))
+ return EFI_NOT_FOUND;
+
+ //
+ // Load the initrd image
+ //
+ InitrdFileBuffer = NULL;
+ InitrdFileSize = 0;
+ Status = LoadFileFromFileSystem (L"\\initrd.img", &InitrdFileBuffer, &InitrdFileSize);
+ if (EFI_ERROR (Status))
+ return EFI_NOT_FOUND;
+
+ //
+ // Prepare the cmd line at 0x1100000
+ //
+ CmdPtr = (UINT8 *) (UINTN) CMDLINE_OFFSET;
+ ZeroMem (CmdPtr, 0x200);
+ CopyMem (CmdPtr, DefaultCmdLine, sizeof (DefaultCmdLine));
+ CmdPtr += (sizeof (DefaultCmdLine) - 1);
+ *CmdPtr = 0x20;
+ CmdPtr += 1;
+ CopyMem (CmdPtr, MainBootMode, sizeof (MainBootMode));
+ CmdPtr += (sizeof (MainBootMode) - 1);
+ *CmdPtr = 0x0A;
+
+ //
+ // Copy the kernel image to 0x1102000
+ //
+ CmdPtr = (UINT8 *) (UINTN) BZIMAGE_OFFSET;
+ CopyMem (CmdPtr, KernelFileBuffer, KernelFileSize);
+
+ //
+ // Start Efi Boot Stub
+ //
+ EfiBootStub ((UINT8 *) (UINTN) CMDLINE_OFFSET, (UINT8 *) (UINTN) BZIMAGE_OFFSET, KernelFileSize, InitrdFileBuffer, InitrdFileSize);
+
+ FreePool (KernelFileBuffer);
+ FreePool (InitrdFileBuffer);
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+EFI_STATUS
+LoadOsipImageFromBlockDevices (
+ IN UINTN ImageIndex,
+ OUT EFI_PHYSICAL_ADDRESS *ImageBase,
+ OUT UINTN *ImageSize,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *BlockIoHandles;
+ UINTN NumberBlockIoHandles;
+ UINTN Index;
+ EFI_BLOCK_IO_PROTOCOL *TestBlockIo;
+ EFI_BLOCK_IO_PROTOCOL *EmmcBlockIo;
+ VOID *OsipBuffer;
+ OSIP_HEADER *pOSIP;
+ UINTN FirstBlock;
+ UINTN NumberBlocks;
+ VOID *pLoadAddress;
+ UINTN OSSize;
+ UINTN VrlSize;
+ BOOLEAN SignedOs;
+
+ EmmcBlockIo = NULL;
+ pOSIP = NULL;
+
+ OsipBuffer = NULL;
+ OsipBuffer = AllocatePages (OSP_BLOCKS_TO_PAGES (OSIP_SIZE_IN_BLOCKS));
+ if (!OsipBuffer)
+ return EFI_OUT_OF_RESOURCES;
+
+ BlockIoHandles = NULL;
+ gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiBlockIoProtocolGuid,
+ NULL,
+ &NumberBlockIoHandles,
+ &BlockIoHandles
+ );
+
+ for (Index = 0; Index < NumberBlockIoHandles; Index++) {
+ TestBlockIo = NULL;
+ Status = gBS->HandleProtocol(
+ BlockIoHandles[Index],
+ &gEfiBlockIoProtocolGuid,
+ (VOID **) &TestBlockIo
+ );
+ if ((EFI_ERROR (Status)) || (TestBlockIo == NULL)) {
+ continue;
+ }
+
+ //
+ // Read OSIP block from the block devices
+ //
+ ZeroMem (OsipBuffer, OSIP_SIZE_IN_BLOCKS * OSP_BLOCK_SIZE);
+ Status = TestBlockIo->ReadBlocks(
+ TestBlockIo,
+ TestBlockIo->Media->MediaId,
+ (EFI_LBA) 0, // OSIP hard coded to start at LBA 0
+ OSIP_SIZE_IN_BLOCKS * OSP_BLOCK_SIZE,
+ (VOID *) (UINTN) OsipBuffer);
+ if (EFI_ERROR (Status))
+ continue;
+
+ pOSIP = (OSIP_HEADER *) (UINTN) OsipBuffer;
+ if (pOSIP->Signature == OSIP_HEADER_SIGNATURE) {
+ EmmcBlockIo = TestBlockIo;
+ ValidateOsip(pOSIP, 1);
+ break;
+ }
+
+ pOSIP = NULL;
+ }
+
+ if (BlockIoHandles) {
+ FreePool (BlockIoHandles);
+ }
+
+ if ((!EmmcBlockIo) || (!pOSIP)) {
+ if (OsipBuffer) {
+ FreePages (OsipBuffer, OSP_BLOCKS_TO_PAGES(OSIP_SIZE_IN_BLOCKS));
+ }
+
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Parse OSII entry and find OS Image size in bytes
+ //
+ FirstBlock = pOSIP->Osii[ImageIndex].FirstBlock;
+ NumberBlocks = pOSIP->Osii[ImageIndex].BlockCount;
+ pLoadAddress = (VOID *) (UINTN)(pOSIP->Osii[ImageIndex].LoadAddress);
+ OSSize = NumberBlocks * OSP_BLOCK_SIZE;
+
+ //
+ // Load OS image to the address required
+ //
+ Status = EmmcBlockIo->ReadBlocks(
+ EmmcBlockIo,
+ EmmcBlockIo->Media->MediaId,
+ FirstBlock,
+ OSSize,
+ (VOID *) (UINTN) pLoadAddress);
+ if (EFI_ERROR(Status)) {
+ if (OsipBuffer) {
+ FreePages (OsipBuffer, OSP_BLOCKS_TO_PAGES (OSIP_SIZE_IN_BLOCKS));
+ }
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ SignedOs = ((pOSIP->Osii[ImageIndex].Attributes & 1) == 0) ? TRUE : FALSE;
+ if (SignedOs) {
+ VrlSize = 0x1e0;
+ } else {
+ VrlSize = 0;
+ }
+
+ OSSize -= VrlSize;
+
+ if (ImageBase)
+ *ImageBase = (EFI_PHYSICAL_ADDRESS) (UINTN)pLoadAddress;
+
+ if (ImageSize)
+ *ImageSize = OSSize;
+
+ if (EntryPoint)
+ *EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) pOSIP->Osii[ImageIndex].EntryPoint;
+
+ if (OsipBuffer) {
+ FreePages (OsipBuffer, OSP_BLOCKS_TO_PAGES (OSIP_SIZE_IN_BLOCKS));
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+BdsBootAndroidFromEmmc (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN KernelSize;
+ VOID *InitrdBuffer;
+ UINTN InitrdSize;
+ UINT8 *CmdPtr;
+ CHAR8 DefaultCmdLine [] = "console=ttyS0,115200 console=logk0 earlyprintk=nologger loglevel=8 kmemleak=off androidboot.bootmedia=sdcard androidboot.hardware=baylake emmc_ipanic.ipanic_part_number=1 vga=current i915.modeset=1 drm.vblankoffdelay=1 acpi_backlight=vendor";
+ CHAR8 MainBootMode [] = "androidboot.wakesrc=00 androidboot.mode=main";
+
+ Status = LoadOsipImageFromBlockDevices (0, NULL, NULL, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Failed to find OSIP Structure in any block devices \n"));
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Prepare the cmd line at 0x1100000
+ //
+ CmdPtr = (UINT8 *) (UINTN) CMDLINE_OFFSET;
+ ZeroMem (CmdPtr, 0x200);
+ CopyMem (CmdPtr, DefaultCmdLine, sizeof (DefaultCmdLine));
+ CmdPtr += (sizeof (DefaultCmdLine) - 1);
+ *CmdPtr = 0x20;
+ CmdPtr += 1;
+ CopyMem (CmdPtr, MainBootMode, sizeof (MainBootMode));
+ CmdPtr += (sizeof (MainBootMode) - 1);
+ *CmdPtr = 0x0A;
+
+ //
+ // Get the kernel and initrd information
+ //
+ KernelSize = *((UINT32 *) (UINTN) BZIMAGE_SIZE_OFFSET);
+ InitrdSize = *((UINT32 *) (UINTN) INITRD_SIZE_OFFSET);
+ InitrdBuffer = (VOID *) (UINTN) (BZIMAGE_OFFSET + KernelSize);
+
+ //
+ // Start Efi Boot Stub
+ //
+ EfiBootStub ((UINT8 *) (UINTN) CMDLINE_OFFSET, (UINT8 *) (UINTN) BZIMAGE_OFFSET, KernelSize, InitrdBuffer, InitrdSize);
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+EFI_STATUS
+BdsBootAndroid (
+ VOID
+ )
+{
+ UINTN KernelSize;
+ VOID *InitrdBuffer;
+ UINTN InitrdSize;
+
+ //
+ // Get the kernel and initrd information
+ //
+ KernelSize = *((UINT32 *) (UINTN) BZIMAGE_SIZE_OFFSET);
+ InitrdSize = *((UINT32 *) (UINTN) INITRD_SIZE_OFFSET);
+ InitrdBuffer = (VOID *) (UINTN) (BZIMAGE_OFFSET + KernelSize);
+
+ //
+ // Start Efi Boot Stub
+ //
+ EfiBootStub ((UINT8 *) (UINTN) CMDLINE_OFFSET, (UINT8 *) (UINTN) BZIMAGE_OFFSET, KernelSize, InitrdBuffer, InitrdSize);
+
+ return EFI_DEVICE_ERROR;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.h b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.h
new file mode 100644
index 0000000000..71a9048a24
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/EfiBootStub.h
@@ -0,0 +1,330 @@
+/** @file
+ This file include all platform action which can be customized by IBV/OEM.
+
+ Copyright (c) 1999 - 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
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DevicePathLib.h>
+#include "BdsPlatform.h"
+
+#pragma pack(1)
+
+typedef unsigned char __u8;
+typedef unsigned short __u16;
+typedef unsigned int __u32;
+typedef unsigned long long __u64;
+
+#define EDD_MBR_SIG_MAX 16
+#define E820MAX 128
+#define EDDMAXNR 6
+
+struct screen_info {
+ __u8 orig_x;
+ __u8 orig_y;
+ __u16 ext_mem_k;
+ __u16 orig_video_page;
+ __u8 orig_video_mode;
+ __u8 orig_video_cols;
+ __u16 unused2;
+ __u16 orig_video_ega_bx;
+ __u16 unused3;
+ __u8 orig_video_lines;
+ __u8 orig_video_isVGA;
+ __u16 orig_video_points;
+
+ //
+ // VESA graphic mode -- linear frame buffer
+ //
+ __u16 lfb_width;
+ __u16 lfb_height;
+ __u16 lfb_depth;
+ __u32 lfb_base;
+ __u32 lfb_size;
+ __u16 cl_magic, cl_offset;
+ __u16 lfb_linelength;
+ __u8 red_size;
+ __u8 red_pos;
+ __u8 green_size;
+ __u8 green_pos;
+ __u8 blue_size;
+ __u8 blue_pos;
+ __u8 rsvd_size;
+ __u8 rsvd_pos;
+ __u16 vesapm_seg;
+ __u16 vesapm_off;
+ __u16 pages;
+ __u16 vesa_attributes;
+ __u32 capabilities;
+ __u8 _reserved[6];
+};
+
+
+struct apm_bios_info {
+ __u16 version;
+ __u16 cseg;
+ __u32 offset;
+ __u16 cseg_16;
+ __u16 dseg;
+ __u16 flags;
+ __u16 cseg_len;
+ __u16 cseg_16_len;
+ __u16 dseg_len;
+};
+
+struct ist_info {
+ __u32 signature;
+ __u32 command;
+ __u32 event;
+ __u32 perf_level;
+};
+
+struct sys_desc_table {
+ __u16 length;
+ __u8 table[14];
+};
+
+struct efi_info {
+ __u32 efi_loader_signature;
+ __u32 efi_systab;
+ __u32 efi_memdesc_size;
+ __u32 efi_memdesc_version;
+ __u32 efi_memmap;
+ __u32 efi_memmap_size;
+ __u32 efi_systab_hi;
+ __u32 efi_memmap_hi;
+};
+
+struct setup_header {
+ __u8 setup_sects;
+ __u16 root_flags;
+ __u32 syssize;
+ __u16 ram_size;
+ __u16 vid_mode;
+ __u16 root_dev;
+ __u16 boot_flag;
+ __u16 jump;
+ __u32 header;
+ __u16 version;
+ __u32 realmode_swtch;
+ __u16 start_sys;
+ __u16 kernel_version;
+ __u8 type_of_loader;
+ __u8 loadflags;
+ __u16 setup_move_size;
+ __u32 code32_start;
+ __u32 ramdisk_image;
+ __u32 ramdisk_size;
+ __u32 bootsect_kludge;
+ __u16 heap_end_ptr;
+ __u16 _pad1;
+ __u32 cmd_line_ptr;
+ __u32 initrd_addr_max;
+ __u32 kernel_alignment;
+ __u8 relocatable_kernel;
+ __u8 _pad2[3];
+ __u32 cmdline_size;
+ __u32 hardware_subarch;
+ __u64 hardware_subarch_data;
+ __u32 payload_offset;
+ __u32 payload_length;
+ __u64 setup_data;
+};
+
+struct edid_info {
+ unsigned char dummy[128];
+};
+
+struct e820entry {
+ __u64 addr; ///< start of memory segment
+ __u64 size; ///< size of memory segment
+ __u32 type; ///< type of memory segment
+};
+
+struct edd_device_params {
+ __u16 length;
+ __u16 info_flags;
+ __u32 num_default_cylinders;
+ __u32 num_default_heads;
+ __u32 sectors_per_track;
+ __u64 number_of_sectors;
+ __u16 bytes_per_sector;
+ __u32 dpte_ptr; ///< 0xFFFFFFFF for our purposes
+ __u16 key; ///< = 0xBEDD
+ __u8 device_path_info_length; ///< = 44
+ __u8 reserved2;
+ __u16 reserved3;
+ __u8 host_bus_type[4];
+ __u8 interface_type[8];
+ union {
+ struct {
+ __u16 base_address;
+ __u16 reserved1;
+ __u32 reserved2;
+ } isa;
+ struct {
+ __u8 bus;
+ __u8 slot;
+ __u8 function;
+ __u8 channel;
+ __u32 reserved;
+ } pci;
+
+ //
+ // pcix is same as pci
+ //
+ struct {
+ __u64 reserved;
+ } ibnd;
+ struct {
+ __u64 reserved;
+ } xprs;
+ struct {
+ __u64 reserved;
+ } htpt;
+ struct {
+ __u64 reserved;
+ } unknown;
+ } interface_path;
+ union {
+ struct {
+ __u8 device;
+ __u8 reserved1;
+ __u16 reserved2;
+ __u32 reserved3;
+ __u64 reserved4;
+ } ata;
+ struct {
+ __u8 device;
+ __u8 lun;
+ __u8 reserved1;
+ __u8 reserved2;
+ __u32 reserved3;
+ __u64 reserved4;
+ } atapi;
+ struct {
+ __u16 id;
+ __u64 lun;
+ __u16 reserved1;
+ __u32 reserved2;
+ } scsi;
+ struct {
+ __u64 serial_number;
+ __u64 reserved;
+ } usb;
+ struct {
+ __u64 eui;
+ __u64 reserved;
+ } i1394;
+ struct {
+ __u64 wwid;
+ __u64 lun;
+ } fibre;
+ struct {
+ __u64 identity_tag;
+ __u64 reserved;
+ } i2o;
+ struct {
+ __u32 array_number;
+ __u32 reserved1;
+ __u64 reserved2;
+ } raid;
+ struct {
+ __u8 device;
+ __u8 reserved1;
+ __u16 reserved2;
+ __u32 reserved3;
+ __u64 reserved4;
+ } sata;
+ struct {
+ __u64 reserved1;
+ __u64 reserved2;
+ } unknown;
+ } device_path;
+ __u8 reserved4;
+ __u8 checksum;
+};
+
+struct edd_info {
+ __u8 device;
+ __u8 version;
+ __u16 interface_support;
+ __u16 legacy_max_cylinder;
+ __u8 legacy_max_head;
+ __u8 legacy_sectors_per_track;
+ struct edd_device_params params;
+};
+
+//
+// The so-called "zeropage"
+//
+struct boot_params {
+ struct screen_info screen_info;
+ struct apm_bios_info apm_bios_info;
+ __u8 _pad2[12];
+ struct ist_info ist_info;
+ __u8 _pad3[16];
+ __u8 hd0_info[16];
+ __u8 hd1_info[16];
+ struct sys_desc_table sys_desc_table;
+ __u8 _pad4[144];
+ struct edid_info edid_info;
+ struct efi_info efi_info;
+ __u32 alt_mem_k;
+ __u32 scratch;
+ __u8 e820_entries;
+ __u8 eddbuf_entries;
+ __u8 edd_mbr_sig_buf_entries;
+ __u8 _pad6[6];
+ struct setup_header hdr;
+ __u8 _pad7[0x290 - 0x1f1 - sizeof (struct setup_header)];
+ __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX];
+ struct e820entry e820_map[E820MAX];
+ __u8 _pad8[48];
+ struct edd_info eddbuf[EDDMAXNR];
+ __u8 _pad9[276];
+} ;
+
+#define X86_SUBARCH_PC 0
+#define X86_SUBARCH_LGUEST 1
+#define X86_SUBARCH_XEN 2
+#define X86_SUBARCH_MRST 3
+
+typedef struct _GDT_ENTRY {
+ UINT16 Limit15_0;
+ UINT16 Base15_0;
+ UINT8 Base23_16;
+ UINT8 Type;
+ UINT8 Limit19_16_and_flags;
+ UINT8 Base31_24;
+} GDT_ENTRY;
+
+typedef struct _GDT_ENTRIES {
+ GDT_ENTRY Null;
+ GDT_ENTRY Null2;
+ GDT_ENTRY SysCode;
+ GDT_ENTRY SysData;
+} GDT_ENTRIES;
+
+#pragma pack()
+
+#define CMDLINE_OFFSET 0x1100000
+#define BZIMAGE_SIZE_OFFSET (CMDLINE_OFFSET + 0x400)
+#define INITRD_SIZE_OFFSET (BZIMAGE_SIZE_OFFSET + 4)
+#define STACK_OFFSET 0x1101000
+#define BZIMAGE_OFFSET 0x1102000
+
+#define SETUP_HEADER_OFFSET (BZIMAGE_OFFSET + 0x1F1)
+#define SETUP_HEADER_SIZE (0x0202 + *(unsigned char*)(0x0201+BZIMAGE_OFFSET))
+#define BOOT_PARAMS_OFFSET 0x8000
+
+#define SETUP_SIGNATURE 0x5a5aaa55
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.Asm b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.Asm
new file mode 100644
index 0000000000..4cd4bfe001
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.Asm
@@ -0,0 +1,54 @@
+;; @file
+; This is the ASM for Jump to a specific address.
+;
+; Copyright (c) 1999 - 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
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+ .686P
+ .MMX
+ .MODEL SMALL
+ .CODE
+
+
+JumpToVector PROTO C \
+ EntryPoint:PTR DWORD, \
+ Parameter:DWORD
+;
+; Routine Description:
+; This allows the caller to switch the stack and goes to the new entry point
+;
+; Arguments:
+; EntryPoint - Pointer to the location to enter
+; Parameter - Parameter to pass in
+;
+; Returns:
+;
+; Nothing. Goes to the Entry Point passing in the new parameters
+;
+JumpToVector PROC C \
+ EntryPoint:PTR DWORD, \
+ Parameter:DWORD
+
+ push ebx
+
+ mov ebx, Parameter
+ mov ecx, EntryPoint
+ push ebx
+ push 0
+ jmp ecx
+
+ pop ebx
+ ret
+
+JumpToVector ENDP
+ END
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.S b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.S
new file mode 100644
index 0000000000..657158ddd7
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/JumpToVector.S
@@ -0,0 +1,42 @@
+## @file
+# This is the ASM for Jump to a specific address
+#
+# Copyright (c) 1999 - 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
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+#
+##
+
+#
+# Routine Description:
+# This allows the caller to switch the stack and goes to the new entry point
+#
+# Arguments:
+# EntryPoint - Pointer to the location to enter
+# Parameter - Parameter to pass in
+#
+# Returns:
+#
+# Nothing. Goes to the Entry Point passing in the new parameters
+#
+ASM_GLOBAL ASM_PFX(JumpToVector)
+ASM_PFX(JumpToVector):
+
+ push %ebx
+
+ mov 12(%esp), %ebx # ebx = Parameter
+ mov 8(%esp), %ecx # ecx = EntryPoint
+ push %ebx
+ push $0
+ jmp %ecx
+
+ pop %ebx
+ ret
+
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.Asm b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.Asm
new file mode 100644
index 0000000000..87cc8c4467
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.Asm
@@ -0,0 +1,49 @@
+;; @file
+; This is the ASM for starting a linux kernel.
+;
+; Copyright (c) 1999 - 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
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php.
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+;
+;;
+
+ .686P
+ .MMX
+ .MODEL SMALL
+ .CODE
+
+AsmStartLinuxKernel PROC near C PUBLIC
+ mov eax, [esp+4]
+ sub esp, 010h
+ lea ebx, NewSelectorJmp
+ mov [esp], ebx
+ mov ebx, 010h
+ mov [esp+4], ebx
+ jmp fword ptr [esp]
+
+NewSelectorJmp:
+ add esp, 010h
+
+ mov ebx, 018h
+ mov ds, ebx
+ mov es, ebx
+ mov fs, ebx
+ mov gs, ebx
+ mov ss, ebx
+
+ mov esi, 08000h
+ xor ebp, ebp
+ xor edi, edi
+ xor ebx, ebx
+ jmp eax
+ ret
+AsmStartLinuxKernel ENDP
+
+ END
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.S b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.S
new file mode 100644
index 0000000000..847ae342d2
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/Ia32/StartKernel.S
@@ -0,0 +1,41 @@
+## @file
+# This is the ASM for starting a linux kernel.
+#
+# Copyright (c) 1999 - 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
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED
+#
+##
+
+ASM_GLOBAL ASM_PFX(AsmStartLinuxKernel)
+ASM_PFX(AsmStartLinuxKernel):
+ movl 4(%esp), %eax
+ subl $0x10, %esp
+ leal NewSelectorJmp, %ebx
+ movl %ebx, (%esp)
+ movl $0x10, %ebx
+ movl %ebx, 4(%esp)
+ jmpl (%esp)
+
+NewSelectorJmp:
+ addl $0x10, %esp
+
+ movl $0x18, %ebx
+ movl %ebx, %ds
+ movl %ebx, %es
+ movl %ebx, %fs
+ movl %ebx, %gs
+ movl %ebx, %ss
+
+ movl $0x8000, %esi
+ xorl %ebp, %ebp
+ xorl %edi, %edi
+ xorl %ebx, %ebx
+ jmpl %eax
+ ret
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipPrivate.h b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipPrivate.h
new file mode 100644
index 0000000000..9567e42c90
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipPrivate.h
@@ -0,0 +1,168 @@
+/** @file
+ This file include all platform action which can be customized by IBV/OEM.
+
+ Copyright (c) 1999 - 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
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DevicePathLib.h>
+#include "BdsPlatform.h"
+
+#pragma pack(1)
+//
+// Forward declarations
+//
+typedef struct _OSIP_HEADER_V0100 OSIP_HEADER_V0100;
+typedef struct _OSII_ENTRY_V0100 OSII_ENTRY_V0100 ;
+
+//
+// Supported values for OSIP version 1.0 (PNW A0)
+//
+#define OSIP_HEADER_MAJOR_REVISION 1
+#define OSIP_HEADER_MINOR_REVISION 0
+#define OSIP_HEADER_SIGNATURE 0x24534F24
+#define OSIP_SIZE_IN_BLOCKS 1
+#define OSIP_HEADER OSIP_HEADER_V0100
+#define OSII_ENTRY OSII_ENTRY_V0100
+
+//
+// Module global definitions
+//
+#define OSP_BLOCK_SIZE 512
+#define OSP_BLOCKS_TO_PAGES(x) (EFI_SIZE_TO_PAGES(x * OSP_BLOCK_SIZE))
+#define MAX_OSII_ENTRIES ((OSIP_SIZE_IN_BLOCKS * OSP_BLOCK_SIZE - sizeof (OSIP_HEADER)) / sizeof (OSII_ENTRY))
+#define VRL_SIZE_LOCATION 0x20
+
+//
+// Definitions for PNW A0...
+//
+typedef struct _SMIP_FHOB_DWORD0 {
+ UINT8 MsicModuleId : 2;
+ UINT8 Qualifier : 1;
+ UINT8 OSRCR : 1;
+ UINT8 EOSR : 1;
+ UINT8 SafeModeJumper : 1;
+ UINT8 MM : 1;
+ UINT8 NOREn : 1; ///< 8
+ UINT8 OSVEn : 1;
+ UINT8 OSDnX : 1;
+ UINT8 Reserved11to10 : 2;
+ UINT8 Reserved19to12 : 8; ///< 20
+ UINT8 Reserved25to20 : 6;
+ UINT8 MemoryChannels : 1;
+ UINT8 MemoryBurstLength : 1; ///< 28
+ UINT8 MemoryDeviceDensity : 2;
+ UINT8 MemoryRanks : 1;
+ UINT8 MemoryFrequencyRatio : 1; ///< 32
+} SMIP_FHOB_DWORD0 ;
+
+struct _OSII_ENTRY_V0100 {
+ UINT16 MinorRevision;
+ UINT16 MajorRevision;
+ UINT32 FirstBlock;
+ UINT32 LoadAddress;
+ UINT32 EntryPoint;
+ UINT32 BlockCount;
+ UINT8 Attributes;
+ UINT8 Reserved1[3];
+} ;
+
+struct _OSIP_HEADER_V0100 {
+ UINT32 Signature;
+ UINT8 Reserved1;
+ UINT8 MinorRevision;
+ UINT8 MajorRevision;
+ UINT8 Checksum;
+ UINT8 NumberOfPointers;
+ UINT8 NumberOfImages;
+ UINT16 HeaderSize;
+ UINT8 Reserved2[0x14];
+ OSII_ENTRY Osii[1];
+} ;
+
+#pragma pack()
+
+//
+// Global Variables
+//
+#include <Protocol/BlockIo.h>
+
+extern OSIP_HEADER *mOsip;
+extern OSIP_HEADER *mOsip;
+extern BOOLEAN mOsipFound;
+extern EFI_BLOCK_IO_PROTOCOL *mEmmcBlockIo;
+extern EFI_BLOCK_IO_PROTOCOL *mSdBlockIo;
+extern EFI_BLOCK_IO_PROTOCOL *mBootableBlockIo;
+
+//
+// Functions oustide of the main module
+//
+
+//
+// OspUtil.c
+//
+EFI_STATUS
+ValidateFvHeader (
+ IN VOID *Buffer,
+ IN UINTN Size
+ );
+
+EFI_STATUS
+ValidateOsip (
+ IN OSIP_HEADER *OsipHdr,
+ IN UINTN MaxBlocks
+ );
+
+EFI_STATUS
+ConnectSecondStageFvDevice (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePathToConnect,
+ OUT EFI_HANDLE *MatchingHandle
+ );
+
+VOID
+RebaseImage (
+ IN EFI_PHYSICAL_ADDRESS DstBuffer,
+ IN EFI_PHYSICAL_ADDRESS SrcBuffer,
+ IN UINTN NumberOfBytes
+ );
+
+UINTN
+GetImageSizeByNumber (
+ IN UINTN ImageNumber
+ );
+
+EFI_STATUS
+LoadImageByNumber (
+ IN UINTN ImageNumber,
+ OUT EFI_PHYSICAL_ADDRESS *ImageBase,
+ OUT UINTN *NumberOfPages
+ );
+
+//
+// OsrIpc.c
+//
+EFI_STATUS
+OsrIpcGetDnx ();
+
+EFI_STATUS
+OsrIpcGetOsip (
+ IN EFI_PHYSICAL_ADDRESS osipBase
+ );
+
+EFI_STATUS
+OsrIpcGetOsImage (
+ IN OSII_ENTRY *osiiEntry,
+ OUT EFI_PHYSICAL_ADDRESS osBuffer
+ );
+
+EFI_STATUS
+OsrIpcEndOfUpdate ();
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipUtil.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipUtil.c
new file mode 100644
index 0000000000..b277a3562f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/OsipUtil.c
@@ -0,0 +1,247 @@
+/** @file
+ This file include all platform action which can be customized by IBV/OEM.
+
+ Copyright (c) 1999 - 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
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include "OsipPrivate.h"
+#include "BdsPlatform.h"
+
+#define EFI_MAX_E820_ENTRY 100
+
+typedef enum {
+ EfiAcpiAddressRangeMemory = 1,
+ EfiAcpiAddressRangeReserved = 2,
+ EfiAcpiAddressRangeACPI = 3,
+ EfiAcpiAddressRangeNVS = 4
+} EFI_ACPI_MEMORY_TYPE;
+
+#pragma pack(1)
+
+typedef struct {
+ UINT32 BaseAddr;
+ UINT32 Length;
+ UINT32 Type;
+} EFI_E820_ENTRY;
+
+#pragma pack()
+
+EFI_STATUS
+ValidateFvHeader (
+ IN VOID *Buffer,
+ IN UINTN Size
+ )
+{
+ EFI_FIRMWARE_VOLUME_HEADER *FvHdr;
+
+ FvHdr = (EFI_FIRMWARE_VOLUME_HEADER *) Buffer;
+
+ if (FvHdr->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((EFI_D_ERROR, "Error: Invalid FV signature\n"));
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ if (FvHdr->FvLength > Size) {
+ DEBUG ((EFI_D_ERROR,
+ "Error: FV length (0x%x) is larger than data read (0x%x)\n",
+ FvHdr->FvLength,
+ Size));
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+ValidateOsip (
+ IN OSIP_HEADER *Osip,
+ IN UINTN MaxBlocks
+ )
+{
+ UINTN idx;
+ UINTN nextBlock = OSIP_SIZE_IN_BLOCKS;
+
+ DEBUG ((EFI_D_INFO, "Parsing OSIP Header...\n")) ;
+ DEBUG ((EFI_D_INFO, " Signature : %x\n", Osip->Signature));
+ DEBUG ((EFI_D_INFO, " MajorRevision : %x\n", Osip->MajorRevision));
+ DEBUG ((EFI_D_INFO, " MinorRevision : %x\n", Osip->MinorRevision));
+ DEBUG ((EFI_D_INFO, " NumberOfPointers : %x\n", Osip->NumberOfPointers));
+ DEBUG ((EFI_D_INFO, " NumberOfImages : %x\n", Osip->NumberOfImages));
+ DEBUG ((EFI_D_INFO, " Checksum : %x\n", Osip->Checksum));
+
+ if (Osip->Signature != OSIP_HEADER_SIGNATURE) return EFI_INVALID_PARAMETER;
+ if (Osip->MajorRevision != OSIP_HEADER_MAJOR_REVISION) return EFI_INVALID_PARAMETER;
+ if (Osip->MinorRevision != OSIP_HEADER_MINOR_REVISION) return EFI_INVALID_PARAMETER;
+ if (Osip->NumberOfPointers == 0) return EFI_INVALID_PARAMETER;
+ if (Osip->NumberOfPointers > MAX_OSII_ENTRIES) return EFI_INVALID_PARAMETER;
+ if (Osip->NumberOfImages == 0) return EFI_INVALID_PARAMETER;
+ if (Osip->NumberOfImages > Osip->NumberOfPointers) return EFI_INVALID_PARAMETER;
+
+ //
+ // TODO: Validate checksum, not sure what good that does though...
+ //
+ DEBUG ((EFI_D_INFO, "Parsing OSII Entries...\n"));
+
+ for (idx = 0; idx < Osip->NumberOfPointers; idx++) {
+ DEBUG((EFI_D_INFO, "Image %d\n", idx + 1));
+ DEBUG((EFI_D_INFO, " MajorRevision : %x\n", Osip->Osii[idx].MajorRevision));
+ DEBUG((EFI_D_INFO, " MinorRevision : %x\n", Osip->Osii[idx].MinorRevision));
+ DEBUG((EFI_D_INFO, " FirstBlock : %x\n", Osip->Osii[idx].FirstBlock));
+ DEBUG((EFI_D_INFO, " LoadAddress : %x\n", Osip->Osii[idx].LoadAddress));
+ DEBUG((EFI_D_INFO, " EntryPoint : %x\n", Osip->Osii[idx].EntryPoint));
+ DEBUG((EFI_D_INFO, " BlockCount : %x\n", Osip->Osii[idx].BlockCount));
+ DEBUG((EFI_D_INFO, " Attributes : %x\n", Osip->Osii[idx].Attributes));
+
+ //
+ // Enforce ordering, do not permit empty entries or holes
+ //
+ if (Osip->Osii[idx].FirstBlock != nextBlock) return EFI_INVALID_PARAMETER;
+ if (Osip->Osii[idx].BlockCount == 0) return EFI_INVALID_PARAMETER;
+ nextBlock += Osip->Osii[idx].BlockCount;
+
+ //
+ // TODO: More intensive OSII validation
+ //
+ }
+
+ //
+ // Make sure numBlocks is not pointing past the end of the device
+ //
+ if (nextBlock > MaxBlocks) return EFI_INVALID_PARAMETER;
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+RebaseImage (
+ IN EFI_PHYSICAL_ADDRESS DstBuffer,
+ IN EFI_PHYSICAL_ADDRESS SrcBuffer,
+ IN UINTN NumberOfBytes
+ )
+{
+ UINT8 *sptr;
+ UINT8 *dptr;
+ UINTN idx;
+
+ sptr = (UINT8 *) (UINTN) SrcBuffer;
+ dptr = (UINT8 *) (UINTN) DstBuffer;
+
+ for (idx = 0; idx < NumberOfBytes; ++idx, ++dptr, ++sptr) {
+ *dptr = *sptr;
+ }
+
+ return;
+}
+
+
+UINTN
+GetImageSizeByNumber (
+ IN UINTN ImageNumber
+ )
+{
+ return mOsip->Osii[ImageNumber].BlockCount * OSP_BLOCK_SIZE;
+}
+
+
+EFI_STATUS
+LoadImageByNumber (
+ IN UINTN ImageNumber,
+ OUT EFI_PHYSICAL_ADDRESS *ImageBase,
+ OUT UINTN *NumberOfPages
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS physAddr;
+ UINTN firstBlock;
+ UINTN numBlocks;
+ UINTN numPages;
+
+ //
+ // Parse OSII entry and find OS Image size in bytes
+ //
+ firstBlock = mOsip->Osii[ImageNumber].FirstBlock;
+ numBlocks = mOsip->Osii[ImageNumber].BlockCount;
+ numPages = OSP_BLOCKS_TO_PAGES (numBlocks);
+
+ //
+ // Allocate image buffer
+ //
+ Status = gBS->AllocatePages (
+ AllocateAnyPages,
+ EfiBootServicesData,
+ numPages,
+ &physAddr);
+
+ if (EFI_ERROR (Status)) ASSERT_EFI_ERROR (Status);
+
+ //
+ // Copy OSII[ImageNumber] to buffer
+ //
+ Status = mBootableBlockIo->ReadBlocks (
+ mBootableBlockIo,
+ mBootableBlockIo->Media->MediaId,
+ firstBlock,
+ numBlocks * OSP_BLOCK_SIZE,
+ (VOID *) (UINTN) physAddr
+ );
+
+ if (EFI_ERROR (Status)) {
+ gBS->FreePages (physAddr, numPages);
+ return EFI_DEVICE_ERROR;
+ }
+
+ *ImageBase = physAddr;
+ *NumberOfPages = numPages;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Convert EFI Memory Type to E820 Memory Type.
+
+ @param[in] Type EFI Memory Type
+
+ @retval ACPI Memory Type for EFI Memory Type
+
+**/
+EFI_ACPI_MEMORY_TYPE
+EfiMemoryTypeToE820Type (
+ IN UINT32 Type
+ )
+{
+ switch (Type) {
+ case EfiLoaderCode:
+ case EfiLoaderData:
+ case EfiBootServicesCode:
+ case EfiBootServicesData:
+ case EfiConventionalMemory:
+ case EfiRuntimeServicesCode:
+ case EfiRuntimeServicesData:
+ return EfiAcpiAddressRangeMemory;
+
+ case EfiACPIReclaimMemory:
+ return EfiAcpiAddressRangeACPI;
+
+ case EfiACPIMemoryNVS:
+ return EfiAcpiAddressRangeNVS;
+
+ default:
+ return EfiAcpiAddressRangeReserved;
+ }
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformBdsLib.inf b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformBdsLib.inf
new file mode 100644
index 0000000000..777d5f97a8
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformBdsLib.inf
@@ -0,0 +1,142 @@
+## @file
+# Component name for module PlatformBdsLib.
+#
+# Copyright (c) 2008 - 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
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformBdsLib
+ FILE_GUID = A6BC385D-59E5-4b77-87D7-200ABAA83C15
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformBootManagerLib|DXE_DRIVER
+ EDK_RELEASE_VERSION = 0x00020000
+ EFI_SPECIFICATION_VERSION = 0x0002000A
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ BdsPlatform.c
+ BdsPlatform.h
+ PlatformData.c
+ OsipUtil.c
+ EfiBootStub.c
+
+[Sources.IA32]
+ Ia32/JumpToVector.Asm
+ Ia32/JumpToVector.S
+ Ia32/StartKernel.Asm
+ Ia32/StartKernel.S
+
+[Packages]
+ BroxtonPlatformPkg/PlatformPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+ ShellPkg/ShellPkg.dec
+ CryptoPkg/CryptoPkg.dec
+ SecurityPkg/SecurityPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ GenericBdsLib
+ DevicePathLib
+ UefiLib
+ HobLib
+ PciLib
+ PrintLib
+ BaseCryptLib
+ FileHandleLib
+ DxeServicesLib
+ CpuPlatformLib
+ CustomizedDisplayLib
+ Tcg2PhysicalPresenceLib
+ TcgPhysicalPresenceLib
+ UefiBootManagerLib
+ TimerLib
+
+[Protocols]
+ gEfiFirmwareVolume2ProtocolGuid
+ gEfiSimpleNetworkProtocolGuid
+ gEfiLoadFileProtocolGuid
+ gEfiPciIoProtocolGuid
+ gEfiSmmAccess2ProtocolGuid
+ gEfiDxeSmmReadyToLockProtocolGuid
+ gEfiUserManagerProtocolGuid
+ gEfiDeferredImageLoadProtocolGuid
+ gEfiAcpiS3SaveProtocolGuid
+ gEfiSeCOperationProtocolGuid ## PROTOCOL CONSUMES
+ gEfiSpiProtocolGuid ## PROTOCOL CONSUMES
+ gEfiBlockIoProtocolGuid
+ gEfiSimpleFileSystemProtocolGuid
+ gExitPmAuthProtocolGuid
+ gEfiTdtOperationProtocolGuid
+ gEfiGlobalNvsAreaProtocolGuid
+ gEfiUsbKeyboardConnectGuid
+ gEfiMmioDeviceProtocolGuid
+ gEfiI2cMasterProtocolGuid
+ gEfiI2cHostProtocolGuid
+ gExitPmAuthProtocolGuid
+ gEfiDiskInfoProtocolGuid
+
+[Guids]
+ gEfiEndOfDxeEventGroupGuid
+ gEfiMemoryTypeInformationGuid
+ gEfiSetupVariableGuid
+ gEfiCapsuleVendorGuid
+ gEfiGlobalVariableGuid
+ gEfiNormalSetupGuid
+ gEfiPartTypeSystemPartGuid
+ gEfiAcpi20TableGuid
+ gEfiAcpi10TableGuid
+ gEfiTpmDeviceInstanceTpm12Guid
+ gEfiTpmDeviceInstanceTpm20DtpmGuid
+ gTpmDeviceInstanceTpm20PttPtpGuid
+ gUndiDriverImageGuid
+ gSetupEnterGuid
+ gEfiPhysicalPresenceGuid
+
+[Pcd]
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBRBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvOBBBase
+ gPlatformModuleTokenSpaceGuid.PcdFlashFvIBBMBase
+ gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile
+ gPlatformModuleTokenSpaceGuid.PcdIFWISigBaseAddress
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootState
+ gPlatformModuleTokenSpaceGuid.PcdConnectUSBKeyboardonWaitForKeyStroke
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gPlatformModuleTokenSpaceGuid.PcdBdsDispatchAdditionalOprom
+ gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformData.c b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformData.c
new file mode 100644
index 0000000000..8f619da558
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PlatformBdsLib/PlatformData.c
@@ -0,0 +1,242 @@
+/** @file
+ Defined the platform specific device path which will be used by
+ platform Bbd to perform the platform policy connect.
+
+ Copyright (c) 2006 - 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
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "BdsPlatform.h"
+
+//
+// Predefined platform default time out value
+//
+UINT16 gPlatformBootTimeOutDefault = 10;
+
+//
+// Predefined platform root bridge
+//
+PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0 = {
+ gPciRootBridge,
+ gEndEntire
+};
+
+EFI_DEVICE_PATH_PROTOCOL* gPlatformRootBridges [] = {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gPlatformRootBridge0,
+ NULL
+};
+
+//
+// Platform specific ISA keyboard device path
+//
+PLATFORM_ISA_KEYBOARD_DEVICE_PATH gIsaKeyboardDevicePath = {
+ gPciRootBridge,
+ gPciIsaBridge,
+ gPnpPs2Keyboard,
+ gEndEntire
+};
+
+//
+// Platform specific on chip PCI VGA device path
+//
+PLATFORM_ONBOARD_VGA_DEVICE_PATH gOnChipPciVgaDevicePath = {
+ gPciRootBridge,
+ PCI_DEVICE_PATH_NODE (0, 0x2),
+ gEndEntire
+};
+
+//
+// Platform specific plug in PCI VGA device path
+//
+PLATFORM_OFFBOARD_VGA_DEVICE_PATH gPlugInPciVgaDevicePath = {
+ gPciRootBridge,
+ PCI_DEVICE_PATH_NODE (0, 0x1),
+ PCI_DEVICE_PATH_NODE (0, 0x0),
+ gEndEntire
+};
+
+//
+// Platform specific ISA serial device path
+//
+PLATFORM_ISA_SERIAL_DEVICE_PATH gIsaSerialDevicePath = {
+ gPciRootBridge,
+ gPciIsaBridge,
+ gPnp16550ComPort,
+ gUart (115200, 8, 1, 1),
+ gPcAnsiTerminal,
+ gEndEntire
+};
+
+//
+// Platform specific SPI Uart device path
+//
+PLATFORM_ISA_SERIAL_DEVICE_PATH gSpiDevicePath = {
+ gPciRootBridge,
+ gPciSpiBridge,
+ gPnp16550ComPort,
+ gUart (115200, 8, 1, 1),
+ gPcAnsiTerminal,
+ gEndEntire
+};
+
+USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevicePath = {
+ gUsbKeyboardMouse,
+ gEndEntire
+};
+
+//
+// Predefined platform default console device path
+//
+BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole [] = {
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gSpiDevicePath, (CONSOLE_OUT | CONSOLE_IN)},
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gIsaSerialDevicePath, (CONSOLE_OUT | CONSOLE_IN)},
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gIsaKeyboardDevicePath, CONSOLE_IN},
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath, CONSOLE_IN},
+ {NULL, 0}
+};
+
+//
+// All the possible platform PCI VGA device path
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformAllPossiblePciVgaConsole [] = {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gOnChipPciVgaDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &gPlugInPciVgaDevicePath,
+ NULL
+};
+
+//
+// Legacy hard disk boot option
+//
+LEGACY_HD_DEVICE_PATH gLegacyHd = {
+ {
+ BBS_DEVICE_PATH,
+ BBS_BBS_DP,
+ (UINT8) (sizeof (BBS_BBS_DEVICE_PATH)),
+ (UINT8) ((sizeof (BBS_BBS_DEVICE_PATH)) >> 8),
+ BBS_TYPE_HARDDRIVE,
+ 0,
+ 0
+ },
+ gEndEntire
+};
+
+//
+// Legacy cdrom boot option
+//
+LEGACY_HD_DEVICE_PATH gLegacyCdrom = {
+ {
+ BBS_DEVICE_PATH,
+ BBS_BBS_DP,
+ (UINT8) (sizeof (BBS_BBS_DEVICE_PATH)),
+ (UINT8) ((sizeof (BBS_BBS_DEVICE_PATH)) >> 8),
+ BBS_TYPE_CDROM,
+ 0,
+ 0
+ },
+ gEndEntire
+};
+
+//
+// Predefined platform specific perdict boot option
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformBootOption [] = {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gLegacyHd,
+ (EFI_DEVICE_PATH_PROTOCOL *) &gLegacyCdrom,
+ NULL
+};
+
+EFI_DEVICE_PATH_PROTOCOL* gSerialIoConnect[] = {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gIsaSerialDevicePath,
+ NULL
+};
+
+//
+// Predefined platform specific driver option
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformDriverOption [] = {
+ NULL
+};
+
+//
+// Platform specific SATA controller device path
+//
+PLATFORM_PCI_DEVICE_PATH gSataBootDevPath0 = {
+ gPciRootBridge,
+ PCI_DEVICE_PATH_NODE (0x00, 0x12),
+ gEndEntire
+};
+
+//
+// eMMC device at BDF(0x0, 0x1C, 0x0)
+//
+PLATFORM_PCI_DEVICE_PATH gEmmcBootDevPath0 = {
+ gPciRootBridge,
+ PCI_DEVICE_PATH_NODE (0x00, 0x1C),
+ gEndEntire
+};
+
+//
+// Predefined platform connect sequence
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformConnectSequence [] = {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gPlatformRootBridge0, // Force PCI enumer before Legacy OpROM shadow
+ (EFI_DEVICE_PATH_PROTOCOL *) &gSataBootDevPath0,
+ (EFI_DEVICE_PATH_PROTOCOL *) &gEmmcBootDevPath0,
+ NULL
+};
+
+//
+// Platform specific USB controller device path
+//
+PLATFORM_USB_DEVICE_PATH gUsbDevicePath0 = {
+ gPciRootBridge,
+ PCI_DEVICE_PATH_NODE (0, 0x15),
+ gEndEntire
+};
+
+//
+// Predefined platform device path for user authtication
+//
+EFI_DEVICE_PATH_PROTOCOL* gUserAuthenticationDevice[] = {
+ //
+ // Predefined device path for secure card (USB disk).
+ //
+ (EFI_DEVICE_PATH_PROTOCOL *) &gUsbDevicePath0,
+ NULL
+};
+
+//
+// Predefined platform console device path
+//
+BDS_CONSOLE_CONNECT_ENTRY gPlatformSimpleOnChipPciVgaConOutConsole [] = {
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gOnChipPciVgaDevicePath, CONSOLE_OUT},
+ {NULL, 0}
+};
+
+BDS_CONSOLE_CONNECT_ENTRY gPlatformSimpleUsbConInConsole [] = {
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gUsbClassKeyboardDevicePath, CONSOLE_IN},
+ {NULL, 0}
+};
+
+BDS_CONSOLE_CONNECT_ENTRY gPlatformSimplePs2ConInConsole [] = {
+ {(EFI_DEVICE_PATH_PROTOCOL *) &gIsaKeyboardDevicePath, CONSOLE_IN},
+ {NULL, 0}
+};
+
+//
+// Predefined platform specific perdict boot option
+//
+EFI_DEVICE_PATH_PROTOCOL* gPlatformSimpleBootOption [] = {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gEmmcBootDevPath0,
+ (EFI_DEVICE_PATH_PROTOCOL *) &gSataBootDevPath0,
+ NULL
+};
+