From 2c85c3eefbcd21b02e73bf2054ecfcdcbcbe1f01 Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Wed, 3 Aug 2016 09:59:56 +0800 Subject: BraswellPlatformPkg: Move FspSupport to Common/FspSupport Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang Reviewed-by: David Wei --- .../Common/FspSupport/GraphicsOutputDxe/BltLib.h | 148 +++ .../FspSupport/GraphicsOutputDxe/ComponentName.c | 190 ++++ .../FspSupport/GraphicsOutputDxe/GraphicsOutput.c | 664 ++++++++++++ .../FspSupport/GraphicsOutputDxe/GraphicsOutput.h | 52 + .../GraphicsOutputDxe/GraphicsOutputDxe.inf | 58 + .../BaseFspPlatformInfoLibSample.inf | 124 +++ .../FspPlatformInfoLibSample.c | 591 ++++++++++ .../MemoryMappedVariable.c | 1132 ++++++++++++++++++++ .../MemoryMappedVariable.h | 148 +++ .../Library/FrameBufferBltLib/FrameBufferBltLib.c | 572 ++++++++++ .../FrameBufferBltLib/FrameBufferBltLib.inf | 33 + .../Library/PeiFspHobProcessLib/FspHobProcessLib.c | 528 +++++++++ .../PeiFspHobProcessLib/PeiFspHobProcessLib.inf | 122 +++ 13 files changed, 4362 insertions(+) create mode 100644 BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/BltLib.h create mode 100644 BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/ComponentName.c create mode 100644 BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutput.c create mode 100644 BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutput.h create mode 100644 BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutputDxe.inf create mode 100644 BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf create mode 100644 BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/FspPlatformInfoLibSample.c create mode 100644 BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/MemoryMappedVariable.c create mode 100644 BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/MemoryMappedVariable.h create mode 100644 BraswellPlatformPkg/Common/FspSupport/Library/FrameBufferBltLib/FrameBufferBltLib.c create mode 100644 BraswellPlatformPkg/Common/FspSupport/Library/FrameBufferBltLib/FrameBufferBltLib.inf create mode 100644 BraswellPlatformPkg/Common/FspSupport/Library/PeiFspHobProcessLib/FspHobProcessLib.c create mode 100644 BraswellPlatformPkg/Common/FspSupport/Library/PeiFspHobProcessLib/PeiFspHobProcessLib.inf (limited to 'BraswellPlatformPkg/Common') diff --git a/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/BltLib.h b/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/BltLib.h new file mode 100644 index 0000000000..7dde7d15c6 --- /dev/null +++ b/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/BltLib.h @@ -0,0 +1,148 @@ +/** @file + Library for performing video blt operations + + Copyright (c) 2009 - 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 __BLT_LIB__ +#define __BLT_LIB__ + +#include + +/** + Performs a UEFI Graphics Output Protocol Blt Video Fill. + + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] Color Color to fill the region with + @param[in] DestinationX X location to start fill operation + @param[in] DestinationY Y location to start fill operation + @param[in] Width Width (in pixels) to fill + @param[in] Height Height to fill + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success + +**/ +EFI_STATUS +EFIAPI +BltVideoFill ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height + ); + +/** + Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation. + + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[out] BltBuffer Output buffer for pixel color data + @param[in] SourceX X location within video + @param[in] SourceY Y location within video + @param[in] DestinationX X location within BltBuffer + @param[in] DestinationY Y location within BltBuffer + @param[in] Width Width (in pixels) + @param[in] Height Height + @param[in] Delta Number of bytes in a row of BltBuffer + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success + +**/ +EFI_STATUS +EFIAPI +BltVideoToBuffer ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ); + +/** + Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation. + + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] BltBuffer Output buffer for pixel color data + @param[in] SourceX X location within BltBuffer + @param[in] SourceY Y location within BltBuffer + @param[in] DestinationX X location within video + @param[in] DestinationY Y location within video + @param[in] Width Width (in pixels) + @param[in] Height Height + @param[in] Delta Number of bytes in a row of BltBuffer + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success + +**/ +EFI_STATUS +EFIAPI +BltBufferToVideo ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ); + +/** + Performs a UEFI Graphics Output Protocol Blt Video to Video operation. + + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] SourceX X location within video + @param[in] SourceY Y location within video + @param[in] DestinationX X location within video + @param[in] DestinationY Y location within video + @param[in] Width Width (in pixels) + @param[in] Height Height + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success + +**/ +EFI_STATUS +EFIAPI +BltVideoToVideo ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height + ); + +#endif + diff --git a/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/ComponentName.c b/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/ComponentName.c new file mode 100644 index 0000000000..54864b51f6 --- /dev/null +++ b/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/ComponentName.c @@ -0,0 +1,190 @@ +/** @file + UEFI Component Name(2) protocol implementation for the generic GOP driver. + + 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 +#include + +extern EFI_COMPONENT_NAME_PROTOCOL mGraphicsOutputComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL mGraphicsOutputComponentName2; + +// +// Driver name table for GraphicsOutput module. +// It is shared by the implementation of ComponentName & ComponentName2 Protocol. +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mGraphicsOutputDriverNameTable[] = { + { + "eng;en", + L"Generic Graphics Output Driver" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param[in] Language A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param[out] DriverName A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +GraphicsOutputComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mGraphicsOutputDriverNameTable, + DriverName, + (BOOLEAN) (This == &mGraphicsOutputComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param[in] This A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param[in] ControllerHandle The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param[in] ChildHandle The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param[in] Language A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param[out] ControllerName A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +GraphicsOutputComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + return EFI_UNSUPPORTED; +} + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL mGraphicsOutputComponentName = { + GraphicsOutputComponentNameGetDriverName, + GraphicsOutputComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL mGraphicsOutputComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) GraphicsOutputComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) GraphicsOutputComponentNameGetControllerName, + "en" +}; diff --git a/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutput.c b/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutput.c new file mode 100644 index 0000000000..eccd973ccf --- /dev/null +++ b/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutput.c @@ -0,0 +1,664 @@ +/** @file + Implementation for a generic GOP driver. + + 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 "GraphicsOutput.h" + +ACPI_ADR_DEVICE_PATH mGraphicsOutputAdrNode = { + { + ACPI_DEVICE_PATH, + ACPI_ADR_DP, + sizeof (ACPI_ADR_DEVICE_PATH), + 0 + }, + ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0) +}; + +/** + Returns information for an available graphics mode that the graphics device + and the set of active video output devices supports. + + @param[in] This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance. + @param[in] ModeNumber The mode number to return information on. + @param[out] SizeOfInfo A pointer to the size, in bytes, of the Info buffer. + @param[out] Info A pointer to callee allocated buffer that returns information about ModeNumber. + + @retval EFI_SUCCESS Valid mode information was returned. + @retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode. + @retval EFI_INVALID_PARAMETER ModeNumber is not valid. + +**/ +EFI_STATUS +EFIAPI +GraphicsOutputQueryMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber, + OUT UINTN *SizeOfInfo, + OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info + ) +{ + if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) { + return EFI_INVALID_PARAMETER; + } + + *SizeOfInfo = This->Mode->SizeOfInfo; + *Info = AllocateCopyPool (*SizeOfInfo, This->Mode->Info); + + return EFI_SUCCESS; +} + +/** + Set the video device into the specified mode and clears the visible portions of + the output display to black. + + @param[in] This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance. + @param[in] ModeNumber Abstraction that defines the current video mode. + + @retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected. + @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. + @retval EFI_UNSUPPORTED ModeNumber is not supported by this device. + +**/ +EFI_STATUS +EFIAPI +GraphicsOutputSetMode ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN UINT32 ModeNumber + ) +{ + EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black; + + if (ModeNumber >= This->Mode->MaxMode) { + return EFI_UNSUPPORTED; + } + + Black.Blue = 0; + Black.Green = 0; + Black.Red = 0; + Black.Reserved = 0; + + return BltVideoFill ((VOID *) (UINTN) This->Mode->FrameBufferBase, This->Mode->Info, &Black, 0, 0, This->Mode->Info->HorizontalResolution, This->Mode->Info->VerticalResolution); +} + +/** + Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer. + + @param[in] This Protocol instance pointer. + @param[in] BltBuffer The data to transfer to the graphics screen. + Size is at least Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL). + @param[in] BltOperation The operation to perform when copying BltBuffer on to the graphics screen. + @param[in] SourceX The X coordinate of source for the BltOperation. + @param[in] SourceY The Y coordinate of source for the BltOperation. + @param[in] DestinationX The X coordinate of destination for the BltOperation. + @param[in] DestinationY The Y coordinate of destination for the BltOperation. + @param[in] Width The width of a rectangle in the blt rectangle in pixels. + @param[in] Height The height of a rectangle in the blt rectangle in pixels. + @param[in] Delta Not used for EfiBltVideoFill or the EfiBltVideoToVideo operation. + If a Delta of zero is used, the entire BltBuffer is being operated on. + If a subrectangle of the BltBuffer is being used then Delta + represents the number of bytes in a row of the BltBuffer. + + @retval EFI_SUCCESS BltBuffer was drawn to the graphics screen. + @retval EFI_INVALID_PARAMETER BltOperation is not valid. + @retval EFI_DEVICE_ERROR The device had an error and could not complete the request. + +**/ +EFI_STATUS +EFIAPI +GraphicsOutputBlt ( + IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL + IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta OPTIONAL + ) +{ + EFI_STATUS Status; + EFI_TPL Tpl; + // + // We have to raise to TPL_NOTIFY, so we make an atomic write to the frame buffer. + // We would not want a timer based event (Cursor, ...) to come in while we are + // doing this operation. + // + Tpl = gBS->RaiseTPL (TPL_NOTIFY); + + switch (BltOperation) { + case EfiBltVideoToBltBuffer: + Status = BltVideoToBuffer ( + (VOID *) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, + BltBuffer, + SourceX, + SourceY, + DestinationX, + DestinationY, + Width, + Height, + Delta + ); + break; + + case EfiBltVideoToVideo: + Status = BltVideoToVideo ( + (VOID *) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, + SourceX, + SourceY, + DestinationX, + DestinationY, + Width, + Height + ); + break; + + case EfiBltVideoFill: + Status = BltVideoFill ( + (VOID *) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, + BltBuffer, + DestinationX, + DestinationY, + Width, + Height + ); + break; + + case EfiBltBufferToVideo: + Status = BltBufferToVideo ( + (VOID *) (UINTN) This->Mode->FrameBufferBase, + This->Mode->Info, + BltBuffer, + SourceX, + SourceY, + DestinationX, + DestinationY, + Width, + Height, + Delta + ); + break; + + default: + Status = EFI_INVALID_PARAMETER; + break; + } + + gBS->RestoreTPL (Tpl); + + return Status; +} + +GRAPHICS_OUTPUT_PRIVATE_DATA mGraphicsOutputInstance = { + NULL, // GraphicsOutputHandle + { + GraphicsOutputQueryMode, + GraphicsOutputSetMode, + GraphicsOutputBlt, + &mGraphicsOutputInstance.GraphicsOutputMode + }, + { + 1, // MaxMode + 0, // Mode + NULL, // Info + sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), // SizeOfInfo + 0, // FrameBufferBase + 0 // FrameBufferSize + }, + NULL, // DevicePath + NULL, // PciIo + 0 // PciAttributes +}; + +/** + Test whether the Controller can be managed by the driver. + + @param[in] This Driver Binding protocol instance pointer. + @param[in] Controller The PCI controller. + @param[in] RemainingDevicePath Optional parameter use to pick a specific child + device to start. + + @retval EFI_SUCCESS The driver can manage the video device. + @retval other The driver cannot manage the video device. +**/ +EFI_STATUS +EFIAPI +GraphicsOutputDriverBindingSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + + // + // Since there is only one GraphicsInfo HOB, the driver only manages one video device. + // + if (mGraphicsOutputInstance.GraphicsOutputHandle != NULL) { + return EFI_ALREADY_STARTED; + } + + // + // Test the PCI I/O Protocol + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (Status == EFI_ALREADY_STARTED) { + Status = EFI_SUCCESS; + } + if (EFI_ERROR (Status)) { + return Status; + } + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + // + // Test the DevicePath protocol + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &DevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (Status == EFI_ALREADY_STARTED) { + Status = EFI_SUCCESS; + } + if (EFI_ERROR (Status)) { + return Status; + } + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + if ((RemainingDevicePath == NULL) || + IsDevicePathEnd (RemainingDevicePath) || + CompareMem (RemainingDevicePath, &mGraphicsOutputAdrNode, sizeof (mGraphicsOutputAdrNode)) == 0) { + return EFI_SUCCESS; + } else { + return EFI_INVALID_PARAMETER; + } +} + +/** + Start the video controller. + + @param[in] This Driver Binding protocol instance pointer. + @param[in] ControllerHandle The PCI controller. + @param[in] RemainingDevicePath Optional parameter use to pick a specific child + device to start. + + @retval EFI_SUCCESS The driver starts to manage the video device. + @retval other The driver cannot manage the video device. +**/ +EFI_STATUS +EFIAPI +GraphicsOutputDriverBindingStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath + ) +{ + EFI_STATUS Status; + EFI_PCI_IO_PROTOCOL *PciIo; + EFI_HANDLE Handle; + EFI_DEVICE_PATH *PciDevicePath; + PCI_TYPE00 Pci; + UINT8 Index; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Resources; + + // + // Open the PCI I/O Protocol + // + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &PciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (Status == EFI_ALREADY_STARTED) { + Status = EFI_SUCCESS; + } + ASSERT_EFI_ERROR (Status); + + Status = gBS->OpenProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + (VOID **) &PciDevicePath, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + if (Status == EFI_ALREADY_STARTED) { + Status = EFI_SUCCESS; + } + ASSERT_EFI_ERROR (Status); + + // + // Read the PCI Class Code from the PCI Device + // + Status = PciIo->Pci.Read ( + PciIo, + EfiPciIoWidthUint8, + OFFSET_OF (PCI_TYPE00, Hdr.ClassCode), + sizeof (Pci.Hdr.ClassCode), + &Pci.Hdr.ClassCode + ); + if (!EFI_ERROR (Status)) { + if (!IS_PCI_DISPLAY (&Pci)) { + Status = EFI_UNSUPPORTED; + } else { + // + // If it's a video device, check whether the device's frame buffer size matches the one in HOB. + // And update the frame buffer base. + // + for (Index = 1; Index < MAX_PCI_BAR; Index++) { + Status = PciIo->GetBarAttributes (PciIo, Index, NULL, (VOID**) &Resources); + if (!EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "[GraphicsOutputDxe]: BAR[%d]: Base = %lx, Length = %lx\n", Index, Resources->AddrRangeMin, Resources->AddrLen)); + if (Resources->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR && + Resources->Len == (UINT16) (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3) && + Resources->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM && + Resources->AddrLen >= mGraphicsOutputInstance.GraphicsOutputMode.FrameBufferSize) { + mGraphicsOutputInstance.GraphicsOutputMode.FrameBufferBase = Resources->AddrRangeMin; + if (!EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "[GraphicsOutputDxe]: ... matched!\n")); + break; + } + } + } + } + if (Index == MAX_PCI_BAR) { + Status = EFI_UNSUPPORTED; + } + } + } + + if (EFI_ERROR (Status)) { + goto Error; + } + + // + // Set attributes + // + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationGet, + 0, + &mGraphicsOutputInstance.PciAttributes + ); + if (!EFI_ERROR (Status)) { + Status = PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationEnable, + EFI_PCI_DEVICE_ENABLE, + NULL + ); + } + + if (EFI_ERROR (Status)) { + goto Error; + } + + if ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath)) { + return EFI_SUCCESS; + } + + + mGraphicsOutputInstance.DevicePath = AppendDevicePathNode (PciDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &mGraphicsOutputAdrNode); + ASSERT (mGraphicsOutputInstance.DevicePath != NULL); + + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &mGraphicsOutputInstance.GraphicsOutputHandle, + &gEfiGraphicsOutputProtocolGuid, &mGraphicsOutputInstance.GraphicsOutput, + &gEfiDevicePathProtocolGuid, mGraphicsOutputInstance.DevicePath, + NULL + ); + + if (!EFI_ERROR (Status)) { + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &mGraphicsOutputInstance.PciIo, + This->DriverBindingHandle, + mGraphicsOutputInstance.GraphicsOutputHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + if (EFI_ERROR (Status)) { + gBS->UninstallMultipleProtocolInterfaces ( + mGraphicsOutputInstance.GraphicsOutputHandle, + &gEfiGraphicsOutputProtocolGuid, &mGraphicsOutputInstance.GraphicsOutput, + &gEfiDevicePathProtocolGuid, mGraphicsOutputInstance.DevicePath, + NULL + ); + } + } + + if (EFI_ERROR (Status)) { + mGraphicsOutputInstance.GraphicsOutputHandle = NULL; + // + // Restore original PCI attributes + // + PciIo->Attributes ( + PciIo, + EfiPciIoAttributeOperationSet, + mGraphicsOutputInstance.PciAttributes, + NULL + ); + FreePool (mGraphicsOutputInstance.DevicePath); + } + +Error: + if (EFI_ERROR (Status)) { + // + // Close the PCI I/O Protocol + // + gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + + // + // Close the PCI I/O Protocol + // + gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + } + + return Status; +} + +/** + Stop the video controller. + + @param[in] This Driver Binding protocol instance pointer. + @param[in] Controller The PCI controller. + @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer. + @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL + if NumberOfChildren is 0. + + @retval EFI_SUCCESS The device was stopped. + @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error. +**/ +EFI_STATUS +EFIAPI +GraphicsOutputDriverBindingStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer + ) +{ + EFI_STATUS Status; + + if (NumberOfChildren == 0) { + // + // Restore original PCI attributes + // + Status = mGraphicsOutputInstance.PciIo->Attributes ( + mGraphicsOutputInstance.PciIo, + EfiPciIoAttributeOperationSet, + mGraphicsOutputInstance.PciAttributes, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Close the PCI I/O Protocol + // + Status = gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->CloseProtocol ( + Controller, + &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, + Controller + ); + ASSERT_EFI_ERROR (Status); + return EFI_SUCCESS; + } + + ASSERT (NumberOfChildren == 1); + ASSERT (ChildHandleBuffer[0] == mGraphicsOutputInstance.GraphicsOutputHandle); + Status = gBS->CloseProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + mGraphicsOutputInstance.GraphicsOutputHandle + ); + ASSERT_EFI_ERROR (Status); + // + // Remove the GOP protocol interface from the system + // + Status = gBS->UninstallMultipleProtocolInterfaces ( + mGraphicsOutputInstance.GraphicsOutputHandle, + &gEfiGraphicsOutputProtocolGuid, &mGraphicsOutputInstance.GraphicsOutput, + &gEfiDevicePathProtocolGuid, mGraphicsOutputInstance.DevicePath, + NULL + ); + if (!EFI_ERROR (Status)) { + mGraphicsOutputInstance.GraphicsOutputHandle = NULL; + FreePool (mGraphicsOutputInstance.DevicePath); + } else { + Status = gBS->OpenProtocol ( + Controller, + &gEfiPciIoProtocolGuid, + (VOID **) &mGraphicsOutputInstance.PciIo, + This->DriverBindingHandle, + mGraphicsOutputInstance.GraphicsOutputHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + ASSERT_EFI_ERROR (Status); + } + + return Status; +} + +EFI_DRIVER_BINDING_PROTOCOL mGraphicsOutputDriverBinding = { + GraphicsOutputDriverBindingSupported, + GraphicsOutputDriverBindingStart, + GraphicsOutputDriverBindingStop, + 0xffffffff, + NULL, + NULL +}; + +/** + The Entry Point for GraphicsOutput driver. + + It installs DriverBinding, ComponentName and ComponentName2 protocol if there is + GraphicsInfo HOB passed from Graphics PEIM. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +InitializeGraphicsOutput ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + VOID *HobStart; + EFI_PEI_GRAPHICS_INFO_HOB *GraphicsInfo; + + HobStart = GetFirstGuidHob (&gEfiGraphicsInfoHobGuid); + + if ((HobStart == NULL) || (GET_GUID_HOB_DATA_SIZE (HobStart) != sizeof (*GraphicsInfo))) { + return EFI_NOT_FOUND; + } + + GraphicsInfo = (EFI_PEI_GRAPHICS_INFO_HOB *) (GET_GUID_HOB_DATA (HobStart)); + + // + // Cache in global data + // + DEBUG ((EFI_D_INFO, "FrameBuffer = %lx/%lx\n", GraphicsInfo->FrameBufferBase, GraphicsInfo->FrameBufferSize)); + mGraphicsOutputInstance.GraphicsOutputMode.Info = &GraphicsInfo->GraphicsMode; + mGraphicsOutputInstance.GraphicsOutputMode.FrameBufferBase = GraphicsInfo->FrameBufferBase; + mGraphicsOutputInstance.GraphicsOutputMode.FrameBufferSize = GraphicsInfo->FrameBufferSize; + + Status = EfiLibInstallDriverBindingComponentName2 ( + ImageHandle, + SystemTable, + &mGraphicsOutputDriverBinding, + ImageHandle, + &mGraphicsOutputComponentName, + &mGraphicsOutputComponentName2 + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutput.h b/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutput.h new file mode 100644 index 0000000000..48c486418d --- /dev/null +++ b/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutput.h @@ -0,0 +1,52 @@ +/** @file + Header file for a generic GOP driver. + + 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 _GRAPHICS_OUTPUT_DXE_H_ +#define _GRAPHICS_OUTPUT_DXE_H_ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "BltLib.h" +#include +#include +#include +#include + +#define MAX_PCI_BAR 6 + + +typedef struct { + EFI_HANDLE GraphicsOutputHandle; + EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput; + EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE GraphicsOutputMode; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_PCI_IO_PROTOCOL *PciIo; + UINT64 PciAttributes; +} GRAPHICS_OUTPUT_PRIVATE_DATA; + +extern EFI_COMPONENT_NAME_PROTOCOL mGraphicsOutputComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL mGraphicsOutputComponentName2; +#endif diff --git a/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutputDxe.inf b/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutputDxe.inf new file mode 100644 index 0000000000..c7c0435ec4 --- /dev/null +++ b/BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutputDxe.inf @@ -0,0 +1,58 @@ +## @file +# This driver produces GraphicsOutput protocol based on the GraphicsInfo HOB information. +# +# 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = GraphicsOutputDxe + FILE_GUID = 20830080-CC28-4169-9836-7F42B8D0C8C9 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = InitializeGraphicsOutput + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.common] + GraphicsOutput.h + GraphicsOutput.c + ComponentName.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + DxeServicesTableLib + DebugLib + MemoryAllocationLib + BaseMemoryLib + DevicePathLib + BltLib + UefiLib + HobLib + +[Guids] + gEfiGraphicsInfoHobGuid # HOB TO_START + +[Protocols] + gEfiGraphicsOutputProtocolGuid # PROTOCOL BY_START + gEfiDevicePathProtocolGuid # PROTOCOL BY_START + gEfiPciIoProtocolGuid # PROTOCOL TO_START diff --git a/BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf b/BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf new file mode 100644 index 0000000000..a6e8103fa1 --- /dev/null +++ b/BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf @@ -0,0 +1,124 @@ +## @file +# Sample to provide FSP platform information related function. +# +# Copyright (c) 2014 - 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 Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseFspPlatformInfoLibSample + FILE_GUID = 7CB6D6ED-5012-4e35-A42E-4C6512085A9E + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspPlatformInfoLib + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources] + FspPlatformInfoLibSample.c + MemoryMappedVariable.c + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + IntelFspPkg/IntelFspPkg.dec + IntelFspWrapperPkg/IntelFspWrapperPkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + ChvRefCodePkg/ChvRefCodePkg.dec + ChvFspBinPkg/ChvFspBinPkg.dec + SecurityPkg/SecurityPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + UefiCpuLib + FspApiLib + HobLib + PcdLib + PeiServicesTablePointerLib + +[Ppis] + gEfiPeiReadOnlyVariable2PpiGuid ## CONSUMES + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdTemporaryRamBase ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdTemporaryRamSize ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdFlashFvSecondFspBase ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvVbtBase ## SOMETIME_CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFlashFvVbtSize ## SOMETIME_CONSUMES + gPlatformModuleTokenSpaceGuid.PcdCustomizedVbtFile ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdMaxUpdRegionSize ## CONSUMES + + gEfiEdkIIPlatformTokenSpaceGuid.PcdPlatformInfo ## CONSUMES + gEfiCHVTokenSpaceGuid.PcdBmpImageGuid ## SOMETIME_CONSUMES + gEfiEdkIIPlatformTokenSpaceGuid.PcdMemorySpdPtr ## CONSUMES + gEfiEdkIIPlatformTokenSpaceGuid.PcdOemMemeoryDimmType ## CONSUMES + gChvFspBinPkgTokenSpaceGuid.PcdMrcInitSpdAddr1 ## CONSUMES + gChvFspBinPkgTokenSpaceGuid.PcdMrcInitSpdAddr2 ## CONSUMES + + ## SOMETIMES_CONSUMES + gIntelSiBasicPkgTokenSpaceGuid.PcdMmioBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES + gPlatformModuleTokenSpaceGuid.PcdFspAuthenticatedVariable ## SOMETIMES_CONSUMES + +[PcdEx] + ## CONSUMES + gEfiEdkIIPlatformTokenSpaceGuid.PcdSystemConfiguration +[Guids] + gEfiChvVariableGuid + ## SOMETIMES_CONSUMES ## HOB + gEfiVariableGuid + ## SOMETIMES_CONSUMES ## HOB + gEfiVariableIndexTableGuid + gEfiSystemNvDataFvGuid ## SOMETIMES_CONSUMES ## GUID + ## SOMETIMES_CONSUMES ## HOB + gEdkiiFaultTolerantWriteGuid + ## SOMETIMES_CONSUMES + gEfiAuthenticatedVariableGuid + ## SOMETIMES_CONSUMES + gEfiVariableGuid + ## SOMETIMES_CONSUMES ## Guid + gEfiAcpiVariableCompatiblityGuid + + ## SOMETIMES_CONSUMES ## Guid + gEfiPlatformInfoGuid + + diff --git a/BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/FspPlatformInfoLibSample.c b/BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/FspPlatformInfoLibSample.c new file mode 100644 index 0000000000..6b436bb2b3 --- /dev/null +++ b/BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/FspPlatformInfoLibSample.c @@ -0,0 +1,591 @@ +/** @file + Sample to provide FSP platform information related function. + + Copyright (c) 2014 - 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +CHAR16 EfiMemoryConfigVariable[] = L"MemoryConfig"; + + +EFI_STATUS +FindVbt ( + IN EFI_GUID *FileName, + OUT EFI_PHYSICAL_ADDRESS *Vbt + ) +{ + EFI_STATUS Status; + UINTN Size; + UINT32 Pages; + VOID* Memory; + UINTN Instance; + EFI_PEI_FV_HANDLE VolumeHandle; + EFI_PEI_FILE_HANDLE FileHandle; + UINT8 *VbtData; + BOOLEAN Found; + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + + Size = PcdGet32 (PcdFlashFvVbtSize); + Pages= EFI_SIZE_TO_PAGES (Size); + + Memory = AllocatePages (Pages); + CopyMem(Memory , (VOID *) PcdGet32(PcdFlashFvVbtBase) , Size); + + PeiServicesInstallFvInfoPpi ( + NULL, + (VOID *) ((UINTN)Memory), + PcdGet32 (PcdFlashFvVbtSize), + NULL, + NULL + ); + + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)Memory; + BuildFvHob ((UINTN)FvHeader, FvHeader->FvLength); + + Found = FALSE; + Instance = 0; + while (TRUE) { + // + // Traverse all firmware volume instances + // + Status = PeiServicesFfsFindNextVolume (Instance, &VolumeHandle); + + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + return EFI_NOT_FOUND; + } + + // + // Find the PEIM file type from the beginning in this firmware volume. + // + FileHandle = NULL; + Status = PeiServicesFfsFindFileByName (FileName, VolumeHandle, &FileHandle); + if (!EFI_ERROR (Status)) { + Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &VbtData); + if (!EFI_ERROR (Status)) { + *Vbt = (EFI_PHYSICAL_ADDRESS)VbtData; + Found = TRUE; + break; + } + } + // + // We cannot find DxeCore in this firmware volume, then search the next volume. + // + Instance++; + } + + if (Found == TRUE) { + return EFI_SUCCESS; + } else { + return EFI_NOT_FOUND; + } +} + +STATIC +EFI_STATUS +UpdateSilicionInitUpd ( + IN EFI_PEI_SERVICES **PeiServices, + IN SILICON_INIT_UPD *SiliconInitUpd +) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS VbtAddress; + SYSTEM_CONFIGURATION SystemConfiguration; + EFI_PLATFORM_INFO_HOB *PlatformInfo = NULL; + EFI_BOOT_MODE BootMode; + + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + + PlatformInfo = PcdGetPtr (PcdPlatformInfo); + + if (*((UINT32 *)PcdGetPtr (PcdCustomizedVbtFile)) == SIGNATURE_32 ('$', 'V', 'B', 'T')) { + // It is a valid VBT Table + VbtAddress = (EFI_PHYSICAL_ADDRESS) (UINTN)PcdGetPtr (PcdCustomizedVbtFile); + } else { + Status = FindVbt (PcdGetPtr (PcdBmpImageGuid), &VbtAddress); + ASSERT_EFI_ERROR (Status); + } + + // + // Should skip FSP graphic initialization for S3 resume. + // + SiliconInitUpd->GraphicsConfigPtr = 0; + if (BootMode != BOOT_ON_S3_RESUME) { + SiliconInitUpd->GraphicsConfigPtr = (UINT32)VbtAddress; + } + + SiliconInitUpd->PcdLogoPtr = 0; + SiliconInitUpd->PcdLogoSize = 0; + + SiliconInitUpd->PcdDispClkSsc = 0x00; + SiliconInitUpd->GpioPadInitTablePtr = NULL; + SiliconInitUpd->GpioFamilyInitTablePtr = NULL; + + // + // Power Source Configuration for Cherry Hill. + // + SiliconInitUpd->PunitPwrConfigDisable = 0; // Enable PunitPwrConfig + SiliconInitUpd->ChvSvidConfig = PlatformInfo->BoardSvidConfig; + SiliconInitUpd->PMIC_I2CBus = 0; + + + DEBUG ((EFI_D_INFO, "FspSiliconInitUpd->PcdDispClkSsc = 0x%x\n", (UINT32)(UINTN)SiliconInitUpd->PcdDispClkSsc)); + DEBUG ((EFI_D_INFO, "PcdLogoPtr - 0x%x\n", SiliconInitUpd->PcdLogoPtr)); + DEBUG ((EFI_D_INFO, "PcdLogoSize - 0x%x\n", SiliconInitUpd->PcdLogoSize)); + DEBUG ((EFI_D_INFO, "GraphicsConfigPtr - 0x%x\n", SiliconInitUpd->GraphicsConfigPtr)); + DEBUG ((EFI_D_INFO, "VBT Sign - 0x%x\n", *(UINT32 *)(UINTN)SiliconInitUpd->GraphicsConfigPtr)); + + + // + // Update UPD accroding to platform SetUp. + // + CopyMem (&SystemConfiguration, PcdGetPtr (PcdSystemConfiguration), sizeof(SYSTEM_CONFIGURATION)); + + SiliconInitUpd->PcdEnableAzalia = SystemConfiguration.PchAzalia; + SiliconInitUpd->PcdEnableSata = SystemConfiguration.PchSata; + + SiliconInitUpd->PcdEnableXhci = SystemConfiguration.PchUsb30Mode; + SiliconInitUpd->PcdPchSsicEnable = SystemConfiguration.PchSsicEnable; + SiliconInitUpd->PcdPchUsbSsicPort = SystemConfiguration.PchUsbSsicPort[0]; + SiliconInitUpd->PcdPchUsbHsicPort = SystemConfiguration.PchUsbHsicPort[0]; + + SiliconInitUpd->Usb2Port0PerPortPeTxiSet = 0x7; + SiliconInitUpd->Usb2Port0PerPortTxiSet = 0x3; + SiliconInitUpd->Usb2Port0IUsbTxEmphasisEn = 0x2; + SiliconInitUpd->Usb2Port0PerPortTxPeHalf = 0x01; + + SiliconInitUpd->Usb2Port1PerPortPeTxiSet = 0x7; + SiliconInitUpd->Usb2Port1PerPortTxiSet = 0x3; + SiliconInitUpd->Usb2Port1IUsbTxEmphasisEn = 0x2; + SiliconInitUpd->Usb2Port1PerPortTxPeHalf = 0x01; + + SiliconInitUpd->Usb2Port2PerPortPeTxiSet = 0x7; + SiliconInitUpd->Usb2Port2PerPortTxiSet = 0x3; + SiliconInitUpd->Usb2Port2IUsbTxEmphasisEn = 0x2; + SiliconInitUpd->Usb2Port2PerPortTxPeHalf = 0x01; + + SiliconInitUpd->Usb2Port3PerPortPeTxiSet = 0x7; + SiliconInitUpd->Usb2Port3PerPortTxiSet = 0x3; + SiliconInitUpd->Usb2Port3IUsbTxEmphasisEn = 0x2; + SiliconInitUpd->Usb2Port3PerPortTxPeHalf = 0x01; + + SiliconInitUpd->Usb3Lane0Ow2tapgen2deemph3p5 = 0x3a; + SiliconInitUpd->Usb3Lane1Ow2tapgen2deemph3p5 = 0x3a; + SiliconInitUpd->Usb3Lane2Ow2tapgen2deemph3p5 = 0x3a; + SiliconInitUpd->Usb3Lane3Ow2tapgen2deemph3p5 = 0x3a; + + // + // LPSS devices. + // + SiliconInitUpd->PcdEnableHsuart0 = SystemConfiguration.LpssHsuart0Enabled; + SiliconInitUpd->PcdEnableHsuart1 = SystemConfiguration.LpssHsuart1Enabled; + SiliconInitUpd->PcdEnableLpe = SystemConfiguration.PchLpeEnabled; + SiliconInitUpd->PcdEnableDma0 = SystemConfiguration.LpssDma0Enabled; + SiliconInitUpd->PcdEnableDma1 = SystemConfiguration.LpssDma1Enabled; + SiliconInitUpd->PcdEnableI2C0 = SystemConfiguration.LpssI2C0Enabled; + SiliconInitUpd->PcdEnableI2C1 = SystemConfiguration.LpssI2C1Enabled; + SiliconInitUpd->PcdEnableI2C2 = SystemConfiguration.LpssI2C2Enabled; + SiliconInitUpd->PcdEnableI2C3 = SystemConfiguration.LpssI2C3Enabled; + SiliconInitUpd->PcdEnableI2C4 = SystemConfiguration.LpssI2C4Enabled; + SiliconInitUpd->PcdEnableI2C5 = SystemConfiguration.LpssI2C5Enabled; + SiliconInitUpd->PcdEnableI2C6 = SystemConfiguration.LpssI2C6Enabled; + + // + // SCC devices. + // + if (BootMode != BOOT_ON_S3_RESUME) { + // + // Config FSP not to initiliaze this device in its Notify function. PchDxe will do it in ExitBootService CallBack + // + if (SystemConfiguration.SccSdcardEnabled != PchDisabled) { + SiliconInitUpd->PcdSdcardMode = PchPciMode; + } else { + SiliconInitUpd->PcdSdcardMode = PchDisabled; + } + + if (SystemConfiguration.ScceMMCEnabled != PchDisabled) { + SiliconInitUpd->PcdEmmcMode = PchPciMode; + } else { + SiliconInitUpd->PcdEmmcMode = PchDisabled; + } + + } else { + // + // For S3 resume, let FSP swtich PCI mode/ACPI mode according to setup option. + // + SiliconInitUpd->PcdSdcardMode = SystemConfiguration.SccSdcardEnabled; + SiliconInitUpd->PcdEmmcMode = SystemConfiguration.ScceMMCEnabled; + } + + + + SiliconInitUpd->DptfDisable = 1; + if (SystemConfiguration.EnableDptf == 1) { + SiliconInitUpd->DptfDisable = 0; + } + + SiliconInitUpd->PcdSataInterfaceSpeed = SystemConfiguration.SataInterfaceSpeed; + SiliconInitUpd->ISPEnable = SystemConfiguration.ISPEn; + SiliconInitUpd->ISPPciDevConfig = SystemConfiguration.ISPDevSel; + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +UpdateMemoryInitUpd ( + MEMORY_INIT_UPD *FspUpdRgn +) +{ + MEMORY_INIT_UPD *MemoryInitUpd; + + + MemoryInitUpd = (MEMORY_INIT_UPD *)FspUpdRgn; + + DEBUG ((EFI_D_ERROR, "Memory Related UPD's can be overwritten here\n")); + + MemoryInitUpd->PcdMemChannel0Config = PcdGet8(PcdOemMemeoryDimmType); + MemoryInitUpd->PcdMemChannel1Config = PcdGet8(PcdOemMemeoryDimmType); + MemoryInitUpd->PcdMrcInitSpdAddr1 = PcdGet8(PcdMrcInitSpdAddr1); + MemoryInitUpd->PcdMrcInitSpdAddr2 = PcdGet8(PcdMrcInitSpdAddr2); + MemoryInitUpd->PcdMemorySpdPtr = (UINT32)(UINTN)PcdGet64 (PcdMemorySpdPtr); + + DEBUG ((DEBUG_INFO, "PcdMemorySpdPtr - 0x%x (0x%x)\n", MemoryInitUpd->PcdMemorySpdPtr, &(MemoryInitUpd->PcdMemorySpdPtr))); + + MemoryInitUpd->PcdGttSize = 2; // GTT_SIZE_4MB; + + // + // MMIO region below 4GB(MMIO Base - 4GB). Granuity is 1MB(0x10000) + // + MemoryInitUpd->PcdMrcInitMmioSize = (UINT16)(PcdGet32 (PcdMmioBase) >> 20); + + return EFI_SUCCESS; +} + +/** + Get current boot mode. + + @note At this point, memory is ready, PeiServices are NOT available to use. + Platform can get some data from chipset register. + + @return BootMode current boot mode. +**/ +UINT32 +EFIAPI +GetBootMode ( + VOID + ) +{ + EFI_PEI_SERVICES **PeiServices; + EFI_BOOT_MODE BootMode; + EFI_STATUS Status; + + PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (); + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + + if (BootMode == BOOT_ON_S3_RESUME) { + return BOOT_ON_S3_RESUME; + } + + return BOOT_WITH_FULL_CONFIGURATION; +} + +/** + Get NVS buffer parameter. + + @note At this point, memory is NOT ready, PeiServices are available to use. + + @return NvsBuffer NVS buffer parameter. + +**/ +VOID * +EFIAPI +GetNvsBuffer ( + VOID + ) +{ + UINTN VariableSize; + EFI_STATUS Status; + EFI_PEI_SERVICES **PeiServices; + UINT8* MrcData; + EFI_BOOT_MODE BootMode; + + PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (); + Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode); + VariableSize = 0; + MrcData = NULL; + + // + // TODO: Will remove this hardcode address. + // + VariableSize = 0x6C58; + + DEBUG((EFI_D_INFO, "VarSize=0x%x.\n", VariableSize)); + + // + // Get the MRC Parameters from SPI Flash. This function return the address of this variable in SPI Flash. + // + Status = PeiGetVariable ( + EfiMemoryConfigVariable, + &gEfiChvVariableGuid, + NULL, + &VariableSize, + &MrcData + ); + DEBUG((EFI_D_INFO, "Get MRC data from SPI Flash at 0x0x%=. \n", (UINT32)MrcData)); + + if (EFI_ERROR(Status)) + MrcData = NULL; + + return MrcData; +} + +/** + Get UPD region size. + + @note At this point, memory is NOT ready, PeiServices are available to use. + + @return UPD region size. + +**/ +UINT32 +EFIAPI +GetUpdRegionSize ( + VOID + ) +{ + return sizeof(UPD_DATA_REGION); +} + +/** + This function overrides the default configurations in the UPD data region. + + @note At this point, memory is NOT ready, PeiServices are available to use. + + @param[in, out] FspUpdRgnPtr A pointer to the UPD data region data strcture. + + @return FspUpdRgnPtr A pointer to the UPD data region data strcture. +**/ +VOID * +EFIAPI +UpdateFspUpdConfigs ( + IN OUT VOID *FspUpdRgnPtr + ) +{ + FSP_INFO_HEADER *pFspHeader = NULL; + VPD_DATA_REGION *FspVpdRgn = NULL; + UINT32 UpdRegionSize = sizeof(UPD_DATA_REGION); + MEMORY_INIT_UPD *MemoryInitUpd = NULL; + UPD_DATA_REGION *pFspUpdRgnPtrTmp = NULL; + + if (NULL == FspUpdRgnPtr) + return NULL; + + pFspUpdRgnPtrTmp = (UPD_DATA_REGION *)FspUpdRgnPtr; + if (PcdGet32 (PcdFlashFvSecondFspBase) == 0) { + pFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); + } else { + pFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvSecondFspBase)); + } + if (NULL == pFspHeader) { + return NULL; + } + + FspVpdRgn = (VPD_DATA_REGION *)(UINTN)(pFspHeader->ImageBase + pFspHeader->CfgRegionOffset); + + CopyMem (FspUpdRgnPtr, (void *)(pFspHeader->ImageBase + FspVpdRgn->PcdUpdRegionOffset), UpdRegionSize); + + MemoryInitUpd = (MEMORY_INIT_UPD *)((UINT8 *)FspUpdRgnPtr + pFspUpdRgnPtrTmp->MemoryInitUpdOffset); + + UpdateMemoryInitUpd((MEMORY_INIT_UPD *)MemoryInitUpd); + + return (VOID *)MemoryInitUpd; +} + +/** + Get BootLoader Tolum size. + + @note At this point, memory is NOT ready, PeiServices are available to use. + + @return BootLoader Tolum size. + +**/ +UINT32 +EFIAPI +GetBootLoaderTolumSize ( + VOID + ) +{ + return 0; +} + +/** + Get TempRamExit parameter. + + @note At this point, memory is ready, PeiServices are available to use. + + @return TempRamExit parameter. + +**/ +VOID * +EFIAPI +GetTempRamExitParam ( + VOID + ) +{ + return NULL; +} + +/** + Get FspSiliconInit parameter. + + @note At this point, memory is ready, PeiServices are available to use. + + @return FspSiliconInit parameter. + +**/ +VOID * +EFIAPI +GetFspSiliconInitParam ( + VOID + ) +{ + FSP_INFO_HEADER *FspHeader; + VPD_DATA_REGION *FspVpdRgn; + UPD_DATA_REGION *FspUpdRgnPtr; + SILICON_INIT_UPD *FspSiliconInitUpd; + EFI_PEI_SERVICES **PeiServices; + + if (PcdGet32 (PcdFlashFvSecondFspBase) == 0) { + FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); + } else { + FspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvSecondFspBase)); + } + if (FspHeader == NULL) { + return NULL; + } + + PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (); + if (PeiServices == NULL) { + return NULL; + } + + // + //Get VPD region start + // + FspVpdRgn = (VPD_DATA_REGION *)(UINTN)(FspHeader->ImageBase + FspHeader->CfgRegionOffset); + + ASSERT (PcdGet32 (PcdMaxUpdRegionSize) >= sizeof(UPD_DATA_REGION)); + FspUpdRgnPtr = (UPD_DATA_REGION *)AllocatePool (PcdGet32 (PcdMaxUpdRegionSize)); + if (NULL == FspUpdRgnPtr) { + DEBUG ((EFI_D_INFO, "Allocate failed.\n")); + return NULL; + } + + CopyMem ((UINT8 *)FspUpdRgnPtr, (UINT8 *)(FspHeader->ImageBase + FspVpdRgn->PcdUpdRegionOffset), sizeof(UPD_DATA_REGION)); + FspSiliconInitUpd = (SILICON_INIT_UPD *)((UINT8 *)FspUpdRgnPtr + FspUpdRgnPtr->SiliconInitUpdOffset); + DEBUG ((EFI_D_INFO, "FspSiliconInitUpd->Signature = 0x%x\n", (UINT32)(UINTN)FspSiliconInitUpd->Signature)); + DEBUG ((EFI_D_INFO, "FspSiliconInitUpd->PcdDispClkSsc = 0x%x\n", (UINT32)(UINTN)FspSiliconInitUpd->PcdDispClkSsc)); + + UpdateSilicionInitUpd (PeiServices, FspSiliconInitUpd); + + return FspSiliconInitUpd; +} + +/** + Get S3 PEI memory information. + + @note At this point, memory is ready, and PeiServices are available to use. + Platform can get some data from SMRAM directly. + + @param[out] S3PeiMemSize PEI memory size to be installed in S3 phase. + @param[out] S3PeiMemBase PEI memory base to be installed in S3 phase. + + @return If S3 PEI memory information is got successfully. + +**/ +EFI_STATUS +EFIAPI +GetS3MemoryInfo ( + OUT UINT64 *S3PeiMemSize, + OUT EFI_PHYSICAL_ADDRESS *S3PeiMemBase + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Get stack information according to boot mode. + + @note If BootMode is BOOT_ON_S3_RESUME or BOOT_ON_FLASH_UPDATE, + this stack should be in some reserved memory space. + + @note If FspInitDone is TRUE, memory is ready, but no PeiServices there. + Platform can get some data from SMRAM directly. + @note If FspInitDone is FALSE, memory is NOT ready, but PeiServices are available to use. + Platform can get some data from variable via VariablePpi. + + @param[in] BootMode Current boot mode. + @param[in] FspInitDone If FspInit is called. + @param[out] StackSize Stack size to be used in PEI phase. + @param[out] StackBase Stack base to be used in PEI phase. + + @return If Stack information is got successfully. + +**/ +EFI_STATUS +EFIAPI +GetStackInfo ( + IN UINT32 BootMode, + IN BOOLEAN FspInitDone, + OUT UINT64 *StackSize, + OUT EFI_PHYSICAL_ADDRESS *StackBase + ) +{ + *StackBase = PcdGet32 (PcdTemporaryRamBase); + *StackSize = PcdGet32 (PcdTemporaryRamSize); + + if (BootMode == BOOT_ON_S3_RESUME) { + if (!FspInitDone) { + } else { + } + } else if (BootMode == BOOT_ON_FLASH_UPDATE) { + if (!FspInitDone) { + } else { + } + } + + return EFI_SUCCESS; +} diff --git a/BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/MemoryMappedVariable.c b/BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/MemoryMappedVariable.c new file mode 100644 index 0000000000..dc142e003b --- /dev/null +++ b/BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/MemoryMappedVariable.c @@ -0,0 +1,1132 @@ +/** @file + Implement ReadOnly Variable Services required by PEIM and install + PEI ReadOnly Varaiable2 PPI. These services operates the non volatile storage space. + +Copyright (c) 2006 - 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 "MemoryMappedVariable.h" + + +/** + + Gets the pointer to the first variable header in given variable store area. + + @param VarStoreHeader Pointer to the Variable Store Header. + + @return Pointer to the first variable header + +**/ +VARIABLE_HEADER * +GetStartPointer ( + IN VARIABLE_STORE_HEADER *VarStoreHeader + ) +{ + // + // The end of variable store + // + return (VARIABLE_HEADER *) HEADER_ALIGN (VarStoreHeader + 1); +} + + +/** + This code gets the pointer to the last variable memory pointer byte. + + @param VarStoreHeader Pointer to the Variable Store Header. + + @return VARIABLE_HEADER* pointer to last unavailable Variable Header. + +**/ +VARIABLE_HEADER * +GetEndPointer ( + IN VARIABLE_STORE_HEADER *VarStoreHeader + ) +{ + // + // The end of variable store + // + return (VARIABLE_HEADER *) HEADER_ALIGN ((UINTN) VarStoreHeader + VarStoreHeader->Size); +} + + +/** + This code checks if variable header is valid or not. + + @param Variable Pointer to the Variable Header. + + @retval TRUE Variable header is valid. + @retval FALSE Variable header is not valid. + +**/ +BOOLEAN +IsValidVariableHeader ( + IN VARIABLE_HEADER *Variable + ) +{ + if (Variable == NULL || Variable->StartId != VARIABLE_DATA ) { + return FALSE; + } + + return TRUE; +} + +/** + This code gets the size of variable header. + + @param AuthFlag Authenticated variable flag. + + @return Size of variable header in bytes in type UINTN. + +**/ +UINTN +GetVariableHeaderSize ( + IN BOOLEAN AuthFlag + ) +{ + UINTN Value; + + if (AuthFlag) { + Value = sizeof (AUTHENTICATED_VARIABLE_HEADER); + } else { + Value = sizeof (VARIABLE_HEADER); + } + + return Value; +} + +/** + This code gets the size of name of variable. + + @param Variable Pointer to the Variable Header. + @param AuthFlag Authenticated variable flag. + + @return Size of variable in bytes in type UINTN. + +**/ +UINTN +NameSizeOfVariable ( + IN VARIABLE_HEADER *Variable, + IN BOOLEAN AuthFlag + ) +{ + AUTHENTICATED_VARIABLE_HEADER *AuthVariable; + + AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable; + if (AuthFlag) { + if (AuthVariable->State == (UINT8) (-1) || + AuthVariable->DataSize == (UINT32) (-1) || + AuthVariable->NameSize == (UINT32) (-1) || + AuthVariable->Attributes == (UINT32) (-1)) { + return 0; + } + return (UINTN) AuthVariable->NameSize; + } else { + if (Variable->State == (UINT8) (-1) || + Variable->DataSize == (UINT32) (-1) || + Variable->NameSize == (UINT32) (-1) || + Variable->Attributes == (UINT32) (-1)) { + return 0; + } + return (UINTN) Variable->NameSize; + } +} + + +/** + This code gets the size of data of variable. + + @param Variable Pointer to the Variable Header. + @param AuthFlag Authenticated variable flag. + + @return Size of variable in bytes in type UINTN. + +**/ +UINTN +DataSizeOfVariable ( + IN VARIABLE_HEADER *Variable, + IN BOOLEAN AuthFlag + ) +{ + AUTHENTICATED_VARIABLE_HEADER *AuthVariable; + + AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable; + if (AuthFlag) { + if (AuthVariable->State == (UINT8) (-1) || + AuthVariable->DataSize == (UINT32) (-1) || + AuthVariable->NameSize == (UINT32) (-1) || + AuthVariable->Attributes == (UINT32) (-1)) { + return 0; + } + return (UINTN) AuthVariable->DataSize; + } else { + if (Variable->State == (UINT8) (-1) || + Variable->DataSize == (UINT32) (-1) || + Variable->NameSize == (UINT32) (-1) || + Variable->Attributes == (UINT32) (-1)) { + return 0; + } + return (UINTN) Variable->DataSize; + } +} + +/** + This code gets the pointer to the variable name. + + @param Variable Pointer to the Variable Header. + @param AuthFlag Authenticated variable flag. + + @return A CHAR16* pointer to Variable Name. + +**/ +CHAR16 * +GetVariableNamePtr ( + IN VARIABLE_HEADER *Variable, + IN BOOLEAN AuthFlag + ) +{ + return (CHAR16 *) ((UINTN) Variable + GetVariableHeaderSize (AuthFlag)); +} + +/** + This code gets the pointer to the variable guid. + + @param Variable Pointer to the Variable Header. + @param AuthFlag Authenticated variable flag. + + @return A EFI_GUID* pointer to Vendor Guid. + +**/ +EFI_GUID * +GetVendorGuidPtr ( + IN VARIABLE_HEADER *Variable, + IN BOOLEAN AuthFlag + ) +{ + AUTHENTICATED_VARIABLE_HEADER *AuthVariable; + + AuthVariable = (AUTHENTICATED_VARIABLE_HEADER *) Variable; + if (AuthFlag) { + return &AuthVariable->VendorGuid; + } else { + return &Variable->VendorGuid; + } +} + +/** + This code gets the pointer to the variable data. + + @param Variable Pointer to the Variable Header. + @param VariableHeader Pointer to the Variable Header that has consecutive content. + @param AuthFlag Authenticated variable flag. + + @return A UINT8* pointer to Variable Data. + +**/ +UINT8 * +GetVariableDataPtr ( + IN VARIABLE_HEADER *Variable, + IN VARIABLE_HEADER *VariableHeader, + IN BOOLEAN AuthFlag + ) +{ + UINTN Value; + + // + // Be careful about pad size for alignment + // + Value = (UINTN) GetVariableNamePtr (Variable, AuthFlag); + Value += NameSizeOfVariable (VariableHeader, AuthFlag); + Value += GET_PAD_SIZE (NameSizeOfVariable (VariableHeader, AuthFlag)); + + return (UINT8 *) Value; +} + + +/** + This code gets the pointer to the next variable header. + + @param StoreInfo Pointer to variable store info structure. + @param Variable Pointer to the Variable Header. + @param VariableHeader Pointer to the Variable Header that has consecutive content. + + @return A VARIABLE_HEADER* pointer to next variable header. + +**/ +VARIABLE_HEADER * +GetNextVariablePtr ( + IN VARIABLE_STORE_INFO *StoreInfo, + IN VARIABLE_HEADER *Variable, + IN VARIABLE_HEADER *VariableHeader + ) +{ + EFI_PHYSICAL_ADDRESS TargetAddress; + EFI_PHYSICAL_ADDRESS SpareAddress; + UINTN Value; + + Value = (UINTN) GetVariableDataPtr (Variable, VariableHeader, StoreInfo->AuthFlag); + Value += DataSizeOfVariable (VariableHeader, StoreInfo->AuthFlag); + Value += GET_PAD_SIZE (DataSizeOfVariable (VariableHeader, StoreInfo->AuthFlag)); + // + // Be careful about pad size for alignment + // + Value = HEADER_ALIGN (Value); + + if (StoreInfo->FtwLastWriteData != NULL) { + TargetAddress = StoreInfo->FtwLastWriteData->TargetAddress; + SpareAddress = StoreInfo->FtwLastWriteData->SpareAddress; + if (((UINTN) Variable < (UINTN) TargetAddress) && (Value >= (UINTN) TargetAddress)) { + // + // Next variable is in spare block. + // + Value = (UINTN) SpareAddress + (Value - (UINTN) TargetAddress); + } + } + + return (VARIABLE_HEADER *) Value; +} + +/** + Get variable store status. + + @param VarStoreHeader Pointer to the Variable Store Header. + + @retval EfiRaw Variable store is raw + @retval EfiValid Variable store is valid + @retval EfiInvalid Variable store is invalid + +**/ +VARIABLE_STORE_STATUS +GetVariableStoreStatus ( + IN VARIABLE_STORE_HEADER *VarStoreHeader + ) +{ + if ((CompareGuid (&VarStoreHeader->Signature, &gEfiAuthenticatedVariableGuid) || + CompareGuid (&VarStoreHeader->Signature, &gEfiVariableGuid)) && + VarStoreHeader->Format == VARIABLE_STORE_FORMATTED && + VarStoreHeader->State == VARIABLE_STORE_HEALTHY + ) { + + return EfiValid; + } + + if (((UINT32 *)(&VarStoreHeader->Signature))[0] == 0xffffffff && + ((UINT32 *)(&VarStoreHeader->Signature))[1] == 0xffffffff && + ((UINT32 *)(&VarStoreHeader->Signature))[2] == 0xffffffff && + ((UINT32 *)(&VarStoreHeader->Signature))[3] == 0xffffffff && + VarStoreHeader->Size == 0xffffffff && + VarStoreHeader->Format == 0xff && + VarStoreHeader->State == 0xff + ) { + + return EfiRaw; + } else { + return EfiInvalid; + } +} + +/** + Compare two variable names, one of them may be inconsecutive. + + @param StoreInfo Pointer to variable store info structure. + @param Name1 Pointer to one variable name. + @param Name2 Pointer to another variable name. + @param NameSize Variable name size. + + @retval TRUE Name1 and Name2 are identical. + @retval FALSE Name1 and Name2 are not identical. + +**/ +BOOLEAN +CompareVariableName ( + IN VARIABLE_STORE_INFO *StoreInfo, + IN CONST CHAR16 *Name1, + IN CONST CHAR16 *Name2, + IN UINTN NameSize + ) +{ + EFI_PHYSICAL_ADDRESS TargetAddress; + EFI_PHYSICAL_ADDRESS SpareAddress; + UINTN PartialNameSize; + + if (StoreInfo->FtwLastWriteData != NULL) { + TargetAddress = StoreInfo->FtwLastWriteData->TargetAddress; + SpareAddress = StoreInfo->FtwLastWriteData->SpareAddress; + if (((UINTN) Name1 < (UINTN) TargetAddress) && (((UINTN) Name1 + NameSize) > (UINTN) TargetAddress)) { + // + // Name1 is inconsecutive. + // + PartialNameSize = (UINTN) TargetAddress - (UINTN) Name1; + // + // Partial content is in NV storage. + // + if (CompareMem ((UINT8 *) Name1, (UINT8 *) Name2, PartialNameSize) == 0) { + // + // Another partial content is in spare block. + // + if (CompareMem ((UINT8 *) (UINTN) SpareAddress, (UINT8 *) Name2 + PartialNameSize, NameSize - PartialNameSize) == 0) { + return TRUE; + } + } + return FALSE; + } else if (((UINTN) Name2 < (UINTN) TargetAddress) && (((UINTN) Name2 + NameSize) > (UINTN) TargetAddress)) { + // + // Name2 is inconsecutive. + // + PartialNameSize = (UINTN) TargetAddress - (UINTN) Name2; + // + // Partial content is in NV storage. + // + if (CompareMem ((UINT8 *) Name2, (UINT8 *) Name1, PartialNameSize) == 0) { + // + // Another partial content is in spare block. + // + if (CompareMem ((UINT8 *) (UINTN) SpareAddress, (UINT8 *) Name1 + PartialNameSize, NameSize - PartialNameSize) == 0) { + return TRUE; + } + } + return FALSE; + } + } + + // + // Both Name1 and Name2 are consecutive. + // + if (CompareMem ((UINT8 *) Name1, (UINT8 *) Name2, NameSize) == 0) { + return TRUE; + } + return FALSE; +} + +/** + This function compares a variable with variable entries in database. + + @param StoreInfo Pointer to variable store info structure. + @param Variable Pointer to the variable in our database + @param VariableHeader Pointer to the Variable Header that has consecutive content. + @param VariableName Name of the variable to compare to 'Variable' + @param VendorGuid GUID of the variable to compare to 'Variable' + @param PtrTrack Variable Track Pointer structure that contains Variable Information. + + @retval EFI_SUCCESS Found match variable + @retval EFI_NOT_FOUND Variable not found + +**/ +EFI_STATUS +CompareWithValidVariable ( + IN VARIABLE_STORE_INFO *StoreInfo, + IN VARIABLE_HEADER *Variable, + IN VARIABLE_HEADER *VariableHeader, + IN CONST CHAR16 *VariableName, + IN CONST EFI_GUID *VendorGuid, + OUT VARIABLE_POINTER_TRACK *PtrTrack + ) +{ + VOID *Point; + EFI_GUID *TempVendorGuid; + + TempVendorGuid = GetVendorGuidPtr (VariableHeader, StoreInfo->AuthFlag); + + if (VariableName[0] == 0) { + PtrTrack->CurrPtr = Variable; + return EFI_SUCCESS; + } else { + // + // Don't use CompareGuid function here for performance reasons. + // Instead we compare the GUID a UINT32 at a time and branch + // on the first failed comparison. + // + if ((((INT32 *) VendorGuid)[0] == ((INT32 *) TempVendorGuid)[0]) && + (((INT32 *) VendorGuid)[1] == ((INT32 *) TempVendorGuid)[1]) && + (((INT32 *) VendorGuid)[2] == ((INT32 *) TempVendorGuid)[2]) && + (((INT32 *) VendorGuid)[3] == ((INT32 *) TempVendorGuid)[3]) + ) { + ASSERT (NameSizeOfVariable (VariableHeader, StoreInfo->AuthFlag) != 0); + Point = (VOID *) GetVariableNamePtr (Variable, StoreInfo->AuthFlag); + if (CompareVariableName (StoreInfo, VariableName, Point, NameSizeOfVariable (VariableHeader, StoreInfo->AuthFlag))) { + PtrTrack->CurrPtr = Variable; + return EFI_SUCCESS; + } + } + } + + return EFI_NOT_FOUND; +} + +/** + Return the variable store header and the store info based on the Index. + + @param Type The type of the variable store. + @param StoreInfo Return the store info. + + @return Pointer to the variable store header. +**/ +VARIABLE_STORE_HEADER * +GetVariableStore ( + IN VARIABLE_STORE_TYPE Type, + OUT VARIABLE_STORE_INFO *StoreInfo + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; + EFI_PHYSICAL_ADDRESS NvStorageBase; + UINT32 NvStorageSize; + FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *FtwLastWriteData; + UINT32 BackUpOffset; + + StoreInfo->IndexTable = NULL; + StoreInfo->FtwLastWriteData = NULL; + StoreInfo->AuthFlag = FALSE; + VariableStoreHeader = NULL; + switch (Type) { + case VariableStoreTypeHob: + GuidHob = GetFirstGuidHob (&gEfiAuthenticatedVariableGuid); + if (GuidHob != NULL) { + VariableStoreHeader = (VARIABLE_STORE_HEADER *) GET_GUID_HOB_DATA (GuidHob); + StoreInfo->AuthFlag = TRUE; + } else { + GuidHob = GetFirstGuidHob (&gEfiVariableGuid); + if (GuidHob != NULL) { + VariableStoreHeader = (VARIABLE_STORE_HEADER *) GET_GUID_HOB_DATA (GuidHob); + StoreInfo->AuthFlag = FALSE; + } + } + break; + + case VariableStoreTypeNv: + if (GetBootModeHob () != BOOT_IN_RECOVERY_MODE) { + // + // The content of NV storage for variable is not reliable in recovery boot mode. + // + + NvStorageSize = PcdGet32 (PcdFlashNvStorageVariableSize); + NvStorageBase = (EFI_PHYSICAL_ADDRESS) (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0 ? + PcdGet64 (PcdFlashNvStorageVariableBase64) : + PcdGet32 (PcdFlashNvStorageVariableBase) + ); + // + // First let FvHeader point to NV storage base. + // + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) NvStorageBase; + + // + // Check the FTW last write data hob. + // + BackUpOffset = 0; + GuidHob = GetFirstGuidHob (&gEdkiiFaultTolerantWriteGuid); + if (GuidHob != NULL) { + FtwLastWriteData = (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *) GET_GUID_HOB_DATA (GuidHob); + if (FtwLastWriteData->TargetAddress == NvStorageBase) { + // + // Let FvHeader point to spare block. + // + FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FtwLastWriteData->SpareAddress; + DEBUG ((EFI_D_INFO, "PeiVariable: NV storage is backed up in spare block: 0x%x\n", (UINTN) FtwLastWriteData->SpareAddress)); + } else if ((FtwLastWriteData->TargetAddress > NvStorageBase) && (FtwLastWriteData->TargetAddress < (NvStorageBase + NvStorageSize))) { + StoreInfo->FtwLastWriteData = FtwLastWriteData; + // + // Flash NV storage from the offset is backed up in spare block. + // + BackUpOffset = (UINT32) (FtwLastWriteData->TargetAddress - NvStorageBase); + DEBUG ((EFI_D_INFO, "PeiVariable: High partial NV storage from offset: %x is backed up in spare block: 0x%x\n", BackUpOffset, (UINTN) FtwLastWriteData->SpareAddress)); + // + // At least one block data in flash NV storage is still valid, so still leave FvHeader point to NV storage base. + // + } + } + + // + // Check if the Firmware Volume is not corrupted + // + if ((FvHeader->Signature != EFI_FVH_SIGNATURE) || (!CompareGuid (&gEfiSystemNvDataFvGuid, &FvHeader->FileSystemGuid))) { + DEBUG ((EFI_D_ERROR, "Firmware Volume for Variable Store is corrupted\n")); + break; + } + + VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINT8 *) FvHeader + FvHeader->HeaderLength); + + StoreInfo->AuthFlag = (BOOLEAN) (CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid)); + + GuidHob = GetFirstGuidHob (&gEfiVariableIndexTableGuid); + if (GuidHob != NULL) { + StoreInfo->IndexTable = GET_GUID_HOB_DATA (GuidHob); + } else { + // + // If it's the first time to access variable region in flash, create a guid hob to record + // VAR_ADDED type variable info. + // Note that as the resource of PEI phase is limited, only store the limited number of + // VAR_ADDED type variables to reduce access time. + // + StoreInfo->IndexTable = (VARIABLE_INDEX_TABLE *) BuildGuidHob (&gEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE)); + StoreInfo->IndexTable->Length = 0; + StoreInfo->IndexTable->StartPtr = GetStartPointer (VariableStoreHeader); + StoreInfo->IndexTable->EndPtr = GetEndPointer (VariableStoreHeader); + StoreInfo->IndexTable->GoneThrough = 0; + } + } + break; + + default: + ASSERT (FALSE); + break; + } + + StoreInfo->VariableStoreHeader = VariableStoreHeader; + return VariableStoreHeader; +} + +/** + Get variable header that has consecutive content. + + @param StoreInfo Pointer to variable store info structure. + @param Variable Pointer to the Variable Header. + @param VariableHeader Pointer to Pointer to the Variable Header that has consecutive content. + + @retval TRUE Variable header is valid. + @retval FALSE Variable header is not valid. + +**/ +BOOLEAN +GetVariableHeader ( + IN VARIABLE_STORE_INFO *StoreInfo, + IN VARIABLE_HEADER *Variable, + OUT VARIABLE_HEADER **VariableHeader + ) +{ + EFI_PHYSICAL_ADDRESS TargetAddress; + EFI_PHYSICAL_ADDRESS SpareAddress; + EFI_HOB_GUID_TYPE *GuidHob; + UINTN PartialHeaderSize; + + if (Variable == NULL) { + return FALSE; + } + + // + // First assume variable header pointed by Variable is consecutive. + // + *VariableHeader = Variable; + + if (StoreInfo->FtwLastWriteData != NULL) { + TargetAddress = StoreInfo->FtwLastWriteData->TargetAddress; + SpareAddress = StoreInfo->FtwLastWriteData->SpareAddress; + if (((UINTN) Variable > (UINTN) SpareAddress) && + (((UINTN) Variable - (UINTN) SpareAddress + (UINTN) TargetAddress) >= (UINTN) GetEndPointer (StoreInfo->VariableStoreHeader))) { + // + // Reach the end of variable store. + // + return FALSE; + } + if (((UINTN) Variable < (UINTN) TargetAddress) && (((UINTN) Variable + GetVariableHeaderSize (StoreInfo->AuthFlag)) > (UINTN) TargetAddress)) { + // + // Variable header pointed by Variable is inconsecutive, + // create a guid hob to combine the two partial variable header content together. + // + GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid); + if (GuidHob != NULL) { + *VariableHeader = (VARIABLE_HEADER *) GET_GUID_HOB_DATA (GuidHob); + } else { + *VariableHeader = (VARIABLE_HEADER *) BuildGuidHob (&gEfiCallerIdGuid, GetVariableHeaderSize (StoreInfo->AuthFlag)); + PartialHeaderSize = (UINTN) TargetAddress - (UINTN) Variable; + // + // Partial content is in NV storage. + // + CopyMem ((UINT8 *) *VariableHeader, (UINT8 *) Variable, PartialHeaderSize); + // + // Another partial content is in spare block. + // + CopyMem ((UINT8 *) *VariableHeader + PartialHeaderSize, (UINT8 *) (UINTN) SpareAddress, GetVariableHeaderSize (StoreInfo->AuthFlag) - PartialHeaderSize); + } + } + } else { + if (Variable >= GetEndPointer (StoreInfo->VariableStoreHeader)) { + // + // Reach the end of variable store. + // + return FALSE; + } + } + + return IsValidVariableHeader (*VariableHeader); +} + +/** + Get variable name or data to output buffer. + + @param StoreInfo Pointer to variable store info structure. + @param NameOrData Pointer to the variable name/data that may be inconsecutive. + @param Size Variable name/data size. + @param Buffer Pointer to output buffer to hold the variable name/data. + +**/ +VOID +GetVariableNameOrData ( + IN VARIABLE_STORE_INFO *StoreInfo, + IN UINT8 *NameOrData, + IN UINTN Size, + OUT UINT8 *Buffer + ) +{ + EFI_PHYSICAL_ADDRESS TargetAddress; + EFI_PHYSICAL_ADDRESS SpareAddress; + UINTN PartialSize; + + if (StoreInfo->FtwLastWriteData != NULL) { + TargetAddress = StoreInfo->FtwLastWriteData->TargetAddress; + SpareAddress = StoreInfo->FtwLastWriteData->SpareAddress; + if (((UINTN) NameOrData < (UINTN) TargetAddress) && (((UINTN) NameOrData + Size) > (UINTN) TargetAddress)) { + // + // Variable name/data is inconsecutive. + // + PartialSize = (UINTN) TargetAddress - (UINTN) NameOrData; + // + // Partial content is in NV storage. + // + CopyMem (Buffer, NameOrData, PartialSize); + // + // Another partial content is in spare block. + // + CopyMem (Buffer + PartialSize, (UINT8 *) (UINTN) SpareAddress, Size - PartialSize); + return; + } + } + + // + // Variable name/data is consecutive. + // + CopyMem (Buffer, NameOrData, Size); +} + +/** + Find the variable in the specified variable store. + + @param StoreInfo Pointer to the store info structure. + @param VariableName Name of the variable to be found + @param VendorGuid Vendor GUID to be found. + @param PtrTrack Variable Track Pointer structure that contains Variable Information. + + @retval EFI_SUCCESS Variable found successfully + @retval EFI_NOT_FOUND Variable not found + @retval EFI_INVALID_PARAMETER Invalid variable name + +**/ +EFI_STATUS +FindVariableEx ( + IN VARIABLE_STORE_INFO *StoreInfo, + IN CONST CHAR16 *VariableName, + IN CONST EFI_GUID *VendorGuid, + OUT VARIABLE_POINTER_TRACK *PtrTrack + ) +{ + VARIABLE_HEADER *Variable; + VARIABLE_HEADER *LastVariable; + VARIABLE_HEADER *MaxIndex; + UINTN Index; + UINTN Offset; + BOOLEAN StopRecord; + VARIABLE_HEADER *InDeletedVariable; + VARIABLE_STORE_HEADER *VariableStoreHeader; + VARIABLE_INDEX_TABLE *IndexTable; + VARIABLE_HEADER *VariableHeader; + + VariableStoreHeader = StoreInfo->VariableStoreHeader; + + if (VariableStoreHeader == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (GetVariableStoreStatus (VariableStoreHeader) != EfiValid) { + return EFI_UNSUPPORTED; + } + + if (~VariableStoreHeader->Size == 0) { + return EFI_NOT_FOUND; + } + + IndexTable = StoreInfo->IndexTable; + PtrTrack->StartPtr = GetStartPointer (VariableStoreHeader); + PtrTrack->EndPtr = GetEndPointer (VariableStoreHeader); + + InDeletedVariable = NULL; + + // + // No Variable Address equals zero, so 0 as initial value is safe. + // + MaxIndex = NULL; + VariableHeader = NULL; + + if (IndexTable != NULL) { + // + // traverse the variable index table to look for varible. + // The IndexTable->Index[Index] records the distance of two neighbouring VAR_ADDED type variables. + // + for (Offset = 0, Index = 0; Index < IndexTable->Length; Index++) { + ASSERT (Index < sizeof (IndexTable->Index) / sizeof (IndexTable->Index[0])); + Offset += IndexTable->Index[Index]; + MaxIndex = (VARIABLE_HEADER *) ((UINT8 *) IndexTable->StartPtr + Offset); + GetVariableHeader (StoreInfo, MaxIndex, &VariableHeader); + if (CompareWithValidVariable (StoreInfo, MaxIndex, VariableHeader, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) { + if (VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { + InDeletedVariable = PtrTrack->CurrPtr; + } else { + return EFI_SUCCESS; + } + } + } + + if (IndexTable->GoneThrough != 0) { + // + // If the table has all the existing variables indexed, return. + // + PtrTrack->CurrPtr = InDeletedVariable; + return (PtrTrack->CurrPtr == NULL) ? EFI_NOT_FOUND : EFI_SUCCESS; + } + } + + if (MaxIndex != NULL) { + // + // HOB exists but the variable cannot be found in HOB + // If not found in HOB, then let's start from the MaxIndex we've found. + // + Variable = GetNextVariablePtr (StoreInfo, MaxIndex, VariableHeader); + LastVariable = MaxIndex; + } else { + // + // Start Pointers for the variable. + // Actual Data Pointer where data can be written. + // + Variable = PtrTrack->StartPtr; + LastVariable = PtrTrack->StartPtr; + } + + // + // Find the variable by walk through variable store + // + StopRecord = FALSE; + while (GetVariableHeader (StoreInfo, Variable, &VariableHeader)) { + if (VariableHeader->State == VAR_ADDED || VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { + // + // Record Variable in VariableIndex HOB + // + if ((IndexTable != NULL) && !StopRecord) { + Offset = (UINTN) Variable - (UINTN) LastVariable; + if ((Offset > 0x0FFFF) || (IndexTable->Length == sizeof (IndexTable->Index) / sizeof (IndexTable->Index[0]))) { + // + // Stop to record if the distance of two neighbouring VAR_ADDED variable is larger than the allowable scope(UINT16), + // or the record buffer is full. + // + StopRecord = TRUE; + } else { + IndexTable->Index[IndexTable->Length++] = (UINT16) Offset; + LastVariable = Variable; + } + } + + if (CompareWithValidVariable (StoreInfo, Variable, VariableHeader, VariableName, VendorGuid, PtrTrack) == EFI_SUCCESS) { + if (VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { + InDeletedVariable = PtrTrack->CurrPtr; + } else { + return EFI_SUCCESS; + } + } + } + + Variable = GetNextVariablePtr (StoreInfo, Variable, VariableHeader); + } + // + // If gone through the VariableStore, that means we never find in Firmware any more. + // + if ((IndexTable != NULL) && !StopRecord) { + IndexTable->GoneThrough = 1; + } + + PtrTrack->CurrPtr = InDeletedVariable; + + return (PtrTrack->CurrPtr == NULL) ? EFI_NOT_FOUND : EFI_SUCCESS; +} + +/** + Find the variable in HOB and Non-Volatile variable storages. + + @param VariableName Name of the variable to be found + @param VendorGuid Vendor GUID to be found. + @param PtrTrack Variable Track Pointer structure that contains Variable Information. + @param StoreInfo Return the store info. + + @retval EFI_SUCCESS Variable found successfully + @retval EFI_NOT_FOUND Variable not found + @retval EFI_INVALID_PARAMETER Invalid variable name +**/ +EFI_STATUS +FindVariable ( + IN CONST CHAR16 *VariableName, + IN CONST EFI_GUID *VendorGuid, + OUT VARIABLE_POINTER_TRACK *PtrTrack, + OUT VARIABLE_STORE_INFO *StoreInfo + ) +{ + EFI_STATUS Status; + VARIABLE_STORE_TYPE Type; + + if (VariableName[0] != 0 && VendorGuid == NULL) { + return EFI_INVALID_PARAMETER; + } + + for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax; Type++) { + GetVariableStore (Type, StoreInfo); + Status = FindVariableEx ( + StoreInfo, + VariableName, + VendorGuid, + PtrTrack + ); + if (!EFI_ERROR (Status)) { + return Status; + } + } + + return EFI_NOT_FOUND; +} + +/** + This service retrieves a variable's value using its name and GUID. + + Read the specified variable from the UEFI variable store. If the Data + buffer is too small to hold the contents of the variable, the error + EFI_BUFFER_TOO_SMALL is returned and DataSize is set to the required buffer + size to obtain the data. + + @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI. + @param VariableName A pointer to a null-terminated string that is the variable's name. + @param VariableGuid A pointer to an EFI_GUID that is the variable's GUID. The combination of + VariableGuid and VariableName must be unique. + @param Attributes If non-NULL, on return, points to the variable's attributes. + @param DataSize On entry, points to the size in bytes of the Data buffer. + On return, points to the size of the data returned in Data. + @param Data Points to the buffer which will hold the returned variable value. + + @retval EFI_SUCCESS The variable was read successfully. + @retval EFI_NOT_FOUND The variable could not be found. + @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the resulting data. + DataSize is updated with the size required for + the specified variable. + @retval EFI_INVALID_PARAMETER VariableName, VariableGuid, DataSize or Data is NULL. + @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error. + +**/ +EFI_STATUS +EFIAPI +PeiGetVariable ( + IN CONST CHAR16 *VariableName, + IN CONST EFI_GUID *VariableGuid, + OUT UINT32 *Attributes, + IN OUT UINTN *DataSize, + OUT UINT8 **Data + ) +{ + VARIABLE_POINTER_TRACK Variable; + EFI_STATUS Status; + VARIABLE_STORE_INFO StoreInfo; + VARIABLE_HEADER *VariableHeader; + + if (VariableName == NULL || VariableGuid == NULL || DataSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + VariableHeader = NULL; + + // + // Find existing variable + // + Status = FindVariable (VariableName, VariableGuid, &Variable, &StoreInfo); + if (EFI_ERROR (Status)) { + return Status; + } + GetVariableHeader (&StoreInfo, Variable.CurrPtr, &VariableHeader); + + *Data = GetVariableDataPtr (Variable.CurrPtr, VariableHeader, StoreInfo.AuthFlag); + + if (Attributes != NULL) { + *Attributes = VariableHeader->Attributes; + } + + return EFI_SUCCESS; +} + +/** + Return the next variable name and GUID. + + This function is called multiple times to retrieve the VariableName + and VariableGuid of all variables currently available in the system. + On each call, the previous results are passed into the interface, + and, on return, the interface returns the data for the next + interface. When the entire variable list has been returned, + EFI_NOT_FOUND is returned. + + @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI. + + @param VariableNameSize On entry, points to the size of the buffer pointed to by VariableName. + On return, the size of the variable name buffer. + @param VariableName On entry, a pointer to a null-terminated string that is the variable's name. + On return, points to the next variable's null-terminated name string. + @param VariableGuid On entry, a pointer to an EFI_GUID that is the variable's GUID. + On return, a pointer to the next variable's GUID. + + @retval EFI_SUCCESS The variable was read successfully. + @retval EFI_NOT_FOUND The variable could not be found. + @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the resulting + data. VariableNameSize is updated with the size + required for the specified variable. + @retval EFI_INVALID_PARAMETER VariableName, VariableGuid or + VariableNameSize is NULL. + @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error. + +**/ +EFI_STATUS +EFIAPI +PeiGetNextVariableName ( + IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This, + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VariableGuid + ) +{ + VARIABLE_STORE_TYPE Type; + VARIABLE_POINTER_TRACK Variable; + VARIABLE_POINTER_TRACK VariableInHob; + VARIABLE_POINTER_TRACK VariablePtrTrack; + UINTN VarNameSize; + EFI_STATUS Status; + VARIABLE_STORE_HEADER *VariableStoreHeader[VariableStoreTypeMax]; + VARIABLE_HEADER *VariableHeader; + VARIABLE_STORE_INFO StoreInfo; + VARIABLE_STORE_INFO StoreInfoForNv; + VARIABLE_STORE_INFO StoreInfoForHob; + + if (VariableName == NULL || VariableGuid == NULL || VariableNameSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + VariableHeader = NULL; + + Status = FindVariable (VariableName, VariableGuid, &Variable, &StoreInfo); + if (Variable.CurrPtr == NULL || Status != EFI_SUCCESS) { + return Status; + } + + if (VariableName[0] != 0) { + // + // If variable name is not NULL, get next variable + // + GetVariableHeader (&StoreInfo, Variable.CurrPtr, &VariableHeader); + Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); + } + + VariableStoreHeader[VariableStoreTypeHob] = GetVariableStore (VariableStoreTypeHob, &StoreInfoForHob); + VariableStoreHeader[VariableStoreTypeNv] = GetVariableStore (VariableStoreTypeNv, &StoreInfoForNv); + + while (TRUE) { + // + // Switch from HOB to Non-Volatile. + // + while (!GetVariableHeader (&StoreInfo, Variable.CurrPtr, &VariableHeader)) { + // + // Find current storage index + // + for (Type = (VARIABLE_STORE_TYPE) 0; Type < VariableStoreTypeMax; Type++) { + if ((VariableStoreHeader[Type] != NULL) && (Variable.StartPtr == GetStartPointer (VariableStoreHeader[Type]))) { + break; + } + } + ASSERT (Type < VariableStoreTypeMax); + // + // Switch to next storage + // + for (Type++; Type < VariableStoreTypeMax; Type++) { + if (VariableStoreHeader[Type] != NULL) { + break; + } + } + // + // Capture the case that + // 1. current storage is the last one, or + // 2. no further storage + // + if (Type == VariableStoreTypeMax) { + return EFI_NOT_FOUND; + } + Variable.StartPtr = GetStartPointer (VariableStoreHeader[Type]); + Variable.EndPtr = GetEndPointer (VariableStoreHeader[Type]); + Variable.CurrPtr = Variable.StartPtr; + GetVariableStore (Type, &StoreInfo); + } + + if (VariableHeader->State == VAR_ADDED || VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { + if (VariableHeader->State == (VAR_IN_DELETED_TRANSITION & VAR_ADDED)) { + // + // If it is a IN_DELETED_TRANSITION variable, + // and there is also a same ADDED one at the same time, + // don't return it. + // + Status = FindVariableEx ( + &StoreInfo, + GetVariableNamePtr (Variable.CurrPtr, StoreInfo.AuthFlag), + GetVendorGuidPtr (VariableHeader, StoreInfo.AuthFlag), + &VariablePtrTrack + ); + if (!EFI_ERROR (Status) && VariablePtrTrack.CurrPtr != Variable.CurrPtr) { + Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); + continue; + } + } + + // + // Don't return NV variable when HOB overrides it + // + if ((VariableStoreHeader[VariableStoreTypeHob] != NULL) && (VariableStoreHeader[VariableStoreTypeNv] != NULL) && + (Variable.StartPtr == GetStartPointer (VariableStoreHeader[VariableStoreTypeNv])) + ) { + Status = FindVariableEx ( + &StoreInfoForHob, + GetVariableNamePtr (Variable.CurrPtr, StoreInfo.AuthFlag), + GetVendorGuidPtr (VariableHeader, StoreInfo.AuthFlag), + &VariableInHob + ); + if (!EFI_ERROR (Status)) { + Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); + continue; + } + } + + VarNameSize = NameSizeOfVariable (VariableHeader, StoreInfo.AuthFlag); + ASSERT (VarNameSize != 0); + + if (VarNameSize <= *VariableNameSize) { + GetVariableNameOrData (&StoreInfo, (UINT8 *) GetVariableNamePtr (Variable.CurrPtr, StoreInfo.AuthFlag), VarNameSize, (UINT8 *) VariableName); + + CopyMem (VariableGuid, GetVendorGuidPtr (VariableHeader, StoreInfo.AuthFlag), sizeof (EFI_GUID)); + + Status = EFI_SUCCESS; + } else { + Status = EFI_BUFFER_TOO_SMALL; + } + + *VariableNameSize = VarNameSize; + // + // Variable is found + // + return Status; + } else { + Variable.CurrPtr = GetNextVariablePtr (&StoreInfo, Variable.CurrPtr, VariableHeader); + } + } +} diff --git a/BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/MemoryMappedVariable.h b/BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/MemoryMappedVariable.h new file mode 100644 index 0000000000..23eada6473 --- /dev/null +++ b/BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/MemoryMappedVariable.h @@ -0,0 +1,148 @@ +/** @file + The internal header file includes the common header files, defines + internal structure and functions used by PeiVariable module. + +Copyright (c) 2006 - 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 _PEI_VARIABLE_H_ +#define _PEI_VARIABLE_H_ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +typedef enum { + VariableStoreTypeHob, + VariableStoreTypeNv, + VariableStoreTypeMax +} VARIABLE_STORE_TYPE; + +typedef struct { + VARIABLE_STORE_HEADER *VariableStoreHeader; + VARIABLE_INDEX_TABLE *IndexTable; + // + // If it is not NULL, it means there may be an inconsecutive variable whose + // partial content is still in NV storage, but another partial content is backed up + // in spare block. + // + FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *FtwLastWriteData; + BOOLEAN AuthFlag; +} VARIABLE_STORE_INFO; + +// +// Functions +// +/** + Provide the functionality of the variable services. + + @param FileHandle Handle of the file being invoked. + Type EFI_PEI_FILE_HANDLE is defined in FfsFindNextFile(). + @param PeiServices General purpose services available to every PEIM. + + @retval EFI_SUCCESS If the interface could be successfully installed + @retval Others Returned from PeiServicesInstallPpi() + +**/ +EFI_STATUS +EFIAPI +PeimInitializeVariableServices ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +/** + This service retrieves a variable's value using its name and GUID. + + Read the specified variable from the UEFI variable store. If the Data + buffer is too small to hold the contents of the variable, the error + EFI_BUFFER_TOO_SMALL is returned and DataSize is set to the required buffer + size to obtain the data. + + @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI. + @param VariableName A pointer to a null-terminated string that is the variable's name. + @param VariableGuid A pointer to an EFI_GUID that is the variable's GUID. The combination of + VariableGuid and VariableName must be unique. + @param Attributes If non-NULL, on return, points to the variable's attributes. + @param DataSize On entry, points to the size in bytes of the Data buffer. + On return, points to the size of the data returned in Data. + @param Data Points to the buffer which will hold the returned variable value. + + @retval EFI_SUCCESS The variable was read successfully. + @retval EFI_NOT_FOUND The variable could not be found. + @retval EFI_BUFFER_TOO_SMALL The DataSize is too small for the resulting data. + DataSize is updated with the size required for + the specified variable. + @retval EFI_INVALID_PARAMETER VariableName, VariableGuid, DataSize or Data is NULL. + @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error. + +**/ +EFI_STATUS +EFIAPI +PeiGetVariable ( + IN CONST CHAR16 *VariableName, + IN CONST EFI_GUID *VariableGuid, + OUT UINT32 *Attributes, + IN OUT UINTN *DataSize, + OUT UINT8 **Data + ); + +/** + Return the next variable name and GUID. + + This function is called multiple times to retrieve the VariableName + and VariableGuid of all variables currently available in the system. + On each call, the previous results are passed into the interface, + and, on return, the interface returns the data for the next + interface. When the entire variable list has been returned, + EFI_NOT_FOUND is returned. + + @param This A pointer to this instance of the EFI_PEI_READ_ONLY_VARIABLE2_PPI. + + @param VariableNameSize On entry, points to the size of the buffer pointed to by VariableName. + @param VariableName On entry, a pointer to a null-terminated string that is the variable's name. + On return, points to the next variable's null-terminated name string. + + @param VariableGuid On entry, a pointer to an UEFI _GUID that is the variable's GUID. + On return, a pointer to the next variable's GUID. + + @retval EFI_SUCCESS The variable was read successfully. + @retval EFI_NOT_FOUND The variable could not be found. + @retval EFI_BUFFER_TOO_SMALL The VariableNameSize is too small for the resulting + data. VariableNameSize is updated with the size + required for the specified variable. + @retval EFI_INVALID_PARAMETER VariableName, VariableGuid or + VariableNameSize is NULL. + @retval EFI_DEVICE_ERROR The variable could not be retrieved because of a device error. + +**/ +EFI_STATUS +EFIAPI +PeiGetNextVariableName ( + IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This, + IN OUT UINTN *VariableNameSize, + IN OUT CHAR16 *VariableName, + IN OUT EFI_GUID *VariableGuid + ); + +#endif diff --git a/BraswellPlatformPkg/Common/FspSupport/Library/FrameBufferBltLib/FrameBufferBltLib.c b/BraswellPlatformPkg/Common/FspSupport/Library/FrameBufferBltLib/FrameBufferBltLib.c new file mode 100644 index 0000000000..6f2cff6e81 --- /dev/null +++ b/BraswellPlatformPkg/Common/FspSupport/Library/FrameBufferBltLib/FrameBufferBltLib.c @@ -0,0 +1,572 @@ +/** @file + FrameBufferBltLib - Library to perform blt operations on a frame buffer. + + Copyright (c) 2007 - 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 +#include +#include +#include +#include + +#if 0 +#define VDEBUG DEBUG +#else +#define VDEBUG(x) +#endif + +#define MAX_LINE_BUFFER_SIZE (SIZE_4KB * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) + +UINT8 mBltLibLineBuffer[MAX_LINE_BUFFER_SIZE]; +EFI_PIXEL_BITMASK mBltLibRgbPixelMasks = {0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000}; +EFI_PIXEL_BITMASK mBltLibBgrPixelMasks = {0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000}; + +EFI_STATUS +BltLibParsePixelFormat ( + IN EFI_GRAPHICS_PIXEL_FORMAT PixelFormat, + IN EFI_PIXEL_BITMASK *PixelInformation, + OUT UINT8 *PixelShl, + OUT UINT8 *PixelShr, + OUT UINT32 *PixelMask, + OUT UINT8 *BytesPerPixel + ) +{ + UINTN Index; + UINT32 MergedMasks; + UINT32 *Mask; + + switch (PixelFormat) { + case PixelRedGreenBlueReserved8BitPerColor: + return BltLibParsePixelFormat (PixelBitMask, &mBltLibRgbPixelMasks, PixelShl, PixelShr, PixelMask, BytesPerPixel); + + case PixelBlueGreenRedReserved8BitPerColor: + return BltLibParsePixelFormat (PixelBitMask, &mBltLibBgrPixelMasks, PixelShl, PixelShr, PixelMask, BytesPerPixel); + + case PixelBitMask: + break; + + default: + return EFI_INVALID_PARAMETER; + } + + MergedMasks = 0; + Mask = (UINT32 *) PixelInformation; + for (Index = 0; Index < 4; Index++) { + // + // Only ReservedMask can be 0 + // + if (Index != 3 && Mask[Index] == 0) { + return EFI_INVALID_PARAMETER; + } + // + // The Mask of each color shouldn't overlap + // + if ((MergedMasks & Mask[Index]) != 0) { + return EFI_INVALID_PARAMETER; + } + MergedMasks |= Mask[Index]; + + if (PixelShl != NULL && PixelShr != NULL) { + PixelShl[Index] = (UINT8) (HighBitSet32 (Mask[Index]) - 23 + (Index * 8)); + PixelShl[Index] %= 32; + if ((INT8) PixelShl[Index] < 0) { + PixelShr[Index] = -PixelShl[Index]; + PixelShl[Index] = 0; + } else { + PixelShr[Index] = 0; + } + VDEBUG ((EFI_D_INFO, "%d: shl:%d shr:%d mask:%x\n", Index, PixelShl[Index], PixelShr[Index], Mask[Index])); + } + } + if (PixelMask != NULL) { + CopyMem (PixelMask, PixelInformation, sizeof (EFI_PIXEL_BITMASK)); + } + + if (BytesPerPixel != NULL) { + *BytesPerPixel = (UINT8) ((HighBitSet32 (MergedMasks) + 7) / 8); + VDEBUG ((EFI_D_INFO, "Bytes per pixel: %d\n", *BytesPerPixel)); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +BltLibVerifyLocation ( + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + IN UINTN X, + IN UINTN Y, + IN UINTN Width, + IN UINTN Height + ) +{ + if ((X >= FrameBufferInfo->HorizontalResolution) || + (Width > FrameBufferInfo->HorizontalResolution - X)) { + VDEBUG ((EFI_D_INFO, "VideoFill: Past screen (X)\n")); + return EFI_INVALID_PARAMETER; + } + + if ((Y >= FrameBufferInfo->VerticalResolution) || + (Height > FrameBufferInfo->VerticalResolution - Y)) { + VDEBUG ((EFI_D_INFO, "VideoFill: Past screen (Y)\n")); + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + +/** + Performs a UEFI Graphics Output Protocol Blt Video Fill. + + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] Color Color to fill the region with + @param[in] DestinationX X location to start fill operation + @param[in] DestinationY Y location to start fill operation + @param[in] Width Width (in pixels) to fill + @param[in] Height Height to fill + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success + +**/ +EFI_STATUS +EFIAPI +BltVideoFill ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Color, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height + ) +{ + EFI_STATUS Status; + UINTN Y; + UINT8 *Destination; + UINTN X; + UINT8 Uint8; + UINT32 Uint32; + UINT64 WideFill; + BOOLEAN UseWideFill; + BOOLEAN LineBufferReady; + UINTN Offset; + UINTN WidthInBytes; + UINTN SizeInBytes; + UINT8 PixelShr[4]; + UINT8 PixelShl[4]; + UINT32 PixelMask[4]; + UINT8 BytesPerPixel; + + Status = BltLibVerifyLocation (FrameBufferInfo, DestinationX, DestinationY, Width, Height); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = BltLibParsePixelFormat ( + FrameBufferInfo->PixelFormat, + &FrameBufferInfo->PixelInformation, + PixelShr, PixelShl, PixelMask, &BytesPerPixel + ); + if (EFI_ERROR (Status)) { + return Status; + } + + WidthInBytes = Width * BytesPerPixel; + + Uint32 = *(UINT32 *) Color; + WideFill = (((Uint32 << PixelShl[0]) >> PixelShr[0]) & PixelMask[0]) | + (((Uint32 << PixelShl[1]) >> PixelShr[1]) & PixelMask[1]) | + (((Uint32 << PixelShl[2]) >> PixelShr[2]) & PixelMask[2]) | + (((Uint32 << PixelShl[3]) >> PixelShr[3]) & PixelMask[3]); + VDEBUG ((EFI_D_INFO, "VideoFill: color=0x%x, wide-fill=0x%x\n", Uint32, WideFill)); + + // + // If the size of the pixel data evenly divides the sizeof + // WideFill, then a wide fill operation can be used + // + UseWideFill = TRUE; + if (sizeof (WideFill) % BytesPerPixel == 0) { + for (X = BytesPerPixel; X < sizeof (WideFill); X++) { + ((UINT8 *) &WideFill)[X] = ((UINT8 *) &WideFill)[X % BytesPerPixel]; + } + } else { + // + // If all the bytes in the pixel are the same value, then use + // a wide fill operation. + // + for (X = 1, Uint8 = ((UINT8*) &WideFill)[0]; X < BytesPerPixel; X++) { + if (Uint8 != ((UINT8*) &WideFill)[X]) { + UseWideFill = FALSE; + break; + } + } + if (UseWideFill) { + SetMem (&WideFill, sizeof (WideFill), Uint8); + } + } + + if (UseWideFill && (DestinationX == 0) && (Width == FrameBufferInfo->HorizontalResolution)) { + VDEBUG ((EFI_D_INFO, "VideoFill (wide, one-shot)\n")); + Offset = DestinationY * FrameBufferInfo->PixelsPerScanLine * BytesPerPixel; + Destination = (UINT8 *) FrameBuffer + Offset; + SizeInBytes = WidthInBytes * Height; + if (SizeInBytes >= 8) { + SetMem64 (Destination, SizeInBytes & ~7, WideFill); + Destination += (SizeInBytes & ~7); + SizeInBytes &= 7; + } + if (SizeInBytes > 0) { + CopyMem (Destination, &WideFill, SizeInBytes); + } + } else { + LineBufferReady = FALSE; + for (Y = DestinationY; Y < (Height + DestinationY); Y++) { + Offset = ((Y * FrameBufferInfo->PixelsPerScanLine) + DestinationX) * BytesPerPixel; + Destination = (UINT8 *) FrameBuffer + Offset; + + if (UseWideFill && (((UINTN) Destination & 7) == 0)) { + VDEBUG ((EFI_D_INFO, "VideoFill (wide)\n")); + SizeInBytes = WidthInBytes; + if (SizeInBytes >= 8) { + SetMem64 (Destination, SizeInBytes & ~7, WideFill); + Destination += (SizeInBytes & ~7); + SizeInBytes &= 7; + } + if (SizeInBytes > 0) { + CopyMem (Destination, &WideFill, SizeInBytes); + } + } else { + VDEBUG ((EFI_D_INFO, "VideoFill (not wide)\n")); + if (!LineBufferReady) { + CopyMem (mBltLibLineBuffer, &WideFill, BytesPerPixel); + for (X = 1; X < Width; ) { + CopyMem ( + (mBltLibLineBuffer + (X * BytesPerPixel)), + mBltLibLineBuffer, + MIN (X, Width - X) * BytesPerPixel + ); + X += MIN (X, Width - X); + } + LineBufferReady = TRUE; + } + CopyMem (Destination, mBltLibLineBuffer, WidthInBytes); + } + } + } + + return EFI_SUCCESS; +} + +/** + Performs a UEFI Graphics Output Protocol Blt Video to Buffer operation. + + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[out] BltBuffer Output buffer for pixel color data + @param[in] SourceX X location within video + @param[in] SourceY Y location within video + @param[in] DestinationX X location within BltBuffer + @param[in] DestinationY Y location within BltBuffer + @param[in] Width Width (in pixels) + @param[in] Height Height + @param[in] Delta Number of bytes in a row of BltBuffer + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success + +**/ +EFI_STATUS +EFIAPI +BltVideoToBuffer ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ) +{ + EFI_STATUS Status; + UINTN DstY; + UINTN SrcY; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; + UINT8 *Source; + UINT8 *Destination; + UINTN X; + UINT32 Uint32; + UINTN Offset; + UINTN WidthInBytes; + UINT8 PixelShr[4]; + UINT8 PixelShl[4]; + UINT32 PixelMask[4]; + UINT8 BytesPerPixel; + + // + // Video to BltBuffer: Source is Video, destination is BltBuffer + // + Status = BltLibVerifyLocation (FrameBufferInfo, SourceX, SourceY, Width, Height); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = BltLibParsePixelFormat ( + FrameBufferInfo->PixelFormat, + &FrameBufferInfo->PixelInformation, + PixelShl, PixelShr, PixelMask, &BytesPerPixel + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // If Delta is zero, then the entire BltBuffer is being used, so Delta + // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size, + // the number of bytes in each row can be computed. + // + if (Delta == 0) { + Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); + } + + WidthInBytes = Width * BytesPerPixel; + + // + // Video to BltBuffer: Source is Video, destination is BltBuffer + // + for (SrcY = SourceY, DstY = DestinationY; DstY < (DestinationY + Height); SrcY++, DstY++) { + + Offset = ((SrcY * FrameBufferInfo->PixelsPerScanLine) + SourceX) * BytesPerPixel; + Source = (UINT8 *) FrameBuffer + Offset; + + if (FrameBufferInfo->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) { + Destination = (UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + } else { + Destination = mBltLibLineBuffer; + } + + CopyMem (Destination, Source, WidthInBytes); + + if (FrameBufferInfo->PixelFormat != PixelBlueGreenRedReserved8BitPerColor) { + for (X = 0; X < Width; X++) { + Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ((UINT8 *) BltBuffer + (DstY * Delta) + (DestinationX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + Uint32 = * (UINT32 *) (mBltLibLineBuffer + (X * BytesPerPixel)); + *(UINT32*) Blt = (((Uint32 & PixelMask[0]) >> PixelShl[0]) << PixelShr[0]) | + (((Uint32 & PixelMask[1]) >> PixelShl[1]) << PixelShr[1]) | + (((Uint32 & PixelMask[2]) >> PixelShl[2]) << PixelShr[2]) | + (((Uint32 & PixelMask[3]) >> PixelShl[3]) << PixelShr[3]); + } + } + } + + return EFI_SUCCESS; +} + +/** + Performs a UEFI Graphics Output Protocol Blt Buffer to Video operation. + + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] BltBuffer Output buffer for pixel color data + @param[in] SourceX X location within BltBuffer + @param[in] SourceY Y location within BltBuffer + @param[in] DestinationX X location within video + @param[in] DestinationY Y location within video + @param[in] Width Width (in pixels) + @param[in] Height Height + @param[in] Delta Number of bytes in a row of BltBuffer + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success + +**/ +EFI_STATUS +EFIAPI +BltBufferToVideo ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height, + IN UINTN Delta + ) +{ + EFI_STATUS Status; + UINTN DstY; + UINTN SrcY; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt; + UINT8 *Source; + UINT8 *Destination; + UINTN X; + UINT32 Uint32; + UINTN Offset; + UINTN WidthInBytes; + UINT8 PixelShr[4]; + UINT8 PixelShl[4]; + UINT32 PixelMask[4]; + UINT8 BytesPerPixel; + + // + // BltBuffer to Video: Source is BltBuffer, destination is Video + // + Status = BltLibVerifyLocation (FrameBufferInfo, DestinationX, DestinationY, Width, Height); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = BltLibParsePixelFormat ( + FrameBufferInfo->PixelFormat, + &FrameBufferInfo->PixelInformation, + PixelShl, PixelShr, PixelMask, &BytesPerPixel + ); + if (EFI_ERROR (Status)) { + return Status; + } + // + // If Delta is zero, then the entire BltBuffer is being used, so Delta + // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size, + // the number of bytes in each row can be computed. + // + if (Delta == 0) { + Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL); + } + + WidthInBytes = Width * BytesPerPixel; + + for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) { + + Offset = ((DstY * FrameBufferInfo->PixelsPerScanLine) + DestinationX) * BytesPerPixel; + Destination = (UINT8 *) FrameBuffer + Offset; + + if (FrameBufferInfo->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) { + Source = (UINT8 *) BltBuffer + (SrcY * Delta); + } else { + for (X = 0; X < Width; X++) { + Blt = + (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) ( + (UINT8 *) BltBuffer + + (SrcY * Delta) + + ((SourceX + X) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL)) + ); + Uint32 = *(UINT32*) Blt; + *(UINT32*) (mBltLibLineBuffer + (X * BytesPerPixel)) = + (((Uint32 << PixelShl[0]) >> PixelShr[0]) & PixelMask[0]) | + (((Uint32 << PixelShl[1]) >> PixelShr[1]) & PixelMask[1]) | + (((Uint32 << PixelShl[2]) >> PixelShr[2]) & PixelMask[2]) | + (((Uint32 << PixelShl[3]) >> PixelShr[3]) & PixelMask[3]); + } + Source = mBltLibLineBuffer; + } + + CopyMem (Destination, Source, WidthInBytes); + } + + return EFI_SUCCESS; +} + +/** + Performs a UEFI Graphics Output Protocol Blt Video to Video operation. + + @param[in] FrameBuffer Pointer to the start of the frame buffer + @param[in] FrameBufferInfo Describes the frame buffer characteristics + @param[in] SourceX X location within video + @param[in] SourceY Y location within video + @param[in] DestinationX X location within video + @param[in] DestinationY Y location within video + @param[in] Width Width (in pixels) + @param[in] Height Height + + @retval EFI_DEVICE_ERROR A hardware error occured + @retval EFI_INVALID_PARAMETER Invalid parameter passed in + @retval EFI_SUCCESS Blt operation success + +**/ +EFI_STATUS +EFIAPI +BltVideoToVideo ( + IN VOID *FrameBuffer, + IN EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *FrameBufferInfo, + IN UINTN SourceX, + IN UINTN SourceY, + IN UINTN DestinationX, + IN UINTN DestinationY, + IN UINTN Width, + IN UINTN Height + ) +{ + EFI_STATUS Status; + UINT8 *Source; + UINT8 *Destination; + UINTN Offset; + UINTN WidthInBytes; + INTN LineStride; + UINT8 BytesPerPixel; + + // + // Video to Video: Source is Video, destination is Video + // + Status = BltLibVerifyLocation (FrameBufferInfo, SourceX, SourceY, Width, Height); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = BltLibVerifyLocation (FrameBufferInfo, DestinationX, DestinationY, Width, Height); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = BltLibParsePixelFormat ( + FrameBufferInfo->PixelFormat, + &FrameBufferInfo->PixelInformation, + NULL, NULL, NULL, &BytesPerPixel + ); + if (EFI_ERROR (Status)) { + return Status; + } + + WidthInBytes = Width * BytesPerPixel; + + Offset = ((SourceY * FrameBufferInfo->PixelsPerScanLine) + SourceX) * BytesPerPixel; + Source = (UINT8 *) FrameBuffer + Offset; + + Offset = ((DestinationY * FrameBufferInfo->PixelsPerScanLine) + DestinationX) * BytesPerPixel; + Destination = (UINT8 *) FrameBuffer + Offset; + + LineStride = FrameBufferInfo->PixelsPerScanLine * BytesPerPixel; + if (Destination > Source) { + // + // Copy from last line to avoid source is corrupted by copying + // + Source += Height * LineStride; + Destination += Height * LineStride; + LineStride = -LineStride; + } + + while (Height-- > 0) { + CopyMem (Destination, Source, WidthInBytes); + + Source += LineStride; + Destination += LineStride; + } + + return EFI_SUCCESS; +} diff --git a/BraswellPlatformPkg/Common/FspSupport/Library/FrameBufferBltLib/FrameBufferBltLib.inf b/BraswellPlatformPkg/Common/FspSupport/Library/FrameBufferBltLib/FrameBufferBltLib.inf new file mode 100644 index 0000000000..ec6fdbcf1c --- /dev/null +++ b/BraswellPlatformPkg/Common/FspSupport/Library/FrameBufferBltLib/FrameBufferBltLib.inf @@ -0,0 +1,33 @@ +## @file +# FrameBufferBltLib - Library to perform blt operations on a frame buffer. +# +# Copyright (c) 2006 - 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 = FrameBufferBltLib + FILE_GUID = 2a40f516-c852-4baa-b7a8-0e9ea090d659 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = BltLib + +[Sources.common] + FrameBufferBltLib.c + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + +[Packages] + MdePkg/MdePkg.dec diff --git a/BraswellPlatformPkg/Common/FspSupport/Library/PeiFspHobProcessLib/FspHobProcessLib.c b/BraswellPlatformPkg/Common/FspSupport/Library/PeiFspHobProcessLib/FspHobProcessLib.c new file mode 100644 index 0000000000..8fb53c526d --- /dev/null +++ b/BraswellPlatformPkg/Common/FspSupport/Library/PeiFspHobProcessLib/FspHobProcessLib.c @@ -0,0 +1,528 @@ +/** @file + Null instance of Platform Sec Lib. + + Copyright (c) 2014 - 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FspUpdVpd.h" +#include +#include + +extern EFI_GUID gFspSmbiosMemoryInfoHobGuid; + +typedef struct { + UINT32 RegEax; + UINT32 RegEbx; + UINT32 RegEcx; + UINT32 RegEdx; +} EFI_CPUID_REGISTER; + +#include +#include +EFI_GUID gFspReservedMemoryResourceHobTsegGuid = {0xd038747c, 0xd00c, 0x4980, {0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55}}; +EFI_GUID gEfiMemoryConfigDataGuid = { 0x80dbd530, 0xb74c, 0x4f11, {0x8c, 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31}}; +EFI_GUID gDummyGuid = { 0x00000000, 0xb74c, 0x4f11, {0x8c, 0x03, 0x41, 0x86, 0x65, 0x53, 0x28, 0x31}}; + +EFI_MEMORY_TYPE_INFORMATION mDefaultMemoryTypeInformation[] = { + { EfiACPIReclaimMemory, 0x2B }, // ASL + { EfiACPIMemoryNVS, 0xCF }, // ACPI NVS + { EfiReservedMemoryType, 0xC8 }, // BIOS Reserved + { EfiRuntimeServicesCode, 0x39 }, + { EfiRuntimeServicesData, 0x50 }, + { EfiMaxMemoryType, 0 } +}; + +// +// Additional pages are used by DXE memory manager. +// It should be consistent between RetrieveRequiredMemorySize() and GetPeiMemSize() +// +#define PEI_ADDITIONAL_MEMORY_SIZE (16 * EFI_PAGE_SIZE) + +EFI_STATUS +PlatformHobCreateFromFsp ( + IN CONST EFI_PEI_SERVICES **PeiServices, + VOID *HobList + ) +{ + return EFI_SUCCESS; +} + +/** + Get the mem size in memory type infromation table. + + @param[in] PeiServices PEI Services table. + + @return the mem size in memory type infromation table. +**/ +UINT64 +GetMemorySizeInMemoryTypeInformation ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + EFI_PEI_HOB_POINTERS Hob; + EFI_MEMORY_TYPE_INFORMATION *MemoryData; + UINT8 Index; + UINTN TempPageNum; + + MemoryData = NULL; + + Status = (*PeiServices)->GetHobList (PeiServices, (VOID **) &Hob.Raw); + while (!END_OF_HOB_LIST (Hob)) { + if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION && + CompareGuid (&Hob.Guid->Name, &gEfiMemoryTypeInformationGuid)) { + MemoryData = (EFI_MEMORY_TYPE_INFORMATION *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID)); + break; + } + + Hob.Raw = GET_NEXT_HOB (Hob); + } + + if (MemoryData == NULL) { + return 0; + } + + TempPageNum = 0; + for (Index = 0; MemoryData[Index].Type != EfiMaxMemoryType; Index++) { + // + // Accumulate default memory size requirements + // + TempPageNum += MemoryData[Index].NumberOfPages; + } + + return TempPageNum * EFI_PAGE_SIZE; +} + +/** + Get the mem size need to be reserved in PEI phase. + + @param[in] PeiServices PEI Services table. + + @return the mem size need to be reserved in PEI phase. +**/ +UINT64 +RetrieveRequiredMemorySize ( + IN EFI_PEI_SERVICES **PeiServices + ) +{ + UINT64 Size; + + Size = GetMemorySizeInMemoryTypeInformation (PeiServices); + + return Size + PEI_ADDITIONAL_MEMORY_SIZE; +} + +/** + Get the mem size need to be consumed and reserved in PEI phase. + + @param[in] PeiServices PEI Services table. + @param[in] BootMode Current boot mode. + + @return the mem size need to be consumed and reserved in PEI phase. +**/ +UINT64 +GetPeiMemSize ( + IN EFI_PEI_SERVICES **PeiServices, + IN UINT32 BootMode + ) +{ + UINT64 Size; + UINT64 MinSize; + + if (BootMode == BOOT_IN_RECOVERY_MODE) { + return PcdGet32 (PcdPeiRecoveryMinMemSize); + } + + Size = GetMemorySizeInMemoryTypeInformation (PeiServices); + + if (BootMode == BOOT_ON_FLASH_UPDATE) { + // + // Maybe more size when in CapsuleUpdate phase ? + // + MinSize = PcdGet32 (PcdPeiMinMemSize); + } else { + MinSize = PcdGet32 (PcdPeiMinMemSize); + } + + return MinSize + Size + PEI_ADDITIONAL_MEMORY_SIZE; +} + +EFI_STATUS +GetS3AcpiReservedMemory ( + IN EFI_PHYSICAL_ADDRESS TsegBase, + OUT EFI_PHYSICAL_ADDRESS *S3PeiMemBase, + OUT UINT64 *S3PeiMemSize +) +{ + RESERVED_ACPI_S3_RANGE *AcpiS3Range; + + AcpiS3Range = (RESERVED_ACPI_S3_RANGE*) (UINTN) (TsegBase + RESERVED_ACPI_S3_RANGE_OFFSET); + *S3PeiMemBase = (EFI_PHYSICAL_ADDRESS)(AcpiS3Range->AcpiReservedMemoryBase); + *S3PeiMemSize = (UINT64) (AcpiS3Range->AcpiReservedMemorySize); + + return EFI_SUCCESS; +} + +/** + BIOS process FspBobList. + + @param[in] FspHobList Pointer to the HOB data structure produced by FSP. + + @return If platform process the FSP hob list successfully. +**/ +EFI_STATUS +EFIAPI +FspHobProcessForMemoryResource ( + IN VOID *FspHobList + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_PEI_HOB_POINTERS PeiMemoryHob; + UINT64 FspMemorySize; + EFI_PHYSICAL_ADDRESS FspMemoryBase; + UINT64 RequiredMemSize; + BOOLEAN FoundFspMemHob; + EFI_STATUS Status; + EFI_BOOT_MODE BootMode; + EFI_PEI_SERVICES **PeiServices; + UINT64 TsegSize; + EFI_PHYSICAL_ADDRESS TsegBase; + BOOLEAN FoundTsegHob; + UINT64 PeiMemSize; + EFI_PHYSICAL_ADDRESS PeiMemBase; + PEI_CAPSULE_PPI *Capsule; + VOID *CapsuleBuffer; + UINTN CapsuleBufferLength; + + + PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (); + + PeiServicesGetBootMode (&BootMode); + + PeiMemoryHob.ResourceDescriptor = NULL; + PeiMemBase = BASE_512MB; + PeiMemSize = BASE_256MB; + RequiredMemSize = BASE_128MB; // initial DXE required memory + FspMemorySize = 0; + FspMemoryBase = 0; + FoundFspMemHob = FALSE; + TsegSize = 0; + TsegBase = 0; + FoundTsegHob = FALSE; + CapsuleBufferLength = 0; + CapsuleBuffer = NULL; + Capsule = NULL; + + if (BootMode == BOOT_ON_S3_RESUME) { + Status = PeiServicesLocatePpi ( + &gPeiCapsulePpiGuid, + 0, + NULL, + (VOID **) &Capsule + ); + if (!EFI_ERROR(Status)) { + Status = Capsule->CheckCapsuleUpdate(PeiServices); + // + // Capsule exists, switch boot mode to Flash Update + // + if (Status == EFI_SUCCESS) { + BootMode = BOOT_ON_FLASH_UPDATE; + PeiServicesSetBootMode(BootMode); + } + } + } + + // + // Parse the hob list from fsp + // Report all the memory resource hob. + // + Hob.Raw = (UINT8 *)(UINTN)FspHobList; + DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList)); + + while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) { + DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType)); + if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) || + (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) { + DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute)); + DEBUG((DEBUG_INFO, "PhysicalStart: 0x%lx\n", Hob.ResourceDescriptor->PhysicalStart)); + DEBUG((DEBUG_INFO, "ResourceLength: 0x%lx\n", Hob.ResourceDescriptor->ResourceLength)); + DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner)); + } + + if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) { + BuildResourceDescriptorHob ( + Hob.ResourceDescriptor->ResourceType, + Hob.ResourceDescriptor->ResourceAttribute, + Hob.ResourceDescriptor->PhysicalStart, + Hob.ResourceDescriptor->ResourceLength + ); + + if ((Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB) + && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB) + && (Hob.ResourceDescriptor->ResourceLength) >= PeiMemSize + RequiredMemSize) { + PeiMemBase = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength - PeiMemSize - RequiredMemSize; + // + // Record Pei Memory Hob + // + PeiMemoryHob = Hob; + } + } + + if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length below 4G + && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB) + && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB) + && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) { + FoundFspMemHob = TRUE; + FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart; + FspMemorySize = Hob.ResourceDescriptor->ResourceLength; + DEBUG((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize)); + } + + if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found Tseg + && (Hob.ResourceDescriptor->PhysicalStart >= 0x100000) + && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= 0x100000000) + && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobTsegGuid))) { + FoundTsegHob = TRUE; + TsegBase = Hob.ResourceDescriptor->PhysicalStart; + + if ((Hob.ResourceDescriptor->ResourceLength == 0 ) || (Hob.ResourceDescriptor->ResourceLength > 0x800000)){ + Hob.ResourceDescriptor->ResourceLength = 0x800000; + } + + TsegSize = Hob.ResourceDescriptor->ResourceLength; + DEBUG((EFI_D_ERROR, "Find Tseg mem hob, base 0x%lx, len 0x%lx\n", TsegBase, TsegSize)); + } + + Hob.Raw = GET_NEXT_HOB (Hob); + } + + if (!FoundFspMemHob) { + DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n")); + } + + if (BootMode == BOOT_ON_FLASH_UPDATE) { + Hob.Raw = (UINT8 *)(UINTN)FspHobList; + // + // Find the largest memory range excluding that given to Capsule. + // + while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) { + + if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY + && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB) + && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB) + ) { + if (PeiMemoryHob.ResourceDescriptor != Hob.ResourceDescriptor) { + if (Hob.ResourceDescriptor->ResourceLength > CapsuleBufferLength) { + CapsuleBuffer = (VOID *) ((UINTN) Hob.ResourceDescriptor->PhysicalStart); + CapsuleBufferLength = (UINTN)Hob.ResourceDescriptor->ResourceLength; + } + } else { + if ((Hob.ResourceDescriptor->ResourceLength - PeiMemSize- RequiredMemSize) >= CapsuleBufferLength) { + CapsuleBuffer = (VOID *) ((UINTN) Hob.ResourceDescriptor->PhysicalStart); + CapsuleBufferLength = (UINTN)(Hob.ResourceDescriptor->ResourceLength - PeiMemSize - RequiredMemSize); + } + } + } + + Hob.Raw = GET_NEXT_HOB (Hob); + } + + // + // Call the Capsule PPI Coalesce function to coalesce the capsule data. + // + Status = Capsule->Coalesce ((EFI_PEI_SERVICES **)PeiServices, &CapsuleBuffer, &CapsuleBufferLength); + + DEBUG((DEBUG_INFO, "Capsule Buffer: 0x%x, Length : 0x%x\n", CapsuleBuffer, CapsuleBufferLength)); + } + + if (BootMode == BOOT_ON_S3_RESUME) { + DEBUG ((EFI_D_INFO, "Install S3 Memory. \n")); + Status = GetS3AcpiReservedMemory(TsegBase, &PeiMemBase, &PeiMemSize); + ASSERT_EFI_ERROR (Status); + } else { + DEBUG ((EFI_D_INFO, "Install Normal Boot Mmeory. \n")); + } + DEBUG ((EFI_D_INFO, "PeiMemBase = %0x\n", PeiMemBase)); + DEBUG ((EFI_D_INFO, "PeiMemSize = %0x\n", PeiMemSize)); + + Status = PeiServicesInstallPeiMemory (PeiMemBase, PeiMemSize); + ASSERT_EFI_ERROR (Status); + + if (BootMode == BOOT_ON_FLASH_UPDATE && Capsule != NULL) { + Status = Capsule->CreateState ((EFI_PEI_SERVICES **)PeiServices, CapsuleBuffer, CapsuleBufferLength); + DEBUG((EFI_D_INFO, "Capsule CreateState :%d\n", Status)); + } + + return EFI_SUCCESS; +} + +typedef struct { + EFI_GUID *Guid; + BOOLEAN NeedTransfer; +} FSP_TRANSFER_HOB_LIST; + +FSP_TRANSFER_HOB_LIST mFspTransferHobList[] = { + {&gFspNonVolatileStorageHobGuid, TRUE}, // This HOB stores MRC parameters for S3 resume. + {&gFspBootLoaderTemporaryMemoryGuid, TRUE}, + {&gEfiPlatformCpuInfoGuid, TRUE}, + {&gEfiMemoryConfigDataGuid, FALSE}, // This HOB stores MRC parameters for S3 resume. + {&gEfiVariableGuid, TRUE}, + {&gEfiSmmPeiSmramMemoryReserveGuid, TRUE}, // Handled by FspHobProcessForMemoryResource(). + {&gEfiAcpiVariableGuid, TRUE}, // For S3 save/resume. + {&gFspSmbiosMemoryInfoHobGuid, TRUE}, + {&gEfiGraphicsInfoHobGuid, TRUE}, + {&gEfiPlatformInfoGuid, TRUE}, +}; + +BOOLEAN +GetFspGuidHobTransferFlag ( + IN EFI_GUID *Guid + ) +{ + UINTN Index; + for (Index = 0; Index < sizeof(mFspTransferHobList)/sizeof(mFspTransferHobList[0]); Index++) { + if (CompareGuid(Guid, mFspTransferHobList[Index].Guid)) { + return mFspTransferHobList[Index].NeedTransfer; + } + } + return FALSE; +} + +VOID +TransferFspHobs ( + IN VOID *FspHobList +) +{ + EFI_PEI_HOB_POINTERS FspHob; + EFI_PEI_HOB_POINTERS DxeHob; + BOOLEAN TransferFlag; + + // + // Get the HOB list for processing. + // + FspHob.Raw = (VOID *)FspHobList; + + // + // Go through HOBs produced by FSP and pass them to UEFI BIOS. + // + while (!END_OF_HOB_LIST (FspHob)) { + + TransferFlag = FALSE; + + if (FspHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) { + + // + // GUID HOB. + // + TransferFlag = GetFspGuidHobTransferFlag (&FspHob.Guid->Name); + + if (TransferFlag) { + DEBUG ((DEBUG_INFO, "FSP Extended GUID HOB: {%g}\n", &(FspHob.Guid->Name))); + DEBUG ((DEBUG_INFO, " HOB Length: %x\n", (UINT32)(FspHob.Header->HobLength))); + } + + } else if ((FspHob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) && + (FspHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) { + + // + // Reserved Memory Resource HOB. + // + DEBUG ((DEBUG_INFO, "FSP Reserved Memory Resource HOB: %016lX ~ %016lX\n", \ + FspHob.ResourceDescriptor->PhysicalStart, FspHob.ResourceDescriptor->PhysicalStart \ + + FspHob.ResourceDescriptor->ResourceLength)); + + TransferFlag = TRUE; + } + + // + // Pass FSP HOB to UEFI BIOS. + // + if (TransferFlag) { + PeiServicesCreateHob (EFI_HOB_TYPE_UNUSED, FspHob.Header->HobLength, &(DxeHob.Raw)); + CopyMem (DxeHob.Raw, FspHob.Raw, FspHob.Header->HobLength); + } + + FspHob.Raw = GET_NEXT_HOB (FspHob); + } + + return; +} + +/** + BIOS process FspBobList for other data (not Memory Resource Descriptor). + + @param[in] FspHobList Pointer to the HOB data structure produced by FSP. + + @return If platform process the FSP hob list successfully. +**/ +EFI_STATUS +EFIAPI +FspHobProcessForOtherData ( + IN VOID *FspHobList + ) +{ + EFI_PEI_SERVICES **PeiServices; + + PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (); + + // + // Other hob for platform + // + PlatformHobCreateFromFsp ( PeiServices, FspHobList); + + TransferFspHobs (FspHobList); + + return EFI_SUCCESS; +} + +/** + BIOS process FspBobList. + + @param[in] FspHobList Pointer to the HOB data structure produced by FSP. + + @return If platform process the FSP hob list successfully. +**/ +EFI_STATUS +EFIAPI +FspHobProcess ( + IN VOID *FspHobList + ) +{ + EFI_STATUS Status; + + BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof (mDefaultMemoryTypeInformation) ); + + Status = FspHobProcessForMemoryResource (FspHobList); + if (EFI_ERROR (Status)) { + return Status; + } + Status = FspHobProcessForOtherData (FspHobList); + + return Status; +} diff --git a/BraswellPlatformPkg/Common/FspSupport/Library/PeiFspHobProcessLib/PeiFspHobProcessLib.inf b/BraswellPlatformPkg/Common/FspSupport/Library/PeiFspHobProcessLib/PeiFspHobProcessLib.inf new file mode 100644 index 0000000000..dbcec14726 --- /dev/null +++ b/BraswellPlatformPkg/Common/FspSupport/Library/PeiFspHobProcessLib/PeiFspHobProcessLib.inf @@ -0,0 +1,122 @@ +## @file +# +# 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. +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeiFspHobProcessLib + FILE_GUID = C7B7070B-E5A8-4b86-9110-BDCA1095F496 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspHobProcessLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +################################################################################ +# +# Sources Section - list of files that are required for the build to succeed. +# +################################################################################ + +[Sources] + FspHobProcessLib.c + + +################################################################################ +# +# Package Dependency Section - list of Package files that are required for +# this module. +# +################################################################################ + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + IntelFspPkg/IntelFspPkg.dec + IntelFspWrapperPkg/IntelFspWrapperPkg.dec + BraswellPlatformPkg/BraswellPlatformPkg.dec + ChvRefCodePkg/ChvRefCodePkg.dec + ChvFspBinPkg/ChvFspBinPkg.dec + + +[LibraryClasses] + BaseLib + BaseMemoryLib + HobLib + DebugLib + FspPlatformInfoLib + PeiServicesLib + PeiServicesTablePointerLib + +[Pcd] + ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdPeiMinMemSize + + ## CONSUMES + gFspWrapperTokenSpaceGuid.PcdPeiRecoveryMinMemSize + +[Guids] + ## PRODUCES ## HOB + gFspReservedMemoryResourceHobGuid + + ## SOMETIMES_CONSUMES + ## PRODUCES ## HOB + gEfiMemoryTypeInformationGuid + + ## PRODUCES ## HOB + gEfiSmmPeiSmramMemoryReserveGuid + + ## SOMETIMES_CONSUMES ## HOB + ## PRODUCES ## HOB + gEfiPlatformCpuInfoGuid + + ## SOMETIMES_CONSUMES ## Guid + gEfiVariableGuid + + ## PRODUCES ## HOB + gEfiAcpiVariableGuid + + ## SOMETIMES_CONSUMES ## Guid + gFspBootLoaderTemporaryMemoryGuid + + ## SOMETIMES_CONSUMES ## Guid + gFspNonVolatileStorageHobGuid + + ## SOMETIMES_CONSUMES ## Guid + gEfiGraphicsInfoHobGuid + + ## SOMETIMES_CONSUMES ## Guid + gFspSmbiosMemoryInfoHobGuid + + ## SOMETIMES_CONSUMES ## Guid + gEfiPlatformInfoGuid + ## SOMETIMES_CONSUMES ## Guid + gEfiPlatformInfoGuid + +[Ppis] + ## SOMETIMES_CONSUMES + gPeiCapsulePpiGuid + +[Depex] + gPeiCapsulePpiGuid -- cgit v1.2.3