From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by mx.groups.io with SMTP id smtpd.web12.5125.1576631973405397423 for ; Tue, 17 Dec 2019 17:19:33 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: intel.com, ip: 134.134.136.100, mailfrom: nathaniel.l.desimone@intel.com) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Dec 2019 17:19:32 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,327,1571727600"; d="scan'208";a="217987073" Received: from orsmsx106.amr.corp.intel.com ([10.22.225.133]) by orsmga003.jf.intel.com with ESMTP; 17 Dec 2019 17:19:32 -0800 Received: from orsmsx114.amr.corp.intel.com ([169.254.8.106]) by ORSMSX106.amr.corp.intel.com ([169.254.1.81]) with mapi id 14.03.0439.000; Tue, 17 Dec 2019 17:19:32 -0800 From: "Nate DeSimone" To: "Agyeman, Prince" CC: "devel@edk2.groups.io" , "Chiu, Chasel" , "Kubacki, Michael A" Subject: Re: [edk2-platforms] [PATCH 02/11] BoardModulePkg: Add BDS Hook Library Thread-Topic: [edk2-platforms] [PATCH 02/11] BoardModulePkg: Add BDS Hook Library Thread-Index: AQHVsh5hH6eLvNEbvkuN+p4rqnsCKae/pD6A Date: Wed, 18 Dec 2019 01:19:31 +0000 Message-ID: <20191218011925.GA1930@nate-virtualbox> References: <6db8d0100389024cf00c0d1e260ce48cca179d53.1576282834.git.prince.agyeman@intel.com> In-Reply-To: <6db8d0100389024cf00c0d1e260ce48cca179d53.1576282834.git.prince.agyeman@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.7.159.63] MIME-Version: 1.0 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-ID: <2FE1F764E68FDC4C870E4B707EBDC9B0@intel.com> Content-Transfer-Encoding: quoted-printable Hi Prince, Feedback inline. Sat, Dec 14, 2019 at 01:32:28AM +0000, Agyeman, Prince wrote: > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D2336 >=20 > Added a generic board BDS hook library that implements > BDS hook points as defined in the Minimum platform specification. >=20 > This library implements callbacks for the three MinPlatformPkg > BDS event groups, namely gBdsEventBeforeConsoleAfterTrustedConsoleGuid, > gBdsEventBeforeConsoleBeforeEndOfDxeGuid and > gBdsEventAfterConsoleReadyBeforeBootOptionGuid. >=20 > This Library also implements callbacks for pre-existing event groups: > gEfiEndOfDxeEventGroupGuid, gEfiPciEnumerationCompleteProtocolGuid, > gEfiDxeSmmReadyToLockProtocolGuid. >=20 > These callbacks can be registered to their respective event groups, > through other libraries or DXE drivers >=20 > Cc: Michael Kubacki > Cc: Chasel Chiu > Cc: Nate DeSimone >=20 > Signed-off-by: Prince Agyeman > --- > .../Include/Library/BoardBdsHookLib.h | 100 ++ > .../Library/BoardBdsHookLib/BoardBdsHook.h | 211 +++ > .../Library/BoardBdsHookLib/BoardBdsHookLib.c | 1390 +++++++++++++++++ > .../BoardBdsHookLib/BoardBdsHookLib.inf | 95 ++ > .../Library/BoardBdsHookLib/BoardBootOption.c | 598 +++++++ > .../Library/BoardBdsHookLib/BoardMemoryTest.c | 83 + > 6 files changed, 2477 insertions(+) > create mode 100644 Platform/Intel/BoardModulePkg/Include/Library/BoardBd= sHookLib.h > create mode 100644 Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib= /BoardBdsHook.h > create mode 100644 Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib= /BoardBdsHookLib.c > create mode 100644 Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib= /BoardBdsHookLib.inf > create mode 100644 Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib= /BoardBootOption.c > create mode 100644 Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib= /BoardMemoryTest.c >=20 > diff --git a/Platform/Intel/BoardModulePkg/Include/Library/BoardBdsHookLi= b.h b/Platform/Intel/BoardModulePkg/Include/Library/BoardBdsHookLib.h > new file mode 100644 > index 0000000000..ba351b7bf4 > --- /dev/null > +++ b/Platform/Intel/BoardModulePkg/Include/Library/BoardBdsHookLib.h > @@ -0,0 +1,100 @@ > +/** @file > +Header file for BDS Hook Library > + > +Copyright (c) 2019, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef _BDS_HOOK_LIB_H_ > +#define _BDS_HOOK_LIB_H_ Please make the macros match the file name: _BOARD_BDS_HOOK_LIB_H_ > + > +#include > + > + > +/** > + This is the callback function for Bds Ready To Boot event. > + > + @param Event Pointer to this event > + @param Context Event hanlder private data > + > + @retval None. > +**/ > +VOID > +EFIAPI > +BdsReadyToBootCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ); > + > + > +/** > + This is the callback function for Smm Ready To Lock event. > + > + @param[in] Event The Event this notify function registered to. > + @param[in] Context Pointer to the context data registered to the Ev= ent. > +**/ > +VOID > +EFIAPI > +BdsSmmReadyToLockCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ); > + > + > +/** > + This is the callback function for PCI ENUMERATION COMPLETE. > + > + @param[in] Event The Event this notify function registered to. > + @param[in] Context Pointer to the context data registered to the Ev= ent. > +**/ > +VOID > +EFIAPI > +BdsPciEnumCompleteCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ); > + > + > +/** > + Before console after trusted console event callback > + > + @param[in] Event The Event this notify function registered to. > + @param[in] Context Pointer to the context data registered to the Ev= ent. > +**/ > +VOID > +EFIAPI > +BdsBeforeConsoleAfterTrustedConsoleCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ); > + > + > +/** > + Before console before end of DXE event callback > + > + @param[in] Event The Event this notify function registered to. > + @param[in] Context Pointer to the context data registered to the Ev= ent. > +**/ > +VOID > +EFIAPI > +BdsBeforeConsoleBeforeEndOfDxeGuidCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ); > + > + > +/** > + After console ready before boot option event callback > + > + @param[in] Event The Event this notify function registered to. > + @param[in] Context Pointer to the context data registered to the Ev= ent. > +**/ > +VOID > +EFIAPI > +BdsAfterConsoleReadyBeforeBootOptionCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ); > + > +#endif > diff --git a/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardB= dsHook.h b/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardBdsHo= ok.h > new file mode 100644 > index 0000000000..748385499b > --- /dev/null > +++ b/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardBdsHook.= h > @@ -0,0 +1,211 @@ > +/** @file > + Header file for BDS Hook Library > + > +Copyright (c) 2019, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef _BDS_HOOK_H_ > +#define _BDS_HOOK_H_ Please use the same macro name as the file name: _BOARD_BDS_HOOK_H_ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +/// > +/// ConnectType > +/// > +#define CONSOLE_OUT 0x00000001 > +#define STD_ERROR 0x00000002 > +#define CONSOLE_IN 0x00000004 > +#define CONSOLE_ALL (CONSOLE_OUT | CONSOLE_IN | STD_ERROR) > + > +extern EFI_GUID gUefiShellFileGuid; > +extern EFI_BOOT_MODE gBootMode; > + > +#define gPciRootBridge \ > + { \ > + { \ > + ACPI_DEVICE_PATH, \ > + ACPI_DP, \ > + { \ > + (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \ > + (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \ > + }, \ > + }, \ > + EISA_PNP_ID (0x0A03), \ > + 0 \ > + } > + > +#define gEndEntire \ > + { \ > + END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { END_DEVICE_P= ATH_LENGTH, 0 } \ > + } > + > +typedef struct { > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > + UINTN ConnectType; > +} BDS_CONSOLE_CONNECT_ENTRY; > + > +// > +// 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_KEYBOARD_DEVICE_PATH; > + > +typedef struct { > + ACPI_HID_DEVICE_PATH PciRootBridge; > + PCI_DEVICE_PATH PciDevice; > + EFI_DEVICE_PATH_PROTOCOL End; > +} PLATFORM_ONBOARD_CONTROLLER_DEVICE_PATH; > + > +typedef struct { > + ACPI_HID_DEVICE_PATH PciRootBridge; > + PCI_DEVICE_PATH Pci0Device; > + EFI_DEVICE_PATH_PROTOCOL End; > +} PLATFORM_PEG_ROOT_CONTROLLER_DEVICE_PATH; > + > +typedef struct { > + ACPI_HID_DEVICE_PATH PciRootBridge; > + PCI_DEVICE_PATH PciBridge; > + PCI_DEVICE_PATH PciDevice; > + EFI_DEVICE_PATH_PROTOCOL End; > +} PLATFORM_PCI_CONTROLLER_DEVICE_PATH; > + > +// > +// Below is the boot option device path > +// > + > +#define CLASS_HID 3 > +#define SUBCLASS_BOOT 1 > +#define PROTOCOL_KEYBOARD 1 > + > +typedef struct { > + USB_CLASS_DEVICE_PATH UsbClass; > + EFI_DEVICE_PATH_PROTOCOL End; > +} USB_CLASS_FORMAT_DEVICE_PATH; > + > +extern USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyboardDevice= Path; > + > +// > +// Platform BDS Functions > +// > + > + > +/** > + Perform the memory test base on the memory test intensive level, > + and update the memory resource. > + > + @param Level The memory test intensive level. > + > + @retval EFI_STATUS Success test all the system memory and update > + the memory resource > + > +**/ > +EFI_STATUS > +MemoryTest ( > + IN EXTENDMEM_COVERAGE_LEVEL Level > + ); > + > +/** > + Connect with predeined platform connect sequence, > + the OEM/IBV can customize with their own connect sequence. > + > + @param[in] BootMode Boot mode of this boot. > +**/ > +VOID > +ConnectSequence ( > + IN EFI_BOOT_MODE BootMode > + ); > + > + > +/** > + Compares boot priorities of two boot options > + > + @param Left The left boot option > + @param Right The right boot option > + > + @return The difference between the Left and Right > + boot options > + **/ > +INTN > +EFIAPI > +CompareBootOption ( > + CONST VOID *Left, > + CONST VOID *Right > + ); > + > +/** > + This function is called after all the boot options are enumerated and = ordered properly. > +**/ > +VOID > +RegisterStaticHotkey ( > + VOID > + ); > + > + > +/** > + Registers/Unregisters boot option hotkey > + > + @param OptionNumber The boot option number for the key option. > + @param Key The the key input > + @param Add Flag to indicate to add or remove a key > +**/ > +VOID > +RegisterDefaultBootOption ( > + VOID > + ); > + > +#endif > diff --git a/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardB= dsHookLib.c b/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardBd= sHookLib.c > new file mode 100644 > index 0000000000..9d42a8c27f > --- /dev/null > +++ b/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardBdsHookL= ib.c > @@ -0,0 +1,1390 @@ > +/** @file > + This library registers Bds callbacks. It is a default library > + implementation instance of the BDS hook library > + > + Copyright (c) 2019, Intel Corporation. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > + > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > + > +#include "BoardBdsHook.h" > + > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_BOOT_MODE gBootMode; > +BOOLEAN gPPRequireUIConfirm; > +extern UINTN mBootMenuOptionNumber; > + > + > +GLOBAL_REMOVE_IF_UNREFERENCED USB_CLASS_FORMAT_DEVICE_PATH gUsbClassKeyb= oardDevicePath =3D { > + { > + { > + MESSAGING_DEVICE_PATH, > + MSG_USB_CLASS_DP, > + { > + (UINT8) (sizeof (USB_CLASS_DEVICE_PATH)), > + (UINT8) ((sizeof (USB_CLASS_DEVICE_PATH)) >> 8) > + } > + }, > + 0xffff, // VendorId > + 0xffff, // ProductId > + CLASS_HID, // DeviceClass > + SUBCLASS_BOOT, // DeviceSubClass > + PROTOCOL_KEYBOARD // DeviceProtocol > + }, > + gEndEntire > +}; > + > + > +// > +// BDS Platform Functions > +// > +BOOLEAN > +IsMorBitSet ( > + VOID > + ) > +{ > + UINTN MorControl; > + EFI_STATUS Status; > + UINTN DataSize; > + > + // > + // Check if the MOR bit is set. > + // > + DataSize =3D sizeof (MorControl); > + Status =3D gRT->GetVariable ( > + MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME, > + &gEfiMemoryOverwriteControlDataGuid, > + NULL, > + &DataSize, > + &MorControl > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_INFO, " gEfiMemoryOverwriteControlDataGuid doesn't exi= st!!***\n")); > + MorControl =3D 0; > + } else { > + DEBUG ((DEBUG_INFO, " Get the gEfiMemoryOverwriteControlDataGuid =3D= %x!!***\n", MorControl)); > + } > + > + return (BOOLEAN) (MorControl & 0x01); > +} > + > + > +/** > + Prints device paths. > + @param Name The device name. > + @param DevicePath The device path to be printed > +**/ > +VOID > +EFIAPI > +DumpDevicePath ( > + IN CHAR16 *Name, > + IN EFI_DEVICE_PATH *DevicePath > + ) > +{ > + CHAR16 *Str; > + Str =3D ConvertDevicePathToText (DevicePath, TRUE, TRUE); > + DEBUG ((DEBUG_INFO, "%s: %s\n", Name, Str)); > + if (Str !=3D NULL) { > + FreePool (Str); > + } > +} > + > +/** > + Return whether the device is trusted console. > + > + @param Device The device to be tested. > + > + @retval TRUE The device can be trusted. > + @retval FALSE The device cannot be trusted. > +**/ > +BOOLEAN > +IsTrustedConsole ( > + IN CONSOLE_TYPE ConsoleType, > + IN EFI_DEVICE_PATH_PROTOCOL *Device > + ) > +{ > + VOID *TrustedConsoleDevicepath; > + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; > + EFI_DEVICE_PATH_PROTOCOL *Instance; > + UINTN Size; > + EFI_DEVICE_PATH_PROTOCOL *ConsoleDevice; > + > + if (Device =3D=3D NULL) { > + return FALSE; > + } > + > + ConsoleDevice =3D DuplicateDevicePath (Device); > + > + TrustedConsoleDevicepath =3D NULL; > + > + switch (ConsoleType) { > + case ConIn: > + TrustedConsoleDevicepath =3D PcdGetPtr (PcdTrustedConsoleInputDevi= cePath); > + break; > + case ConOut: > + // > + // Check GOP and remove last node > + // > + TempDevicePath =3D ConsoleDevice; > + while (!IsDevicePathEndType (TempDevicePath)) { > + if (DevicePathType (TempDevicePath) =3D=3D ACPI_DEVICE_PATH && > + DevicePathSubType (TempDevicePath) =3D=3D ACPI_ADR_DP) { > + SetDevicePathEndNode (TempDevicePath); > + break; > + } > + TempDevicePath =3D NextDevicePathNode (TempDevicePath); > + } > + > + TrustedConsoleDevicepath =3D PcdGetPtr (PcdTrustedConsoleOutputDev= icePath); > + break; > + default: > + ASSERT (FALSE); > + break; > + } > + > + TempDevicePath =3D TrustedConsoleDevicepath; > + do { > + Instance =3D GetNextDevicePathInstance (&TempDevicePath, &Size); > + if (Instance =3D=3D NULL) { > + break; > + } > + > + if (CompareMem (ConsoleDevice, Instance, Size - END_DEVICE_PATH_LENG= TH) =3D=3D 0) { > + FreePool (Instance); > + FreePool (ConsoleDevice); > + return TRUE; > + } > + > + FreePool (Instance); > + } while (TempDevicePath !=3D NULL); > + > + FreePool (ConsoleDevice); > + > + return FALSE; > +} > + > + > +/** > + Return whether the USB device path is in a short form. > + > + @param DevicePath The device path to be tested. > + > + @retval TRUE The device path is in short form. > + @retval FALSE The device path is not in short form. > +**/ > +BOOLEAN > +IsUsbShortForm ( > + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath > + ) > +{ > + if ((DevicePathType (DevicePath) =3D=3D MESSAGING_DEVICE_PATH) && > + ((DevicePathSubType (DevicePath) =3D=3D MSG_USB_CLASS_DP) || > + (DevicePathSubType (DevicePath) =3D=3D MSG_USB_WWID_DP)) ) { > + return TRUE; > + } > + > + return FALSE; > +} > + > +/** > + Connect the USB short form device path. > + > + @param DevicePath USB short form device path > + > + @retval EFI_SUCCESS Successfully connected the USB device > + @retval EFI_NOT_FOUND Cannot connect the USB device > + @retval EFI_INVALID_PARAMETER The device path is invalid. > +**/ > +EFI_STATUS > +ConnectUsbShortFormDevicePath ( > + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath > + ) > +{ > + EFI_STATUS Status; > + EFI_HANDLE *Handles; > + UINTN HandleCount; > + UINTN Index; > + EFI_PCI_IO_PROTOCOL *PciIo; > + UINT8 Class[3]; > + BOOLEAN AtLeastOneConnected; > + > + // > + // Check the passed in parameters > + // > + if (DevicePath =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (!IsUsbShortForm (DevicePath)) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Find the usb host controller firstly, then connect with the remaini= ng device path > + // > + AtLeastOneConnected =3D FALSE; > + Status =3D gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiPciIoProtocolGuid, > + NULL, > + &HandleCount, > + &Handles > + ); > + for (Index =3D 0; Index < HandleCount; Index++) { > + Status =3D gBS->HandleProtocol ( > + Handles[Index], > + &gEfiPciIoProtocolGuid, > + (VOID **) &PciIo > + ); > + if (!EFI_ERROR (Status)) { > + // > + // Check whether the Pci device is the wanted usb host controller > + // > + Status =3D PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &C= lass); > + if (!EFI_ERROR (Status) && > + ((PCI_CLASS_SERIAL =3D=3D Class[2]) && (PCI_CLASS_SERIAL_USB =3D= =3D Class[1]))) { > + Status =3D gBS->ConnectController ( > + Handles[Index], > + NULL, > + DevicePath, > + FALSE > + ); > + if (!EFI_ERROR(Status)) { > + AtLeastOneConnected =3D TRUE; > + } > + } > + } > + } > + > + return AtLeastOneConnected ? EFI_SUCCESS : EFI_NOT_FOUND; > +} > + > + > +/** > + Return whether the Handle is a vga handle. > + > + @param Handle The handle to be tested. > + > + @retval TRUE The handle is a vga handle. > + @retval FALSE The handle is not a vga handle.. > +**/ > +BOOLEAN > +IsVgaHandle ( > + IN EFI_HANDLE Handle > + ) > +{ > + EFI_PCI_IO_PROTOCOL *PciIo; > + PCI_TYPE00 Pci; > + EFI_STATUS Status; > + > + Status =3D gBS->HandleProtocol ( > + Handle, > + &gEfiPciIoProtocolGuid, > + (VOID **)&PciIo > + ); > + if (!EFI_ERROR (Status)) { > + Status =3D PciIo->Pci.Read ( > + PciIo, > + EfiPciIoWidthUint32, > + 0, > + sizeof (Pci) / sizeof (UINT32), > + &Pci > + ); > + if (!EFI_ERROR (Status)) { > + if (IS_PCI_VGA (&Pci) || IS_PCI_OLD_VGA (&Pci)) { > + return TRUE; > + } > + } > + } > + return FALSE; > +} > + > + > +/** > + Return whether the device path points to a video controller. > + > + @param DevicePath The device path to be tested. > + > + @retval TRUE The device path points to a video controller. > + @retval FALSE The device path does not point to a video controller. > +**/ > +EFI_HANDLE > +IsVideoController ( > + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath > + ) > +{ > + EFI_DEVICE_PATH_PROTOCOL *DupDevicePath; > + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; > + EFI_STATUS Status; > + EFI_HANDLE DeviceHandle; > + > + DupDevicePath =3D DuplicateDevicePath (DevicePath); > + ASSERT (DupDevicePath !=3D NULL); > + if (DupDevicePath =3D=3D NULL) { > + return NULL; > + } > + > + TempDevicePath =3D DupDevicePath; > + Status =3D gBS->LocateDevicePath ( > + &gEfiDevicePathProtocolGuid, > + &TempDevicePath, > + &DeviceHandle > + ); > + FreePool (DupDevicePath); > + if (EFI_ERROR (Status)) { > + return NULL; > + } > + > + if (IsVgaHandle (DeviceHandle)) { > + return DeviceHandle; > + } else { > + return NULL; > + } > +} > + > + > +/** > + Return whether the device path is a GOP device path. > + > + @param DevicePath The device path to be tested. > + > + @retval TRUE The device path is a GOP device path. > + @retval FALSE The device on the device path is not a GOP device path. > +**/ > +BOOLEAN > +IsGopDevicePath ( > + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath > + ) > +{ > + while (!IsDevicePathEndType (DevicePath)) { > + if (DevicePathType (DevicePath) =3D=3D ACPI_DEVICE_PATH && > + DevicePathSubType (DevicePath) =3D=3D ACPI_ADR_DP) { > + return TRUE; > + } > + DevicePath =3D NextDevicePathNode (DevicePath); > + } > + return FALSE; > +} > + > + > +/** > + Remove all GOP device path instance from DevicePath and add the Gop to= the DevicePath. > + > + @param DevicePath The device path to be removed > + @param Gop The device path to be added. > + > + @retval Return The updated device path. > +**/ > +EFI_DEVICE_PATH_PROTOCOL * > +UpdateGopDevicePath ( > + EFI_DEVICE_PATH_PROTOCOL *DevicePath, > + EFI_DEVICE_PATH_PROTOCOL *Gop > + ) > +{ > + UINTN Size; > + UINTN GopSize; > + EFI_DEVICE_PATH_PROTOCOL *Temp; > + EFI_DEVICE_PATH_PROTOCOL *Return; > + EFI_DEVICE_PATH_PROTOCOL *Instance; > + BOOLEAN Exist; > + > + Exist =3D FALSE; > + Return =3D NULL; > + GopSize =3D GetDevicePathSize (Gop); > + do { > + Instance =3D GetNextDevicePathInstance (&DevicePath, &Size); > + if (Instance =3D=3D NULL) { > + break; > + } > + if (!IsGopDevicePath (Instance) || > + (Size =3D=3D GopSize && CompareMem (Instance, Gop, GopSize) =3D= =3D 0) > + ) { > + if (Size =3D=3D GopSize && CompareMem (Instance, Gop, GopSize) =3D= =3D 0) { > + Exist =3D TRUE; > + } > + Temp =3D Return; > + Return =3D AppendDevicePathInstance (Return, Instance); > + if (Temp !=3D NULL) { > + FreePool (Temp); > + } > + } > + FreePool (Instance); > + } while (DevicePath !=3D NULL); > + > + if (!Exist) { > + Temp =3D Return; > + Return =3D AppendDevicePathInstance (Return, Gop); > + if (Temp !=3D NULL) { > + FreePool (Temp); > + } > + } > + return Return; > +} > + > + > +/** > + Get Graphics Controller Handle. > + > + @param NeedTrustedConsole The flag to determine if trusted console > + or non trusted console should be returned > + > + @retval NULL Console not found > + @retval PciHandles Successfully located > +**/ > +EFI_HANDLE > +EFIAPI > +GetGraphicsController ( > + IN BOOLEAN NeedTrustedConsole > + ) > +{ > + EFI_STATUS Status; > + UINTN Index; > + EFI_HANDLE *PciHandles; > + UINTN PciHandlesSize; > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > + > + Status =3D gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiPciIoProtocolGuid, > + NULL, > + &PciHandlesSize, > + &PciHandles > + ); > + if (EFI_ERROR (Status)) { > + return NULL; > + } > + > + for (Index =3D 0; Index < PciHandlesSize; Index++) { > + Status =3D gBS->HandleProtocol ( > + PciHandles[Index], > + &gEfiDevicePathProtocolGuid, > + (VOID **) &DevicePath > + ); > + if (EFI_ERROR(Status)) { > + continue; > + } > + if (!IsVgaHandle (PciHandles[Index])) { > + continue; > + } > + if ((NeedTrustedConsole && IsTrustedConsole (ConOut, DevicePath)) || > + ((!NeedTrustedConsole) && (!IsTrustedConsole (ConOut, DevicePath= )))) { > + return PciHandles[Index]; > + } > + } > + > + return NULL; > +} > + > + > +/** > + Updates Graphic ConOut variable. > + > + @param NeedTrustedConsole The flag that determines if trusted conso= le > + or non trusted console should be returned > +**/ > +VOID > +UpdateGraphicConOut ( > + IN BOOLEAN NeedTrustedConsole > + ) > +{ > + EFI_HANDLE GraphicsControllerHandle; > + EFI_DEVICE_PATH_PROTOCOL *GopDevicePath; > + EFI_DEVICE_PATH_PROTOCOL *ConOutDevicePath; > + EFI_DEVICE_PATH_PROTOCOL *UpdatedConOutDevicePath; > + > + // > + // Update ConOut variable > + // > + GraphicsControllerHandle =3D GetGraphicsController (NeedTrustedConsole= ); > + if (GraphicsControllerHandle !=3D NULL) { > + // > + // Connect the GOP driver > + // > + gBS->ConnectController (GraphicsControllerHandle, NULL, NULL, TRUE); > + > + // > + // Get the GOP device path > + // NOTE: We may get a device path that contains Controller node in i= t. > + // > + GopDevicePath =3D EfiBootManagerGetGopDevicePath (GraphicsController= Handle); > + if (GopDevicePath !=3D NULL) { > + GetEfiGlobalVariable2 (L"ConOut", (VOID **)&ConOutDevicePath, NULL= ); > + UpdatedConOutDevicePath =3D UpdateGopDevicePath (ConOutDevicePath,= GopDevicePath); > + if (ConOutDevicePath !=3D NULL) { > + FreePool (ConOutDevicePath); > + } > + FreePool (GopDevicePath); > + gRT->SetVariable ( > + L"ConOut", > + &gEfiGlobalVariableGuid, > + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_A= CCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS, > + GetDevicePathSize (UpdatedConOutDevicePath), > + UpdatedConOutDevicePath > + ); > + } > + } > +} > + > + > +/** > + The function connects the trusted consoles. > +**/ > +VOID > +ConnectTrustedConsole ( > + VOID > + ) > +{ > + EFI_DEVICE_PATH_PROTOCOL *Consoles; > + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; > + EFI_DEVICE_PATH_PROTOCOL *Instance; > + EFI_DEVICE_PATH_PROTOCOL *Next; > + UINTN Size; > + UINTN Index; > + EFI_HANDLE Handle; > + EFI_STATUS Status; > + CHAR16 *ConsoleVar[] =3D {L"ConIn", L"ConOut"}; > + VOID *TrustedConsoleDevicepath; > + > + TrustedConsoleDevicepath =3D PcdGetPtr (PcdTrustedConsoleInputDevicePa= th); > + DumpDevicePath (L"TrustedConsoleIn", TrustedConsoleDevicepath); > + TrustedConsoleDevicepath =3D PcdGetPtr (PcdTrustedConsoleOutputDeviceP= ath); > + DumpDevicePath (L"TrustedConsoleOut", TrustedConsoleDevicepath); > + > + for (Index =3D 0; Index < sizeof (ConsoleVar) / sizeof (ConsoleVar[0])= ; Index++) { > + > + GetEfiGlobalVariable2 (ConsoleVar[Index], (VOID **)&Consoles, NULL); > + > + TempDevicePath =3D Consoles; > + do { > + Instance =3D GetNextDevicePathInstance (&TempDevicePath, &Size); > + if (Instance =3D=3D NULL) { > + break; > + } > + if (IsTrustedConsole (Index, Instance)) { > + if (IsUsbShortForm (Instance)) { > + ConnectUsbShortFormDevicePath (Instance); > + } else { > + for (Next =3D Instance; !IsDevicePathEnd (Next); Next =3D Next= DevicePathNode (Next)) { > + if (DevicePathType (Next) =3D=3D ACPI_DEVICE_PATH && DeviceP= athSubType (Next) =3D=3D ACPI_ADR_DP) { > + break; > + } else if (DevicePathType (Next) =3D=3D HARDWARE_DEVICE_PATH= && > + DevicePathSubType (Next) =3D=3D HW_CONTROLLER_DP = && > + DevicePathType (NextDevicePathNode (Next)) =3D=3D= ACPI_DEVICE_PATH && > + DevicePathSubType (NextDevicePathNode (Next)) =3D= =3D ACPI_ADR_DP > + ) { > + break; > + } > + } > + if (!IsDevicePathEnd (Next)) { > + SetDevicePathEndNode (Next); > + Status =3D EfiBootManagerConnectDevicePath (Instance, &Handl= e); > + if (!EFI_ERROR (Status)) { > + gBS->ConnectController (Handle, NULL, NULL, TRUE); > + } > + } else { > + EfiBootManagerConnectDevicePath (Instance, NULL); > + } > + } > + } > + FreePool (Instance); > + } while (TempDevicePath !=3D NULL); > + > + if (Consoles !=3D NULL) { > + FreePool (Consoles); > + } > + } > +} > + > + > +/** > + The function connects the trusted Storages. > +**/ > +VOID > +ConnectTrustedStorage ( > + VOID > + ) > +{ > + VOID *TrustedStorageDevicepath; > + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; > + EFI_DEVICE_PATH_PROTOCOL *Instance; > + UINTN Size; > + EFI_DEVICE_PATH_PROTOCOL *TempStorageDevicePath; > + EFI_STATUS Status; > + EFI_HANDLE DeviceHandle; > + > + TrustedStorageDevicepath =3D PcdGetPtr (PcdTrustedStorageDevicePath); > + DumpDevicePath (L"TrustedStorage", TrustedStorageDevicepath); > + > + TempDevicePath =3D TrustedStorageDevicepath; > + do { > + Instance =3D GetNextDevicePathInstance (&TempDevicePath, &Size); > + if (Instance =3D=3D NULL) { > + break; > + } > + > + EfiBootManagerConnectDevicePath (Instance, NULL); > + > + TempStorageDevicePath =3D Instance; > + > + Status =3D gBS->LocateDevicePath ( > + &gEfiDevicePathProtocolGuid, > + &TempStorageDevicePath, > + &DeviceHandle > + ); > + if (!EFI_ERROR (Status)) { > + gBS->ConnectController (DeviceHandle, NULL, NULL, FALSE); > + } > + > + FreePool (Instance); > + } while (TempDevicePath !=3D NULL); > +} > + > + > +/** > + 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; > + BOOLEAN Result; > + EFI_STATUS Status; > + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; > + EFI_DEVICE_PATH_PROTOCOL *LastDeviceNode; > + EFI_GUID *GuidPoint; > + > + BootOption =3D NULL; > + Result =3D FALSE; > + > + // > + // Get BootCurrent variable > + // > + VarSize =3D sizeof (UINT16); > + Status =3D 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", Bo= otCurrent); > + > + GetEfiGlobalVariable2 (BootOptionName, (VOID **) &BootOption, &VarSize= ); > + if (BootOption =3D=3D NULL || VarSize =3D=3D 0) { > + return FALSE; > + } > + > + Ptr =3D BootOption; > + Ptr +=3D sizeof (UINT32); > + Ptr +=3D sizeof (UINT16); > + Ptr +=3D StrSize ((CHAR16 *) Ptr); > + TempDevicePath =3D (EFI_DEVICE_PATH_PROTOCOL *) Ptr; > + LastDeviceNode =3D TempDevicePath; > + while (!IsDevicePathEnd (TempDevicePath)) { > + LastDeviceNode =3D TempDevicePath; > + TempDevicePath =3D NextDevicePathNode (TempDevicePath); > + } > + GuidPoint =3D EfiGetNameGuidFromFwVolDevicePathNode ( > + (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LastDeviceNode > + ); > + if ((GuidPoint !=3D NULL) && > + ((CompareGuid (GuidPoint, &gUefiShellFileGuid)))) { > + // > + // if this option is internal shell, return TRUE > + // > + Result =3D TRUE; > + } > + > + if (BootOption !=3D NULL) { > + FreePool (BootOption); > + BootOption =3D NULL; > + } > + > + return Result; > +} > + > +/** > + This function will change video resolution and text mode > + for internl shell when internal shell is launched. > + > + @param None. > + > + @retval EFI_SUCCESS Mode is changed successfully. > + @retval Others Mode failed to changed. > +**/ > +EFI_STATUS > +EFIAPI > +ChangeModeForInternalShell ( > + VOID > + ) > +{ > + EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; > + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut; > + UINTN SizeOfInfo; > + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; > + UINT32 MaxGopMode; > + UINT32 MaxTextMode; > + UINT32 ModeNumber; > + UINTN HandleCount; > + EFI_HANDLE *HandleBuffer; > + EFI_STATUS Status; > + UINTN Index; > + UINTN CurrentColumn; > + UINTN CurrentRow; > + > + // > + // Internal shell mode > + // > + UINT32 mShellModeColumn; > + UINT32 mShellModeRow; > + UINT32 mShellHorizontalResolution; > + UINT32 mShellVerticalResolution; > + > + > + // > + // Get user defined text mode for internal shell only once. > + // > + mShellHorizontalResolution =3D PcdGet32 (PcdSetupVideoHorizontalResolu= tion); > + mShellVerticalResolution =3D PcdGet32 (PcdSetupVideoVerticalResoluti= on); > + mShellModeColumn =3D PcdGet32 (PcdSetupConOutColumn); > + mShellModeRow =3D PcdGet32 (PcdSetupConOutRow); > + > + > + Status =3D gBS->HandleProtocol ( > + gST->ConsoleOutHandle, > + &gEfiGraphicsOutputProtocolGuid, > + (VOID**)&GraphicsOutput > + ); > + if (EFI_ERROR (Status)) { > + GraphicsOutput =3D NULL; > + } > + > + Status =3D gBS->HandleProtocol ( > + gST->ConsoleOutHandle, > + &gEfiSimpleTextOutProtocolGuid, > + (VOID**)&SimpleTextOut > + ); > + if (EFI_ERROR (Status)) { > + SimpleTextOut =3D NULL; > + } > + > + if ((GraphicsOutput =3D=3D NULL) || (SimpleTextOut =3D=3D NULL)) { > + return EFI_UNSUPPORTED; > + } > + > + MaxGopMode =3D GraphicsOutput->Mode->MaxMode; > + MaxTextMode =3D SimpleTextOut->Mode->MaxMode; > + > + // > + // 1. If current video resolution is same with new video resolution, > + // video resolution need not be changed. > + // 1.1. If current text mode is same with new text mode, text mode = need not be change. > + // 1.2. If current text mode is different with new text mode, text = mode need be change to new text mode. > + // 2. If current video resolution is different with new video resoluti= on, we need restart whole console drivers. > + // > + for (ModeNumber =3D 0; ModeNumber < MaxGopMode; ModeNumber++) { > + Status =3D GraphicsOutput->QueryMode ( > + GraphicsOutput, > + ModeNumber, > + &SizeOfInfo, > + &Info > + ); > + if (!EFI_ERROR (Status)) { > + if ((Info->HorizontalResolution =3D=3D mShellHorizontalResolution)= && > + (Info->VerticalResolution =3D=3D mShellVerticalResolution)) { > + if ((GraphicsOutput->Mode->Info->HorizontalResolution =3D=3D mSh= ellHorizontalResolution) && > + (GraphicsOutput->Mode->Info->VerticalResolution =3D=3D mShellV= erticalResolution)) { > + // > + // If current video resolution is same with new resolution, > + // then check if current text mode is same with new text mode. > + // > + Status =3D SimpleTextOut->QueryMode (SimpleTextOut, SimpleText= Out->Mode->Mode, &CurrentColumn, &CurrentRow); > + ASSERT_EFI_ERROR (Status); > + if (CurrentColumn =3D=3D mShellModeColumn && CurrentRow =3D=3D= mShellModeRow) { > + // > + // Current text mode is same with new text mode, text mode n= eed not be change. > + // > + FreePool (Info); > + return EFI_SUCCESS; > + } else { > + // > + // Current text mode is different with new text mode, text m= ode need be change to new text mode. > + // > + for (Index =3D 0; Index < MaxTextMode; Index++) { > + Status =3D SimpleTextOut->QueryMode (SimpleTextOut, Index,= &CurrentColumn, &CurrentRow); > + if (!EFI_ERROR(Status)) { > + if ((CurrentColumn =3D=3D mShellModeColumn) && (CurrentR= ow =3D=3D mShellModeRow)) { > + // > + // New text mode is supported, set it. > + // > + Status =3D SimpleTextOut->SetMode (SimpleTextOut, Inde= x); > + ASSERT_EFI_ERROR (Status); > + // > + // Update text mode PCD. > + // > + Status =3D PcdSet32S (PcdConOutColumn, mShellModeColum= n); > + ASSERT_EFI_ERROR (Status); > + > + Status =3D PcdSet32S (PcdConOutRow, mShellModeRow); > + ASSERT_EFI_ERROR (Status); > + > + FreePool (Info); > + return EFI_SUCCESS; > + } > + } > + } > + if (Index =3D=3D MaxTextMode) { > + // > + // If new text mode is not supported, return error. > + // > + FreePool (Info); > + return EFI_UNSUPPORTED; > + } > + } > + } else { > + FreePool (Info); > + // > + // If current video resolution is not same with the new one, s= et new video resolution. > + // In this case, the driver which produces simple text out nee= d be restarted. > + // > + Status =3D GraphicsOutput->SetMode (GraphicsOutput, ModeNumber= ); > + if (!EFI_ERROR (Status)) { > + // > + // Set PCD to restart GraphicsConsole and Consplitter to cha= nge video resolution > + // and produce new text mode based on new resolution. > + // > + Status =3D PcdSet32S (PcdVideoHorizontalResolution, mShellHo= rizontalResolution); > + ASSERT_EFI_ERROR (Status); > + > + Status =3D PcdSet32S (PcdVideoVerticalResolution, mShellVert= icalResolution); > + ASSERT_EFI_ERROR (Status); > + > + Status =3D PcdSet32S (PcdConOutColumn, mShellModeColumn); > + ASSERT_EFI_ERROR (Status); > + > + Status =3D PcdSet32S (PcdConOutRow, mShellModeRow); > + ASSERT_EFI_ERROR (Status); > + > + Status =3D gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiSimpleTextOutProtocolGuid, > + NULL, > + &HandleCount, > + &HandleBuffer > + ); > + if (!EFI_ERROR (Status)) { > + for (Index =3D 0; Index < HandleCount; Index++) { > + gBS->DisconnectController (HandleBuffer[Index], NULL, NU= LL); > + } > + for (Index =3D 0; Index < HandleCount; Index++) { > + gBS->ConnectController (HandleBuffer[Index], NULL, NULL,= TRUE); > + } > + if (HandleBuffer !=3D NULL) { > + FreePool (HandleBuffer); > + } > + break; > + } > + } > + } > + } > + FreePool (Info); > + } > + } > + > + if (ModeNumber =3D=3D MaxGopMode) { > + // > + // If the new resolution is not supported, return error. > + // > + return EFI_UNSUPPORTED; > + } > + > + return EFI_SUCCESS; > +} > + > + > +/** > + The function connects the trusted consoles and then call the PP proces= sing library interface. > +**/ > +VOID > +ProcessTcgPp ( > + VOID > + ) > +{ > + gPPRequireUIConfirm |=3D Tcg2PhysicalPresenceLibNeedUserConfirm(); > + > + if (gPPRequireUIConfirm) { > + ConnectTrustedConsole (); > + } > + > + Tcg2PhysicalPresenceLibProcessRequest (NULL); > +} > + > + > +/** > + The function connects the trusted storage to perform TPerReset. > +**/ > +VOID > +ProcessTcgMor ( > + VOID > + ) > +{ > + if (IsMorBitSet ()) { > + ConnectTrustedConsole(); > + ConnectTrustedStorage(); > + } > +} > + > + > +/** > + Update the ConIn variable with USB Keyboard device path,if its not alr= eady exists in ConIn > +**/ > +VOID > +EnumUsbKeyboard ( > + VOID > + ) > +{ > + DEBUG ((DEBUG_INFO, "[EnumUsbKeyboard]\n")); > + EfiBootManagerUpdateConsoleVariable (ConIn, (EFI_DEVICE_PATH_PROTOCOL = *) &gUsbClassKeyboardDevicePath, NULL); > + // > + // Append Usb Keyboard short form DevicePath into "ConInDev" > + // > + EfiBootManagerUpdateConsoleVariable (ConInDev, (EFI_DEVICE_PATH_PROTOC= OL *) &gUsbClassKeyboardDevicePath, NULL); > +} > + > + > +/** > + Connect with predeined platform connect sequence, > + the OEM/IBV can customize with their own connect sequence. > + > + @param[in] BootMode Boot mode of this boot. > +**/ > +VOID > +ConnectSequence ( > + IN EFI_BOOT_MODE BootMode > + ) > +{ > + EfiBootManagerConnectAll (); > +} > + > + > +/** > + The function is to consider the boot order which is not in our expecta= tion. > + In the case that we need to re-sort the boot option. > + > + @retval TRUE Need to sort Boot Option. > + @retval FALSE Don't need to sort Boot Option. > +**/ > +BOOLEAN > +IsNeedSortBootOption ( > + VOID > + ) > +{ > + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; > + UINTN BootOptionCount; > + > + BootOptions =3D EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOp= tionTypeBoot); > + > + // > + // If setup is the first priority in boot option, we need to sort boot= option. > + // > + if ((BootOptionCount > 1) && > + (((StrnCmp (BootOptions->Description, L"Enter Setup", StrLen (L"Ente= r Setup"))) =3D=3D 0) || > + ((StrnCmp (BootOptions->Description, L"BootManagerMenuApp", StrLen (= L"BootManagerMenuApp"))) =3D=3D 0))) { > + return TRUE; > + } > + > + return FALSE; > +} > + > + > +/** > + Connects Root Bridge > + **/ > +VOID > +ConnectRootBridge ( > + BOOLEAN Recursive > + ) > +{ > + UINTN RootBridgeHandleCount; > + EFI_HANDLE *RootBridgeHandleBuffer; > + UINTN RootBridgeIndex; > + > + RootBridgeHandleCount =3D 0; > + gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiPciRootBridgeIoProtocolGuid, > + NULL, > + &RootBridgeHandleCount, > + &RootBridgeHandleBuffer > + ); > + for (RootBridgeIndex =3D 0; RootBridgeIndex < RootBridgeHandleCount; R= ootBridgeIndex++) { > + gBS->ConnectController (RootBridgeHandleBuffer[RootBridgeIndex], NUL= L, NULL, Recursive); > + } > +} > + > +VOID > +AddConsoleVariable ( > + IN CONSOLE_TYPE ConsoleType, > + IN EFI_DEVICE_PATH *ConsoleDevicePath > + ) > +{ > + EFI_DEVICE_PATH *TempDevicePath; > + EFI_DEVICE_PATH *Instance; > + UINTN Size; > + EFI_HANDLE GraphicsControllerHandle; > + EFI_DEVICE_PATH *GopDevicePath; > + > + TempDevicePath =3D ConsoleDevicePath; > + do { > + Instance =3D GetNextDevicePathInstance (&TempDevicePath, &Size); > + if (Instance =3D=3D NULL) { > + break; > + } > + > + switch (ConsoleType) { > + case ConIn: > + if (IsUsbShortForm (Instance)) { > + // > + // Append Usb Keyboard short form DevicePath into "ConInDev" > + // > + EfiBootManagerUpdateConsoleVariable (ConInDev, Instance, NULL)= ; > + } > + EfiBootManagerUpdateConsoleVariable (ConsoleType, Instance, NULL= ); > + break; > + case ConOut: > + GraphicsControllerHandle =3D IsVideoController (Instance); > + if (GraphicsControllerHandle =3D=3D NULL) { > + EfiBootManagerUpdateConsoleVariable (ConsoleType, Instance, NU= LL); > + } else { > + // > + // Connect the GOP driver > + // > + gBS->ConnectController (GraphicsControllerHandle, NULL, NULL, = TRUE); > + // > + // Get the GOP device path > + // NOTE: We may get a device path that contains Controller nod= e in it. > + // > + GopDevicePath =3D EfiBootManagerGetGopDevicePath (GraphicsCont= rollerHandle); > + if (GopDevicePath !=3D NULL) { > + EfiBootManagerUpdateConsoleVariable (ConsoleType, GopDeviceP= ath, NULL); > + } > + } > + break; > + default: > + ASSERT(FALSE); > + break; > + } > + > + FreePool (Instance); > + } while (TempDevicePath !=3D NULL); > +} > + > + > +/** > + This is the callback function for PCI ENUMERATION COMPLETE. > + > + @param[in] Event The Event this notify function registered to. > + @param[in] Context Pointer to the context data registered to the Ev= ent. > +**/ > +VOID > +EFIAPI > +BdsPciEnumCompleteCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + EFI_STATUS Status; > + VOID *ProtocolPointer; > + EFI_DEVICE_PATH_PROTOCOL *VarConOut; > + EFI_DEVICE_PATH_PROTOCOL *VarConIn; > + > + Status =3D EFI_SUCCESS; > + > + // > + // Check if this is first time called by EfiCreateProtocolNotifyEvent(= ) or not, > + // if it is, we will skip it until real event is triggered > + // > + Status =3D gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGui= d, NULL, (VOID **) &ProtocolPointer); > + if (EFI_SUCCESS !=3D Status) { > + return; > + } > + //gBS->CloseEvent (Event); > + > + > + DEBUG ((DEBUG_INFO, "Event BdsPciEnumCompleteCallback callback starts\= n")); > + > + gBootMode =3D GetBootModeHob (); > + > + // > + // Connect Root Bridge to make PCI BAR resource allocated and all PciI= o created > + // > + ConnectRootBridge (FALSE); > + > + // > + // Fill ConIn/ConOut in Full Configuration boot mode > + // > + DEBUG ((DEBUG_INFO, "PlatformBootManagerInit - %x\n", gBootMode)); > + > + > + if (gBootMode =3D=3D BOOT_WITH_FULL_CONFIGURATION || > + gBootMode =3D=3D BOOT_WITH_DEFAULT_SETTINGS || > + gBootMode =3D=3D BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS || > + gBootMode =3D=3D BOOT_IN_RECOVERY_MODE) { > + > + GetEfiGlobalVariable2 (L"ConOut", (VOID **)&VarConOut, NULL); > + if (VarConOut !=3D NULL) { > + FreePool (VarConOut); > + } > + > + GetEfiGlobalVariable2 (L"ConIn", (VOID **)&VarConIn, NULL); > + if (VarConIn !=3D NULL) { > + FreePool (VarConIn); > + } > + > + // > + // Only fill ConIn/ConOut when ConIn/ConOut is empty because we may = drop to Full Configuration boot mode in non-first boot > + // > + if (VarConOut =3D=3D NULL || VarConIn =3D=3D NULL) { > + if (PcdGetSize (PcdTrustedConsoleOutputDevicePath) >=3D sizeof(EFI= _DEVICE_PATH_PROTOCOL)) { > + AddConsoleVariable (ConOut, PcdGetPtr (PcdTrustedConsoleOutputDe= vicePath)); > + } > + if (PcdGetSize (PcdTrustedConsoleInputDevicePath) >=3D sizeof(EFI_= DEVICE_PATH_PROTOCOL)) { > + AddConsoleVariable (ConIn, PcdGetPtr (PcdTrustedConsoleInputDevi= cePath)); > + } > + } > + } > + > +} > + > +/** > + This is the callback function for Smm Ready To Lock. > + > + @param[in] Event The Event this notify function registered to. > + @param[in] Context Pointer to the context data registered to the Ev= ent. > +**/ > +VOID > +EFIAPI > +BdsSmmReadyToLockCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + VOID *ProtocolPointer; > + EFI_STATUS Status; > + // > + // Check if this is first time called by EfiCreateProtocolNotifyEvent(= ) or not, > + // if it is, we will skip it until real event is triggered > + // > + Status =3D gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NU= LL, (VOID **) &ProtocolPointer); > + if (EFI_SUCCESS !=3D Status) { > + return; > + } > + > + DEBUG ((DEBUG_INFO, "Event gEfiDxeSmmReadyToLockProtocolGuid callback = starts\n")); > + > + // > + // Dispatch the deferred 3rd party images. > + // > + EfiBootManagerDispatchDeferredImages (); > + > + // > + // For non-trusted console it must be handled here. > + // > + UpdateGraphicConOut (FALSE); > +} > + > +/** > + ReadyToBoot callback to set video and text mode for internal shell boo= t. > + That will not connect USB controller while CSM and FastBoot are disabl= ed, we need to connect them > + before booting to Shell for showing USB devices in Shell. > + > + When FastBoot is enabled and Windows Console is the chosen Console beh= avior, input devices will not be connected > + by default. Hence, when booting to EFI shell, connecting input console= s are required. > + > + @param Event Pointer to this event > + @param Context Event hanlder private data > + > + @retval None. > +**/ > +VOID > +EFIAPI > +BdsReadyToBootCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + DEBUG ((DEBUG_INFO, "BdsReadyToBootCallback\n")); > + > + if (BootCurrentIsInternalShell ()) { > + > + ChangeModeForInternalShell (); > + EfiBootManagerConnectAllDefaultConsoles (); > + gDS->Dispatch (); > + } > +} > + > + > +/** > + Before console after trusted console event callback > + > + @param[in] Event The Event this notify function registered to. > + @param[in] Context Pointer to the context data registered to the Ev= ent. > +**/ > +VOID > +BdsBeforeConsoleAfterTrustedConsoleCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + DEBUG ((DEBUG_INFO, "Event gBdsEventBeforeConsoleBeforeEndOfDxeGuid ca= llback starts\n")); > + > + // > + // Enumerate USB keyboard > + // > + EnumUsbKeyboard (); > + > + // > + // For trusted console it must be handled here. > + // > + UpdateGraphicConOut (TRUE); > + > + // > + // Register Boot Options > + // > + RegisterDefaultBootOption (); > + > + // > + // Register Static Hot keys > + // > + RegisterStaticHotkey (); > + > + // > + // Process Physical Preo > + // > + PERF_START_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7010); > + if (PcdGetBool (PcdTpm2Enable)) { > + ProcessTcgPp (); > + ProcessTcgMor (); > + } > + PERF_END_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7011); > + > + // > + // Perform memory test > + // We should make all UEFI memory and GCD information populated before= ExitPmAuth. > + // SMM may consume these information. > + // > + MemoryTest((EXTENDMEM_COVERAGE_LEVEL) PcdGet32 (PcdPlatformMemoryCheck= Level)); > +} > + > + > +/** > + Before console before end of DXE event callback > + > + @param[in] Event The Event this notify function registered to. > + @param[in] Context Pointer to the context data registered to the Ev= ent. > +**/ > +VOID > +BdsBeforeConsoleBeforeEndOfDxeGuidCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + DEBUG ((DEBUG_INFO, "Event gBdsBeforeConsoleBeforeEndOfDxeGuid callbac= k starts\n")); > + > +} > + > + > +/** > + After console ready before boot option event callback > + > + @param[in] Event The Event this notify function registered to. > + @param[in] Context Pointer to the context data registered to the Ev= ent. > +**/ > +VOID > +BdsAfterConsoleReadyBeforeBootOptionCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + EFI_BOOT_MODE LocalBootMode; > + > + DEBUG ((DEBUG_INFO, "Event gBdsAfterConsoleReadyBeforeBootOptionEvent = callback starts\n")); > + // > + // Get current Boot Mode > + // > + LocalBootMode =3D gBootMode; > + DEBUG ((DEBUG_INFO, "Current local bootmode - %x\n", LocalBootMode)); > + > + // > + // Go the different platform policy with different boot mode > + // Notes: this part code can be change with the table policy > + // > + switch (LocalBootMode) { > + case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES: > + case BOOT_WITH_MINIMAL_CONFIGURATION: > + case BOOT_ON_S4_RESUME: > + // > + // Perform some platform specific connect sequence > + // > + PERF_START_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7050); > + ConnectSequence (LocalBootMode); > + PERF_END_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7051); > + > + break; > + > + case BOOT_WITH_FULL_CONFIGURATION: > + case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS: > + case BOOT_WITH_DEFAULT_SETTINGS: > + default: > + // > + // Perform some platform specific connect sequence > + // > + ConnectSequence (LocalBootMode); > + > + // > + // Only in Full Configuration boot mode we do the enumeration of b= oot device > + // > + // > + // Dispatch all but Storage Oprom explicitly, because we assume In= t13Thunk driver is there. > + // > + > + // > + // PXE boot option may appear after boot option enumeration > + // > + break; > + } > + > + Print (L"Press F7 for BootMenu!\n"); > + > + EfiBootManagerRefreshAllBootOption (); > + > + if (IsNeedSortBootOption()) { > + EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, CompareBoo= tOption); > + } > +} > diff --git a/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardB= dsHookLib.inf b/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/Board= BdsHookLib.inf > new file mode 100644 > index 0000000000..69f3fcb552 > --- /dev/null > +++ b/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardBdsHookL= ib.inf > @@ -0,0 +1,95 @@ > +### @file > +# Module Information file for the Bds Hook Library. > +# > +# Copyright (c) 2019, Intel Corporation. All rights reserved.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +### > + > +[Defines] > + INF_VERSION =3D 0x00010017 > + BASE_NAME =3D BoardBdsHookLib > + FILE_GUID =3D 649A7502-7301-4E3A-A99B-EA91AD6DD7A= 8 > + VERSION_STRING =3D 1.0 > + MODULE_TYPE =3D DXE_DRIVER > + LIBRARY_CLASS =3D BoardBdsHookLib|DXE_DRIVER > + > +[LibraryClasses] > + BaseLib > + MemoryAllocationLib > + UefiBootServicesTableLib > + UefiRuntimeServicesTableLib > + BaseMemoryLib > + DebugLib > + PcdLib > + PrintLib > + DevicePathLib > + UefiLib > + HobLib > + DxeServicesLib > + DxeServicesTableLib > + HiiLib > + UefiBootManagerLib > + PerformanceLib > + TimerLib > + Tcg2PhysicalPresenceLib > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + SecurityPkg/SecurityPkg.dec > + MinPlatformPkg/MinPlatformPkg.dec > + BoardModulePkg/BoardModulePkg.dec > + > +[Pcd] > + gMinPlatformPkgTokenSpaceGuid.PcdTpm2Enable ## C= ONSUMES > + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut ## P= RODUCES > + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution ## P= RODUCES > + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution ## P= RODUCES > + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow ## P= RODUCES > + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn ## P= RODUCES > + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutColumn ## C= ONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupConOutRow ## C= ONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution ## C= ONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution ## C= ONSUMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand ## P= RODUCES > + gMinPlatformPkgTokenSpaceGuid.PcdPlatformMemoryCheckLevel ## C= ONSUMES > + gMinPlatformPkgTokenSpaceGuid.PcdBootToShellOnly ## C= ONSUMES > + gMinPlatformPkgTokenSpaceGuid.PcdTrustedConsoleInputDevicePath ## C= ONSUMES > + gMinPlatformPkgTokenSpaceGuid.PcdTrustedConsoleOutputDevicePath ## C= ONSUMES > + gMinPlatformPkgTokenSpaceGuid.PcdTrustedStorageDevicePath ## C= ONSUMES > + > +[Sources] > + BoardBdsHook.h > + BoardBdsHookLib.c > + BoardMemoryTest.c > + BoardBootOption.c > + > +[Protocols] > + gEfiPciRootBridgeIoProtocolGuid ## CONSUMES > + gEfiPciIoProtocolGuid ## CONSUMES > + gEfiCpuIo2ProtocolGuid ## CONSUMES > + gEfiDxeSmmReadyToLockProtocolGuid ## PRODUCES > + gEfiGenericMemTestProtocolGuid ## CONSUMES > + gEfiDiskInfoProtocolGuid ## CONSUMES > + gEfiDevicePathToTextProtocolGuid ## CONSUMES > + gEfiSimpleTextInputExProtocolGuid ## CONSUMES > + gEfiFirmwareVolume2ProtocolGuid ## CONSUMES > + gEfiFormBrowser2ProtocolGuid ## CONSUMES > + gEfiGenericMemTestProtocolGuid ## CONSUMES > + gEfiDxeSmmReadyToLockProtocolGuid > + > +[Guids] > + gEfiGlobalVariableGuid ## PRODUCES > + gEfiMemoryOverwriteControlDataGuid ## PRODUCES > + gEfiEndOfDxeEventGroupGuid ## CONSUMES > + gBdsEventBeforeConsoleAfterTrustedConsoleGuid > + gBdsEventBeforeConsoleBeforeEndOfDxeGuid > + gBdsEventAfterConsoleReadyBeforeBootOptionGuid > + > +[Depex.common.DXE_DRIVER] > + gEfiVariableArchProtocolGuid > + > +[Depex] > + TRUE > diff --git a/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardB= ootOption.c b/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardBo= otOption.c > new file mode 100644 > index 0000000000..87138bdd79 > --- /dev/null > +++ b/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardBootOpti= on.c > @@ -0,0 +1,598 @@ > +/** @file > + Driver for Platform Boot Options support. > + > +Copyright (c) 2019, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "BoardBdsHook.h" > + > +BOOLEAN mContinueBoot =3D FALSE; > +BOOLEAN mBootMenuBoot =3D FALSE; > +BOOLEAN mPxeBoot =3D FALSE; > +BOOLEAN mHotKeypressed =3D FALSE; > +EFI_EVENT HotKeyEvent =3D NULL; > + > +UINTN mBootMenuOptionNumber; > + > + > +/** > + This function will create a SHELL BootOption to boot. > + > + @return Shell Device path for booting. > +**/ > +EFI_DEVICE_PATH_PROTOCOL * > +BdsCreateShellDevicePath ( > + VOID > + ) > +{ > + UINTN FvHandleCount; > + EFI_HANDLE *FvHandleBuffer; > + UINTN Index; > + EFI_STATUS Status; > + EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; > + UINTN Size; > + UINT32 AuthenticationStatus; > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > + VOID *Buffer; > + > + DevicePath =3D NULL; > + Status =3D EFI_SUCCESS; > + > + DEBUG ((DEBUG_INFO, "BdsCreateShellDevicePath\n")); > + gBS->LocateHandleBuffer ( > + ByProtocol, > + &gEfiFirmwareVolume2ProtocolGuid, > + NULL, > + &FvHandleCount, > + &FvHandleBuffer > + ); > + > + for (Index =3D 0; Index < FvHandleCount; Index++) { > + gBS->HandleProtocol ( > + FvHandleBuffer[Index], > + &gEfiFirmwareVolume2ProtocolGuid, > + (VOID **) &Fv > + ); > + > + Buffer =3D NULL; > + Size =3D 0; > + Status =3D Fv->ReadSection ( > + Fv, > + &gUefiShellFileGuid, > + EFI_SECTION_PE32, > + 0, > + &Buffer, > + &Size, > + &AuthenticationStatus > + ); > + if (EFI_ERROR (Status)) { > + // > + // Skip if no shell file in the FV > + // > + continue; > + } else { > + // > + // Found the shell > + // > + break; > + } > + } > + > + if (EFI_ERROR (Status)) { > + // > + // No shell present > + // > + if (FvHandleCount) { > + FreePool (FvHandleBuffer); > + } > + return NULL; > + } > + // > + // Build the shell boot option > + // > + DevicePath =3D DevicePathFromHandle (FvHandleBuffer[Index]); > + > + if (FvHandleCount) { > + FreePool (FvHandleBuffer); > + } > + > + return DevicePath; > +} > + > + > +EFI_STATUS > +CreateFvBootOption ( > + EFI_GUID *FileGuid, > + CHAR16 *Description, > + EFI_BOOT_MANAGER_LOAD_OPTION *BootOption, > + UINT32 Attributes, > + UINT8 *OptionalData, OPTIONAL > + UINT32 OptionalDataSize > + ) > +{ > + EFI_STATUS Status; > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; > + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; > + EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; > + UINT32 AuthenticationStatus; > + VOID *Buffer; > + UINTN Size; > + > + if ((BootOption =3D=3D NULL) || (FileGuid =3D=3D NULL) || (Description= =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); > + > + if (!CompareGuid (&gUefiShellFileGuid, FileGuid)) { > + Status =3D gBS->HandleProtocol ( > + gImageHandle, > + &gEfiLoadedImageProtocolGuid, > + (VOID **) &LoadedImage > + ); > + if (!EFI_ERROR (Status)) { > + Status =3D gBS->HandleProtocol ( > + LoadedImage->DeviceHandle, > + &gEfiFirmwareVolume2ProtocolGuid, > + (VOID **) &Fv > + ); > + if (!EFI_ERROR (Status)) { > + Buffer =3D NULL; > + Size =3D 0; > + Status =3D Fv->ReadSection ( > + Fv, > + FileGuid, > + EFI_SECTION_PE32, > + 0, > + &Buffer, > + &Size, > + &AuthenticationStatus > + ); > + if (Buffer !=3D NULL) { > + FreePool (Buffer); > + } > + } > + } > + if (EFI_ERROR (Status)) { > + return EFI_NOT_FOUND; > + } > + > + DevicePath =3D AppendDevicePathNode ( > + DevicePathFromHandle (LoadedImage->DeviceHandle), > + (EFI_DEVICE_PATH_PROTOCOL *) &FileNode > + ); > + } else { > + DevicePath =3D AppendDevicePathNode ( > + BdsCreateShellDevicePath (), > + (EFI_DEVICE_PATH_PROTOCOL *) &FileNode > + ); > + } > + > + Status =3D EfiBootManagerInitializeLoadOption ( > + BootOption, > + LoadOptionNumberUnassigned, > + LoadOptionTypeBoot, > + Attributes, > + Description, > + DevicePath, > + OptionalData, > + OptionalDataSize > + ); > + FreePool (DevicePath); > + return Status; > +} > + > +EFI_GUID mUiFile =3D { > + 0x462CAA21, 0x7614, 0x4503, { 0x83, 0x6E, 0x8A, 0xB6, 0xF4, 0x66, 0x23= , 0x31 } > +}; > +EFI_GUID mBootMenuFile =3D { > + 0xEEC25BDC, 0x67F2, 0x4D95, { 0xB1, 0xD5, 0xF8, 0x1B, 0x20, 0x39, 0xD1= , 0x1D } > +}; > + > + > +/** > + Return the index of the load option in the load option array. > + > + The function consider two load options are equal when the > + OptionType, Attributes, Description, FilePath and OptionalData are equ= al. > + > + @param Key Pointer to the load option to be found. > + @param Array Pointer to the array of load options to be found. > + @param Count Number of entries in the Array. > + > + @retval -1 Key wasn't found in the Array. > + @retval 0 ~ Count-1 The index of the Key in the Array. > +**/ > +INTN > +PlatformFindLoadOption ( > + IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Key, > + IN CONST EFI_BOOT_MANAGER_LOAD_OPTION *Array, > + IN UINTN Count > + ) > +{ > + UINTN Index; > + > + for (Index =3D 0; Index < Count; Index++) { > + if ((Key->OptionType =3D=3D Array[Index].OptionType) && > + (Key->Attributes =3D=3D Array[Index].Attributes) && > + (StrCmp (Key->Description, Array[Index].Description) =3D=3D 0) &= & > + (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePath= Size (Key->FilePath)) =3D=3D 0) && > + (Key->OptionalDataSize =3D=3D Array[Index].OptionalDataSize) && > + (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->= OptionalDataSize) =3D=3D 0)) { > + return (INTN) Index; > + } > + } > + > + return -1; > +} > + > + > +/** > + Registers a boot option > + > + @param FileGuid Boot file GUID > + @param Description Boot option discription > + @param Position Position of the new load option to put i= n the ****Order variable. > + @param Attributes Boot option attributes > + @param OptionalData Optional data of the boot option. > + @param OptionalDataSize Size of the optional data of the boot op= tion > + > + @return boot option number > +**/ > +UINTN > +RegisterFvBootOption ( > + EFI_GUID *FileGuid, > + CHAR16 *Description, > + UINTN Position, > + UINT32 Attributes, > + UINT8 *OptionalData, OPTIONAL > + UINT32 OptionalDataSize > + ) > +{ > + EFI_STATUS Status; > + UINTN OptionIndex; > + EFI_BOOT_MANAGER_LOAD_OPTION NewOption; > + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; > + UINTN BootOptionCount; > + > + NewOption.OptionNumber =3D LoadOptionNumberUnassigned; > + Status =3D CreateFvBootOption (FileGuid, Description, &NewOption, Attr= ibutes, OptionalData, OptionalDataSize); > + if (!EFI_ERROR (Status)) { > + BootOptions =3D EfiBootManagerGetLoadOptions (&BootOptionCount, Load= OptionTypeBoot); > + > + OptionIndex =3D PlatformFindLoadOption (&NewOption, BootOptions, Boo= tOptionCount); > + > + if (OptionIndex =3D=3D -1) { > + Status =3D EfiBootManagerAddLoadOptionVariable (&NewOption, Positi= on); > + ASSERT_EFI_ERROR (Status); > + } else { > + NewOption.OptionNumber =3D BootOptions[OptionIndex].OptionNumber; > + } > + EfiBootManagerFreeLoadOption (&NewOption); > + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); > + } > + > + return NewOption.OptionNumber; > +} > + > + > +/** > + Boot manager wait callback > + > + @param TimeoutRemain The remaingin timeout period > +**/ > +VOID > +EFIAPI > +PlatformBootManagerWaitCallback ( > + UINT16 TimeoutRemain > + ) > +{ > + EFI_STATUS Status; > + EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *TxtInEx; > + EFI_KEY_DATA KeyData; > + BOOLEAN PausePressed; > + > + // > + // Pause on PAUSE key > + // > + Status =3D gBS->HandleProtocol (gST->ConsoleInHandle, &gEfiSimpleTextI= nputExProtocolGuid, (VOID **) &TxtInEx); > + ASSERT_EFI_ERROR (Status); > + > + PausePressed =3D FALSE; > + > + while (TRUE) { > + Status =3D TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData); > + if (EFI_ERROR (Status)) { > + break; > + } > + > + if (KeyData.Key.ScanCode =3D=3D SCAN_PAUSE) { > + PausePressed =3D TRUE; > + break; > + } > + } > + > + // > + // Loop until non-PAUSE key pressed > + // > + while (PausePressed) { > + Status =3D TxtInEx->ReadKeyStrokeEx (TxtInEx, &KeyData); > + if (!EFI_ERROR (Status)) { > + DEBUG (( > + DEBUG_INFO, "[PauseCallback] %x/%x %x/%x\n", > + KeyData.Key.ScanCode, KeyData.Key.UnicodeChar, > + KeyData.KeyState.KeyShiftState, KeyData.KeyState.KeyToggleState > + )); > + PausePressed =3D (BOOLEAN) (KeyData.Key.ScanCode =3D=3D SCAN_PAUSE= ); > + } > + } > +} > + > + > +EFI_GUID gUefiShellFileGuid =3D { 0x7C04A583, 0x9E3E, 0x4f1c, { 0xAD, 0x= 65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 } }; > + > +#define INTERNAL_UEFI_SHELL_NAME L"Internal UEFI Shell 2.0" > +#define UEFI_HARD_DRIVE_NAME L"UEFI Hard Drive" > + > +/** > + Registers default boot option > +**/ > + > +VOID > +RegisterDefaultBootOption ( > + VOID > + ) > +{ > + UINT16 *ShellData; > + UINT32 ShellDataSize; > + > + ShellData =3D NULL; > + ShellDataSize =3D 0; > + RegisterFvBootOption (&gUefiShellFileGuid, INTERNAL_UEFI_SHELL_= NAME, (UINTN) -1, LOAD_OPTION_ACTIVE, (UINT8 *)ShellData, ShellDataSize); > + > + // > + // Boot Menu > + // > + mBootMenuOptionNumber =3D RegisterFvBootOption (&mBootMenuFile, L"Boot= Device List", (UINTN) -1, LOAD_OPTION_CATEGORY_APP | LOAD_OPTION_ACTIVE = | LOAD_OPTION_HIDDEN, NULL, 0); > + > + if (mBootMenuOptionNumber =3D=3D LoadOptionNumberUnassigned) { > + DEBUG ((DEBUG_INFO, "BootMenuOptionNumber (%d) should not be same to= LoadOptionNumberUnassigned(%d).\n", mBootMenuOptionNumber, LoadOptionNumbe= rUnassigned)); > + } > +#if 0 > + // > + // Boot Manager Menu > + // > + EfiInitializeFwVolDevicepathNode (&FileNode, &mUiFile); > + > + gBS->HandleProtocol ( > + gImageHandle, > + &gEfiLoadedImageProtocolGuid, > + (VOID **) &LoadedImage > + ); > + DevicePath =3D AppendDevicePathNode (DevicePathFromHandle (LoadedImage= ->DeviceHandle), (EFI_DEVICE_PATH_PROTOCOL *) &FileNode); > +#endif > + > +} > + > +/** > + Registers/Unregisters boot option hotkey > + > + @param OptionNumber The boot option number for the key option. > + @param Key The the key input > + @param Add Flag to indicate to add or remove a key > +**/ > +VOID > +RegisterBootOptionHotkey ( > + UINT16 OptionNumber, > + EFI_INPUT_KEY *Key, > + BOOLEAN Add > + ) > +{ > + EFI_STATUS Status; > + > + if (!Add) { > + // > + // No enter hotkey when force to setup or there is no boot option > + // > + Status =3D EfiBootManagerDeleteKeyOptionVariable (NULL, 0, Key, NULL= ); > + ASSERT (Status =3D=3D EFI_SUCCESS || Status =3D=3D EFI_NOT_FOUND); > + } else { > + // > + // Register enter hotkey for the first boot option > + // > + Status =3D EfiBootManagerAddKeyOptionVariable (NULL, OptionNumber, 0= , Key,NULL); > + ASSERT (Status =3D=3D EFI_SUCCESS || Status =3D=3D EFI_ALREADY_START= ED); > + } > +} > + > + > +/** > + Detect key press callback > + > + @param The key data > + > + @retval EFI_SUCCESS > +**/ > +EFI_STATUS > +EFIAPI > +DetectKeypressCallback ( > + IN EFI_KEY_DATA *KeyData > +) > +{ > + mHotKeypressed =3D TRUE; > + > + if (HotKeyEvent !=3D NULL) { > + gBS->SignalEvent(HotKeyEvent); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + This function is called after all the boot options are enumerated and = ordered properly. > +**/ > +VOID > +RegisterStaticHotkey ( > + VOID > + ) > +{ > + > + EFI_INPUT_KEY Enter; > + EFI_KEY_DATA F2; > + EFI_KEY_DATA F7; > + BOOLEAN EnterSetup; > + EFI_STATUS Status; > + EFI_BOOT_MANAGER_LOAD_OPTION BootOption; > + > + EnterSetup =3D FALSE; > + > + // > + // [Enter] > + // > + mContinueBoot =3D !EnterSetup; > + if (mContinueBoot) { > + Enter.ScanCode =3D SCAN_NULL; > + Enter.UnicodeChar =3D CHAR_CARRIAGE_RETURN; > + EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL); > + } > + > + > + // > + // [F2]/[F7] > + // > + F2.Key.ScanCode =3D SCAN_F2; > + F2.Key.UnicodeChar =3D CHAR_NULL; > + F2.KeyState.KeyShiftState =3D EFI_SHIFT_STATE_VALID; > + F2.KeyState.KeyToggleState =3D 0; > + Status =3D EfiBootManagerGetBootManagerMenu (&BootOption); > + ASSERT_EFI_ERROR (Status); > + RegisterBootOptionHotkey ((UINT16) BootOption.OptionNumber, &F2.Key, T= RUE); > + EfiBootManagerFreeLoadOption (&BootOption); > + > + F7.Key.ScanCode =3D SCAN_F7; > + F7.Key.UnicodeChar =3D CHAR_NULL; > + F7.KeyState.KeyShiftState =3D EFI_SHIFT_STATE_VALID; > + F7.KeyState.KeyToggleState =3D 0; > + mBootMenuBoot =3D !EnterSetup; > + RegisterBootOptionHotkey ((UINT16) mBootMenuOptionNumber, &F7.Key, mBo= otMenuBoot); > + > +} > + > + > + > +/** > + Returns the boot option type of a device > + > + @param DevicePath The path of device whose boot option typ= e > + to be returned > + @retval -1 Device type not found > + @retval > -1 Device type found > +**/ > +UINT8 > +BootOptionType ( > + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath > + ) > +{ > + EFI_DEVICE_PATH_PROTOCOL *Node; > + EFI_DEVICE_PATH_PROTOCOL *NextNode; > + > + for (Node =3D DevicePath; !IsDevicePathEndType (Node); Node =3D NextDe= vicePathNode (Node)) { > + if (DevicePathType (Node) =3D=3D MESSAGING_DEVICE_PATH) { > + // > + // Make sure the device path points to the driver device. > + // > + NextNode =3D NextDevicePathNode (Node); > + if (DevicePathSubType(NextNode) =3D=3D MSG_DEVICE_LOGICAL_UNIT_DP)= { > + // > + // if the next node type is Device Logical Unit, which specify t= he Logical Unit Number (LUN), > + // skip it > + // > + NextNode =3D NextDevicePathNode (NextNode); > + } > + if (IsDevicePathEndType (NextNode)) { > + if ((DevicePathType (Node) =3D=3D MESSAGING_DEVICE_PATH)) { > + return DevicePathSubType (Node); > + } else { > + return MSG_SATA_DP; > + } > + } > + } > + } > + > + return (UINT8) -1; > +} > + > +/** > + Returns the priority number. > + OptionType EFI > + ------------------------------------ > + PXE 2 > + DVD 4 > + USB 6 > + NVME 7 > + HDD 8 > + EFI Shell 9 > + Others 100 > + > + @param BootOption > +**/ > +UINTN > +BootOptionPriority ( > + CONST EFI_BOOT_MANAGER_LOAD_OPTION *BootOption > + ) > +{ > + // > + // EFI boot options > + // > + switch (BootOptionType (BootOption->FilePath)) { > + case MSG_MAC_ADDR_DP: > + case MSG_VLAN_DP: > + case MSG_IPv4_DP: > + case MSG_IPv6_DP: > + return 2; > + > + case MSG_SATA_DP: > + case MSG_ATAPI_DP: > + case MSG_UFS_DP: > + case MSG_NVME_NAMESPACE_DP: > + return 4; > + > + case MSG_USB_DP: > + return 6; > + > + } > + if (StrCmp (BootOption->Description, INTERNAL_UEFI_SHELL_NAME) =3D= =3D 0) { > + if (PcdGetBool (PcdBootToShellOnly)) { > + return 0; > + } > + return 9; > + } > + if (StrCmp (BootOption->Description, UEFI_HARD_DRIVE_NAME) =3D=3D 0)= { > + return 8; > + } > + return 100; > +} > + > +/** > + Compares boot priorities of two boot options > + > + @param Left The left boot option > + @param Right The right boot option > + > + @return The difference between the Left and Right > + boot options > + **/ > +INTN > +EFIAPI > +CompareBootOption ( > + CONST VOID *Left, > + CONST VOID *Right > + ) > +{ > + return BootOptionPriority ((EFI_BOOT_MANAGER_LOAD_OPTION *) Left) - > + BootOptionPriority ((EFI_BOOT_MANAGER_LOAD_OPTION *) Right); > +} > + > diff --git a/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardM= emoryTest.c b/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardMe= moryTest.c > new file mode 100644 > index 0000000000..e3650721fe > --- /dev/null > +++ b/Platform/Intel/BoardModulePkg/Library/BoardBdsHookLib/BoardMemoryTe= st.c > @@ -0,0 +1,83 @@ > +/** @file > + Perform the platform memory test > + > +Copyright (c) 2019, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "BoardBdsHook.h" > +#include > + > +/** > + Perform the memory test base on the memory test intensive level, > + and update the memory resource. > + > + @param Level The memory test intensive level. > + > + @retval EFI_STATUS Success test all the system memory and update > + the memory resource > + > +**/ > +EFI_STATUS > +MemoryTest ( > + IN EXTENDMEM_COVERAGE_LEVEL Level > + ) > +{ > + EFI_STATUS Status; > + BOOLEAN RequireSoftECCInit; > + EFI_GENERIC_MEMORY_TEST_PROTOCOL *GenMemoryTest; > + UINT64 TestedMemorySize; > + UINT64 TotalMemorySize; > + BOOLEAN ErrorOut; > + BOOLEAN TestAbort; > + > + TestedMemorySize =3D 0; > + TotalMemorySize =3D 0; > + ErrorOut =3D FALSE; > + TestAbort =3D FALSE; > + > + RequireSoftECCInit =3D FALSE; > + > + Status =3D gBS->LocateProtocol ( > + &gEfiGenericMemTestProtocolGuid, > + NULL, > + (VOID **) &GenMemoryTest > + ); > + if (EFI_ERROR (Status)) { > + return EFI_SUCCESS; > + } > + > + Status =3D GenMemoryTest->MemoryTestInit ( > + GenMemoryTest, > + Level, > + &RequireSoftECCInit > + ); > + if (Status =3D=3D EFI_NO_MEDIA) { > + // > + // The PEI codes also have the relevant memory test code to check th= e memory, > + // it can select to test some range of the memory or all of them. If= PEI code > + // checks all the memory, this BDS memory test will has no not-test = memory to > + // do the test, and then the status of EFI_NO_MEDIA will be returned= by > + // "MemoryTestInit". So it does not need to test memory again, just = return. > + // > + return EFI_SUCCESS; > + } > + > + do { > + Status =3D GenMemoryTest->PerformMemoryTest ( > + GenMemoryTest, > + &TestedMemorySize, > + &TotalMemorySize, > + &ErrorOut, > + TestAbort > + ); > + if (ErrorOut && (Status =3D=3D EFI_DEVICE_ERROR)) { > + ASSERT (0); > + } > + } while (Status !=3D EFI_NOT_FOUND); > + > + Status =3D GenMemoryTest->Finished (GenMemoryTest); > + > + return EFI_SUCCESS; > +} > --=20 > 2.19.1.windows.1 >=20 Thanks, Nate=