123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389 |
- /** @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.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Guid/EventGroup.h>
- #include <Library/IoLib.h>
- #include <Library/PciLib.h>
- #include <Library/UefiBootManagerLib.h>
- #include <Library/Tcg2PhysicalPresenceLib.h>
- #include <Protocol/BlockIo.h>
- #include <Protocol/UsbIo.h>
- #include <Protocol/PciEnumerationComplete.h>
- #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 gUsbClassKeyboardDevicePath = {
- {
- {
- 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 = sizeof (MorControl);
- Status = gRT->GetVariable (
- MEMORY_OVERWRITE_REQUEST_VARIABLE_NAME,
- &gEfiMemoryOverwriteControlDataGuid,
- NULL,
- &DataSize,
- &MorControl
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_INFO, " gEfiMemoryOverwriteControlDataGuid doesn't exist!!***\n"));
- MorControl = 0;
- } else {
- DEBUG ((DEBUG_INFO, " Get the gEfiMemoryOverwriteControlDataGuid = %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 = ConvertDevicePathToText (DevicePath, TRUE, TRUE);
- DEBUG ((DEBUG_INFO, "%s: %s\n", Name, Str));
- if (Str != 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 == NULL) {
- return FALSE;
- }
- ConsoleDevice = DuplicateDevicePath (Device);
- TrustedConsoleDevicepath = NULL;
- switch (ConsoleType) {
- case ConIn:
- TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleInputDevicePath);
- break;
- case ConOut:
- //
- // Check GOP and remove last node
- //
- TempDevicePath = ConsoleDevice;
- while (!IsDevicePathEndType (TempDevicePath)) {
- if (DevicePathType (TempDevicePath) == ACPI_DEVICE_PATH &&
- DevicePathSubType (TempDevicePath) == ACPI_ADR_DP) {
- SetDevicePathEndNode (TempDevicePath);
- break;
- }
- TempDevicePath = NextDevicePathNode (TempDevicePath);
- }
- TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleOutputDevicePath);
- break;
- default:
- ASSERT (FALSE);
- break;
- }
- TempDevicePath = TrustedConsoleDevicepath;
- do {
- Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
- if (Instance == NULL) {
- break;
- }
- if (CompareMem (ConsoleDevice, Instance, Size - END_DEVICE_PATH_LENGTH) == 0) {
- FreePool (Instance);
- FreePool (ConsoleDevice);
- return TRUE;
- }
- FreePool (Instance);
- } while (TempDevicePath != 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) == MESSAGING_DEVICE_PATH) &&
- ((DevicePathSubType (DevicePath) == MSG_USB_CLASS_DP) ||
- (DevicePathSubType (DevicePath) == 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 == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- if (!IsUsbShortForm (DevicePath)) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Find the usb host controller firstly, then connect with the remaining device path
- //
- AtLeastOneConnected = FALSE;
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiPciIoProtocolGuid,
- NULL,
- &HandleCount,
- &Handles
- );
- for (Index = 0; Index < HandleCount; Index++) {
- Status = gBS->HandleProtocol (
- Handles[Index],
- &gEfiPciIoProtocolGuid,
- (VOID **) &PciIo
- );
- if (!EFI_ERROR (Status)) {
- //
- // Check whether the Pci device is the wanted usb host controller
- //
- Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);
- if (!EFI_ERROR (Status) &&
- ((PCI_CLASS_SERIAL == Class[2]) && (PCI_CLASS_SERIAL_USB == Class[1]))) {
- Status = gBS->ConnectController (
- Handles[Index],
- NULL,
- DevicePath,
- FALSE
- );
- if (!EFI_ERROR(Status)) {
- AtLeastOneConnected = 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 = gBS->HandleProtocol (
- Handle,
- &gEfiPciIoProtocolGuid,
- (VOID **)&PciIo
- );
- if (!EFI_ERROR (Status)) {
- Status = 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 = DuplicateDevicePath (DevicePath);
- ASSERT (DupDevicePath != NULL);
- if (DupDevicePath == NULL) {
- return NULL;
- }
- TempDevicePath = DupDevicePath;
- Status = 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) == ACPI_DEVICE_PATH &&
- DevicePathSubType (DevicePath) == ACPI_ADR_DP) {
- return TRUE;
- }
- DevicePath = 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 = FALSE;
- Return = NULL;
- GopSize = GetDevicePathSize (Gop);
- do {
- Instance = GetNextDevicePathInstance (&DevicePath, &Size);
- if (Instance == NULL) {
- break;
- }
- if (!IsGopDevicePath (Instance) ||
- (Size == GopSize && CompareMem (Instance, Gop, GopSize) == 0)
- ) {
- if (Size == GopSize && CompareMem (Instance, Gop, GopSize) == 0) {
- Exist = TRUE;
- }
- Temp = Return;
- Return = AppendDevicePathInstance (Return, Instance);
- if (Temp != NULL) {
- FreePool (Temp);
- }
- }
- FreePool (Instance);
- } while (DevicePath != NULL);
- if (!Exist) {
- Temp = Return;
- Return = AppendDevicePathInstance (Return, Gop);
- if (Temp != 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 = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiPciIoProtocolGuid,
- NULL,
- &PciHandlesSize,
- &PciHandles
- );
- if (EFI_ERROR (Status)) {
- return NULL;
- }
- for (Index = 0; Index < PciHandlesSize; Index++) {
- Status = 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 console
- 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 = GetGraphicsController (NeedTrustedConsole);
- if (GraphicsControllerHandle != 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 it.
- //
- GopDevicePath = EfiBootManagerGetGopDevicePath (GraphicsControllerHandle);
- if (GopDevicePath != NULL) {
- GetEfiGlobalVariable2 (L"ConOut", (VOID **)&ConOutDevicePath, NULL);
- UpdatedConOutDevicePath = UpdateGopDevicePath (ConOutDevicePath, GopDevicePath);
- if (ConOutDevicePath != NULL) {
- FreePool (ConOutDevicePath);
- }
- FreePool (GopDevicePath);
- gRT->SetVariable (
- L"ConOut",
- &gEfiGlobalVariableGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | 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[] = {L"ConIn", L"ConOut"};
- VOID *TrustedConsoleDevicepath;
- TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleInputDevicePath);
- DumpDevicePath (L"TrustedConsoleIn", TrustedConsoleDevicepath);
- TrustedConsoleDevicepath = PcdGetPtr (PcdTrustedConsoleOutputDevicePath);
- DumpDevicePath (L"TrustedConsoleOut", TrustedConsoleDevicepath);
- for (Index = 0; Index < sizeof (ConsoleVar) / sizeof (ConsoleVar[0]); Index++) {
- GetEfiGlobalVariable2 (ConsoleVar[Index], (VOID **)&Consoles, NULL);
- TempDevicePath = Consoles;
- do {
- Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
- if (Instance == NULL) {
- break;
- }
- if (IsTrustedConsole (Index, Instance)) {
- if (IsUsbShortForm (Instance)) {
- ConnectUsbShortFormDevicePath (Instance);
- } else {
- for (Next = Instance; !IsDevicePathEnd (Next); Next = NextDevicePathNode (Next)) {
- if (DevicePathType (Next) == ACPI_DEVICE_PATH && DevicePathSubType (Next) == ACPI_ADR_DP) {
- break;
- } else if (DevicePathType (Next) == HARDWARE_DEVICE_PATH &&
- DevicePathSubType (Next) == HW_CONTROLLER_DP &&
- DevicePathType (NextDevicePathNode (Next)) == ACPI_DEVICE_PATH &&
- DevicePathSubType (NextDevicePathNode (Next)) == ACPI_ADR_DP
- ) {
- break;
- }
- }
- if (!IsDevicePathEnd (Next)) {
- SetDevicePathEndNode (Next);
- Status = EfiBootManagerConnectDevicePath (Instance, &Handle);
- if (!EFI_ERROR (Status)) {
- gBS->ConnectController (Handle, NULL, NULL, TRUE);
- }
- } else {
- EfiBootManagerConnectDevicePath (Instance, NULL);
- }
- }
- }
- FreePool (Instance);
- } while (TempDevicePath != NULL);
- if (Consoles != 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 = PcdGetPtr (PcdTrustedStorageDevicePath);
- DumpDevicePath (L"TrustedStorage", TrustedStorageDevicepath);
- TempDevicePath = TrustedStorageDevicepath;
- do {
- Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
- if (Instance == NULL) {
- break;
- }
- EfiBootManagerConnectDevicePath (Instance, NULL);
- TempStorageDevicePath = Instance;
- Status = gBS->LocateDevicePath (
- &gEfiDevicePathProtocolGuid,
- &TempStorageDevicePath,
- &DeviceHandle
- );
- if (!EFI_ERROR (Status)) {
- gBS->ConnectController (DeviceHandle, NULL, NULL, FALSE);
- }
- FreePool (Instance);
- } while (TempDevicePath != 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 = 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, &gUefiShellFileGuid)))) {
- //
- // if this option is internal shell, return TRUE
- //
- Result = TRUE;
- }
- if (BootOption != NULL) {
- FreePool (BootOption);
- BootOption = 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 = PcdGet32 (PcdSetupVideoHorizontalResolution);
- mShellVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
- mShellModeColumn = PcdGet32 (PcdSetupConOutColumn);
- mShellModeRow = PcdGet32 (PcdSetupConOutRow);
- 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) || (SimpleTextOut == NULL)) {
- return EFI_UNSUPPORTED;
- }
- MaxGopMode = GraphicsOutput->Mode->MaxMode;
- MaxTextMode = 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 resolution, we need restart whole console drivers.
- //
- for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
- Status = GraphicsOutput->QueryMode (
- GraphicsOutput,
- ModeNumber,
- &SizeOfInfo,
- &Info
- );
- if (!EFI_ERROR (Status)) {
- if ((Info->HorizontalResolution == mShellHorizontalResolution) &&
- (Info->VerticalResolution == mShellVerticalResolution)) {
- if ((GraphicsOutput->Mode->Info->HorizontalResolution == mShellHorizontalResolution) &&
- (GraphicsOutput->Mode->Info->VerticalResolution == mShellVerticalResolution)) {
- //
- // If current video resolution is same with new resolution,
- // then check if current text mode is same with new text mode.
- //
- Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
- ASSERT_EFI_ERROR (Status);
- if (CurrentColumn == mShellModeColumn && CurrentRow == mShellModeRow) {
- //
- // Current text mode is same with new text mode, text mode need not be change.
- //
- FreePool (Info);
- return EFI_SUCCESS;
- } else {
- //
- // Current text mode is different with new text mode, text mode need be change to new text mode.
- //
- for (Index = 0; Index < MaxTextMode; Index++) {
- Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);
- if (!EFI_ERROR(Status)) {
- if ((CurrentColumn == mShellModeColumn) && (CurrentRow == mShellModeRow)) {
- //
- // New text mode is supported, set it.
- //
- Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
- ASSERT_EFI_ERROR (Status);
- //
- // Update text mode PCD.
- //
- Status = PcdSet32S (PcdConOutColumn, mShellModeColumn);
- ASSERT_EFI_ERROR (Status);
- Status = PcdSet32S (PcdConOutRow, mShellModeRow);
- ASSERT_EFI_ERROR (Status);
- FreePool (Info);
- return EFI_SUCCESS;
- }
- }
- }
- if (Index == 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, set new video resolution.
- // In this case, the driver which produces simple text out need be restarted.
- //
- Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
- if (!EFI_ERROR (Status)) {
- //
- // Set PCD to restart GraphicsConsole and Consplitter to change video resolution
- // and produce new text mode based on new resolution.
- //
- Status = PcdSet32S (PcdVideoHorizontalResolution, mShellHorizontalResolution);
- ASSERT_EFI_ERROR (Status);
- Status = PcdSet32S (PcdVideoVerticalResolution, mShellVerticalResolution);
- ASSERT_EFI_ERROR (Status);
- Status = PcdSet32S (PcdConOutColumn, mShellModeColumn);
- ASSERT_EFI_ERROR (Status);
- Status = PcdSet32S (PcdConOutRow, mShellModeRow);
- ASSERT_EFI_ERROR (Status);
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiSimpleTextOutProtocolGuid,
- NULL,
- &HandleCount,
- &HandleBuffer
- );
- if (!EFI_ERROR (Status)) {
- for (Index = 0; Index < HandleCount; Index++) {
- gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
- }
- for (Index = 0; Index < HandleCount; Index++) {
- gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
- }
- if (HandleBuffer != NULL) {
- FreePool (HandleBuffer);
- }
- break;
- }
- }
- }
- }
- FreePool (Info);
- }
- }
- if (ModeNumber == 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 processing library interface.
- **/
- VOID
- ProcessTcgPp (
- VOID
- )
- {
- gPPRequireUIConfirm |= 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 already 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_PROTOCOL *) &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 expectation.
- 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 = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot);
- //
- // 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"Enter Setup"))) == 0) ||
- ((StrnCmp (BootOptions->Description, L"BootManagerMenuApp", StrLen (L"BootManagerMenuApp"))) == 0))) {
- return TRUE;
- }
- return FALSE;
- }
- /**
- Connects Root Bridge
- **/
- VOID
- ConnectRootBridge (
- BOOLEAN Recursive
- )
- {
- UINTN RootBridgeHandleCount;
- EFI_HANDLE *RootBridgeHandleBuffer;
- UINTN RootBridgeIndex;
- RootBridgeHandleCount = 0;
- gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiPciRootBridgeIoProtocolGuid,
- NULL,
- &RootBridgeHandleCount,
- &RootBridgeHandleBuffer
- );
- for (RootBridgeIndex = 0; RootBridgeIndex < RootBridgeHandleCount; RootBridgeIndex++) {
- gBS->ConnectController (RootBridgeHandleBuffer[RootBridgeIndex], NULL, 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 = ConsoleDevicePath;
- do {
- Instance = GetNextDevicePathInstance (&TempDevicePath, &Size);
- if (Instance == 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 = IsVideoController (Instance);
- if (GraphicsControllerHandle == NULL) {
- EfiBootManagerUpdateConsoleVariable (ConsoleType, Instance, NULL);
- } 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 node in it.
- //
- GopDevicePath = EfiBootManagerGetGopDevicePath (GraphicsControllerHandle);
- if (GopDevicePath != NULL) {
- EfiBootManagerUpdateConsoleVariable (ConsoleType, GopDevicePath, NULL);
- }
- }
- break;
- default:
- ASSERT(FALSE);
- break;
- }
- FreePool (Instance);
- } while (TempDevicePath != 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 Event.
- **/
- 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 = 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 = gBS->LocateProtocol (&gEfiPciEnumerationCompleteProtocolGuid, NULL, (VOID **) &ProtocolPointer);
- if (EFI_SUCCESS != Status) {
- return;
- }
- //gBS->CloseEvent (Event);
- DEBUG ((DEBUG_INFO, "Event BdsPciEnumCompleteCallback callback starts\n"));
- gBootMode = GetBootModeHob ();
- //
- // Fill ConIn/ConOut in Full Configuration boot mode
- //
- DEBUG ((DEBUG_INFO, "PlatformBootManagerInit - %x\n", gBootMode));
- if (gBootMode == BOOT_WITH_FULL_CONFIGURATION ||
- gBootMode == BOOT_WITH_DEFAULT_SETTINGS ||
- gBootMode == BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS ||
- gBootMode == BOOT_IN_RECOVERY_MODE) {
- GetEfiGlobalVariable2 (L"ConOut", (VOID **)&VarConOut, NULL);
- if (VarConOut != NULL) {
- FreePool (VarConOut);
- }
- GetEfiGlobalVariable2 (L"ConIn", (VOID **)&VarConIn, NULL);
- if (VarConIn != 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 == NULL || VarConIn == NULL) {
- if (PcdGetSize (PcdTrustedConsoleOutputDevicePath) >= sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
- AddConsoleVariable (ConOut, PcdGetPtr (PcdTrustedConsoleOutputDevicePath));
- }
- if (PcdGetSize (PcdTrustedConsoleInputDevicePath) >= sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
- AddConsoleVariable (ConIn, PcdGetPtr (PcdTrustedConsoleInputDevicePath));
- }
- }
- }
- //
- // 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 (PcdPlatformMemoryCheckLevel));
- }
- /**
- 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 Event.
- **/
- 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 = gBS->LocateProtocol (&gEfiDxeSmmReadyToLockProtocolGuid, NULL, (VOID **) &ProtocolPointer);
- if (EFI_SUCCESS != 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 boot.
- That will not connect USB controller while CSM and FastBoot are disabled, 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 behavior, input devices will not be connected
- by default. Hence, when booting to EFI shell, connecting input consoles 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 Event.
- **/
- VOID
- BdsBeforeConsoleAfterTrustedConsoleCallback (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- DEBUG ((DEBUG_INFO, "Event gBdsEventBeforeConsoleBeforeEndOfDxeGuid callback starts\n"));
- //
- // Connect Root Bridge to make PCI BAR resource allocated and all PciIo created
- //
- ConnectRootBridge (FALSE);
- }
- /**
- 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 Event.
- **/
- VOID
- BdsBeforeConsoleBeforeEndOfDxeGuidCallback (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- DEBUG ((DEBUG_INFO, "Event gBdsBeforeConsoleBeforeEndOfDxeGuid callback 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 Event.
- **/
- 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 = 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 boot device
- //
- //
- // Dispatch all but Storage Oprom explicitly, because we assume Int13Thunk 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, CompareBootOption);
- }
- }
|