summaryrefslogtreecommitdiff
path: root/BraswellPlatformPkg/Common
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-08-03 09:59:56 +0800
committerGuo Mang <mang.guo@intel.com>2016-08-04 10:29:57 +0800
commit2c85c3eefbcd21b02e73bf2054ecfcdcbcbe1f01 (patch)
tree71e5e269d6af36acc1c7a83fd71e2356d3fe47da /BraswellPlatformPkg/Common
parent64fffaae10db55389ff69dbbfeb3c15aa8af5ea2 (diff)
downloadedk2-platforms-2c85c3eefbcd21b02e73bf2054ecfcdcbcbe1f01.tar.xz
BraswellPlatformPkg: Move FspSupport to Common/FspSupport
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com> Reviewed-by: David Wei <david.wei@intel.com>
Diffstat (limited to 'BraswellPlatformPkg/Common')
-rw-r--r--BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/BltLib.h148
-rw-r--r--BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/ComponentName.c190
-rw-r--r--BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutput.c664
-rw-r--r--BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutput.h52
-rw-r--r--BraswellPlatformPkg/Common/FspSupport/GraphicsOutputDxe/GraphicsOutputDxe.inf58
-rw-r--r--BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/BaseFspPlatformInfoLibSample.inf124
-rw-r--r--BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/FspPlatformInfoLibSample.c591
-rw-r--r--BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/MemoryMappedVariable.c1132
-rw-r--r--BraswellPlatformPkg/Common/FspSupport/Library/BaseFspPlatformInfoLibSample/MemoryMappedVariable.h148
-rw-r--r--BraswellPlatformPkg/Common/FspSupport/Library/FrameBufferBltLib/FrameBufferBltLib.c572
-rw-r--r--BraswellPlatformPkg/Common/FspSupport/Library/FrameBufferBltLib/FrameBufferBltLib.inf33
-rw-r--r--BraswellPlatformPkg/Common/FspSupport/Library/PeiFspHobProcessLib/FspHobProcessLib.c528
-rw-r--r--BraswellPlatformPkg/Common/FspSupport/Library/PeiFspHobProcessLib/PeiFspHobProcessLib.inf122
13 files changed, 4362 insertions, 0 deletions
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.<BR>
+
+ 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 <Protocol/GraphicsOutput.h>
+
+/**
+ 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.<BR>
+
+ 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 <PiDxe.h>
+#include <Library/UefiLib.h>
+
+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.<BR>
+
+ 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.<BR>
+
+ 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 <PiDxe.h>
+#include <IndustryStandard/Pci.h>
+#include <IndustryStandard/Acpi.h>
+#include <Guid/GraphicsInfoHob.h>
+#include <Protocol/DriverBinding.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/ComponentName.h>
+#include <Protocol/ComponentName2.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/DevicePathLib.h>
+#include "BltLib.h"
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiLib.h>
+
+#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.<BR>
+#
+# 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.<BR>
+#
+# 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.<BR>
+
+ 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 <PiPei.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/FspApiLib.h>
+#include <Library/PcdLib.h>
+#include <FspUpdVpd.h>
+#include <Library/GpioLib.h>
+#include <Library/HobLib.h>
+#include <Guid/SetupVariable.h>
+#include <Guid/PlatformInfo.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/ChvPlatformPolicyPpi.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/PchPlatformPolicy.h>
+#include <Protocol/PlatformGopPolicy.h>
+#include <Guid/AcpiVariableCompatibility.h>
+#include <Guid/PlatformInfo.h>
+#include <MemoryMappedVariable.h>
+#include <Guid/Chv2Variable.h>
+
+
+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.<BR>
+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.<BR>
+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 <PiPei.h>
+#include <Ppi/ReadOnlyVariable2.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PeiServicesLib.h>
+
+#include <Guid/VariableFormat.h>
+#include <Guid/VariableIndexTable.h>
+#include <Guid/SystemNvDataGuid.h>
+#include <Guid/FaultTolerantWrite.h>
+
+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.<BR>
+
+ 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 <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Protocol/GraphicsOutput.h>
+
+#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.<BR>
+#
+# 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.<BR>
+
+ 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 <PiPei.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/FspPlatformInfoLib.h>
+#include <Guid/GuidHobFsp.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <Ppi/Capsule.h>
+#include <Guid/SmramMemoryReserve.h>
+#include <Guid/GuidHobFspEas.h>
+#include <Guid/AcpiS3Context.h>
+#include <Guid/VariableFormat.h>
+#include <Guid/GraphicsInfoHob.h>
+#include "FspUpdVpd.h"
+#include <ReservedAcpiS3Range.h>
+#include <Guid/PlatformInfo.h>
+
+extern EFI_GUID gFspSmbiosMemoryInfoHobGuid;
+
+typedef struct {
+ UINT32 RegEax;
+ UINT32 RegEbx;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+} EFI_CPUID_REGISTER;
+
+#include <CpuRegs.h>
+#include <Guid/PlatformCpuInfo.h>
+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.<BR>
+#
+# 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