1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363 |
- /** @file
- This file include all platform action which can be customized by IBV/OEM.
- Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
- Copyright (c) 2021, American Megatrends International LLC.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "BdsPlatform.h"
- #include <Guid/EventGroup.h>
- #include <Protocol/DxeSmmReadyToLock.h>
- #include <Protocol/FirmwareVolume2.h>
- #include <Protocol/PciRootBridgeIo.h>
- #include <Protocol/BlockIo.h>
- #include <Protocol/PciIo.h>
- #include <Library/IoLib.h>
- #include <Library/PciLib.h>
- #include <Guid/EventGroup.h>
- #include <Library/Tcg2PhysicalPresenceLib.h>
- #include <Library/HobLib.h>
- #include <Protocol/UsbIo.h>
- #include <Library/UefiBootManagerLib.h>
- GLOBAL_REMOVE_IF_UNREFERENCED EFI_BOOT_MODE gBootMode;
- BOOLEAN gPPRequireUIConfirm;
- extern UINTN mBootMenuOptionNumber;
- EFI_STATUS
- LinuxBootStart (
- VOID
- );
- 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
- };
- //
- // Internal shell mode
- //
- GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellModeColumn;
- GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellModeRow;
- GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellHorizontalResolution;
- GLOBAL_REMOVE_IF_UNREFERENCED UINT32 mShellVerticalResolution;
- //
- // 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, " PlatformBootMangerLib: gEfiMemoryOverwriteControlDataGuid doesn't exist!!***\n"));
- MorControl = 0;
- } else {
- DEBUG ((DEBUG_INFO, " PlatformBootMangerLib: Get the gEfiMemoryOverwriteControlDataGuid = %x!!***\n", MorControl));
- }
- return (BOOLEAN) (MorControl & 0x01);
- }
- VOID
- 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);
- }
- }
- /**
- An empty function to pass error checking of CreateEventEx ().
- This empty function ensures that EVT_NOTIFY_SIGNAL_ALL is error
- checked correctly since it is now mapped into CreateEventEx() in UEFI 2.0.
- @param Event Event whose notification function is being invoked.
- @param Context The pointer to the notification function's context,
- which is implementation-dependent.
- **/
- VOID
- EFIAPI
- InternalBdsEmptyCallbackFuntion (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- return;
- }
- VOID
- ExitPmAuth (
- VOID
- )
- {
- EFI_HANDLE Handle;
- EFI_STATUS Status;
- EFI_EVENT EndOfDxeEvent;
- DEBUG((DEBUG_INFO,"ExitPmAuth ()- Start\n"));
- //
- // Prepare S3 information, this MUST be done before ExitPmAuth/EndOfDxe
- //
- //
- // Since PI1.2.1, we need signal EndOfDxe as ExitPmAuth
- //
- Status = gBS->CreateEventEx (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- InternalBdsEmptyCallbackFuntion,
- NULL,
- &gEfiEndOfDxeEventGroupGuid,
- &EndOfDxeEvent
- );
- ASSERT_EFI_ERROR (Status);
- gBS->SignalEvent (EndOfDxeEvent);
- gBS->CloseEvent (EndOfDxeEvent);
- DEBUG((DEBUG_INFO,"All EndOfDxe callbacks have returned successfully\n"));
- //
- // NOTE: We need install DxeSmmReadyToLock directly here because many boot script is added via ExitPmAuth/EndOfDxe callback.
- // If we install them at same callback, these boot script will be rejected because BootScript Driver runs first to lock them done.
- // So we seperate them to be 2 different events, ExitPmAuth is last chance to let platform add boot script. DxeSmmReadyToLock will
- // make boot script save driver lock down the interface.
- //
- Handle = NULL;
- Status = gBS->InstallProtocolInterface (
- &Handle,
- &gEfiDxeSmmReadyToLockProtocolGuid,
- EFI_NATIVE_INTERFACE,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
- DEBUG((DEBUG_INFO,"ExitPmAuth ()- End\n"));
- }
- 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);
- }
- }
- /**
- 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;
- }
- 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;
- }
- /**
- 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);
- }
- 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;
- }
- 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;
- }
- }
- 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.
- **/
- 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.
- @retval GraphicsController Successfully located
- @retval NULL Failed to locate
- **/
- 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;
- }
- 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
- );
- }
- }
- }
- 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);
- }
- /**
- 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);
- }
- /**
- 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();
- }
- }
- /**
- 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;
- 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;
- }
- /**
- 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
- OnReadyToBootCallBack (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- DEBUG ((EFI_D_INFO, "OnReadyToBootCallBack\n"));
- if (BootCurrentIsInternalShell ()) {
- ChangeModeForInternalShell ();
- EfiBootManagerConnectAllDefaultConsoles();
- gDS->Dispatch ();
- }
- }
- /**
- Platform Bds init. Incude the platform firmware vendor, revision
- and so crc check.
- **/
- VOID
- EFIAPI
- PlatformBootManagerBeforeConsole (
- VOID
- )
- {
- EFI_STATUS Status;
- EFI_DEVICE_PATH_PROTOCOL *VarConOut;
- EFI_DEVICE_PATH_PROTOCOL *VarConIn;
- EFI_EVENT Event;
- DEBUG ((EFI_D_INFO, "PlatformBootManagerBeforeConsole\n"));
- Status = EFI_SUCCESS;
- //
- // Get user defined text mode for internal shell only once.
- //
- mShellHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
- mShellVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
- mShellModeColumn = PcdGet32 (PcdSetupConOutColumn);
- mShellModeRow = PcdGet32 (PcdSetupConOutRow);
- if (PcdGetBool (PcdUpdateConsoleInBds) == TRUE) {
- //
- // Create event to set proper video resolution and text mode for internal shell.
- //
- Status = EfiCreateEventReadyToBootEx (
- TPL_CALLBACK,
- OnReadyToBootCallBack,
- NULL,
- &Event
- );
- ASSERT_EFI_ERROR (Status);
- //
- // Connect Root Bridge to make PCI BAR resource allocated and all PciIo created
- //
- ConnectRootBridge (FALSE);
- //
- // 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));
- }
- }
- }
- EnumUsbKeyboard ();
- //
- // For trusted console it must be handled here.
- //
- UpdateGraphicConOut (TRUE);
- //
- // Dynamically register hot key: F2/F7/Enter
- //
- RegisterDefaultBootOption ();
- RegisterStaticHotkey ();
- }
-
- PERF_START_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7010);
- if (PcdGetBool (PcdTpm2Enable)) {
- ProcessTcgPp ();
- ProcessTcgMor ();
- }
- PERF_END_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7011);
- //
- // We should make all UEFI memory and GCD information populated before ExitPmAuth.
- // SMM may consume these information.
- //
- MemoryTest((EXTENDMEM_COVERAGE_LEVEL) PcdGet32 (PcdPlatformMemoryCheckLevel));
- PERF_START_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7020);
- ExitPmAuth ();
- PERF_END_EX(NULL,"EventRec", NULL, AsmReadTsc(), 0x7021);
- //
- // Dispatch the deferred 3rd party images.
- //
- EfiBootManagerDispatchDeferredImages ();
- //
- // For non-trusted console it must be handled here.
- //
- if (PcdGetBool (PcdUpdateConsoleInBds) == TRUE) {
- UpdateGraphicConOut (FALSE);
- }
- }
- /**
- 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;
- }
- /**
- The function will excute with as the platform policy, current policy
- is driven by boot mode. IBV/OEM can customize this code for their specific
- policy action.
- @param DriverOptionList - The header of the driver option link list
- @param BootOptionList - The header of the boot option link list
- @param ProcessCapsules - A pointer to ProcessCapsules()
- @param BaseMemoryTest - A pointer to BaseMemoryTest()
- **/
- VOID
- EFIAPI
- PlatformBootManagerAfterConsole (
- VOID
- )
- {
- EFI_BOOT_MODE LocalBootMode;
- DEBUG ((EFI_D_INFO, "PlatformBootManagerAfterConsole\n"));
- //
- // Get current Boot Mode
- //
- LocalBootMode = gBootMode;
- DEBUG ((DEBUG_INFO, "Current local bootmode - %x\n", LocalBootMode));
- LinuxBootStart();
-
- //
- // 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
- //
- if (PcdGetBool (PcdFastBoot) == FALSE) {
- 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.
- //
- EfiBootManagerRefreshAllBootOption ();
- if (IsNeedSortBootOption()) {
- EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, CompareBootOption);
- }
- //
- // PXE boot option may appear after boot option enumeration
- //
- break;
- }
- if (PcdGetBool (PcdFastBoot) == FALSE) {
- Print (L"Press F7 for BootMenu!\n");
- EfiBootManagerRefreshAllBootOption ();
- EfiBootManagerSortLoadOptionVariable (LoadOptionTypeBoot, CompareBootOption);
- }
- }
- /**
- The function is called when no boot option could be launched,
- including platform recovery options and options pointing to applications
- built into firmware volumes.
- If this function returns, BDS attempts to enter an infinite loop.
- **/
- VOID
- EFIAPI
- PlatformBootManagerUnableToBoot (
- VOID
- )
- {
- EFI_STATUS Status;
- EFI_BOOT_MANAGER_LOAD_OPTION BootDeviceList;
- CHAR16 OptionName[sizeof ("Boot####")];
- if (mBootMenuOptionNumber == LoadOptionNumberUnassigned) {
- return;
- }
- UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", mBootMenuOptionNumber);
- Status = EfiBootManagerVariableToLoadOption (OptionName, &BootDeviceList);
- if (EFI_ERROR (Status)) {
- return;
- }
- for (;;) {
- EfiBootManagerBoot (&BootDeviceList);
- }
- }
|