From 42a8f2ceb45ec3beaec1262a7c61333c6be7c0b0 Mon Sep 17 00:00:00 2001 From: Maurice Ma Date: Tue, 17 May 2016 09:32:40 -0700 Subject: [PATCH] CorebootPayloadPkg: Add coreboot PlatfromBootManagerLib implementation In order to use the generic BdsDxe in MdeModulePkg, a platform specific PlatfromBootManagerLib is required. This library will help update the ConIn, ConOut and ErrOut variables. Cc: Prince Agyeman Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Maurice Ma Reviewed-by: Lee Leahy --- CorebootPayloadPkg/CorebootPayloadPkg.dec | 24 +- .../PlatformBootManager.c | 198 ++++++ .../PlatformBootManager.h | 128 ++++ .../PlatformBootManagerLib.inf | 77 +++ .../PlatformBootManagerLib/PlatformConsole.c | 617 ++++++++++++++++++ .../PlatformBootManagerLib/PlatformConsole.h | 76 +++ .../PlatformBootManagerLib/PlatformData.c | 25 + 7 files changed, 1133 insertions(+), 12 deletions(-) create mode 100644 CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c create mode 100644 CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.h create mode 100644 CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf create mode 100644 CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.c create mode 100644 CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.h create mode 100644 CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformData.c diff --git a/CorebootPayloadPkg/CorebootPayloadPkg.dec b/CorebootPayloadPkg/CorebootPayloadPkg.dec index 54eb3d2257..b33b79c1d6 100644 --- a/CorebootPayloadPkg/CorebootPayloadPkg.dec +++ b/CorebootPayloadPkg/CorebootPayloadPkg.dec @@ -1,16 +1,16 @@ ## @file # Coreboot Payload Package # -# Provides drivers and definitions to create uefi payload for coreboot. +# Provides drivers and definitions to create uefi payload for coreboot. # # Copyright (c) 2014, Intel Corporation. All rights reserved.
-# This program and the accompanying materials are licensed and made available under -# the terms and conditions of the BSD License that accompanies this distribution. +# This program and the accompanying materials are licensed and made available under +# the terms and conditions of the BSD License that accompanies this distribution. # The full text of the license may be found at -# http://opensource.org/licenses/bsd-license.php. -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. # ## @@ -19,15 +19,15 @@ PACKAGE_NAME = CorebootPayloadPkg PACKAGE_GUID = 58ABC905-951E-472e-8590-77BA8A50BE63 PACKAGE_VERSION = 0.1 - + [LibraryClasses] - + [Guids] # ## Defines the token space for the Coreboot Payload Package PCDs. # - gUEfiCorebootPayloadPkgTokenSpaceGuid = {0x1d127ea, 0xf6f1, 0x4ef6, {0x94, 0x15, 0x8a, 0x0, 0x0, 0x93, 0xf8, 0x9d}} - + gUEfiCorebootPayloadPkgTokenSpaceGuid = {0x1d127ea, 0xf6f1, 0x4ef6, {0x94, 0x15, 0x8a, 0x0, 0x0, 0x93, 0xf8, 0x9d}} + # # Gop Temp # @@ -51,4 +51,4 @@ [PcdsFixedAtBuild, PcdsPatchableInModule] [PcdsDynamic, PcdsDynamicEx] - + diff --git a/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c new file mode 100644 index 0000000000..200ea95808 --- /dev/null +++ b/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c @@ -0,0 +1,198 @@ +/** @file + This file include all platform action which can be customized + by IBV/OEM. + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "PlatformBootManager.h" +#include "PlatformConsole.h" + +/** + 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 equal. + + @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 = 0; Index < Count; Index++) { + if ((Key->OptionType == Array[Index].OptionType) && + (Key->Attributes == Array[Index].Attributes) && + (StrCmp (Key->Description, Array[Index].Description) == 0) && + (CompareMem (Key->FilePath, Array[Index].FilePath, GetDevicePathSize (Key->FilePath)) == 0) && + (Key->OptionalDataSize == Array[Index].OptionalDataSize) && + (CompareMem (Key->OptionalData, Array[Index].OptionalData, Key->OptionalDataSize) == 0)) { + return (INTN) Index; + } + } + + return -1; +} + +/** + Register a boot option using a file GUID in the FV. + + @param FileGuid The file GUID name in FV. + @param Description The boot option description. + @param Attributes The attributes used for the boot option loading. +**/ +VOID +PlatformRegisterFvBootOption ( + EFI_GUID *FileGuid, + CHAR16 *Description, + UINT32 Attributes +) +{ + EFI_STATUS Status; + UINTN OptionIndex; + EFI_BOOT_MANAGER_LOAD_OPTION NewOption; + EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; + UINTN BootOptionCount; + MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + Status = gBS->HandleProtocol (gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **) &LoadedImage); + ASSERT_EFI_ERROR (Status); + + EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); + DevicePath = AppendDevicePathNode ( + DevicePathFromHandle (LoadedImage->DeviceHandle), + (EFI_DEVICE_PATH_PROTOCOL *) &FileNode + ); + + Status = EfiBootManagerInitializeLoadOption ( + &NewOption, + LoadOptionNumberUnassigned, + LoadOptionTypeBoot, + Attributes, + Description, + DevicePath, + NULL, + 0 + ); + if (!EFI_ERROR (Status)) { + BootOptions = EfiBootManagerGetLoadOptions (&BootOptionCount, LoadOptionTypeBoot); + + OptionIndex = PlatformFindLoadOption (&NewOption, BootOptions, BootOptionCount); + + if (OptionIndex == -1) { + Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN) -1); + ASSERT_EFI_ERROR (Status); + } + EfiBootManagerFreeLoadOption (&NewOption); + EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); + } +} + +/** + Do the platform specific action before the console is connected. + + Such as: + Update console variable; + Register new Driver#### or Boot####; + Signal ReadyToLock event. +**/ +VOID +EFIAPI +PlatformBootManagerBeforeConsole ( + VOID +) +{ + EFI_INPUT_KEY Enter; + EFI_INPUT_KEY F2; + EFI_BOOT_MANAGER_LOAD_OPTION BootOption; + + PlatformConsoleInit (); + + // + // Register ENTER as CONTINUE key + // + Enter.ScanCode = SCAN_NULL; + Enter.UnicodeChar = CHAR_CARRIAGE_RETURN; + EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL); + + // + // Map F2 to Boot Manager Menu + // + F2.ScanCode = SCAN_F2; + F2.UnicodeChar = CHAR_NULL; + EfiBootManagerGetBootManagerMenu (&BootOption); + EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &F2, NULL); + + // + // Register UEFI Shell + // + PlatformRegisterFvBootOption (PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE); +} + +/** + Do the platform specific action after the console is connected. + + Such as: + Dynamically switch output mode; + Signal console ready platform customized event; + Run diagnostics like memory testing; + Connect certain devices; + Dispatch aditional option roms. +**/ +VOID +EFIAPI +PlatformBootManagerAfterConsole ( + VOID +) +{ + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL White; + + Black.Blue = Black.Green = Black.Red = Black.Reserved = 0; + White.Blue = White.Green = White.Red = White.Reserved = 0xFF; + + EfiBootManagerConnectAll (); + EfiBootManagerRefreshAllBootOption (); + + Print ( + L"\n" + L"F2 to enter Boot Manager Menu.\n" + L"ENTER to boot directly.\n" + L"\n" + ); + +} + +/** + This function is called each second during the boot manager waits the timeout. + + @param TimeoutRemain The remaining timeout. +**/ +VOID +EFIAPI +PlatformBootManagerWaitCallback ( + UINT16 TimeoutRemain +) +{ + return; +} diff --git a/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.h b/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.h new file mode 100644 index 0000000000..948ba5796b --- /dev/null +++ b/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.h @@ -0,0 +1,128 @@ +/**@file + Head file for BDS Platform specific code + +Copyright (c) 2015, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#ifndef _PLATFORM_BOOT_MANAGER_H +#define _PLATFORM_BOOT_MANAGER_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +typedef struct { + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN ConnectType; +} PLATFORM_CONSOLE_CONNECT_ENTRY; + +extern PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[]; + +#define gEndEntire \ + { \ + END_DEVICE_PATH_TYPE,\ + END_ENTIRE_DEVICE_PATH_SUBTYPE,\ + END_DEVICE_PATH_LENGTH,\ + 0\ + } + +#define CONSOLE_OUT BIT0 +#define CONSOLE_IN BIT1 +#define STD_ERROR BIT2 + +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + UINT32 Instance; +} WIN_NT_VENDOR_DEVICE_PATH_NODE; + +// +// Below is the platform console device path +// +typedef struct { + VENDOR_DEVICE_PATH NtBus; + WIN_NT_VENDOR_DEVICE_PATH_NODE SerialDevice; + UART_DEVICE_PATH Uart; + VENDOR_DEVICE_PATH TerminalType; + EFI_DEVICE_PATH_PROTOCOL End; +} NT_ISA_SERIAL_DEVICE_PATH; + +typedef struct { + VENDOR_DEVICE_PATH NtBus; + WIN_NT_VENDOR_DEVICE_PATH_NODE NtGopDevice; + EFI_DEVICE_PATH_PROTOCOL End; +} NT_PLATFORM_GOP_DEVICE_PATH; + +/** + Use SystemTable Conout to stop video based Simple Text Out consoles from going + to the video device. Put up LogoFile on every video device that is a console. + + @param[in] LogoFile File name of logo to display on the center of the screen. + + @retval EFI_SUCCESS ConsoleControl has been flipped to graphics and logo displayed. + @retval EFI_UNSUPPORTED Logo not found + +**/ +EFI_STATUS +PlatformBootManagerEnableQuietBoot ( + IN EFI_GUID *LogoFile +); + +/** + Use SystemTable Conout to turn on video based Simple Text Out consoles. The + Simple Text Out screens will now be synced up with all non video output devices + + @retval EFI_SUCCESS UGA devices are back in text mode and synced up. + +**/ +EFI_STATUS +PlatformBootManagerDisableQuietBoot ( + VOID +); + +/** + Show progress bar with title above it. It only works in Graphics mode. + + @param TitleForeground Foreground color for Title. + @param TitleBackground Background color for Title. + @param Title Title above progress bar. + @param ProgressColor Progress bar color. + @param Progress Progress (0-100) + @param PreviousValue The previous value of the progress. + + @retval EFI_STATUS Success update the progress bar + +**/ +EFI_STATUS +PlatformBootManagerShowProgress ( + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleForeground, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL TitleBackground, + IN CHAR16 *Title, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL ProgressColor, + IN UINTN Progress, + IN UINTN PreviousValue +); + +#endif // _PLATFORM_BOOT_MANAGER_H diff --git a/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf b/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf new file mode 100644 index 0000000000..59227c7598 --- /dev/null +++ b/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf @@ -0,0 +1,77 @@ +## @file +# Include all platform action which can be customized by IBV/OEM. +# +# Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatformBootManagerLib + FILE_GUID = F0D9063A-DADB-4185-85E2-D7ACDA93F7A6 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = PlatformBootManagerLib|DXE_DRIVER + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + PlatformData.c + PlatformConsole.c + PlatformConsole.h + PlatformBootManager.c + PlatformBootManager.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + CorebootPayloadPkg/CorebootPayloadPkg.dec + +[LibraryClasses] + BaseLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + UefiLib + UefiBootManagerLib + PcdLib + DxeServicesLib + MemoryAllocationLib + DevicePathLib + HiiLib + PrintLib + +[Guids] + + +[Protocols] + gEfiGenericMemTestProtocolGuid ## CONSUMES + gEfiGraphicsOutputProtocolGuid ## CONSUMES + gEfiUgaDrawProtocolGuid ## CONSUMES + gEfiBootLogoProtocolGuid ## CONSUMES + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut + gEfiMdePkgTokenSpaceGuid.PcdUgaConsumeSupport + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn + gEfiMdeModulePkgTokenSpaceGuid.PcdConInConnectOnDemand + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdBootlogoOnlyEnable + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile + gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity + gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits diff --git a/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.c b/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.c new file mode 100644 index 0000000000..16a146fe53 --- /dev/null +++ b/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.c @@ -0,0 +1,617 @@ +/** @file +This file include all platform action which can be customized by IBV/OEM. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "PlatformBootManager.h" +#include "PlatformConsole.h" + +#define PCI_DEVICE_PATH_NODE(Func, Dev) \ + { \ + { \ + HARDWARE_DEVICE_PATH, \ + HW_PCI_DP, \ + { \ + (UINT8) (sizeof (PCI_DEVICE_PATH)), \ + (UINT8) ((sizeof (PCI_DEVICE_PATH)) >> 8) \ + } \ + }, \ + (Func), \ + (Dev) \ + } + +#define PNPID_DEVICE_PATH_NODE(PnpId) \ + { \ + { \ + ACPI_DEVICE_PATH, \ + ACPI_DP, \ + { \ + (UINT8) (sizeof (ACPI_HID_DEVICE_PATH)), \ + (UINT8) ((sizeof (ACPI_HID_DEVICE_PATH)) >> 8) \ + }, \ + }, \ + EISA_PNP_ID((PnpId)), \ + 0 \ + } + +#define gPciRootBridge \ + PNPID_DEVICE_PATH_NODE(0x0A03) + +#define gPnp16550ComPort \ + PNPID_DEVICE_PATH_NODE(0x0501) + +#define gUartVendor \ + { \ + { \ + HARDWARE_DEVICE_PATH, \ + HW_VENDOR_DP, \ + { \ + (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \ + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \ + } \ + }, \ + {0xD3987D4B, 0x971A, 0x435F, {0x8C, 0xAF, 0x49, 0x67, 0xEB, 0x62, 0x72, 0x41}} \ + } + +#define gUart \ + { \ + { \ + MESSAGING_DEVICE_PATH, \ + MSG_UART_DP, \ + { \ + (UINT8) (sizeof (UART_DEVICE_PATH)), \ + (UINT8) ((sizeof (UART_DEVICE_PATH)) >> 8) \ + } \ + }, \ + 0, \ + 115200, \ + 8, \ + 1, \ + 1 \ + } + +#define gPcAnsiTerminal \ + { \ + { \ + MESSAGING_DEVICE_PATH, \ + MSG_VENDOR_DP, \ + { \ + (UINT8) (sizeof (VENDOR_DEVICE_PATH)), \ + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) \ + } \ + }, \ + DEVICE_PATH_MESSAGING_PC_ANSI \ + } + + +ACPI_HID_DEVICE_PATH gPnp16550ComPortDeviceNode = gPnp16550ComPort; +UART_DEVICE_PATH gUartDeviceNode = gUart; +VENDOR_DEVICE_PATH gTerminalTypeDeviceNode = gPcAnsiTerminal; +VENDOR_DEVICE_PATH gUartDeviceVendorNode = gUartVendor; + +// +// Predefined platform root bridge +// +PLATFORM_ROOT_BRIDGE_DEVICE_PATH gPlatformRootBridge0 = { + gPciRootBridge, + gEndEntire +}; + +EFI_DEVICE_PATH_PROTOCOL *gPlatformRootBridges[] = { + (EFI_DEVICE_PATH_PROTOCOL *) &gPlatformRootBridge0, + NULL +}; + +BOOLEAN mDetectVgaOnly; + +/** + Add UART to ConOut, ConIn, ErrOut. + + @param[in] DeviceHandle - LPC device path. + + @retval EFI_SUCCESS - Serial console is added to ConOut, ConIn, and ErrOut. + @retval EFI_STATUS - No serial console is added. +**/ +EFI_STATUS +PrepareLpcBridgeDevicePath ( + IN EFI_HANDLE DeviceHandle +) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + DevicePath = NULL; + Status = gBS->HandleProtocol ( + DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Register COM1 + // + DevicePath = AppendDevicePathNode ((EFI_DEVICE_PATH_PROTOCOL *)NULL, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceVendorNode); + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode); + + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL); + + return EFI_SUCCESS; +} + +/** + Return the GOP device path in the platform. + + @param[in] PciDevicePath - Device path for the PCI graphics device. + @param[out] GopDevicePath - Return the device path with GOP installed. + + @retval EFI_SUCCESS - PCI VGA is added to ConOut. + @retval EFI_INVALID_PARAMETER - The device path parameter is invalid. + @retval EFI_STATUS - No GOP device found. +**/ +EFI_STATUS +GetGopDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *PciDevicePath, + OUT EFI_DEVICE_PATH_PROTOCOL **GopDevicePath +) +{ + UINTN Index; + EFI_STATUS Status; + EFI_HANDLE PciDeviceHandle; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; + EFI_DEVICE_PATH_PROTOCOL *TempPciDevicePath; + UINTN GopHandleCount; + EFI_HANDLE *GopHandleBuffer; + ACPI_ADR_DEVICE_PATH AcpiAdr; + EFI_DEVICE_PATH_PROTOCOL *MyDevicePath; + + if (PciDevicePath == NULL || GopDevicePath == NULL) { + return EFI_INVALID_PARAMETER; + } + + MyDevicePath = NULL; + + // + // Initialize the GopDevicePath to be PciDevicePath + // + *GopDevicePath = PciDevicePath; + TempPciDevicePath = PciDevicePath; + + Status = gBS->LocateDevicePath ( + &gEfiDevicePathProtocolGuid, + &TempPciDevicePath, + &PciDeviceHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Try to connect this handle, so that GOP dirver could start on this + // device and create child handles with GraphicsOutput Protocol installed + // on them, then we get device paths of these child handles and select + // them as possible console device. + // + AcpiAdr.Header.Type = ACPI_DEVICE_PATH; + AcpiAdr.Header.SubType = ACPI_ADR_DP; + AcpiAdr.ADR= ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_INTERNAL_DIGITAL, 8, 0); + + SetDevicePathNodeLength (&AcpiAdr.Header, sizeof (ACPI_ADR_DEVICE_PATH)); + + MyDevicePath = AppendDevicePathNode(MyDevicePath, (EFI_DEVICE_PATH_PROTOCOL*)&AcpiAdr); + + gBS->ConnectController (PciDeviceHandle, NULL, MyDevicePath, FALSE); + + FreePool(MyDevicePath); + + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiGraphicsOutputProtocolGuid, + NULL, + &GopHandleCount, + &GopHandleBuffer + ); + if (!EFI_ERROR (Status)) { + // + // Add all the child handles as possible Console Device + // + for (Index = 0; Index < GopHandleCount; Index++) { + Status = gBS->HandleProtocol (GopHandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID*)&TempDevicePath); + if (EFI_ERROR (Status)) { + continue; + } + if (CompareMem ( + PciDevicePath, + TempDevicePath, + GetDevicePathSize (PciDevicePath) - END_DEVICE_PATH_LENGTH + ) == 0) { + // + // In current implementation, we only enable one of the child handles + // as console device, i.e. sotre one of the child handle's device + // path to variable "ConOut" + // In futhure, we could select all child handles to be console device + // + *GopDevicePath = TempDevicePath; + + // + // Delete the PCI device's path that added by GetPlugInPciVgaDevicePath() + // Add the integrity GOP device path. + // + EfiBootManagerUpdateConsoleVariable (ConOut, NULL, PciDevicePath); + EfiBootManagerUpdateConsoleVariable (ConOut, TempDevicePath, NULL); + } + } + gBS->FreePool (GopHandleBuffer); + } + + return EFI_SUCCESS; +} + +/** + Add PCI VGA to ConOut, ConIn, ErrOut. + + @param[in] DeviceHandle - Handle of PciIo protocol. + + @retval EFI_SUCCESS - PCI VGA is added to ConOut. + @retval EFI_STATUS - No PCI VGA device is added. + +**/ +EFI_STATUS +PreparePciVgaDevicePath ( + IN EFI_HANDLE DeviceHandle +) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *GopDevicePath; + + DevicePath = NULL; + Status = gBS->HandleProtocol ( + DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + GetGopDevicePath (DevicePath, &GopDevicePath); + DevicePath = GopDevicePath; + + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); + + return EFI_SUCCESS; +} + +/** + Add PCI Serial to ConOut, ConIn, ErrOut. + + @param[in] DeviceHandle - Handle of PciIo protocol. + + @retval EFI_SUCCESS - PCI Serial is added to ConOut, ConIn, and ErrOut. + @retval EFI_STATUS - No PCI Serial device is added. + +**/ +EFI_STATUS +PreparePciSerialDevicePath ( + IN EFI_HANDLE DeviceHandle +) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + DevicePath = NULL; + Status = gBS->HandleProtocol ( + DeviceHandle, + &gEfiDevicePathProtocolGuid, + (VOID*)&DevicePath + ); + if (EFI_ERROR (Status)) { + return Status; + } + + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gUartDeviceNode); + DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&gTerminalTypeDeviceNode); + + EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ConIn, DevicePath, NULL); + EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL); + + return EFI_SUCCESS; +} + + +/** + For every PCI instance execute a callback function. + + @param[in] Id - The protocol GUID for callback + @param[in] CallBackFunction - The callback function + @param[in] Context - The context of the callback + + @retval EFI_STATUS - Callback function failed. + +**/ +EFI_STATUS +EFIAPI +VisitAllInstancesOfProtocol ( + IN EFI_GUID *Id, + IN PROTOCOL_INSTANCE_CALLBACK CallBackFunction, + IN VOID *Context +) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuffer; + UINTN Index; + VOID *Instance; + + // + // Start to check all the PciIo to find all possible device + // + HandleCount = 0; + HandleBuffer = NULL; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + Id, + NULL, + &HandleCount, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->HandleProtocol (HandleBuffer[Index], Id, &Instance); + if (EFI_ERROR (Status)) { + continue; + } + + Status = (*CallBackFunction) ( + HandleBuffer[Index], + Instance, + Context + ); + } + + gBS->FreePool (HandleBuffer); + + return EFI_SUCCESS; +} + + +/** + For every PCI instance execute a callback function. + + @param[in] Handle - The PCI device handle + @param[in] Instance - The instance of the PciIo protocol + @param[in] Context - The context of the callback + + @retval EFI_STATUS - Callback function failed. + +**/ +EFI_STATUS +EFIAPI +VisitingAPciInstance ( + IN EFI_HANDLE Handle, + IN VOID *Instance, + IN VOID *Context +) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + PCI_TYPE00 Pci; + + PciIo = (EFI_PCI_IO_PROTOCOL*) Instance; + + // + // Check for all PCI device + // + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint32, + 0, + sizeof (Pci) / sizeof (UINT32), + &Pci + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return (*(VISIT_PCI_INSTANCE_CALLBACK)(UINTN) Context) ( + Handle, + PciIo, + &Pci + ); + +} + + +/** + For every PCI instance execute a callback function. + + @param[in] CallBackFunction - Callback function pointer + + @retval EFI_STATUS - Callback function failed. + +**/ +EFI_STATUS +EFIAPI +VisitAllPciInstances ( + IN VISIT_PCI_INSTANCE_CALLBACK CallBackFunction +) +{ + return VisitAllInstancesOfProtocol ( + &gEfiPciIoProtocolGuid, + VisitingAPciInstance, + (VOID*)(UINTN) CallBackFunction + ); +} + + +/** + Do platform specific PCI Device check and add them to + ConOut, ConIn, ErrOut. + + @param[in] Handle - Handle of PCI device instance + @param[in] PciIo - PCI IO protocol instance + @param[in] Pci - PCI Header register block + + @retval EFI_SUCCESS - PCI Device check and Console variable update successfully. + @retval EFI_STATUS - PCI Device check or Console variable update fail. + +**/ +EFI_STATUS +EFIAPI +DetectAndPreparePlatformPciDevicePath ( + IN EFI_HANDLE Handle, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN PCI_TYPE00 *Pci +) +{ + EFI_STATUS Status; + + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationEnable, + EFI_PCI_DEVICE_ENABLE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + if (!mDetectVgaOnly) { + // + // Here we decide whether it is LPC Bridge + // + if ((IS_PCI_LPC (Pci)) || + ((IS_PCI_ISA_PDECODE (Pci)) && + (Pci->Hdr.VendorId == 0x8086) + ) + ) { + // + // Add IsaKeyboard to ConIn, + // add IsaSerial to ConOut, ConIn, ErrOut + // + DEBUG ((EFI_D_INFO, "Found LPC Bridge device\n")); + PrepareLpcBridgeDevicePath (Handle); + return EFI_SUCCESS; + } + // + // Here we decide which Serial device to enable in PCI bus + // + if (IS_PCI_16550SERIAL (Pci)) { + // + // Add them to ConOut, ConIn, ErrOut. + // + DEBUG ((EFI_D_INFO, "Found PCI 16550 SERIAL device\n")); + PreparePciSerialDevicePath (Handle); + return EFI_SUCCESS; + } + } + + // + // Here we decide which VGA device to enable in PCI bus + // + if (IS_PCI_VGA (Pci)) { + // + // Add them to ConOut. + // + DEBUG ((EFI_D_INFO, "Found PCI VGA device\n")); + PreparePciVgaDevicePath (Handle); + return EFI_SUCCESS; + } + + return Status; +} + + +/** + Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut + + @param[in] DetectVgaOnly - Only detect VGA device if it's TRUE. + + @retval EFI_SUCCESS - PCI Device check and Console variable update successfully. + @retval EFI_STATUS - PCI Device check or Console variable update fail. + +**/ +EFI_STATUS +DetectAndPreparePlatformPciDevicePaths ( + BOOLEAN DetectVgaOnly +) +{ + mDetectVgaOnly = DetectVgaOnly; + return VisitAllPciInstances (DetectAndPreparePlatformPciDevicePath); +} + + +/** + The function will connect root bridge + + @return EFI_SUCCESS Connect RootBridge successfully. + +**/ +EFI_STATUS +ConnectRootBridge ( + VOID +) +{ + EFI_STATUS Status; + EFI_HANDLE RootHandle; + + // + // Make all the PCI_IO protocols on PCI Seg 0 show up + // + Status = gBS->LocateDevicePath ( + &gEfiDevicePathProtocolGuid, + &gPlatformRootBridges[0], + &RootHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->ConnectController (RootHandle, NULL, NULL, FALSE); + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} + +/** + Platform console init. Include the platform firmware vendor, revision + and so crc check. + +**/ +VOID +EFIAPI +PlatformConsoleInit ( + VOID +) +{ + gUartDeviceNode.BaudRate = PcdGet64 (PcdUartDefaultBaudRate); + gUartDeviceNode.DataBits = PcdGet8 (PcdUartDefaultDataBits); + gUartDeviceNode.Parity = PcdGet8 (PcdUartDefaultParity); + gUartDeviceNode.StopBits = PcdGet8 (PcdUartDefaultStopBits); + + ConnectRootBridge (); + + // + // Do platform specific PCI Device check and add them to ConOut, ConIn, ErrOut + // + DetectAndPreparePlatformPciDevicePaths (FALSE); +} diff --git a/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.h b/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.h new file mode 100644 index 0000000000..5e9fb92610 --- /dev/null +++ b/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformConsole.h @@ -0,0 +1,76 @@ +/** @file +Head file for BDS Platform specific code + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#ifndef _PLATFORM_CONSOLE_H +#define _PLATFORM_CONSOLE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IS_PCI_ISA_PDECODE(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA_PDECODE, 0) +#define IS_PCI_16550SERIAL(_p) IS_CLASS3 (_p, PCI_CLASS_SCC, PCI_SUBCLASS_SERIAL, PCI_IF_16550) + +// +// Type definitions +// + +// +// Platform Root Bridge +// +typedef struct { + ACPI_HID_DEVICE_PATH PciRootBridge; + EFI_DEVICE_PATH_PROTOCOL End; +} PLATFORM_ROOT_BRIDGE_DEVICE_PATH; + +typedef +EFI_STATUS +(EFIAPI *PROTOCOL_INSTANCE_CALLBACK)( + IN EFI_HANDLE Handle, + IN VOID *Instance, + IN VOID *Context +); + +/** + @param[in] Handle - Handle of PCI device instance + @param[in] PciIo - PCI IO protocol instance + @param[in] Pci - PCI Header register block +**/ +typedef +EFI_STATUS +(EFIAPI *VISIT_PCI_INSTANCE_CALLBACK)( + IN EFI_HANDLE Handle, + IN EFI_PCI_IO_PROTOCOL *PciIo, + IN PCI_TYPE00 *Pci +); + +/** + Platform console init. Include the platform firmware vendor, revision + and so crc check. + +**/ +VOID +EFIAPI +PlatformConsoleInit ( + VOID +); + +#endif diff --git a/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformData.c b/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformData.c new file mode 100644 index 0000000000..2fbe3e92b6 --- /dev/null +++ b/CorebootPayloadPkg/Library/PlatformBootManagerLib/PlatformData.c @@ -0,0 +1,25 @@ +/**@file + Defined the platform specific device path which will be filled to + ConIn/ConOut variables. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include "PlatformBootManager.h" + +/// +/// Predefined platform default console device path +/// +PLATFORM_CONSOLE_CONNECT_ENTRY gPlatformConsole[] = { + { + NULL, + 0 + } +}; -- 2.39.2